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:**
```vim
qa
I- <Esc>
j
q
@a " repeat on next line
```
**Replace first word on each line:**
```vim
qa
cw
replacement " type new word
<Esc>
j
q
@a " repeat
```
**Complex: reformat list items:**
```vim
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:
```vim
5j " select 5 lines down (rough select)
:normal @a " apply macro a to each
```
Or use a range:
```vim
: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 u to undo, fix the recording, and try again.
- Macros record absolute movements, not relative. j moves down one line always, while G jumps 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.
