This post is my set of notes about using Emacs and it will evolve over time as I work out how to do new things. The notes will be very personal to me and my use of Emacs but they might be handy for other people so I thought I would make it a public post, albeit one which will evolve over time.
The main things this post will cover are:
- General notes about using Emacs, terminology, etc.
- Notes about the Emacs equivalents to things I do in Neovim, VS Code, etc.
- Reminders to myself about things I want to dig into.
Some Basic Key Sequences
| Key Sequence | Action |
|---|---|
| C-x C-c | Exit Emacs |
| M-x | Execute extended command |
| C-g | ‘Bail out’ |
| Esc Esc Esc | Quit out of prompts, regions, prefix arguments |
Buffers, Windows, Frames, and Tabs
A buffer displays content. Everything you see and type is in a buffer.
A window is a view of the contents of a buffer. A window displays the contents of one buffer (but you can display the same buffer in multiple windows).
Windows are displayed in a frame. A frame can display one or more windows.
The cursor is only ever in one window and that is called the selected window or current window.
At the bottom of each window is the mode line and below that is the echo area.
Buffers
| Key Sequence | Action |
|---|---|
| C-x C-f | Find (open) a file |
| C-x C-s | Save the buffer |
| C-x b | Switch buffer |
| C-x k | Kill (close) a buffer |
| C-x C-b | Display all open buffers |
| M-S-x | Execute extended command relevant for buffer |
Windows
| Key Sequence | Action |
|---|---|
| C-x 0 | Delete the active window |
| C-x 1 | Delete other windows |
| C-x 2 | Split window below |
| C-x 3 | Split window right |
| C-x o | Switch active window |
To make switching windows easier, rebind C-x o to M-o:
(global-set-key (kbd "M-o") 'other-window)
To do something like opening a file in a new window you don’t need to split the current window (which will show the same buffer in both, switch to the other window and then open the file. You can act on other windows instead.
Note that if there is already another window, that will be used. These commands only create a new window if there is currently only one.
| Key Sequence | Action |
|---|---|
| C-x 4 C-f | Find a file in the other window |
| C-x 4 d | Open Dired in the other window |
| C-x 4 C-o | Display a buffer in the other window |
| C-x 4 b | Switch the buffer in the other window and make it the active window |
To have the split be horizontally ([]|[]) by default:
(setq split-width-threshold 1)
Frames
Managing frames is very similar to managing windows:
| Key Sequence | Action |
|---|---|
| C-x 5 0 | Delete the active frame |
| C-x 5 1 | Delete the other frame |
| C-x 5 2 | Create a new frame (follows the standard split rules) |
| C-x 5 C-f | Find a file in the other frame |
| C-x 5 d | Open Dired in the other frame |
| C-x 5 C-o | Display a buffer in the other frame |
| C-x 5 b | Switch the buffer in the other frame and make it the active window |
Note: Frames all share the same Emacs session so whilst they look like different instances of Emacs they are not. They are good for multi-monitor setups however.
Tab Line Mode
By default tab line mode shows tabs for buffers previously opened in a window.
It can be enabled with M-x global-tab-line-mode.
| Key Sequence | Action |
|---|---|
| C-x |
Select previous buffer |
| C-x |
Select next buffer |
This is not enormously useful.
Tab Bar Mode
Tab bar mode essentially manages multiple windows in a tabbed layout rather than in a tiled layout.
This is very similar to how VS Code has tabs for files.
It can be invoked via M-x tab-bar-mode or by invoking one of the key bindings below:
| Key Sequence | Action |
|---|---|
| C-x t 0 | Close the current tab |
| C-x t 1 | Close all other tabs |
| C-x t 2 | Create a new tab |
| C-x t RET | Select tab by name |
| C-x t o, C-<tab> | Next tab |
| C-S-<tab> | Previous tab |
| C-x t r | Rename tab |
| C-x t d | Open Dired in other tab |
| C-x t C-f | Find file in other tab |
| C-x t b | Switch to buffer in other tab |
| M-x tab-list | Shows an interactive tab list |
| M-x tab-undo | Undoes a closed tab |
| M-x tab-recent | Switches to the last visited tab |
General Editing Notes
Line and Column Numbers
;; Show line numbers in text and programming modes
(add-hook 'text-mode-hook 'display-line-numbers-mode)
(add-hook 'prog-mode-hook 'display-line-numbers-mode)
;; Show the column number in the mode line (line number is shown by default)
(setq column-number-mode t)
Cut, Copy, and Paste
The Emacs terminology is:
- Cutting -> Killing
- Copying -> Saving to the kill ring
- Pasting -> Yanking
…
Undo and Redo
…
The Mark and The Mark Ring
The mark is a position in the buffer.
The point is another name for the cursor. It is your current position in a buffer.
A region is the block of text between the mark and the point.
A mark can be set by pressing C-<SPC>. When the point moves the region is shown and changed accordingly. The region can be deactivated by pressing C-<SPC> again (or C-g).
The mark is also used to jump around in a buffer and some commands which change your location in the buffer will add a mark to the mark ring so that you can return to your original position later. For example, M-< and M-> jump to the beginning and end of the buffer but they both mark your current position first so that you can return to it via C-u C-<SPC>.
The mark ring contains all of the marks placed in a buffer, either directly using commands like C-<SPC> or indirectly by commands like M-<.
There is also a global mark ring for commands that work across buffer boundaries.
To manually set a mark without starting to set the region you press C-<SPC> C-<SPC>. Therefore is it possible to set a mark and then jump back to it easily using C-u C-<SPC>.
The following set a region and leaves the region active (you can extend it further):
| Key Sequence | Action |
|---|---|
| C- |
Set the mark |
| M-h | Mark the next paragraph |
| C-x h | Mark the entire buffer |
| M-@ | Mark the next word |
To mark two words you would press M-@ M-@ or combine it with a numeric argument: M-2 M-@. You can change the direction using the negative argument modifier: M-- M-2 M-@.
Rectangular Selection
C-x SPC toggles M-x rectangle-mark-mode on and off.
Bookmarks and Registers
Bookmarks are permanent (they are saved to a file) and are most useful for jumping to frequently used files or directories.
| Key Sequence | Action |
|---|---|
| C-x r l | List bookmarks |
| C-x r m | Set a bookmark |
| C-x r b | Jump to bookmark |
Registers are transient and a single character is used to refer to stored items which can include window configurations and framesets. points, numbers and text.
Numbers and text are useful if you want to repeatedly insert text but storing and jumping to points is useful when editing a codebase.
| Key Sequence | Action |
|---|---|
| C-x r n r | Store a number in register r |
| C-x r s r | Store a region in register r |
| C-x r SPC r | Store the point in register r |
| C-x r i r | Insert the contents of register r |
| C-x r j r | Jump to point in register r |
Neovim dd
Emacs has C-k (kill-line) which deletes from the cursor to the end of the line. To delete the whole line use C-a C-k. But that just removed the ‘contents’ and leaves an empty line so maybe use M-x kill-whole-line.
Spell Checking
You need to have a spelling application and dictionary installed. The most common ones seem to be aspell and hunspell. Currently I use aspell and the en_GB-ise-wo_accents dictionary.
The dictionary can be set in the configuration: (setq ispell-dictionary "en_GB-ise-wo_accents").
If you want to use a different program such as hunspell then you can define that too: (setq ispell-program-name "hunspell").
| Key Sequence | Action |
|---|---|
| M-$, M-x ispell-word | Check word at point |
| M-x ispell | Check spelling in the buffer (or region if one is active) |
| M-x ispell-buffer | Check spelling in the buffer |
| M-x ispell-region | Check spelling in the region |
| C-u M-$, M-x ispell-continue | Continue an interrupted spelling operation |
In addition, flyspell-mode (which shows a line under misspelled words) can be enabled automatically for text mode files (and an equivalent for programming mode files which only checks comments and strings):
(add-hook 'text-mode-hook 'flyspell-mode)
(add-hook 'prog-mode-hook 'flyspell-prog-mode)
Quality of Life Improvements
Improving The Completions Buffer
;; Improve *Completions* buffer behaviour
(setq completion-auto-help 'always)
(setq completion-auto-select 'second-tab)
Project.el
C-x p d to launch Dired in the root of the project’s folder.
C-x p b to switch buffer but only to ones in the current project.
C-x p f to find files in the project. This is an equivalent of VS Code’s Ctrl+p. To extend the search to files outside of the project use C-x p F.
C-x p g to to find in files in the project. This is an equivalent of VS Code’s Ctrl+Shift+f. To extend the search to files outside of the project use C-x p G.
Magit
C-x g to launch Magit.
Tab to open and close sections.
F to pull changes.
s stages a file.
c c initiates a commit. C-c C-c creates the commit.
P u pushes upstream.
k (magit-discard-item) discards changes in a file.
q closes the Magic buffer.
g refreshes the buffer.