Macros
Vim Intermediate/Advanced
Chapter 1 — Macros
The Problem Macros Solve
You've likely already used . (the dot command) to repeat your last single change — a genuinely useful shortcut, but limited to one edit at a time. Real repetitive work is rarely that simple: reformatting fifty lines of a CSV, converting a list of names into function calls, adding the same three-line boilerplate above every function in a file. Each of those is a whole sequence of keystrokes you'd otherwise have to repeat by hand, once per line, for however many lines the task touches.
A macro is a recorded sequence of any keystrokes — motions, edits, searches, even other commands — stored in a register (Chapter 2) and replayable on demand, as many times as you like. Where the dot command repeats one action, a macro repeats anything you can type.
Recording a Macro
q followed by a register letter starts recording; pressing q again stops it. Everything typed in between — in any mode — becomes part of the macro.
qa # start recording into register 'a' 0i"<Esc>A",<Esc> # the actual edit: wrap the line in quotes, add a trailing comma j # move down to the next line, ready for the macro's next run q # stop recording
0, then i, then ", then Esc, and so on, in that exact order. This is exactly why the j at the end of the example above matters: without it, replaying the macro would repeat the edit on the same line every time rather than advancing.
Why register a-z, and not 0-9?
Macros are stored in the exact same named registers (Chapter 2) used for yanked and deleted text — there's no separate "macro register" type. Recording into register a with qa...q and yanking a word into register a with "ayiw both write to the identical storage slot; whichever happened most recently is what's there now. Pick a register you're not actively using for something else during the same editing session.
Playing Back a Macro
@a # play macro 'a' once @@ # repeat the LAST macro played — regardless of which register it came from 5@a # play macro 'a' five times in a row
@@ is worth building into muscle memory early — after playing @a once to confirm it worked correctly, @@ lets you keep repeating it without retyping the register letter each time.
Applying a Macro Across Many Lines
A large count is the simplest way to apply a macro repeatedly down a file:
100@a # attempt to play macro 'a' up to 100 times
a ends with j (move down a line) and you're already on the last line of the file, that j fails — and a failed command inside a macro stops the whole macro immediately, rather than continuing past it. In practice, this means 100@a on a 23-line file safely stops after line 23 instead of erroring out or corrupting later lines — you can specify a count far larger than you actually need without worrying about overrunning the file.
Applying a macro to a Visual selection
When you want a macro applied to a specific range rather than "the rest of the file," select the target lines in Visual Line mode first, then invoke the macro via :normal:
V # enter Visual Line mode jjjj # extend the selection down 4 more lines (5 lines total) :normal @a # Vim auto-fills this as :'<,'>normal @a — runs the macro once per selected line
:normal executes the given keystrokes as if typed in Normal mode, once for every line in the given range — here, the visually selected range. This sidesteps the "will it stop in time?" question entirely: the macro only ever runs across the lines you explicitly selected.
:normal range, play the macro once with a plain @a first and visually confirm the result is correct. A macro that silently does the wrong thing (a mistyped keystroke, a search that doesn't match the way you expected) will happily repeat that mistake across every remaining line just as reliably as it would the correct edit — mass-applying a bug is exactly as easy as mass-applying a fix.
Editing a Macro — Since It's Just a Register
Because a macro is stored in an ordinary register, you're not locked into re-recording from scratch if you spot a mistake. You can paste it into the buffer as text, fix the typo, and yank it back:
Workflow — fixing a mistyped macro without re-recording
a's contents into the buffer, on its own line, as plain editable text.
a, overwriting the old (broken) version.
a.
<Esc> recorded inside a macro shows up as ^[ when pasted as text (and a literal Enter as ^M) — these are the actual character, not a two-character sequence, so editing around them works the same as any other single character. It looks unusual the first time you see it, but it pastes and re-yanks correctly regardless.
A Worked Example
Turning a plain list of names into a quoted, comma-terminated list — the kind of transform that comes up constantly when reshaping data for code:
# Before: John Smith Jane Doe Alex Chen # After: "John Smith", "Jane Doe", "Alex Chen",
# With the cursor on the first line: qa # start recording into 'a' I"<Esc> # insert a quote at the start of the line A",<Esc> # append a closing quote and comma at the end of the line j # move to the next line q # stop recording 2@a # apply to the remaining 2 lines (test with @a first, per this chapter's warn-box, then @@ or a count)
Commands Introduced in This Chapter
Chapter 1 — Command Reference
{count} times, stopping early on the first error