How do I run a substitution or command on every line in the quickfix list?
Answer
:cdo
Explanation
:cdo {cmd} executes {cmd} on each entry in the quickfix list — one by one, jumping to each location in turn. This is the surgical way to apply a change to exactly the files and lines that a previous search or compile step identified, rather than a blanket :bufdo across all open buffers.
How it works
:cdo {cmd}— run{cmd}on every quickfix entry (each matching line):cfdo {cmd}— run{cmd}once per file that appears in the quickfix list (not per line)- After running
:cdo, use:cfdo updateor:wato save the changed files
A typical workflow using :vimgrep + :cdo:
:vimgrep /oldFunction/ **/*.js
:cdo s/oldFunction/newFunction/g | update
Example
Suppose :vimgrep /TODO/ **/*.py finds 12 occurrences across 5 files. To prepend FIXME: to each TODO comment:
:cdo s/TODO/FIXME: TODO/
:cfdo update
This visits each of the 12 lines and runs the substitution, then saves each affected file exactly once with :cfdo update.
Tips
- Combine with
:grepor any tool that populates the quickfix list (e.g.,ripgrepvia:set grepprg=rg\ --vimgrep) - Use
:cdo norm @ato replay a macro on every quickfix entry :ldoand:lfdoare the location-list equivalents if you prefer per-window lists