vim macros, one recording per page
Thirty lessons on recording vim macros with q into a named register, stopping with q, replaying with @ and @@, counts like 3@q, appending with the uppercase qA, pasting a register out and yanking the fix back in, macros that walk lines with j and start with 0, the macro as plan B beside the dot command, running over a range with :normal and why the bang matters, a macro per :global match, recursive registers that call themselves, register hygiene with :reg, saving takes to a file, one-keystroke undo, and one real recording task per page, from quoting lines to swapping fields and running one register across a whole arglist.
One recording, its register, and how to replay it. That's a page.
vim macros, one recording per page
Thirty lessons on recording vim macros with q into a named register, stopping with q, replaying with @ and @@, counts like 3@q, appending with the uppercase qA, pasting a register out and yanking the fix back in, macros that walk lines with j and start with 0, the macro as plan B beside the dot command, running over a range with :normal and why the bang matters, a macro per :global match, recursive registers that call themselves, register hygiene with :reg, saving takes to a file, one-keystroke undo, and one real recording task per page, from quoting lines to swapping fields and running one register across a whole arglist.
Set in Space Grotesk, Inter and JetBrains Mono (SIL Open Font License).
Every fact in this book is as the official source states it, fetched and read during this build: the Vim help files repeat.txt (q recording, the stopping q, @ replay, @@, counted replays, :normal inside :global), motion.txt (the 0 and j motions inside macros), change.txt (CTRL-A on numbers, put and yank), undo.txt (undo blocks, the numbered registers and the dot, the :display command), map.txt (the normal! omap example), the Vim user manual chapter usr_10.txt (record and playback, the #include example, 3@a, the 26 registers, editing a recorded register, appending with an uppercase register), and the Wikipedia article on Vim. Motions, operators, registers as named clipboards and the dot command are assumed from the earlier vim book; no facts are sourced from Reddit, Stack Overflow or tutorials. An independent guide, not affiliated with or endorsed by the Vim project.
Your purchase is for personal use only. You do not have redistribution rights: please do not share, resell, or republish this book or its pages.
© 2026 Steve Hodgkiss. All rights reserved. Personal use only; no redistribution rights.
Edition 1.0 · stevehodgkiss.net
Contents
Per Vim help, repeat.txt: q{0-9a-zA-Z"} records typed characters into the named register, uppercase to append; the Vim user manual usr_10.txt puts the register name between a and z.
Record with q
The dot command repeats one change. When the job is bigger, start a tape: type q, then a register name, a to z. From that keystroke, Vim records everything you type.
The proof sits on the status line: -- RECORDING @a --. It stays there until you stop, so you always know whether your keys are being captured.
Pick a register you do not use for yanks; macros and copied text share the same boxes.
Type qa, check the status line says recording, do a little work, then stop with q before anything else.
Per Vim user manual, usr_10.txt: to append to a register use an uppercase letter; qC then a search and Enter then q appends to register c, and the same rule holds for yank and delete.
Append with qA
Missed a step at the end of the recording? Do not start over: q with the uppercase letter appends. qA adds keys to register a; it never replaces them.
The manual's example records a search onto an existing macro exactly this way. The same case rule governs yanks: "AY adds another line to register a.
Lowercase starts fresh; uppercase continues. One letter of case, two meanings.
Record a macro into a, stop, then qA and append a j so it walks lines; check :reg a shows both parts.
Per Vim user manual, usr_10.txt: a count before @ executes the macro that many times; this book's plan matches the count to the lines remaining when each pass ends one line lower.
One line per pass
When the macro ends in j, each replay consumes exactly one line: the count and the remaining lines must match.
Four lines to fix: record on the first, replay with 3. Six lines: replay with 5. The uncounted extra pass runs j past the last line and the macro misfires on whatever it finds below.
Count before you type the count. It is the one number in the whole manoeuvre.
Fix a six-line column in one take: record on line one, replay 5@a, and confirm the cursor lands on line seven, clean.
Per Vim user manual, usr_10.txt: command recording exists for work more complex than the single change the dot command can repeat.
The macro as plan B
Ask one question before any repetitive edit: is this one change, or several? One, repeated: the dot. Several, repeated: the register.
Plan B kicks in quietly: a change plus a movement plus another change is already past what the dot holds. Record it once and the whole bundle replays.
The dot for one move, q for a plan. Choosing first is faster than either.
Catch yourself repeating a two-step edit; classify it as dot work or macro work before the third repetition.
Per Vim help, repeat.txt: :g/pat/normal runs Normal mode commands on the matching lines and the commands must end with a whole command; usr_10.txt points :global at :normal for Normal mode keys.
:normal over a range
The ex route skips counting: :%normal @a runs the macro on every line of the file. Ranges work as the manual teaches: 5,12 from five to twelve, .,$ to the end, % for all.
No j is needed here; the command steps through the range line by line itself. The help's warning applies: the macro must end with a complete command, or Vim waits for the rest on every line.
Counts for a screenful, :normal for the whole file.
Record a macro without j and run it over a whole file with :%normal @a, then again on a 5,12 range.
Per Vim user manual, usr_10.txt: an uppercase register appends, for recording and for yank alike; this book's plan types the @ tail as text and appends it with an uppercase yank.
Yank the @ line in
The safe recipe, in moves. First record the body into b, clean, no tail. Then type the two characters @b on an empty line, as text, never executed.
Now the uppercase yank: from column 1, yank to the line end appending into b. The tail joins the body without re-recording; clear the scratch line and the loop is ready.
The recursion was typed as text and yanked into place: no runaway take.
Build one recursive macro with the four steps and run it down a twenty-line column until it stops itself at the bottom.
Per Vim help, change.txt: CTRL-A adds the count to the number after the cursor and the number formats option controls what counts as a number; this book's plan records 0, CTRL-A, j.
Increment the column
CTRL-A raises the number after the cursor. Record 0, CTRL-A, j: each replay goes home, bumps that line's number, steps down a line.
Four lines holding 1 become 1, 2, 3, 4 after 4@a. Same three keys, four different results: the macro supplies the plan, the buffer supplies the variety.
Numbered lists, priorities, versions: one macro, the whole column.
Turn a column of ten ones into one to ten with one recording and one count, then undo it all with a single u.
Per Vim user manual, usr_10.txt: :substitute replaces over a range, a visual block with I inserts one prefix across many lines, and gqap formats a paragraph.
When not to macro
Three jobs that look macro-shaped and are not. Plain text swap: :s over a range. One prefix on many lines: the block insert, typed once. Reformatting: gqap, one operator.
The test: if a single command's own range or repetition covers the whole job, wrapping it in a macro is ceremony.
Reach for q when the job is a sequence of steps, not a sweep.
Redo one old macro task with :s or a block insert, and keep whichever take you would defend in a review.