Power-Grepping with Vim
grep is an essential command in the standard UNIX toolkit. Vim brings it to the next level making it more interactive and applicable to a variety of contexts.
1 What is grep anyway?
It's a command-line tool for printing lines from files matching a given pattern. That is, files in their widest sense, since grep will also read from stdin if no files are specified. The behaviour of grep can be adjusted according to the user's need to e.g. print matches in colour (--color
option), or just count matching lines instead (-c
option), or only listing files with matches (-l
option) or, conversely, files without matches (-L
option).
Different versions of the regular expression syntax are supported. You can have grep stick to a basic one, but you can also use a more extended syntax (-E
option or the egrep
variant), or the Perl syntax (-P
option), or no syntax at all to treat your pattern as a verbatim string (-F
option). You can also be case-insensitive (-i
option).
In my early days with UNIX, which coincided with my early days with Windows too, I envied Windows 98 because it could not only search files by names, dates and other attributes, but also by contents. I was particularly pleased when I found that grep could also do this recursively in file hierarchies (-r
option), optionally following symbolic links (-R
option). You can also selectively include or exclude files from searching (with the --include
, --exclude
, --exclude-from
, --exclude-dir
options) although in practice I quite like using shell globbing for this purpose. This is me case-insensitively looking for the word motd
in a tree of Markdown files, which I want to see highlighted in colour:
grep --color -i motd **/*.md
Anyway, grep is an essential, very powerful tool and there isn't a day where I don't use it. A bit like Vim. And very often, I combine the two tools with :vimgrep
to go even further.
2 :vimgrep
Vim has got its own internal grep. The Vim command :vimgrep
will, right from your Vim session, search the specified files for a given pattern. What's convenient is that if you're well-versed in the Vim regular expression syntax, you will be able to use it to perform very advanced lookups. And what's extremely convenient is that the error list will be set to the matches. In other words, you will be able to open the quickfix window with the :cwindow
command to display the results and interactively work with them. Specifically, running the :cwindow
command results in splitting your Vim buffer in two, opening that so-called quickfix window into the lower half. It will list the search results, one match per line. Hit Enter
and you will interactively be taken to the match in the top window.
This means that unlike using just grep, there is no need to use your mouse to copy the matching file to paste it into a command line where you will open the file for looking at where that match was. The :vimgrep
command does all this for you. The quickfix window lets you move in it like you would in any other Vim window. You can further search in it (for instance with the / and ? keys). If you :set modifiable
, you can even edit its contents, e.g. for further filtering, although you really need a good reason for doing so because it will confuse the quickfix and hitting Enter key may not take you where you expect.
Of course, all the other quickfix commands will work: :cn
takes you to the next occurrence, :cp
takes you to the previous one and before long you will find yourself coupling all these into a quick macro to automatically perform operations on all the matches across all their files. The possibilities are, as always with Vim, endless.
It's slower than grep, undoubtedly, but it's so convenient it well makes up for it. I now most often use :vimgrep
right from my shell by directly passing it to Vim with the +
option:
vim +'vimgrep /motd/ **/*.md'
3 :helpgrep
All this makes you think about the power of the quickfix window, and equally makes you wish you could use it for other things too. For instance, if you use the :help
command often, you will probably have found it annoying that it commonly takes you to one and only search result which is never quite the one you wanted. Luckily, the :helpgrep
command is provided too, and a list of possible matches relevant to your search will be listed in a quickfix window which you can open with :cw
. And again, you will be able to jump into different parts of the online help system with e.g. :cn
, :cp
or by hitting Enter on a line which appears to be the one you want to read more about.
4 Any more grep?
It's very tempting at this stage to run:
:helpgrep grep\>
... find all the occurrences of words ending with grep
like vimgrep
and helpgrep
and see what else there is to grep. A quick scan through the results suggests that it's about it, in fact. But QuickFixCmdPre
will remind you of those other commands which can make use of the quickfix window, such as :make
which will list errors and let you interactively jump from one to the next.