How do I define or fix a macro using Vimscript instead of re-recording it?
Answer
:let @q = 'commands'
Explanation
Macros in Vim are just text stored in named registers. You can assign any string directly to a register with :let @{register} = '...', which lets you define complex macros programmatically, pre-load them in your vimrc, or surgically fix a macro without recording the whole thing from scratch.
How it works
:let @q = 'iHello\<Esc>'— assigns a macro to registerqthat enters insert mode, typesHello, and presses Escape- Special keys use
\<Key>notation inside single-quoted strings with\escaping, or you can use double-quoted strings with\<Esc>,\<CR>, etc. - After setting the register, run the macro normally with
@q
Example
You recorded a macro that wraps a word in quotes but forgot to advance to the next word at the end. Instead of re-recording, fix it directly:
" Current (broken) macro in register q:
let @q = 'ciw"<C-r>""'
" Fixed: add 'w' at the end to advance to the next word
:let @q = 'ciw"\<C-r>""w'
Or pre-load a commonly used macro in your vimrc:
" Macro to wrap current line in a markdown code fence
let @c = 'O```\<Esc>jo```\<Esc>'
Tips
- Use
echo @qto inspect the current contents of a register before editing it getreg('q')andsetreg('q', 'commands')are the function equivalents — useful when building macros with:execute- The uppercase register append shortcut
qAis handy for one-off extensions, but:letis better for permanent or complex macros stored in your config