How do I run a recorded macro on every quickfix match without touching unrelated lines?
Answer
:cdo normal! @q
Explanation
When a refactor target spans many files but only specific matches matter, running a macro globally is risky. :cdo scopes execution to quickfix entries only, so your macro runs exactly where your search populated the list. This gives you repeatable bulk edits with tighter blast radius than :argdo or :bufdo.
How it works
- Build a quickfix list first (for example with
:vimgrepor a grep plugin). - Record your edit macro into register
q(qq ... q). :cdoiterates each quickfix entry (file + line).normal! @qexecutes macroqin unmapped Normal mode at each entry location.
Because entries can include multiple hits in the same file, this pattern is ideal for surgical replacements where context matters.
Example
Suppose quickfix contains only lines with deprecated API calls:
app/a.py:14: old_call(user)
app/b.py:99: old_call(admin)
After recording a macro that rewrites old_call( to new_call(, run:
:cdo normal! @q
Only quickfix-targeted lines are modified; unrelated occurrences outside the list are untouched.
Tips
- Dry run first with
:cdo pto print target lines. - Add
updatein a second pass (:cdo update) to write only changed buffers. - Use
normal!(with bang) to ignore custom mappings inside automation.