How do I apply a recorded macro to a range of lines without re-recording it in Vim?
Answer
:[range]normal @a
Explanation
The :[range]normal @a command runs a recorded macro against every line in a given range. Unlike 5@a, which repeats a macro a fixed number of times from the cursor position, :normal @a with a range applies the macro independently to each line in that range — ideal when you know exactly which lines need transforming.
How it works
:[range]— an Ex range such as1,10,'<,'>(visual selection),%(entire file), or.,$(current line to end)normal— execute normal-mode keystrokes on each line in the range@a— replay the macro stored in registera
Vim positions the cursor at the start of each line before executing the macro, so the macro should be written assuming cursor-at-line-start positioning.
Example
Suppose register a contains I// <Esc> (prepend // to a line). After recording it with qa I// <Esc>q, you can comment out lines 5 through 20:
:5,20normal @a
Or apply it to a visual selection:
:'<,'>normal @a
Or to the entire file:
:%normal @a
Tips
- Use
normal!instead ofnormalto ignore user-defined mappings and ensure raw Vim behavior - If the macro uses motions that could fail on some lines (e.g., searching for a pattern not on every line), wrap it defensively or use
:silent! :[range]normal @ato suppress errors - You can use any register:
@b,@q, etc. - Combine with
:g/pattern/normal @ato apply the macro only to lines matching a pattern