avatarAndrew Courter

Summary

The webpage provides guidance on performing multi-file search and replace operations in Neovim using various plugins and commands.

Abstract

The article discusses methods for conducting search and replace actions across multiple files in a Neovim project. It introduces the use of Telescope with :cdo for efficient text replacement, suggesting keymaps for streamlined operation. It also presents Nvim-Spectre as a plugin option for search and replace, detailing its interactive buffer and replacement commands. Additionally, the article covers CtrlSF, a plugin that emulates Sublime Text's search functionality, allowing in-buffer editing and easy navigation between matches. The author concludes by inviting readers to share their preferred methods and promotes further exploration of Neovim through additional resources and their technical interview services.

Opinions

  • The author endorses Telescope with :cdo for its ability to apply regex across quickfix list results, suggesting it as a viable alternative to other workflows.
  • Nvim-Spectre is recommended for its user-friendly interface and inline diffs, although it lacks a built-in undo feature, which the author notes as a limitation.
  • The author expresses a preference for exact matches when using Nvim-Spectre, implying that the default matching behavior may be too aggressive.
  • CtrlSF is praised for its straightforward approach and the advantage of undo capability, which is lost if the results buffer is closed and reopened.
  • The author encourages readers to experiment with the presented options and to engage with the community by sharing their own preferred tools and plugins in the comments.
  • A personal appeal is made for readers to consider the author's technical interview services and to explore their YouTube channel for related content.

Multi-file Search and Replace in Neovim

Been searching for a way to do a search and replace across your project like you would in VSCode? Or looking for alternatives for your existing workflow? Here are a few ways that you can find text and replace it across your project in Neovim.

Telescope + cdo

If you already have Telescope as a plugin then you shouldn’t need any more plugins to get this option to work for you.

If you don’t have Telescope installed here is a link to check it out:

Once you have Telescope installed, open up Telescope to find files or find a string or whatever you are searching for.

Here’s my keymap for opening find_files:

local builtin = require('telescope.builtin')
vim.keymap.set('n', '<leader>ff', builtin.find_files, { desc = "Find Files"})

Once you have your results, open the list in the quickfix list.

The default keymap for this in Telescope is Ctrl+Q.

You should now see those results available in your quickfix list and look something like this:

Now run the :cdo command to apply a regex on each entry in the list

:cdo %s/TEXT/NEW_TEXT/gc

Hit enter and you should be able to confirm each replace in the list.

Omit the ‘c’ if you don’t want to confirm each item.

Success!

Another option is to use :cfdo instead of :cdo, which will apply the command to each file instead of each result. This will result in fewer commands and better performance in large searches across your project.

Nvim-Spectre

Check out the Github link above to setup and view the commands / keymaps available for this plugin after installation.

To begin, hit <leader>S to open the search and replace buffer.

You should see something like the above screenshot.

Hit ? to see the available mappings

First enter insert mode (i) underneath the “Search” and you should see results pop into the bottom section of the buffer.

Next add your “Replace” string and you should see some inline diffs of what will be replaced.

Note: You can toggle how this view mode works using <leader>v.

To toggle items in the results use dd.

To replace all, use <leader>R.

To replace a single item, use <leader>rc.

You will see a “DONE” checkbox at the end of each selection that has been replaced.

Hit Enter to open up the selection in a buffer.

Note: There is no built-in undo capability so you will need to use git or something else if you need to rollback changes.

I have personally found myself toggling off ignore case (e.g. doing only exact matches) since it seems to be a very greedy match and will replace more occurrences than I want.

Here are two other keymaps for replacing text from the GitHub page:

vim.keymap.set('n', '<leader>sw', '<cmd>lua require("spectre").open_visual({select_word=true})<CR>', {
    desc = "Search current word"
})
vim.keymap.set('v', '<leader>sw', '<esc><cmd>lua require("spectre").open_visual()<CR>', {
    desc = "Search current word"
})
vim.keymap.set('n', '<leader>sp', '<cmd>lua require("spectre").open_file_search({select_word=true})<CR>', {
    desc = "Search on current file"
})

CtrlSF

Check out the Github link above to setup and view the commands available for this plugin after installation.

Essentially this plugin will open up a new buffer to allow you to modify search results just like you would in any normal file.

You can use other plugins to allow multi-cursor support or simply use %s replacements.

Start by using the following command to find a string and open it in a results buffer.

:CtrlSF SEARCH_TEXT

You should see something like the above screenshot where you have many files and results shown.

Use Ctrl-j / Ctrl-k to jump between matches and Ctrl-n / Ctrl-p to jump between files in the results.

If you want to preview a file then hit p. Hit P if you want to also focus the selection.

If you want to open that file then hit Enter on the selection.

Next use a %s replace command, hit enter and you should see a confirmation message after doing a :w

If you need to undo then simply hit u and then another :w

This plugin feels quite straight forward and I really like the undo capability in case I mess up a replacement. Note that you will lose this if you close and reopen the buffer from my experience.

Conclusion

You now have 3 different options to choose from when searching and replacing text across your project in Neovim. Which option do you prefer? Do you have a different plugin you use or prefer? Let me know in the comments so I can check it out too!

If you enjoyed this article, consider subscribing to Medium!

Here are a few other Neovim articles you should check out:

If you or your company are interested in having someone conduct technical interviews then please DM me on Twitter (@Exosyphon) or visit my website. If you enjoy topics like this then you might also like my Youtube channel. Have a great day!

Software Development
Software Engineering
Neovim
Vim
Programming
Recommended from ReadMedium