01 What is Emacs?
GNU Emacs is a self-documenting, extensible, customizable text editor — and much more. Originally written by Richard Stallman in the 1970s, it is one of the oldest continuously maintained programs in existence. On a Mac, Emacs functions as a full-featured editor, IDE, file manager, email client, calendar, shell, and anything else you can build with Emacs Lisp.
Editor
World-class text editing with syntax highlighting, completion, and language modes for every language.
Extensible
Everything is customizable in Emacs Lisp — keybindings, UI, behavior. If it doesn't exist, write it.
Self-documenting
Every function, variable, and keybinding is discoverable at runtime via the built-in help system.
Long-running
Emacs is designed to run for weeks or months. Your state persists across files and sessions.
macOS is a UNIX-based system that pairs naturally with Emacs' terminal heritage. Native Emacs builds leverage macOS features: Retina display support, native full-screen, smooth scrolling, macOS spell-check, system pasteboard integration, and the macOS font rendering stack.
02 Installation
There are three main ways to install Emacs on macOS. Each has different trade-offs between macOS native integration and build freshness.
Option A — Emacs for Mac OS X (Recommended for beginners)
A pre-built native macOS application with no dependencies. Download the .dmg from emacsformacosx.com — drag it to your Applications folder and launch it like any Mac app.
After downloading, macOS Gatekeeper may warn you about an unidentified developer. Open System Settings → Privacy & Security and click Open Anyway. This is safe — Emacs is open-source.
Option B — Homebrew (Recommended for developers)
Homebrew gives you a current build with the most control. First install Homebrew if you haven't, then choose one of:
# Standard Emacs (no native macOS GUI frame features) $ brew install emacs # Emacs with full macOS native features (recommended) $ brew install --cask emacs # emacs-mac: native port with best macOS integration $ brew tap railwaycat/emacsmacport $ brew install emacs-mac --with-natural-title-bar
Option C — Emacs Plus (feature-rich Homebrew formula)
$ brew tap d12frosted/emacs-plus $ brew install emacs-plus@29 \ --with-xwidgets \ --with-imagemagick \ --with-native-comp \ --with-modern-doom3-icon
Verifying the installation
$ emacs --version # GNU Emacs 29.4 $ which emacs # /opt/homebrew/bin/emacs (Apple Silicon) # /usr/local/bin/emacs (Intel Mac)
If emacs isn't found in your terminal, add Homebrew to your PATH. In your ~/.zshrc: export PATH="/opt/homebrew/bin:$PATH" (Apple Silicon) or export PATH="/usr/local/bin:$PATH" (Intel). Then restart your terminal or run source ~/.zshrc.
03 First Launch
Launch Emacs from your Applications folder, Spotlight (⌘Space), or from the terminal:
# Open Emacs GUI from terminal $ open -a Emacs # Open a specific file in GUI Emacs $ emacs myfile.txt & # Open Emacs in the terminal (no GUI) $ emacs -nw myfile.txt
When Emacs opens for the first time you'll see the splash screen. Press q to dismiss it or any key to begin editing.
Understanding what you see
The mode line (the line above the status bar) shows: file status, buffer name, cursor position, and active major/minor modes. The bottom area is the minibuffer — Emacs' command line for input and messages.
To quit Emacs: C-x C-c (hold Control, press x, then hold Control, press c). If you're stuck in a command, press C-g to cancel. These two keys will save you endlessly as a beginner.
04 Core Concepts
Buffer
A buffer holds text in memory. Every file you open becomes a buffer, but buffers can also hold output, help, or scratch text without a file.
Window
A pane displaying a buffer inside the Emacs frame. You can split windows horizontally or vertically. Multiple windows can show the same buffer.
Frame
What macOS calls a "window" — the OS-level window. Emacs can have multiple frames, each with multiple windows.
Minibuffer
The single-line input area at the bottom of each frame. Used for commands, file names, search terms, and Emacs messages.
Mode
Every buffer has one major mode (e.g. python-mode) and any number of minor modes that add features (e.g. auto-save-mode).
Point & Mark
The point is the cursor position. The mark is a saved position. The region between point and mark is the active region (selection).
Kill Ring
Emacs' clipboard history. Killed (cut) or copied text is pushed onto the kill ring. You can yank (paste) any previous entry.
Prefix Arguments
C-u followed by a number before a command repeats it N times. C-u alone multiplies by 4 (default).
The *scratch* buffer
When Emacs starts, it shows the *scratch* buffer in lisp-interaction-mode. This is a live Lisp REPL — you can type any Emacs Lisp expression, press C-j to evaluate it and see the result below, or C-x C-e to evaluate and show in the minibuffer.
05 Key Notation
Emacs uses a compact notation for its key bindings. On macOS the physical keys are:
| Emacs Notation | Mac Key | Notes |
|---|---|---|
| C- | ⌃ Control | Hold Control while pressing the next key |
| M- | ⌥ Option or ESC | Option is Meta on Mac; ESC is an alternative |
| s- | ⌘ Command | Super key — macOS-specific bindings |
| S- | ⇧ Shift | Used in combinations: C-S-f |
| RET | ⏎ Return | Enter/Return key |
| SPC | Space bar | Space character |
| DEL | ⌫ Delete | Backspace (deletes backward) |
| TAB | ⇥ Tab | Tab key (indent or complete) |
Reading key sequences
A sequence like C-x C-f means: hold ⌃ and press x, release, then hold ⌃ and press f. A sequence like C-x b means: hold ⌃ and press x, release both, then press b alone.
By default, Terminal.app may not send Option as Meta. Fix this: in Terminal → Settings → Profiles → Keyboard, check "Use Option as Meta key". In iTerm2: Preferences → Profiles → Keys, set Left/Right Option Key to Esc+. In the GUI Emacs app, Option works as Meta automatically.
06 Navigation
Character & word movement
| Key | Action |
|---|---|
| C-f | Forward one character → |
| C-b | Backward one character ← |
| M-f | Forward one word |
| M-b | Backward one word |
| C-n | Next line ↓ |
| C-p | Previous line ↑ |
| C-a | Beginning of line |
| C-e | End of line |
Sentence & paragraph
| Key | Action |
|---|---|
| M-a | Beginning of sentence |
| M-e | End of sentence |
| M-{ | Beginning of paragraph |
| M-} | End of paragraph |
Buffer-level navigation
| Key | Action |
|---|---|
| M-< | Go to beginning of buffer |
| M-> | Go to end of buffer |
| M-g g | Go to line number (prompts) |
| M-g c | Go to character position |
| C-v | Scroll down one screenful |
| M-v | Scroll up one screenful |
| C-l | Recentre cursor (top/middle/bottom) |
Prefix a movement with C-u + a number to repeat it. For example, C-u 10 C-n moves down 10 lines. C-u 5 M-f moves forward 5 words.
07 Editing
Deleting text
| Key | Action |
|---|---|
| DEL | Delete character before point (backspace) |
| C-d | Delete character after point (forward delete) |
| M-DEL | Kill (cut) word before point |
| M-d | Kill word after point |
| C-k | Kill to end of line |
| M-k | Kill to end of sentence |
| C-S-DEL | Kill entire current line |
Kill ring (cut, copy, paste)
| Key | Action |
|---|---|
| C-w | Kill (cut) the selected region |
| M-w | Copy the selected region (save without killing) |
| C-y | Yank (paste) most recent kill |
| M-y | After C-y, cycle through kill ring history |
In a native Emacs GUI build, ⌘ C, ⌘ V, and ⌘ X work as standard Mac clipboard shortcuts and are synced with the system clipboard. The Emacs kill ring and the macOS clipboard are separate; Emacs automatically syncs the most recent kill to the system clipboard.
Transposing
| Key | Action |
|---|---|
| C-t | Transpose characters around point |
| M-t | Transpose words around point |
| C-x C-t | Transpose current and previous lines |
Case changing
| Key | Action |
|---|---|
| M-u | Uppercase word |
| M-l | Lowercase word |
| M-c | Capitalize word (first letter uppercase) |
| C-x C-u | Uppercase the selected region |
| C-x C-l | Lowercase the selected region |
Indentation & filling
| Key | Action |
|---|---|
| TAB | Indent current line (context-aware) |
| C-M-\ | Indent selected region |
| M-q | Re-fill paragraph to fill-column width |
| C-x f | Set fill column width |
08 Files & Buffers
File operations
| Key | Action |
|---|---|
| C-x C-f | Find file (open or create) |
| C-x C-s | Save current buffer |
| C-x C-w | Save as (write to new name) |
| C-x s | Save all modified buffers (prompts each) |
| C-x C-r | Open file read-only |
| C-x C-q | Toggle read-only on current buffer |
| C-x i | Insert a file at point |
Buffer operations
| Key | Action |
|---|---|
| C-x b | Switch to buffer (prompts for name) |
| C-x C-b | List all open buffers |
| C-x k | Kill (close) a buffer |
| C-x Left | Previous buffer |
| C-x Right | Next buffer |
| M-x revert-buffer | Reload file from disk |
The Buffer Menu (*Buffer List*)
When you open the buffer list with C-x C-b, you can manage all buffers in that window:
- d — mark buffer for deletion
- x — execute deletions
- s — save buffer
- o — open buffer in other window
- g — refresh the list
- q — quit the buffer list
Dired — the built-in file manager
Open a directory with C-x C-f to launch Dired. Navigate and manipulate files:
;; Open current directory in Dired M-x dired RET ~ RET ; opens home directory
| Key in Dired | Action |
|---|---|
| n / p | Next / previous file |
| RET | Open file or directory |
| d | Mark for deletion |
| R | Rename / move file |
| C | Copy file |
| + | Create new directory |
| x | Execute marked actions |
| q | Quit Dired |
09 Windows & Frames
Window splitting
| Key | Action |
|---|---|
| C-x 2 | Split window horizontally (top/bottom) |
| C-x 3 | Split window vertically (left/right) |
| C-x 0 | Delete current window |
| C-x 1 | Delete all other windows (maximize current) |
| C-x o | Move to other window |
| C-x ^ | Enlarge window vertically |
| C-x } | Widen window horizontally |
| C-x { | Narrow window horizontally |
Frame operations
| Key | Action |
|---|---|
| C-x 5 2 | Create a new frame (macOS window) |
| C-x 5 0 | Delete current frame |
| C-x 5 o | Switch to other frame |
| C-x 5 f | Find file in new frame |
Use ⌘ ⌃ F to toggle native macOS full-screen mode (or the green maximize button). With emacs-mac port, each frame can individually enter full-screen — great for distraction-free writing.
Window configuration recall
| Key | Action |
|---|---|
| C-x r w r | Save window config to register r |
| C-x r j r | Restore window config from register r |
10 Search & Replace
Incremental search
| Key | Action |
|---|---|
| C-s | Incremental search forward (type to search) |
| C-r | Incremental search backward |
| C-s again | Find next match (during search) |
| C-r again | Find previous match |
| RET | End search, stay at current match |
| C-g | Cancel search, return to start |
| M-s o | occur — list all lines matching pattern |
Regexp search
| Key | Action |
|---|---|
| C-M-s | Regexp incremental search forward |
| C-M-r | Regexp incremental search backward |
| M-x re-search-forward | Non-incremental regexp search |
Replace
| Key | Action |
|---|---|
| M-% | Query-replace (prompts for old and new text) |
| C-M-% | Query-replace with regexp |
| M-x replace-string | Replace all occurrences (no prompting) |
| M-x replace-regexp | Replace regexp (no prompting) |
During query-replace, press:
- y or SPC — replace this occurrence
- n or DEL — skip this occurrence
- ! — replace all remaining without asking
- q or RET — quit query-replace
- . — replace this one, then quit
- ^ — go back to previous occurrence
- e — edit the replacement string
11 The Help System
Emacs is entirely self-documenting. Every key, function, and variable has documentation you can access instantly.
| Key | Action |
|---|---|
| C-h t | Open the interactive Emacs tutorial (start here!) |
| C-h k | Describe a key: press the key to see what it does |
| C-h f | Describe a function by name |
| C-h v | Describe a variable by name |
| C-h m | Describe current major and minor modes |
| C-h a | Apropos — search for commands matching a pattern |
| C-h i | Open the Info documentation browser (full manual) |
| C-h r | Open the Emacs manual directly |
| C-h ? | Show all available help commands |
| C-h l | View recent keystrokes (last 300) |
| C-h w | Which key invokes a given function |
Press C-h k then any key or key sequence and Emacs shows you the function it calls, with full documentation. This is the fastest way to learn what any binding does. Press C-h f on the function name shown to dive deeper into the source code.
12 Undo, Marks & Registers
Undo
Emacs has an unusual undo system — there is no separate redo. Instead, undo itself becomes undoable.
| Key | Action |
|---|---|
| C-/ | Undo last change |
| C-_ | Undo (alternate binding) |
| C-x u | Undo (visual buffer indicator) |
| C-g then C-/ | Redo (cancel undo direction, start redoing) |
Mark & Region
| Key | Action |
|---|---|
| C-SPC | Set mark at point (start selection) |
| C-x C-x | Swap point and mark |
| M-h | Mark paragraph |
| C-x h | Mark entire buffer (select all) |
| M-@ | Mark next word |
Registers — named positions & text
| Key | Action |
|---|---|
| C-x r SPC r | Save position to register r |
| C-x r j r | Jump to position in register r |
| C-x r s r | Save region text to register r |
| C-x r i r | Insert text from register r |
13 init.el — Configuration File
Emacs reads its configuration from ~/.config/emacs/init.el (Emacs 29+) or ~/.emacs.d/init.el (older convention). Create this file to customize your Emacs environment. Configuration is written in Emacs Lisp.
;; ~/.config/emacs/init.el — macOS starter config ;; ── PERFORMANCE ────────────────────────────────────── ;; Increase GC threshold to speed up startup (setq gc-cons-threshold 100000000) (setq read-process-output-max (* 1024 1024)) ; 1MB ;; ── UI BASICS ──────────────────────────────────────── (setq inhibit-startup-message t) ; no splash screen (scroll-bar-mode -1) ; hide scrollbar (tool-bar-mode -1) ; hide toolbar (menu-bar-mode 1) ; keep menu bar on Mac (global-display-line-numbers-mode t) ; line numbers (column-number-mode t) ; column in mode line (global-hl-line-mode t) ; highlight current line ;; ── FONT (pick a Retina-friendly font) ────────────── (set-face-attribute 'default nil :family "JetBrains Mono" :height 140 ; 14pt (units are 1/10pt) :weight 'regular) ;; ── macOS SPECIFIC ────────────────────────────────── (setq mac-option-modifier 'meta) ; ⌥ = Meta (setq mac-command-modifier 'super) ; ⌘ = Super (setq mac-right-option-modifier 'none) ; right ⌥ = normal (for accents) (setq ns-use-native-fullscreen t) ; use macOS full screen ;; macOS-style ⌘ shortcuts (global-set-key (kbd "s-c") 'kill-ring-save) ; ⌘C copy (global-set-key (kbd "s-v") 'yank) ; ⌘V paste (global-set-key (kbd "s-x") 'kill-region) ; ⌘X cut (global-set-key (kbd "s-z") 'undo) ; ⌘Z undo (global-set-key (kbd "s-a") 'mark-whole-buffer) ; ⌘A select all (global-set-key (kbd "s-s") 'save-buffer) ; ⌘S save (global-set-key (kbd "s-f") 'isearch-forward) ; ⌘F find ;; ── EDITING DEFAULTS ──────────────────────────────── (setq-default tab-width 4 indent-tabs-mode nil ; use spaces, not tabs fill-column 80) (electric-pair-mode 1) ; auto-close parens/brackets (show-paren-mode 1) ; highlight matching parens (delete-selection-mode 1) ; typing replaces selection ;; ── BACKUPS ───────────────────────────────────────── ;; Keep backup files in one place instead of scattered everywhere (setq backup-directory-alist \`(("." . ,(concat user-emacs-directory "backups")))) (setq auto-save-file-name-transforms \`((".*" ,(concat user-emacs-directory "auto-saves/") t)))
After editing your init file, apply changes with M-x eval-buffer (if init.el is open) or M-x load-file RET ~/.config/emacs/init.el RET.
14 Package Management
Built-in package.el
Emacs has a built-in package manager. The most important repository is MELPA (Milkypostman's Emacs Lisp Package Archive), which hosts thousands of community packages.
;; Add MELPA to package archives in init.el (require 'package) (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) (package-initialize)
Then: M-x package-refresh-contents to update the package list, and M-x package-install to install packages.
use-package (recommended)
use-package is built into Emacs 29+ and provides a clean, declarative way to configure packages. It handles lazy loading (packages are loaded only when needed), reducing startup time.
;; Bootstrap use-package (Emacs 29 has it built-in) (unless (package-installed-p 'use-package) (package-install 'use-package)) (require 'use-package) (setq use-package-always-ensure t) ; auto-install if missing ;; Example: install and configure a theme (use-package doom-themes :config (load-theme 'doom-one t)) ;; Example: install with lazy loading on a command (use-package magit :bind ("C-x g" . magit-status)) ;; Example: install with mode-specific activation (use-package company :hook (prog-mode . company-mode) :custom (company-idle-delay 0.2) (company-minimum-prefix-length 2))
Package management commands
| Command | Action |
|---|---|
M-x package-list-packages | Browse all available packages |
M-x package-install | Install a specific package by name |
M-x package-delete | Remove an installed package |
M-x package-upgrade-all | Upgrade all installed packages (Emacs 29+) |
M-x package-refresh-contents | Sync the package archive list |
15 Popular Packages
Themes
Dozens of beautiful themes from the Doom Emacs project. The most popular Emacs theme collection.
VisualAccessible, WCAG-compliant themes by Protesilaos Stavrou. Built into Emacs 28+. Excellent readability.
Built-in 28+A newer accessible theme collection. High contrast and colorblind-friendly variants.
VisualCompletion frameworks
Vertical interactive completion for the minibuffer. Lightweight and composable. Works beautifully with marginalia and consult.
A comprehensive completion and selection framework. Heavier than Vertico but extremely powerful, with fuzzy matching and persistent history.
UIA leaner completion alternative to Helm. counsel replaces built-in commands with Ivy-enhanced versions.
Space-separated completion style — type any words in any order and Emacs finds the match.
CompletionCode editing
Complete Anything — in-buffer text and code completion with popup menus. Works with many backends.
CodeLanguage Server Protocol client. Brings IDE features (go-to-definition, refactoring, diagnostics) to Emacs for any language with an LSP server.
CodeMinimalist built-in LSP client (Emacs 29+). Less configuration than lsp-mode; excellent for simpler setups.
Built-in 29+Syntax checking and linting on the fly. Shows errors and warnings in the margin as you type.
CodeParser-based syntax highlighting and navigation. Built into Emacs 29+ with treesit. Dramatically better than regex-based highlighting.
Project navigation and management — quickly jump between files in a project, grep project-wide, run tests.
CodeUtilities
Shows available key bindings as you type a prefix. After pressing C-x, shows all valid next keys in a popup. Essential for learners.
EssentialA beautiful, icon-rich mode line. Shows Git branch, LSP status, and more in a compact design.
UIEdit multiple locations simultaneously — like VS Code's multi-cursor mode, but in Emacs.
EditingIncrementally expand selection by semantic units: word → string → statement → block → function.
Editing16 Org-mode
Org-mode is one of Emacs' most beloved features — a plain-text system for notes, to-do lists, project planning, literate programming, and document export. Files use the .org extension.
Basic structure
* Heading level 1
** Heading level 2
*** Heading level 3
Text flows freely under headings.
- Bullet list item
- Nested item
1. Numbered list item
2. Second item
Navigation & visibility
| Key | Action |
|---|---|
| TAB | Cycle visibility of current heading's subtree |
| S-TAB | Cycle global visibility (all headings) |
| C-c C-n | Next heading |
| C-c C-p | Previous heading |
| C-c C-f | Next heading at same level |
| C-c C-b | Previous heading at same level |
| C-c C-u | Go to parent heading |
TODO items
* TODO Write the project proposal
* DONE Review the code
** TODO [#A] High priority task [#B] = medium, [#C] = low
DEADLINE: <2025-01-15 Wed>
SCHEDULED: <2025-01-10 Fri>
| Key | Action |
|---|---|
| C-c C-t | Cycle TODO state (TODO → DONE → none) |
| C-c C-d | Set a DEADLINE date |
| C-c C-s | Schedule a task |
| C-c , | Set priority |
| C-c a t | Show global TODO list |
| C-c a a | Open agenda view |
Tables
Org-mode tables are created and maintained automatically. Type a |-separated row and press TAB:
| Name | Age | Role |
|---------|-----|-------------|
| Alice | 30 | Engineer |
| Bob | 25 | Designer |
| Key in table | Action |
|---|---|
| TAB | Move to next cell (auto-aligns) |
| S-TAB | Move to previous cell |
| C-c | | Create table from selected region |
| M-Left/Right | Move column left / right |
| M-Up/Down | Move row up / down |
Export
Press C-c C-e to open the export dispatcher. You can export to HTML, PDF (via LaTeX), Markdown, plain text, ODT, and more with a single keypress.
17 Magit — Git inside Emacs
Magit is widely considered the best Git interface in existence. It makes Git operations visual, composable, and extremely fast. Install it with (use-package magit :bind ("C-x g" . magit-status)).
Basic workflow
C-x g ; Open Magit status buffer
; Press ? for help at any point
| Key in Magit | Action |
|---|---|
| s | Stage file / hunk under cursor |
| u | Unstage file / hunk |
| S | Stage all changes |
| c c | Commit staged changes (opens commit message buffer) |
| c a | Amend last commit |
| P p | Push to remote |
| F p | Pull from remote (fetch + merge) |
| b b | Switch branch |
| b c | Create and checkout new branch |
| l l | Show commit log |
| d d | Show diff |
| z z | Stash working changes |
| ? | Show all available Magit commands |
| q | Quit / bury Magit buffer |
In the status buffer, expand a changed file with TAB to see individual hunks (diff sections). Press s on a hunk to stage just that portion of the file — without touching the rest. This is finer-grained control than git add -p.
18 Emacs Lisp Basics
Emacs is configured and extended in Emacs Lisp (elisp) — a dialect of Lisp. You don't need to become an expert, but understanding the basics lets you read, modify, and write your own customizations.
Fundamental syntax
;; Comments start with semicolons ;; Function call: (function-name arguments...) (message "Hello, Emacs!") ; displays in minibuffer (+ 2 3) ; returns 5 (concat "Hello" ", world") ; "Hello, world" ;; Variables (setq my-name "Stephen") ; set variable (defvar my-count 0 "A counter.") ; declare with docstring ;; Defining functions (defun greet (name) "Greet NAME with a message." (message (format "Hello, %s!" name))) (greet "World") ; call the function ;; Conditionals (if (> 5 3) (message "Five is greater") (message "Three is greater")) (cond ((= x 1) (message "one")) ((= x 2) (message "two")) (t (message "other"))) ;; Lists (the core data structure) (setq fruits '(apple banana cherry)) (car fruits) ; apple (first element) (cdr fruits) ; (banana cherry) (rest) (length fruits) ; 3 ;; Interactive commands (callable with M-x) (defun my-insert-date () "Insert the current date at point." (interactive) (insert (format-time-string "%Y-%m-%d"))) ;; Bind to a key (global-set-key (kbd "C-c d") 'my-insert-date)
Useful evaluation commands
| Key | Action |
|---|---|
| C-x C-e | Evaluate the expression before point |
| C-j | Evaluate and insert result (in *scratch*) |
| M-: | Evaluate any expression typed in minibuffer |
| M-x eval-buffer | Evaluate entire current buffer as Elisp |
| M-x eval-region | Evaluate selected region |
| M-x ielm | Open interactive Emacs Lisp REPL |
19 macOS-Specific Tips & Tweaks
Font rendering on Retina displays
;; Use macOS's native font smoothing (setq mac-allow-anti-aliasing t) ;; Set a Retina-friendly font size (height = 1/10pt, so 160 = 16pt) (set-face-attribute 'default nil :family "SF Mono" :height 140) ;; Or use the system monospace font (set-face-attribute 'default nil :family "Menlo" :height 140)
Emoji and ligature support (Emacs 28+)
;; Enable ligatures (requires a compatible font like Fira Code) (use-package ligature :config (ligature-set-ligatures 'prog-mode '("->" "=>" "!=" "==" ">=" "<=" "::" "...")) (global-ligature-mode t))
Finder integration
;; Open current file in Finder (defun reveal-in-finder () "Open current file's directory in macOS Finder." (interactive) (shell-command (format "open -R %s" (shell-quote-argument (buffer-file-name))))) (global-set-key (kbd "C-c o f") 'reveal-in-finder) ;; Open current file with default macOS app (defun open-with-default-app () "Open current file with the default macOS application." (interactive) (shell-command (format "open %s" (shell-quote-argument (buffer-file-name))))) (global-set-key (kbd "C-c o o") 'open-with-default-app)
Spell checking with macOS dictionary
;; Use aspell or hunspell (install via Homebrew) $ brew install aspell ;; In init.el: (setq ispell-program-name "aspell") (setq ispell-extra-args '("--sug-mode=ultra" "--lang=en_US"))
| Key | Action |
|---|---|
| M-$ | Check spelling of word at point |
| M-x flyspell-mode | Enable live spell checking (highlights errors) |
| M-x flyspell-buffer | Check entire buffer spelling |
Shell integration on macOS
;; Fix PATH inside Emacs.app (doesn't inherit shell PATH by default) (use-package exec-path-from-shell :if (memq window-system '(mac ns x)) :config (exec-path-from-shell-initialize)) ;; Open a terminal shell inside Emacs (global-set-key (kbd "C-c t") 'term) ; built-in terminal (global-set-key (kbd "C-c v") 'vterm) ; vterm (better; install separately)
When you launch Emacs.app from Spotlight or the Dock, it doesn't inherit your shell's PATH, so Homebrew tools like git, node, and python may not be found. The exec-path-from-shell package fixes this by reading your shell's PATH at startup. Install it with M-x package-install RET exec-path-from-shell.
macOS system integration shortcuts
;; Useful macOS keybindings to add to init.el (global-set-key (kbd "s-<return>") 'toggle-frame-fullscreen) ; ⌘⏎ fullscreen (global-set-key (kbd "s-=") 'text-scale-increase) ; ⌘= bigger text (global-set-key (kbd "s--") 'text-scale-decrease) ; ⌘- smaller text (global-set-key (kbd "s-`") 'other-frame) ; ⌘` next frame (global-set-key (kbd "s-w") 'delete-frame) ; ⌘W close frame (global-set-key (kbd "s-n") 'make-frame-command) ; ⌘N new frame
20 Quick Reference Card
Essential — learn these first
| Key | Action |
|---|---|
| C-g | Cancel current command |
| C-x C-c | Quit Emacs |
| C-x C-f | Open file |
| C-x C-s | Save file |
| C-/ | Undo |
| C-s | Search |
| M-x | Run a command by name |
| C-h t | Open tutorial |
Frequently used
| Key | Action |
|---|---|
| M-x | Execute any command |
| C-x b | Switch buffer |
| C-x 2 | Split horizontal |
| C-x 3 | Split vertical |
| C-x 1 | One window only |
| C-x o | Other window |
| M-% | Query replace |
| C-h k | Describe key |
M-x commands to know
| Command (after M-x) | What it does |
|---|---|
customize | Open the GUI configuration interface |
shell | Open a shell buffer inside Emacs |
eshell | Open Emacs' built-in Lisp shell |
calendar | Open the built-in calendar |
tetris | Play Tetris (yes, really) |
doctor | Talk to Emacs' psychotherapist (ELIZA) |
artist-mode | Draw ASCII art |
zone | Entertaining screen saver |
text-scale-increase | Make text bigger (or use C-x C-=) |
toggle-truncate-lines | Toggle line wrapping |
whitespace-mode | Visualize whitespace characters |
global-auto-revert-mode | Auto-reload files changed on disk |
If you want a fully configured Emacs out of the box, consider Doom Emacs (github.com/doomemacs/doomemacs) or Spacemacs (spacemacs.org). Both provide curated package sets and keybindings, making Emacs immediately productive — at the cost of some abstraction over the underlying mechanics covered in this guide.
Built-in: C-h r for the Emacs manual. C-h i for Info browser.
Online: emacs.stackexchange.com, reddit.com/r/emacs, the EmacsWiki at emacswiki.org, and the official GNU Emacs manual at gnu.org/software/emacs/manual/.
Community: The Emacs subreddit and the Emacs IRC channel on Libera.Chat (#emacs) are welcoming to beginners.