Skip to content

Instantly share code, notes, and snippets.

@Integralist
Last active September 4, 2025 05:56
Show Gist options
  • Select an option

  • Save Integralist/8d01300efcd2006c69e8b9492c0eada8 to your computer and use it in GitHub Desktop.

Select an option

Save Integralist/8d01300efcd2006c69e8b9492c0eada8 to your computer and use it in GitHub Desktop.
Vim: search and replace content using native vim cdo and cfdo commands #vim #replace #macro #quickfix

There are two 'types' to be aware of with a quickfix window:

  1. entry: the actual line content (e.g. :grep foo will show a specific line that matched within a file).
  2. file: the actual file itself (e.g. the path to the file that contained the match).

To replace content using vim (via the quickfix window) you need to choose whether you want to apply the change via the quickfix 'entry' or via the 'file' as a whole.

If you use cdo, then your 'action' (i.e. how you're going to replace content) will be applied to every entry in the quickfix window.

If you use cfdo, then your action will be applied to each file in the quickfix window.


So to understand the difference, let's consider an example scenario:

We have quickfix window that has two files:

  1. example1.txt
  2. example2.txt

The file example1.txt shows up multiple times, while example2.txt only shows up once.

The file example1.txt shows up multiple times because we searched for a phrase such as foo and that phrase happened to appear multiple times within example1.txt, while it only appeared once within example2.txt.

If you wanted to replace foo with bar using a subtitution like s/foo/bar, and you used cdo, then all occurences of foo would be replaced because the substitution would be executed across each entry in the quickfix window. But if you used cfdo then the substitution would only be applied once to the file and because you've not used % (e.g. :%s/foo/bar meaning apply the substitution across the entire buffer) only the first line of the file would be seen.

You could still use cfdo but you would either need to specify % or use a macro (see below example).

Examples

To execute a substitution for every 'entry' listed in the quickfix window use cdo:

:cdo s/v2/v3 | update

To execute a macro for every 'file' listed in the quickfix window use cfdo:

:cfdo execute "norm @q" | update
@juanramirezc2
Copy link

Awesome notes πŸ‘ Now I understand the difference between cdo and cfdo.
Thank you

@miltonkowalewski
Copy link

πŸ‘

@HarimbolaSantatra
Copy link

Thanks!

@morzel85
Copy link

morzel85 commented Oct 31, 2024

Just mind that if you want to really change all instances (in case there's many in a line) you might need a /g flag (depending on gdefault option). So run: :cfdo %s/foo/bar/g

@krehwell
Copy link

krehwell commented Jan 9, 2025

2025 and still the best explanation! πŸ‘

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment