Vim Search, Find and Replace: a Detailed Guide
Tags: vim, terminal, productivity, mouseless
Published: 2020-08-05 14:45:33

---
title: Vim Search, Find and Replace: a Detailed Guide
published: true
description: Everything you need to search, find, and replace content in Vim, in one or multiple files, with or without plug-ins.
tags: #vim #terminal #productivity #mouseless
cover_image: https://thevaluable.dev/images/2017/vim-search/searching-lightsaber-vim.webp
canonical_url: https://thevaluable.dev/vim-search-find-replace/
---

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?

Nobody indeed.

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](https://themouseless.dev/), 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](https://www.sbf5.com/~cduan/technical/vi/vi-2.shtml) `:pwd` can tell you what's yours. To change it, you can use `:cd mydirectory`.

If you don't feel comfortable using Vim, I cover the [basics you need to know here](https://thevaluable.dev/vim-for-beginners/).

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](https://thevaluable.dev/learning-developer-efficiently-effectively/).

## Vim Search in the Current File

### Basics

To search in the current file, you just need to type `/` in [normal mode](https://en.wikibooks.org/wiki/Learning_the_vi_Editor/Vim/Modes). 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 `n` and `N` (for `n`ext) respectively.

Using `/` will search forward in the file. If you need to directly search backward, you can use `?` instead.

### Search Highlighting

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 `vimrc`.

If you use [Neovim](https://neovim.io/), 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 of by trying (almost) every button on your keyboard. You know, like when you tried to [quit Vim the first time](https://stackoverflow.com/questions/11828270/how-do-i-exit-the-vim-editor).

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](http://vim.wikia.com/wiki/Open_vimrc_file) 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.

### Searching the Word Under the Cursor

To search the word under your cursor:

1. Place your cursor on the word you want to search.
2. Type `*` or `g*`. 

As with `/`, every result will be highlighted. 

To search for partial words (including word parts in the results), you can use the keystroke `g*`.

### Search With Case Sentitive / Insensitive

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 `vimrc`:

* `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.

## Vim Search in Multiple Files

Searching in one file is great, but what about a whole project? It's where you realize that Vim is crazy fast.

### Searching with vimgrep

![vimgrep quickfix window](https://thevaluable.dev/images/2017/vim-search/vim-search-2.jpg)

Searching with `vimgrep` will populate the [quickfix list](http://vimdoc.sourceforge.net/htmldoc/quickfix.html) (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` (or `:cn`) and `:cprev` (or :`cp`) 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 *` - 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 `@:` keystroke.

For more information about `vimgrep`, I strongly advice you to look at the excellent [vimcast](http://vimcasts.org/episodes/search-multiple-files-with-vimgrep/) 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.

### Searching with grep

`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](https://en.wikipedia.org/wiki/Grep) directly in Vim. Obviously you need `grep` to be installed on your machine. Something tells me that it is.

Using `grep` and `vimgrep` is similar. For example:

* `:grep mySearch *` - Search every occurences of `mySearch` in the working directory
* `:grep mySearch a.txt b.txt c.txt` - Search every occurences of `mySearch` 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 (`man grep` or [grep manual](https://www.gnu.org/software/grep/manual/grep.html)). For its use in Vim you can type execute `:help grep`.

## Vim Find and Replace

### Substitution In the Current File

Vim has a powerful find and replace functionality thanks to the `substitute` command.

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 `s` stands for `substitute`.
* The keyword `%` will target the entire file instead of the current line. You can use it with different commands in different context.
* The keyword `g` means "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](https://github.com/tpope/vim-abolish) plugin. A must have for every cool Vim users out there! 

And I know you're cool.

![Vim substitute](https://thevaluable.dev/images/2017/vim-search/vim-search-3.jpg)
*This substitute will crash Symfony 4 kernel*

### 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:

1. Execute a regular search with `/`.
2. Use the keystroke `cgn` on the first result to replace it.
3. Type `n` or `N` to go to the next result.
4. 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'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 `cgN` or `dgn` will work as well. 

With this simple technique, you can do a granular *find and replace* in the whole file.

### Find and Replace in Multiple Files

To find and replace in multiple files, you can use the excellent Vim [arglist](http://vimcasts.org/episodes/meet-the-arglist/). Think of it as an internal list of files you can modify.

If you want to replace an occurrence in every `html` and `twig` files, you can type the following:

1. `:arg *.html` - Empty the [buffer](http://vim.wikia.com/wiki/Vim_buffer_FAQ) and populate the arglist with all `html` files in the current working directory.
2. `:argadd *.twig` - Add `twig` files to the arglist.
3. `:argdo %s/pattern/replace/ge | update` - Replace the occurence `pattern` by `replace` in 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:

* `:arg **/*.html`
* `:argadd **/*.php`

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? `:help arglist`.

## Vim Search with External Plugins

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 `vimrc`

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 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](https://thevaluable.dev/vim-php-ide/), in case you're interested.

### One Plugin to Rule Them All, One Plugin to Find Them

If there is one plugin I would take with me on a lost inhabited island (with a computer and Vim), it would be [fzf.vim](https://github.com/junegunn/fzf.vim) with its terminal twin [fzf](https://github.com/junegunn/fzf). This is a must-have. I beg you to try it. 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 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.

### Search, Vim, Search! Faster!

`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](https://github.com/BurntSushi/ripgrep).

This tool is very similar to `grep`. Actually, if you look closer at its name, it even tries to kill `grep`. Coupled to `fzf`, `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 `fzf` with `ripgrep`, you can look at my [fzf config file](https://github.com/Phantas0s/.dotfiles/blob/master/nvim/pluggedconf/fzf.nvimrc) on Github.

Then you just have to enter the command `:Rg pattern` to search "pattern" in every file in the working directory.

![Vim search is a beast with fzf and ripgrep ](https://thevaluable.dev/images/2017/vim-search/vim-search-4.jpg)
*The sweet combo fzf and ripgrep*

You can use as well `ripgrep` instead of `grep` for the `:grep` command. In the terminal, you call it with `rg`.

### Find and Replace in Multiple Files with Vim ferret

The last plugin I use is [ferret](https://github.com/wincent/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](https://github.com/BurntSushi/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.

Then, typing `:Acks /pattern/replacement/` will replace every results still present in the quickfix window.

Simple, granular, and powerful: that's what we want.

## Vim is Now Your Personal Search Beast

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: 

* [fzf](https://github.com/junegunn/fzf.vim)
* [ripgrep](https://github.com/BurntSushi/ripgrep)
* [ferret](https://github.com/wincent/ferret)

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.

![I love Vim so much!](https://thevaluable.dev/images/2017/vim-search/vim-search-5.jpg)