vimtricks.wiki Concise Vim tricks, one at a time.

How do I edit a macro in-place using Vimscript without re-recording it?

Answer

:let @a = substitute(@a, "old", "new", "g")

Explanation

When a recorded macro has a typo or wrong command buried inside it, you don't have to re-record the entire thing. Vimscript's :let command lets you read, modify, and reassign register values directly — treating the macro as a plain string.

How it works

  • @a reads the current contents of register a as a string
  • substitute(@a, 'old', 'new', 'g') runs a string substitution on that raw keysequence
  • :let @a = ... writes the result back into register a
  • The register now holds the corrected macro, ready to replay with @a

You can also inspect the macro first with :echo @a or assign it wholesale:

:let @a = 'I// <Esc>j0'

This completely replaces the macro with a literal key sequence (use <Esc>, <CR>, <C-w> etc. as literal strings in the assignment).

Example

Suppose you recorded a macro to add // comments but accidentally typed /// instead. Rather than re-recording:

:echo @a
" → I/// <Esc>j0

:let @a = substitute(@a, '///', '//', '')
:echo @a
" → I// <Esc>j0

The macro is now fixed without a single keystroke of re-recording.

Tips

  • Combine with :put a to paste the macro into a buffer, edit it visually, then yank it back with "ayy for complex edits
  • Use setreg() for finer control: :call setreg('a', 'new content', 'c') sets type to characterwise
  • Works on any register including @q, @w, etc. — whatever you used when recording

Next

How do I re-insert the text from my last insert session and immediately return to normal mode?