Editing commands
Beyond raw motion, Macros provides the core Emacs editing commands — region-aware where Emacs is, and each command's edits coalesce into a single undo group so they undo as a unit.
The region and the kill ring
Set the mark with C-Space, then move point; the text between mark and point is the region. Commands that say "region" act on it (or fall back sensibly when there's no active region).
| Key | Command | Action |
|---|---|---|
| C-Space | set-mark |
Start a selection |
| C-w | kill-region |
Cut the region to the kill ring |
| M-w | kill-ring-save |
Copy the region |
| C-y | yank |
Paste the latest kill |
| M-y | yank-pop |
Cycle through earlier kills (after a yank) |
| C-x C-x | exchange-point-and-mark |
Swap point and mark |
| C-x C-h / cmd-a | mark-whole-buffer |
Select all |
The kill ring and the system clipboard are kept in sync by the clipboard commands (cmd-c/x/v), so copying in Macros and pasting in another app just works.
Killing & transposing
| Key | Command |
|---|---|
| C-k | kill-line |
| M-d / M-Backspace | kill-word / backward-kill-word |
| M-z | zap-to-char |
| C-t | transpose-chars |
| C-x C-t | transpose-lines |
| M-^ | join-line |
| C-o | open-line |
Search
Incremental search, Emacs-style:
| Key | Command |
|---|---|
| C-s | isearch-forward |
| C-r | isearch-backward |
Type to extend the match; C-s / C-r again to jump to the next/previous hit; C-g to cancel and return to where you started.
Replace
replace-string performs a literal, whole-buffer replacement:
M-% → replace-string
It prompts for the search text and the replacement and runs over the buffer; the edits form one undo group.
Occur
C-c o (occur) prompts for a pattern and opens an *occur* buffer listing every matching line. Move with n / p, press Enter to jump to a match in the source, q to close.
Comment toggling
M-; (comment-dwim) toggles a line comment on the current line (or region). The comment prefix is a buffer-local string set per mode (comment-string), defaulting to // ; modes like steel-mode set their own.
Sorting & case
These act on the region, or the whole buffer when there's no region:
sort-lines— sort the lines.upcase-region/downcase-region/capitalize-region— case conversion.
Run them by name with M-x, or bind them in your init.scm.
Undo & redo
| Key | Command | Action |
|---|---|---|
| C-/ | undo |
Undo the last change |
| C-? | redo |
Redo |
Undo is branching (Emacs undo-tree): undoing and then making a new edit starts a branch rather than discarding the redone edits, so no work is ever lost. M-x vundo opens a read-only view of the undo tree (g refreshes, q closes); navigate the history itself with C-/ and C-?.
Expanding the selection
Grow the region outward along tree-sitter syntax boundaries — word, then expression, statement, block (Emacs expand-region). It works in any buffer with a tree-sitter grammar, no language server needed.
| Key | Command | Action |
|---|---|---|
| C-= | er/expand |
Widen the selection to the enclosing node |
| M-= | er/contract |
Step back to the previous, narrower selection |
In evil visual state, + and - do the same.
Multiple cursors
Edit in many places at once (Emacs mc.el). Add secondary cursors, then typed text, Enter, and Backspace are replicated at every cursor.
| Key | Command | Action |
|---|---|---|
| C-c C-n | mc-add-cursor-below |
Add a cursor on the next line |
| C-c C-p | mc-add-cursor-above |
Add a cursor on the previous line |
| C-c C-d | mc-mark-next-like-this |
Add a cursor at the next occurrence of the word at point |
| C-g | mc-clear |
Collapse back to a single cursor |
Plain motions move only the primary cursor — add the cursors first, then type or delete.
Jumping to a character
Jump anywhere on screen in a couple of keystrokes (Emacs avy / ace-jump).
| Key | Command | Action |
|---|---|---|
| C-c j | avy-goto-char |
Type a character; every visible occurrence is tagged with a hint letter — press the letter to jump |
In evil normal state this is g s. C-g cancels the jump.
The buffer list
C-x C-b (ibuffer) opens a buffer manager (Emacs ibuffer) listing every open buffer. Enter switches to the buffer on the line, d or x kills it, g refreshes. (To pick a buffer through Helm instead, use C-x b.)