Skip to main content

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

  1. Position carefully before recording — macros replay exactly, so start in a consistent position (usually 0 to go to line start)
  2. Use search within macros/pattern inside a macro makes it position-independent
  3. Use text objectsciw, di" are better than dw (they work regardless of cursor position within the word)
  4. Test on one line before applying to hundreds
  5. Use:normal @a for 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

What's Next