4 ms·
This has one huge shortcoming: when the next match is off-screen, pressing . jumps immediately to the next match and replaces it, before you had the opportunity
by nightcracker 6y ago
This has one huge shortcoming: when the next match is off-screen, pressing . jumps immediately to the next match and replaces it, before you had the opportunity to review whether you want that.
To solve this I wrote a little plugin (that I finished as a plugin yesterday and uploaded just now): https://github.com/orlp/vim-quick-replace https://github.com/orlp/vim-quick-replace
It requires vim-repeat (and a patched one because the current one has an issue): https://github.com/orlp/vim-repeat https://github.com/orlp/vim-repeat
The nice thing is that it always jumps to the next match before replacing, and if you choose to replace the current match it immediately jumps to the next one, so that you can evaluate whether you want to replace it.
You can start in two quick ways: using the current word under the cursor or the current visual selection, so it's very flexible. For me replacing a variable name is often just putting my cursor on it, pressing space + r, typing the replacement name and then a couple .'s, n's and if I mess up some u's.
To see it in action: https://i.imgur.com/wEX6O1w.mp4 https://i.imgur.com/wEX6O1w.mp4
- tasty_freeze 6y agoI'm not sure exactly what your plugin does, but are you aware of the "c" flag to substitute, eg :%s/debug/dbg/c vim will show the text which is about to be modified, and you have a prompt to confirm, skip, or quit (and some others).
- nightcracker 6y agoYes, I am aware, but it's not nearly as flexible and quick. It doesn't allow me to in the meantime move my cursor around, switch buffers, undo, open/close a fold, etc. It takes complete control of your workflow to temporarily put you in some special 'search/replace mode' in a very non-Vimlike manner. My plugin has a simple operation (if cursor is on a match, replace, regardless jump to next match) that gets repeated with ., combined with nN and u and you have complete control while also rapidly doing search/replace. And you would still need some nice mappings to substitute the word/selection underneath the cursor with :%s///gc.
- chrismorgan 6y agoIf using the [c] flag and you want to interrupt it, a convenient way of continuing where you left off (and not touching previous lines, which may have new matches, depending on the nature of the replacement) may be :.,$&&<Enter>, which means “operating on the range current line (.) to end of file ($), execute the last substitution (&) with the same flags as last time (&)”. (This is very unlikely to interest you, but I mention it for the sake of others. I’ve commonly seen people not really know about ranges especially, never stopping and thinking about what the % means (see `:help :%` if you don’t know), beyond possibly having encountered '<,'> by accident when pressing : in Visual mode (for explanation of these, see the help for :', '< and '>).)
- coliveira 6y agoYou can just type n, followed by ., to view the next match before changing it.
- nightcracker 6y agoI used to do that but my brain messes up "n." for replace, "n" for skip, whereas "." for replace, "n" for skip is really easy.
- bxparks 6y agoThat's a good point about previewing. So instead of "cgn", it looks like you can do "gns", which highlights the match, then enters into substitution mode, and you type the replacement, then hit <ESC>. Then you can hit "n." "n." "n." repeatedly, where the "n" goes to the next match so that you can preview, and the "." applies the replacement. Not quite as efficient as a single ".", but the "n." sequence is a familiar one.
- tvrg 6y agoIs this much different from searching with * or :s for a match and use something like "ciwReplacement<Esc>", then "n." or just "n" if I don't want to change the match? I can imagine that the plugin works in more complicated cases, but most of the time I probably just want to replace a word with ciw or ciW.
- nightcracker 6y agoWell, assuming you already have a plugin or mapping that makes * search your visual selection, it's similar. You'd have to do *, then N to back to where you just were, then cgn, type your replacement, and then n., n., n., n (skip), n., etc. With my plugin that just becomes one mapping, type your replacement, ., ., n (skip), ., etc. It's just very smooth, which I like because I use this operation literally all the time. Hell, I'll even use it when changing a single variable, just to make sure there isn't another sneaky one in the file somewhere.
- ThrustVectoring 6y agoIMO the "correct" way to handle this is with vanilla vim's built-in macros. Find the next match, record a macro making the edit you want, then find the next match and finish recording the macro. The macro starts with the cursor over the match you want, the edit can be more complex than a simple replacement, and skipping is simply a matter of pressing `n` instead of `@@`. Vim can also take a command that yields a list of filenames as a launch parameter via something like `vim $(ag -l target_string)`, letting you go through each file with a `:n`, letting you complete large refactors surprisingly quickly.
- thomastjeffery 6y agoBut if you're not sure you wanted it, you can just press u to undo and n to skip. Since Vim keeps an undo tree, you are guaranteed not to lose anything anyway.
- ABitMoreDepth 6y agoCan't you just press n to jump to the next match without substituting, then if you're happy to continue, press . and it'll replace it? I use n and p with cgn all the time. Works a treat!