Let’s dive into vim search
Can a developer live without a good search engine in his editor or IDE? What developer never used the famous find and replace in multiple files?
Yep. Nobody.
You can be happy though, dear Vim user: your editor totally shine by its search features! With a minimum of configuration you can be able to search whatever you want, wherever you want at light speed.
You need to use Vim to find and replace occurrences in thousand of files and filter with a maximum of granularity? This article will teach you the “how” if you are ready to learn it.
A little precision: I will often refer to Vim current working directory in this article. To know what directory it is for you, execute in Vim the ex command :pwd
. To change it, you can use :cd mydirectory
.
Enough small talk. Let’s dive in!
Vanilla Vim search capabilities
Learning vanilla Vim capabilities without trying plugins at first allow you to be efficient regardless of Vim’s configuration.
Being efficient in Vim without your precious vimrc is priceless. Specially when you are lost on a remote server trying to fix-quickly-this-wrong-configuration-which-crash-the-whole-thing.
Vim search in the current file
The basics
In order to search in the current open file, you just need to type /
in normal mode. Then you need to type your search pattern and the result become highlighted in your file.
To go back and forth through the results, you can type n
to go forward in the file and N
to go backward.
Using /
will search forward in the file. If you need to directly search backward, you can use ?
instead.
Setting the search highlights
It is very practical to see the search highlighted in the file. However in Vim it’s not activated by default. To activate it, you can type :set hlsearch
or set it in your vimrc
.
If you use Neovim, the highlighting is set by default.
Clearing the last search highlight
The command :noh
in normal mode will clear this highlight you tried to get rid off by trying (almost) every button on your keyboard.
Since you don’t really want to type this command each time you do a search (we are all lazy here), you can map a key to the command in your vimrc as follow: map <esc> :noh<cr>
.
Each time you will type esc
, you will clear the last search highlighted and therefore keep your sanity. Lucky you.
Searching the word under the cursor
- Place your cursor on the word you want to search
- Type
*
og*
.
As with /
, every results will be highlighted.
To search for partial words (include word parts in the results), you can use the keystroke g*
.
Vim search case insensitive
/search\c
– Search with case insensitive/search\C
– Search with case sensitive
You can as well write the following command in your vimrc:
set ignorecase
– All your searches will be case insensitiveset smartcase
– Your search will be case sensitive if it contains an uppercase letter
Be aware that ignorecase
needs to be set for smartcase
to be set as well.
Vim search in files
vimgrep
The quickfix window after executing vimgrep kernel **/*.php
and :copen
Searching with vimgrep
will populate the quickfix list (see :help quickfix
and :help quickfix-window
in Vim) with the result of the search.
It implies that you need to use the command :cnext
and :cprev
to go through the results (instead of n
and N
respectively).
You can as well open the quickfix window with :copen
and go through the results.
For example:
:vimgrep pattern *
will search in every files of the working directory the word “pattern”.:vimgrep pattern a.txt b.txt c.txt
will search the same word only in the files a.txt, b.txt and c.txt.:vimgrep pattern *.php
will search “pattern” in every php files:vimgrep pattern **/*.php
will search “pattern” in every php files in the working directory and every subdirectories
Quick tip: since the command @:
repeat your last command, you can go through all your results by taping :cnext
and then only using the @:
keystroke.
For more information about vimgrep
, I strongly advice you to look at the excellent vimcast about it.
Last but not least: you should read Vim’s help about vimgrep by typing :help vimgrep
.
Vim coupled with Grep
Vimgrep
is good but unfortunately pretty slow. As an alternative you can use the external program grep directly in Vim. Obviously you need grep
to be installed on your machine.
Using grep and vimgrep
is similar. For example:
:grep mySearch *
will search every occurences ofmySearch
in the working directory:grep mySearch a.txt b.txt c.txt
will search every occurences ofmySearch
in the files a.txt, b.txt, c.txt
I won’t cover here every use of grep
. You can read more about it in the official grep manual. For its use in Vim you can type in Vim :help grep
.
Vim find and replace
Vim substitute in the current file
Vim has a very powerful find and replace functionality thanks to the substitute
command.
Let’s look at some examples:
:s/pattern/replace/g
change each “pattern” by “replace” on the current line:%s/pattern/replace/g
change each “pattern” by “replace” in the current file:%s//replace/g
change your last search by “replace” in the current file
You may ask: what the hell those letters and signs mean? You’re curious, I like that.
- The letter
s
stands forsubstitute
- The keyword
%
will target the entire file instead of the current line. - The keyword
g
means “global” – more than one occurrences are targeted
Those are the most common substitute
command you will use. Nevertheless I encourage you to consult Vim’s help (again?) by typing :help substitute
.
Note that the substitute
command can be grandly enhanced by the excellent Tim Pope’s vim-abolish plugin. A must have for every cool Vim users out there!
And I know you’re cool.
This substitute will crash Symfony 4 kernel
Vim find and replace one occurrence at a time
It’s very simple to search and then decide if you want to keep or replace each result in a file:
- Execute a regular search like
/pattern
- Use the keystroke
cgn
on the first result to replace it - Type
n
orN
to go to the next result - Use
.
to replace the occurrence with the same replacement (or go to the next result if you want to keep it)
What is this cgn
keystroke you may ask? What does it mean? If you read :help gn
you will see that gn
is the same as n
but will as well start Visual mode and select the occurrence. We just do a change (c
) on the next (selected) search occurrence. From there you can can easily understand that things like cgN
or dgn
will work as well.
With this simple technique you can do a granular find and replace in the whole file.
Vim find and replace in files
You can use the excellent Vim arglist to do so. Think of it as an internal list of files you can populate and modify.
If you want to replace an occurrence in every html
and twig
files, you can type the following:
:arg *.html
– Empty the buffer and populate the arglist with allhtml
file in the current working directory:argadd *.twig
– Addtwig
files to the arglist:argdo %s/pattern/replace/ge | update
– Replace the occurencepattern
byreplace
in every files of the arglist
At that point you may scream to your screen, shacked violently by curiosity: what means e
at the end of the substitute
command? It simply prevent Vim to display an error message when the pattern is not found in a file.
What about doing a find and replace for the files in the working directory and subdirectories? You need to populate the arglist as follow:
:arg **/*.html
:argadd **/*.php
You need to find and replace in the open buffer? Well, it’s easy. I expected you to have more difficult questions. Simply execute:
:bufdo %s/pattern/replace/ge | update
Do you know what I encourage you to read? Yes: :help arglist
!
Vim search with external plugins
I have a good new: there are better alternatives for vimgrep
, grep
or using the arglist
to find and replace in files. The plugins described here will change your search life!
Be aware: I won’t cover every search plugins available. There are simply too many and I ’m too lazy for that. However I will give you the most powerful combo for any of your search needs.
That’s all we want, isn’t it?
Since we speak about Vim plugins, I wrote another article which list the necessary Vim plugins to build a Vim PHP IDE. In case you’re interested.
One Plugin to rule them all, One Plugin to find them
If there was one plugin I would take with me on a lost inhabited island (with a computer and Vim) it would be fzf.vim coupled with the command line fuzzy finder fzf. This is a must have. I beg you to try it and here’s why:
- It’s blazing fast (written in Go). Einstein was wrong: you can go beyond light speed
- It allows you to search in your terminal whatever file or history entry you want
- It can be coupled with Vim to search a lot of useful things like buffers, open files history…
Here some basic examples:
:Files
– Search a file in your working directory and subdirectories:Buffers
– Search a file open in one of your buffer:History
– Search a file in your open file history
Simple and highly configurable!
Search in files with Ripgrep
fzf is a powerful tool but it’s not enough to search a precise occurrence in a whole bunch of files. You need another crazy fast terminal program: ripgrep.
Ripgrep coupled with fzf will bring under your little fingers the best search engine I’ve ever seen in any IDE. No more, no less.
In order to link fzf with ripgrep, you can look to my fzf config file on github.
Then you just have to enter the command :Rg pattern
to search “pattern” in every files of the working directory. Mind blowing.
The sweet combo fzf / ripgrep
You can use as well ripgrep
instead of grep
for the :grep
command.
Find and replace in files with Vim ferret
The last plugin I use is ferret. It allows you to search an occurrence in multiple files, select what results you want to replace and finally replace them.
Moreover if you have ripgrep installed on your system, this plugin will use it by default!
:Ack pattern
will search in the working directory:Ack pattern /path/to/directory
will search in the specified path and its subdirectories
At that point Ferret will populate the quickfix window with every results found. You can delete the result by typing dd
in case you don’t want to replace it. You can as well type enter to open the file with the result highlighted.
Then typing :Acks /pattern/replacement/
will replace every results still present in the quickfix window.
Simple, granular, powerful: that’s what we want!
Vim is now a search-killing-machine
This overview will bring you whatever search functionality you need as a developer.
I personally use built-in vim search functionality when I search (or search in replace) in one file. When the search operation needs to be in a whole project or on multiple files, I use fzf, ripgrep and ferret.
If you know other functionalities / plugins which can bring even more coolness in our life, please don’t hesitate to let a comment!
You know, sharing is caring.