How do I execute a macro on each quickfix match and write files only when changed?
Answer
:cdo normal! @a | update
Explanation
When you already have a precise quickfix list, :cdo is one of the safest ways to run a macro only where it matters. :cdo normal! @a | update executes macro register a at each quickfix entry, then writes the file only if it changed. This avoids blanket :argdo edits across unrelated files and gives you tight scope control for large refactors.
How it works
:cdoiterates over quickfix entries (not every line in every file)normal! @aruns macroawithout custom mapping interference| updatewrites the current buffer only when modified
This pairing is powerful because quickfix defines where to edit, and the macro defines what to edit. You can build the list with :vimgrep, :grep, or LSP diagnostics, then apply the same structural fix consistently.
Example
Imagine quickfix contains matches for a legacy API call across many files.
foo_old(arg1)
foo_old(arg2)
foo_old(arg3)
Record macro a once on a representative line to transform to foo_new(...), then run:
:cdo normal! @a | update
Each quickfix hit gets the same edit, and only changed files are saved.
Tips
- Dry-run first with
:copenand inspect entries before executing - Prefer
normal!overnormalto avoid user mappings affecting macro behavior - If you need confirmation per location, use a substitution command with
cflag instead of a macro - For window-local lists, use the parallel pattern
:ldo ...