How do I fix or modify a recorded macro without re-recording it from scratch?
Answer
:let @a = substitute(@a, 'old', 'new', 'g')
Explanation
Macros are plain text stored in registers, which means you can patch them using Vimscript's substitute() function — no re-recording needed. This is invaluable when you have a long macro with a small mistake deep in the middle.
How it works
substitute({expr}, {pat}, {sub}, {flags}) works like a string-level s/// — it takes the current contents of register a (via @a), replaces matches of {pat} with {sub}, and assigns the result back:
:let @a = substitute(@a, 'oldcmd', 'newcmd', 'g')
Other useful transformations:
- Prepend a step:
:let @a = 'dd' . @a - Append a step:
:let @a = @a . 'j' - Remove the last keystroke:
:let @a = @a[:-2](Vim uses 1-based index;[:-2]drops the final character) - Inspect before editing:
:echo @a— shows the raw keystroke sequence with special characters visible
Example
You recorded a macro that appends a semicolon and moves down, but forgot the 0 to go to line start first:
:echo @a
" output: A;^[j
:let @a = '0' . @a
:echo @a
" output: 0A;^[j
Now run the corrected macro: @a
Tips
- Special keys in macros appear as literal control characters (e.g.,
<Esc>shows as^[). Thesubstitute()call works on these raw bytes, so match them literally if needed :reg ashows the register content in a human-readable format useful for inspection before editing- Pair with
:let @a = @a[:-2]when the last recorded keystroke was accidental (a common issue whenqor<Esc>slips in at the end)