Table of Contents
Neovim Macros and Automation
Macros are recorded sequences of keystrokes. Record once, replay many times to automate repetitive edits.
Recording and playback
q + letter — start recording macro (e.g., qa records to register 'a'). Keystrokes are captured. Press q again to stop.
@ + letter — replay macro (e.g., @a replays register 'a'). @@ — replay last macro.
qa " start recording in register 'a' i- <Esc> " add dash and space at line start j " move to next line q " stop recording @a " replay macro a 3@a " replay 3 times
Macros are stored in registers, so "a contains the keystrokes. :registers` shows all.
Practical examples
Add dashes to line starts:
qa I- <Esc> j q @a " repeat on next line
Replace first word on each line:
qa cw replacement " type new word <Esc> j q @a " repeat
Complex: reformat list items:
qa 0 " start of line cw( " change word to ( <Esc> A) <Esc> " add ) at end j q @a
Apply macro to multiple lines
Select lines visually, then :normal @a applies macro to each line:
5j " select 5 lines down (rough select) :normal @a " apply macro a to each
Or use a range:
:10,20normal @a " apply macro to lines 10-20
Macro tips
- Keep macros simple. Complex macros are hard to debug.
- Use marks to bookmark positions:
ma(mark 'a'),`a(jump to 'a'). - Break complex operations into steps (edit, move, repeat).
- If macro fails, press
uto undo, fix the recording, and try again. - Macros record absolute movements, not relative.
jmoves down one line always, whileGjumps to end of file (depends on buffer size). Use counts (5j) for relative counts.
When to use Lua instead
Macros are great for one-off repetitive edits. For repeated tasks across sessions, write an ex command or Lua script:
-- ~/.config/nvim/plugin/format_list.lua vim.api.nvim_create_user_command('FormatList', function() -- transform list items vim.cmd(":%s/^/- /") -- add dash vim.cmd(":%s/$/.,/") -- add comma end, {})
Then :FormatList applies everywhere, always.
Macro vs search-replace
For find-and-replace, use :s / :%s (faster, regex support). Use macros for structural changes that vary per line.
Example: swap names from “First Last” to “Last, First”
qa 0 " start ci s " change inside spaces <C-r>" " insert word (register) , <Esc> e " end x " delete space I <Esc> " insert space at start j q :%normal @a " apply to all
Or with search-replace:
:%s/\(\w\+\) \(\w\+\)/\2, \1/g
Search-replace is cleaner here. Use macros for edits that don't fit regex patterns.
