Executing a Command in Multiple Files in Vim
When editing, you may need to execute a command across multiple files. For example, replacing all let
with const
.
There are eight different ways you can do this in Vim.
:argdo argument list (files)
:bufdo buffers
:windo windows in the current tab
:tabdo tabs
:cdo each item in the quickfix list
:cfdo each file in the quickfix list
:ldo each item in the location list
:lfdo each file in the location list
Eight sounds like a lot of methods learn at once. However, the principle behind all of them is the same: make a list of what you want to change, then run the command to the entire member of that group, then save. The only difference is the scope of each entry.
Let's go over two of them here. Once you get a feeling how it works, using any of the methods above is just a matter of syntactical differences.
Argument List
The argument list (argdo
) uses file as the scope. To create an argument list consisting of file1.txt
, file2.txt
, and file3.txt
, run :args file1.txt file2.txt file3.txt
(you can also use the blob operator: run :args *txt
to collect all txt files in the current directory, run :args **txt
to collect all txt files recursively, run :args z*txt
to collect all txt files in the current directory that starts with "z").
To check that you have the correct files, run :args
. On the bottom screen, you should see something like [file1.txt] file2.txt file3.txt
, indicating that you are currently on file1.txt
. You can move around the argument list with :next
, :prev
, :first
, :last
, etc. Make sure that you are on the first entry before running the command.
Now run :argdo %s/kale/pancake/g | update
. That's it. All kales inside file1.txt
, file2.txt
, and file3.txt
are now substituted with pancakes. Sweet!
Command breakdown:
-
:argdo
performs the given command on all entry in the argument list. -
:%s/kale/pancake/g
is the substitute command. -
|
lets you to chain multiple commands together. -
update
saves each file.
Quickfix List
Next, let's go over the quickfix list. If you not familiar, quickfix is Vim's special mode originally created to handle edit-compile-edit cycle error messages, but eventually evolved and used for all sorts of other things from displaying STDOUT when running async operations in vim-dispatch, fuzzy searching in fzf.vim, etc. For our purpose, think of it as a list of pointers to various location in your files.
Some commands in Vim automatically uses quickfix, like :make
, :grep
, and :vimgrep
.
If you need to list all occurrences of "veggies" inside any text file, run :vimgrep /veggies/ **txt
. To see the quickfix matches, run :copen
(quickfix open). To apply the substitute command to all quickfix matches, run :cfdo %s/kale/pancake/g | update
. That's it. It follows a similar pattern like the argument list: collect-apply-save.
You can move around in a quickfix list with :cfirst
, :clast
, :cnext
, :cprev
, etc.
If you notice, on the list above you'll see cfdo
and cdo
quickfix operations. What's the difference? The difference is that cfdo
is a per-file operator and cdo
is a per-match operator. cfdo
will run the command once per file and cdo
will run the command once per match.
If you have 5 matches for "veggies" inside file1.txt
, running :cfdo %s/kale/pancake/g
will run the command once while running :cdo %s/kale/pancake/g
will run the command 5 times.
Since we are running a file-wide command (%s
), it makes sense to run it only once per file.
Conclusion
Vim's multi-file operations are useful to apply a change across multiple files. There are eight different ways to accomplish this, although the underlying principle is the same: collect-apply-save. Play around with the args
/ argdo
and vimgrep
/ cfdo
combos. Once you get comfortable with them, play around with the other commands.
Happy Vimming!
Shameless disclaimer: if you enjoy this, there's a 98.39% (not scientifically proven) you will also enjoy my Vim Cookbook: Gourmet Vim. Check it out!
Top comments (1)
In my experience, though not extensively tested, vimgrep hangs up for a second before populating the quickfix/location list while if one uses grep from vim's command mode, it doesn't do that.
check :h :grep , for external grep inside vim help.
if performing a project wide search, make sure to exclude directories such as node_modules.