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

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
  • @a plays back register a as 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 @a to apply to lines 5–10 without visual selection
  • :% norm @a applies the macro to every line in the file
  • If the macro fails on a line (e.g. pattern not found), :norm skips that line and continues — unlike recursive macros which stop at the first error

Next

How do I match a pattern only when it is preceded or followed by another pattern, without including that context in the match?