Neovim - how to do project-wide find and replace?
HTML-код
- Опубликовано: 1 июл 2024
- So you are using Neovim but being able to do something as simple as find and replace across your project seems baffling. I'll show you how I do it. It is quick and efficient, especially if you have Telescope.
Here is what I use: `cfdo %s/stringOne/stringTwo/g | update | bd`
There is also a great gist with further clarification on differences between ‘cdo’ and ‘cfdo’ here: gist.github.com/Integralist/8... (in reference to my example you need the % symbol with cfdo so it goes over the whole file)
Here are my Neovim config files: gist.github.com/benfrain/97f2...
0:00 Introduction
0:36 Once at normal speed (short version)
1:09 Command about to be run
1:50 Explaining what is actually being done
1:56 First, find the strings
2:33 Send the instances to the Quickfix list
3:30 Iterate on the instances with `cfdo`
4:20 The command piping into update and bd
6:00 Conclusion, like, subscribe (please!) Наука
Thank you! I've been postponing this learning for ages.
Thank you! Impressive tip!
I recently learned about `cdo` and I was just wondering `what's the difference between that and cdo?` haha and you just exaplained that in a very easy to understand approach. Thanks!
Excellent. Some good extra nuance in the gist by Integralist that’s linked in the description 👍
TIL update command exists. Thanks Ben.
Thanks for this video, great tutorial! I didn't know about cfdo, I have been using cdo, but it's time to change that :)
Ben you're a legend
Hi Ben, I saw your dotfiles repo is empty. Any plans to share your config? Looks clean!
Ah! Just added a link to the description. They are in a gist here: gist.github.com/benfrain/97f2b91087121b2d4ba0dcc4202d252f (ones that start x are unused plugins currently)
@@benfrainuk Thanks a lot! I appreciate this very much. Subscribed. :)
Cool and all, but typing the search term again is.. not so good
does refactor in coc.vim not work in php?
Don’t use CoC. But LSP replace (assuming that is the kind of thing you mean) only works in certain languages, and of those, the ones you have an LSP installed for.
Why won't you use the LSP rename functionality? You basically use the LSP function to rename and don't have to worry about references that are not part of whatever you are renaming. Meaning if a local object has a similar name inside a function that needs to keep its name it won't change that. And LSP refactor is similar to a regular IDE rename function. I have the following keybinding: `vim.keymap.set('n', 'r', vim.lsp.buf.rename, {})` and then you do `:wa` to write to all the buffers
You don’t always have an LSP.
@@benfrainuk I do appreciate your time and effort, so keep up the good work 👍. But for most languages you have one (including PHP). The description + intro makes it sound that this is the way to do it in Neovim which is not really true, only in cases where you don't have a LSP for that project (obscure languages). Anyway still think this is interesting, but I just wanted to post this because the LSP rename function is much more convenient for most users.
@@norlockI use LSP rename plenty too but there are often occasions when I am working on a bunch of JSON and text files or just some random string that doesn’t sit well with LSP so need to do this on occasions where LSP won’t help
Is location list only for one file? So that is the difference...
One window as opposed to whole session. Here is a good overview with more info: freshman.tech/vim-quickfix-and-location-list/
I'm one of the devs of nvim-spectre (after inactivity of windwp). It's hard to keep it up. Maybe better people make replace and find without plugins tho. Let spectre rest, lmao.
I can imagine it’s often a thankless task, so thanks 🙏
Thanks for the work you do! Spectre can be a little buggy sometimes but its worlds better than the quickfix workflow. I think the idea of the search and replace ui as a buffer and seeing how your changes will look live is genius.
BTW I usally prefer `cdo` because if you 2 or more lines on a file, it will change everything and the second time it will send you an error that the line isn't exist anymore in it's older state,
and another thing in cdo you don't need to add the `%` because you already have the specific line
so you basically going over all of file again and again
it tend to be very slow in my workspace (maybe I have lots of big files)
and another thing, you can also close the buffer only after you run it so it's already keeps the buffer open
anyhow who ever reads it can try `cdo s/get_header/get_sausages/g ` then ` xa!`
and another thing, you can use telescope to search only on the git files that is not searching on all of the ignore files,
or even better use the vimgrep and grep only on your specific files (in this example *.php)
Wait, are you saying you find ‘cdo’ faster than ‘cfdo’ ? I find exactly the opposite?? 🤔
Actually, just found a good gist from Integralist which helps explain what each does. 👍 gist.github.com/Integralist/8d01300efcd2006c69e8b9492c0eada8# will also add that to video description
Thanks Ben, helpful video! If you have lsp setup, this is much easier, I have vim.lsp.buf.rename mapped to rn and it just prompts for the new name and does the update over the whole project - of course doesn't work if there's no lsp for that project but that is super rare
LSP rename is only useful for well defined language symbols (usually variable names).
If you want to refactor something else, or your language symbols are more vague, such that the LSP struggles to trace all the usages, manual substitution can be more powerful.
Then there's the scenario where you're working with a language or project you don't often use and you don't want to install and configure an LSP for the one-off task.
@@benfrainuk so I guess it's explained in the gist
so it will be faster if you do cdo without the %
and then sava all buffer at once in `xa`
but if you are using the % and "update"
cdo will be slower