How do I apply a recorded macro to every line in a visual selection?
Answer
:'<,'>norm @a
Explanation
Combining :normal with a visual range lets you replay a macro on each line of a selection individually — far more targeted than recursive macros or @@ repeating. The :norm command runs a sequence of normal-mode keystrokes on every line in the given range, so pairing it with @a applies macro a to each selected line in turn.
How it works
:'<,'>is the range corresponding to the last visual selection (Vim inserts this automatically when you press:in visual mode)norm(short for:normal) executes its argument as if you typed it in normal mode, once per line@aplays back registeraas a macro- Vim positions the cursor at the start of each line before running the command
Example
You have a list of function names and want to wrap each in console.log(...). Record a macro on the first line:
getUser
fetchData
render
With cursor on getUser, record: qaconsole.log(<Esc>A)<Esc>q
Now select all three lines with VG and run:
:'<,'>norm @a
Result:
console.log(getUser)
console.log(fetchData)
console.log(render)
Tips
- Use a line range directly:
:5,10norm @ato apply to lines 5–10 without visual selection :% norm @aapplies the macro to every line in the file- If the macro fails on a line (e.g. pattern not found),
:normskips that line and continues — unlike recursive macros which stop at the first error