Macros
Macros allow you to record a sequence of keystrokes and replay them. They are Vim's answer to "I need to do this same sequence of edits 50 times."
Core Idea
A macro is just recorded keystrokes stored in a register. Replay it once or a hundred times. Compose macros by referencing other macros.
Recording a Macro
q{register} → Start recording into register (a-z)
... keystrokes ...
q → Stop recording
qa → start recording into register 'a'
... → make your edits
q → stop recording
@a → replay macro 'a' once
@@ → replay last macro again
5@a → replay macro 'a' 5 times
A Complete Macro Example
Goal: Transform each line from name, value to const name = value;
Input:
alice, 100
bob, 200
charlie, 300
Steps:
1. Go to first line (alice, 100)
2. qa → start recording into 'a'
3. 0 → go to line start
4. i const Esc → insert "const " before word
5. f, → find comma
6. r → replace comma with space
7. a = Esc → append " = " after the space
8. A; Esc → append ; at end of line
9. j → move to next line
10. q → stop recording
Now: @a @a (or 2@a) to apply to lines 2 and 3
Result:
const alice = 100;
const bob = 200;
const charlie = 300;
Viewing Macro Contents
:registers a → show what's in register 'a'
"ap → paste macro 'a' into buffer (to inspect or edit!)
Editing a Macro
Macros are just text in registers. You can edit them:
1. "ap → paste macro into buffer
2. Edit the text (fix a typo, add a step)
3. V → select the line
4. "ay → yank back into register 'a'
Recursive Macros
A macro can call itself to process an unknown number of lines:
qa → start recording
0 → go to line start
... edits ...
j → move to next line
@a → call itself (recursive)
q → stop
@a → start the chain — runs until end of file or error
warning
Recursive macros stop when they hit an error (e.g., can't move down further). This is usually the desired behavior — it stops at end of file.
Applying a Macro to All Lines in a Range
:1,20 normal @a → run macro 'a' on lines 1-20
:%normal @a → run macro 'a' on every line
:'<,'>normal @a → run macro on visual selection
This is often more controlled than recursive macros.
Counting Arguments
99@a → run macro up to 99 times (stops on error)
Macro Workflow Best Practices
- Position carefully before recording — macros replay exactly, so start in a consistent position (usually
0to go to line start) - Use search within macros —
/patterninside a macro makes it position-independent - Use text objects —
ciw,di"are better thandw(they work regardless of cursor position within the word) - Test on one line before applying to hundreds
- Use
:normal @afor controlled bulk application
Practical Macro Patterns
Pattern 1: Add trailing comma to JSON lines
Input: "name": "Alice"
Output: "name": "Alice",
# Macro:
qa 0 A, Esc j q
@a (or :%normal @a if on all lines)
Pattern 2: Wrap each line in quotes
Input: apple
Output: "apple"
# Macro:
qa 0 i" Esc A" Esc j q
Pattern 3: Convert from snake_case to camelCase (simplified)
This is better done with a substitute, but shows macro flexibility:
qa
/_ → search for underscore
x → delete underscore
gU → uppercase next char (use gUl for one char)
@a → recurse
q