How do I edit or modify an existing Vim macro programmatically without re-recording it?
Answer
:let @q = substitute(@q, "old", "new", "g")
Explanation
Vim macros are stored as plain text in registers, which means you can inspect and modify them like any other string. Instead of re-recording an entire macro just to fix a small typo or swap one command for another, you can rewrite the register directly using :let and Vimscript's substitute() function.
How it works
:let @q = ...assigns a new value to registerq(where the macro lives)substitute(@q, 'old', 'new', 'g')runs a search-and-replace on the current macro string- You can inspect the raw macro content first with
:echo @qor:reg q
Example
You recorded a macro that inserts foo, but you want it to insert bar instead:
" Inspect what the macro currently contains
:echo @q
" Fix the typo without re-recording
:let @q = substitute(@q, 'foo', 'bar', 'g')
To concatenate two macros into one — run what @a does, then what @b does:
:let @q = @a . @b
To strip an accidentally recorded trailing <Esc> from the end of a macro:
:let @q = substitute(@q, '\e$', '', '')
Tips
- For more complex edits, paste the macro into a scratch buffer (
"qp), edit it as text, then yank it back ("qy$) to reload the register - Use
:execute 'normal @q'to test the modified macro immediately after editing - This approach works for any register, making it useful to build composite macros by combining existing ones