How do I apply a macro to every line in a specific range without running it manually each time?
Answer
:[range]normal @q
Explanation
The :[range]normal @q command replays the macro in register q on every line within a given range. This is one of the most efficient ways to batch-apply a recorded transformation across a predictable set of lines without relying on a counter or recursive technique.
How it works
:[range]— any standard Vim range: line numbers (5,20), marks ('a,'b), the whole file (%), or the visual selection ('<,'>)normal— executes the following keystrokes as Normal mode commands on each line in the range@q— replays the macro stored in registerq(substitute any register letter)
Vim positions the cursor at the beginning of each line in the range before replaying the macro, which is the same as manually moving to each line and pressing @q.
Example
Suppose register q contains I// <Esc> (prepend // to comment a line). To comment lines 10 through 25:
:10,25normal @q
Or apply the macro to all lines in the file:
:%normal @q
Combine with :global to target only matching lines:
:g/TODO/normal @q
Tips
- Use
@@instead of@qto replay the most recently executed macro::%normal @@ - Unlike recursive macros, this stops cleanly at the end of the range with no risk of running past the target lines
- Prefer
:[range]normal @qoverN@q(repeat N times) when you know exactly which lines to target — it is more predictable and easier to undo - Works with any register, not just
q::%normal @a,:%normal @z, etc.