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.
#
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.
#
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.
Short 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. This can for
example be done with the grep command.
:grep 'To take' **/*.astro
Tip
I recommend using a plugin like telescope or fzf-lua to streamline
this process. With telescope, the workflow looks like this:
- 1. Open telescope regex search
- 2. Search for the keyword
-
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/
Tip
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