When editing, you may need to execute a command across multiple files. For example, replacing all
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.
The argument list (
argdo) uses file as the scope. To create an argument list consisting of
: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
:last, etc. Make sure that you are on the first entry before running the command.
:argdo %s/kale/pancake/g | update. That's it. All kales inside
file3.txt are now substituted with pancakes. Sweet!
:argdoperforms the given command on all entry in the argument list.
:%s/kale/pancake/gis the substitute command.
|lets you to chain multiple commands together.
updatesaves each file.
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
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
If you notice, on the list above you'll see
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
: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.
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
cfdo combos. Once you get comfortable with them, play around with the other commands.
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!