How do I save a recorded macro permanently so it persists across Vim sessions?
Answer
let @a = 'macro_contents'
Explanation
Recorded macros are stored in registers, which are lost when you quit Vim (unless viminfo saves them). To make a macro permanent, you can paste its contents into your vimrc as a let @{register} assignment. Every time Vim starts, the register is pre-loaded with your macro, ready to replay with @a.
How it works
- Record your macro normally with
qa...q - View the raw keystrokes stored in the register with
:reg a - In your vimrc, add a line like
let @a = 'keystrokes' - When Vim starts, register
ais populated with those keystrokes - Run the macro anytime with
@a
Step-by-step
- Record the macro you want to save:
qa 0f:dwA;Esc j q
- Open your vimrc and type
let @a = 'then press<C-r><C-r>ato paste the register contents literally, then close the quote with':
let @a = '0f:dwA;\<Esc>j'
- Alternatively, paste the register with
"ap, then wrap it in theletassignment and escape special characters.
Escaping special keys
Special keys need to be escaped in the string:
let @a = "0f:dwA;\<Esc>j"
When using double quotes, Vim interprets \<Esc>, \<CR>, \<C-a>, etc. as the actual key codes. With single quotes, no interpretation happens — you would need literal control characters.
Using double quotes with \<keyname> notation is the recommended approach:
let @a = "0f:dwA;\<Esc>j"
let @b = ":%s/foo/bar/g\<CR>"
let @c = "ggVG=\<Esc>"
Tips
- Use double-quoted strings (
"...") in your vimrc so you can write\<Esc>,\<CR>,\<C-w>etc. in human-readable form - To extract a macro's exact contents, use
":put ato paste registerainto the buffer, then inspect and clean up the raw keystrokes - Be careful with special characters in single-quoted strings — single quotes do not interpret escape sequences, so
\<Esc>would be treated as literal text - You can also use
:reg ato view the register and manually transcribe the keystrokes - Macros saved this way are available immediately on Vim startup — no need to re-record them each session
- Consider naming registers mnemonically:
let @d = ...for a delete macro,let @f = ...for a format macro - If the macro is complex, consider converting it into a function or mapping instead — macros are fragile and hard to debug, while functions are readable and maintainable