Can developers survive without a good search in their editor? Who has never used the famous find and replace trick in one or multiple files?
The good new is: Vim search features are pure awesomeness. With a minimum of configuration, you can search whatever you want, wherever you want, at light speed.
We'll see in this article how to:
- Search in the current file.
- Search in multiple files.
- Find and replace everything you dream of.
- Use great plug-ins to transform Vim in a Search Monster™.
Without the search features I'll present you in this article, Vim would maybe not be part of my Mouseless Development Environment.
I'm currently writing a book to build your own Mouseless Development Environment, where I explain how to combine powerful tools to improve and customize your development worklow.
A little precision: I will often refer to Vim current working directory in this article. The ex command
:pwd can tell you what's yours. To change it, you can use
If you don't feel comfortable using Vim, I cover the basics you need to know here.
Enough babbling. Let's launch Vim, and let's search! I invite you to try the tips of this article while you read them: it will help you learn and remember.
To search in the current file, you just need to type
/ in normal mode. Then, you need to type your search pattern, press
enter, and the result becomes highlighted in your file.
To go backward and forward through the results, you can type
/ will search forward in the file. If you need to directly search backward, you can use
It's practical to see the search highlighted in the file, but it's not enabled by default. To do so, you can type the command
:set hlsearch, or set it permanently in your
If you use Neovim, the highlighting is set by default.
:noh in normal mode will clear this highlight you tried to get rid of by trying (almost) every button on your keyboard. You know, like when you tried to quit Vim the first time.
Since you don't really want to type this command each time you do a search, you can map a key to this command in your vimrc as follows:
map <esc> :noh<cr>.
Each time you will type
esc, you will clear the last search highlighted and therefore keep your sanity. Lucky you.
To search the word under your cursor:
- Place your cursor on the word you want to search.
/, every result will be highlighted.
To search for partial words (including word parts in the results), you can use the keystroke
If you want to ignore the case, here you go:
/search\C- Case-sensitive search.
/search\c- Case-insensitive search.
You can as well write the following command in your
set ignorecase- All your searches will be case-insensitive.
set smartcase- Your search will be case-sensitive if it contains an uppercase letter.
Be aware that
ignorecase needs to be set for
smartcase to work.
Searching in one file is great, but what about a whole project? It's where you realize that Vim is crazy fast.
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
:cprev (or :
cp) to go through the results (instead of
You can as well open the quickfix window with
:copen and go through the results.
:vimgrep pattern *- Search the pattern in every file of the working directory.
:vimgrep pattern a.txt b.txt c.txt- Search the same pattern only in the files "a.txt", "b.txt" and "c.txt".
:vimgrep pattern *.php- Search "pattern" in every php files.
:vimgrep pattern **/*.php- Search "pattern" in every php files in the working directory and every subdirectory.
Quick tip: since the command
@: repeat your last command, you can go through all your results by taping
:cnext and then only using the
For more information about
vimgrep, I strongly advice you to look at the excellent vimcast about it.
I encourage you to read Vim's help about vimgrep by typing
:help vimgrep. Actually, I encourage you to use Vim's help as often as you can.
Vimgrep is good but unfortunately "slow". Don't panic: compared to some IDE, it's still fast.
As an alternative you can use the external grep directly in Vim. Obviously you need
grep to be installed on your machine. Something tells me that it is.
vimgrep is similar. For example:
:grep mySearch *- Search every occurences of
mySearchin the working directory
:grep mySearch a.txt b.txt c.txt- Search every occurences of
mySearchin 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 (
man grep or grep manual). For its use in Vim you can type execute
Vim has a powerful find and replace functionality thanks to the
Let's look at some examples:
:s/pattern/replace/g- Substitute "pattern" by "replace" on the current line.
:%s/pattern/replace/g- Substitute "pattern" by "replace" in the current file.
:%s//replace/g- Substitute your last search by "replace" in the current file.
You may ask yourself: what the hell those letters and signs mean? Good question!
- The letter
- The keyword
%will target the entire file instead of the current line. You can use it with different commands in different context.
- The keyword
gmeans "global": more than one occurrence is targeted. Without it, only the first occurrence in the file (or the in line) would be replaced.
Those are the most common
substitute command you'll use. I encourage you to consult Vim's help (again?) by typing
:help substitute. I'll never say it enough.
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.
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 with
- Use the keystroke
cgnon the first result to replace it.
Nto go to the next result.
.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'll see that
gn is the same as
n, except that it will start Visual mode and select the occurrence. We just do a change (
c) on the next (selected) searched occurrence. From there, you can easily understand that keystrokes like
dgn will work as well.
With this simple technique, you can do a granular find and replace in the whole file.
To find and replace in multiple files, you can use the excellent Vim arglist. Think of it as an internal list of files you can modify.
If you want to replace an occurrence in every
twig files, you can type the following:
:arg *.html- Empty the buffer and populate the arglist with all
htmlfiles in the current working directory.
:argadd *.twig- Add
twigfiles to the arglist.
:argdo %s/pattern/replace/ge | update- Replace the occurence
replacein every file of the arglist.
At that point you might scream to your screen, violently shacked by extrem curiosity: what means
e at the end of the
substitute command? It prevents 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 the subdirectories? You need to populate the arglist as follows:
You need to find and replace in the open buffer? Easy! I expected you to have more difficult questions. You can execute:
:bufdo %s/pattern/replace/ge | update
Do you know what I encourage you to read?
It's good to know how to search in bare bone Vim, especially when you're lost in a remote server far aways from your lovely
I have a good new: there are better alternatives for
grep or using the
arglist to find and replace in files. The plugins described here might change your search life forever!
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.
- 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 you want.
- It can be coupled with Vim to search in many stuff like buffers, tags, the command history, the open files history…
Here are 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.
fzf is a powerful tool, but it's not enough to search a precise occurrence in a bunch of files. You need another crazy fast terminal program: ripgrep.
This tool is very similar to
grep. Actually, if you look closer at its name, it even tries to kill
grep. Coupled to
ripgrep 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
ripgrep, you can look at my fzf config file on Github.
Then you just have to enter the command
:Rg pattern to search "pattern" in every file in the working directory.
You can use as well
ripgrep instead of
grep for the
:grep command. In the terminal, you call it with
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. If you have ripgrep installed on your system, this plugin will use it by default.
Here's how it works:
:Ack pattern- Search in the working directory.
:Ack pattern /path/to/directory- Search in the specified path and its subdirectories.
At that point, Ferret will populate the quickfix window with every result 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.
:Acks /pattern/replacement/ will replace every results still present in the quickfix window.
Simple, granular, and powerful: that's what we want.
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 needs to be in a whole project, or in multiple files, I use the combo:
If you know other functionalities (or plugins) which can bring even more coolness in our search life, the comment section is ready for you.
You know, sharing is caring.