Here's two vim versions of the "recursive, lazy, sed substitute" that the function is performing.
Both involve the same technique: filling one of vim's special lists and then calling the corresponding
arglist can be filled with files and traversed with
:prev, and a few other commands. Conveniently, we can run commands on all files in it with
In order to avoid messing with the global
arglist, we'll open a new window and use
What to but in the
… depends, but in this case let's grab all files under
src (this can be a bit slow on large directories):
(Unfortunately, this also finds directories; if you're interested in, say,
.c files, you can add the extension and get better matches. Otherwise, you need something like
:arglocal `find src -type f` on a *nix.)
Now substitute in
/e for ignoring files with no match and
:update to lazily write the changed files (don't forget
/g if you need it):
:argdo %substitute/…/…/e | update
You can wrap it up in a function, if you want (have a look at
Using the quickfix list.
Same idea, but more targeted.
In this case, we'll populate the quickfix list with
:grep (your choice; I use ripgrep, so while I use
:vimgrep for searching buffers already in vim, I prefer
:grep for general code searches).
:vimgrep /…/ src/**/*
" or, e.g.,
:grep -R … src
Now we can traverse all the entries with
:cdo or all the files with
:cfdo (optionally, filter the entries with
:help cfilter-plugin first):
:cdo substitute/…/…/ | update
We don't need
/e this time because
:substitute will only be run on lines already matching the pattern; similarly, we don't need
/g because all matching lines will be there.
Note that if you used
:vimgrep and the pattern for the search and substitute are the same, you can write
:cdo substitute//…/ | update
Both solutions avoid modifying files outside of vim, so you don't run into checktime/edit issues.