Search and replace in Neovim

Find. Replace. Repeat.

August 27, 2025

Refactoring large projects in Neovim can be daunting, but it does not have to be. One of the most common questions I get is "How can I do proper search and replace in Neovim without a dedicated plugin?". Fortunately, there are two main approaches we could take.

1. Using a language server

Most of the common language servers implement the textDocument/rename method, which allows you to rename a variable, class, or function across the entire project. This is the safest way to perform project-wide refactoring since the server understands your code's structure.

2. Using substitute and cdo

Sometimes, you may be working in a project or environment where no language server is available, or you need to refactor something that is not tracked, like comments. In these cases, you can use the :substitute command to replace every occurance of a term.

:%s/foo/bar/
%Range specifier for the whole file ssubstitute fooOld value barNew value

Unfortunately substitute works only for the specified file so we can not make workspace wide changes, but thats where :cdo comes in.

Sort for "command do, ":cdo lets you run a command, such a substitute, across all files listed in the quickfix list.

To take advantage of this, the first step is to populate the quickfix list with the files or matches you want to modify.I recommend using a plugin like telescope or fzf-lua to streamline this process. With telescope, the workflow looks like this:

  1. 1. Open telescope regex search
  2. 2. Search for the keyword
  3. 3. Press Ctrl+q to put all items in the quickfix list

Now that the quickfix list is populated, you can run a substitute across all matching results using:

:cdo s/foo/bar/

Tipp

You can customize the behavior of the :substitute command by appending flags at the end. Here are two commonly used ones:

gReplace all occurrences in the line. Without this argument, only the first occurrence in each line is replaced cAsk for confirmation before each substitution
Share

Comments (0)