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

How do I run a substitution over every quickfix hit and save only changed files?

Answer

:cdo s/foo/bar/ge | update

Explanation

When quickfix already contains exactly the lines you want to touch, :cdo is the safest way to batch-edit with tight scope. Instead of running a blind project-wide substitution, you iterate only quickfix entries and write files only when they changed. This makes large refactors both faster and easier to audit.

How it works

  • :cdo runs the following Ex command on each quickfix entry
  • s/foo/bar/ge performs substitution on each visited line
  • g replaces all matches on that line
  • e suppresses “pattern not found” errors so the loop keeps moving
  • | update writes only buffers that were modified

This pattern is effective after :vimgrep, :grep, LSP diagnostics exports, or any workflow that materializes a curated quickfix list.

Example

Suppose quickfix is populated with deprecated API hits. Run:

:cdo s/old_api/new_api/ge | update

Vim walks each quickfix target, applies the replacement where it matches, and saves changed files without forcing writes on untouched buffers.

Tips

  • Add c to substitute flags (gec) for per-match confirmations during risky migrations.
  • Pair with :copen to review entries first and :colder/:cnewer to navigate quickfix history.
  • Use a more exact regex (word boundaries, namespaces) before running :cdo to avoid collateral edits.

Next

How do I populate a window-local location list from the current file and open it immediately?