vim 2022-11-03

I’d like to change a sequence of the same characters in multiple places within a file. Ideally I would select the characters, highlight all the matches (with an indicator to show how many matches) and then change the sequence, in part or in full Example: I’d like to change mutliple occurances of ./bin/test with clojure -X:env/test:test/run (which can also be in a register after cutting from elsewhere) I am aware I can do :/s/patern/replacement/gn but that does mean typing the initial pattern rather than selection. Any other approaches? is there an equivalent neovim plugin for https://github.com/victorhge/iedit ?

If i understand the requirement correctly, you want to do a replace in a selection? In that case maybe doing a visual-line select of the area and then doing the search replace would work? Neovim should also preview the replacement as you type

Martynas Maciulevičius 2022-11-03T09:17:07.327899Z

Try this (replace hello with world and c means that you will go one-by-one): :%s/hello/world/gc Then press y to replace each occurence and n to skip

when replacing in a selection, the command would look something like :'<,'>s/foo/bar/gc

The '<,'> would be put automatically when you hit : in visual mode

What I would do in this simple example: * select text I want to replace using visual mode * press * to search for other occurrences * run substitution :%s//new-text note the substitute command uses the latest search pattern when left empty (the one started with *)

➕ 5

Registers are available in command-line mode via CTRL-R , so with the cursor on what you'd like to replace, doing :%s/ CTRL-R CTRL-A /new-text will pull the WORD under the cursor into the ex command. CTRL-R CTRL-W for word under the cursor, and if you're using evil-mode, CTRL-R CTRL-O for symbol under the cursor, which is really handy for clojure. Little bit more control than @nbardiuk’s suggestion, which I also like.

This sounds great, although in my particular example * is not matching the whole sequence, it stops when it gets to / character. The same issue with / occurs when entering the replacement text, as I assume Vim command line thinks its a command or something other than the text to replace. Without the / in the search and replace characters, then this is a very useful tip, thanks.

/ is arbitrary. You can do :%s#foo#bar (or any char you like) [edit: not sure I understood you correctly, but maybe a useful tip anyway]

Martynas Maciulevičius 2022-11-03T14:40:44.245279Z

You can also escape / by typing \/ 🤷

As, so for replace I can use any character as a separator, so long as its not in the sequence of characters that are the replacement text. I havent figured out how to select past a / character using * yet..

Closest I have come is as @rahul080327 mentioned, select all the text and do a substitute command, using # as a separator character

:'<,'>s#./bin/test#clojure -X:env/test:test/run
Not as simple as iedit in Emacs, but good to know. Thanks everyone.

what do you get by doing :set iskeyword ? in neovim I see it includes / for lisps, but not in vim. You can add a / by doing :set iskeyword+=/

There is also cdo , can do a search to find it in the “project”, and then cdo to update them… see this post https://chrisarcand.com/vims-new-cdo-command/

also, if you have already searched for the match, you can do a :'<,'>s##clojure -X:env/test:test/run and leave the search empty and it will use the last search

I have the following in place: 1. * and # are overridden with the https://vim.fandom.com/wiki/Search_for_visually_selected_text#Advanced 2. I have set inccommand=nosplit set so that when I type a replacement it shows it in the buffer. 3. I visually highlight what I want to replace and hit *, and this shows me a count in the command area. 4. I run :%s//replacement/g to do the replacement. a. I can optionally add a c for confirmation b. Sometimes between the first two // I do [ctrl-r]/ which will fill in the search, fully escaped thanks to the mapping in #1

Setting set inccommand=split will pop up a window at the bottom showing matches and updating as you type the replacement.

➕ 1
🤔 1

1. v<movement> - select the text I'd like to replace 2. * - search for selection (with the "advanced mappings" that @nate mentioned) 3. gv - reselect last selection 4. c<new-text><Esc> - 5. Go n.n.n.... for each search match This is far less elegant than the other solutions, but has a few advantages: • Working on a selection is much more reliable to me, than trying to get the search pattern right in cmd-mode. Especially when there are special chars involved that need to be escaped. (Name spaced keywords have /s too 😓) • You can use full insert mode to create your replacement text. This is handy when (e.g.) you want to replace text with something long and auto-completable. • You have the same one-at-a-time semantics as with :s//c. I find that I often don't want to replace all occurrences, especially when doing sub-word replacements.

Steps 3+4 are actually just a lazy way to do c<n><Space>. This could also be replaced with any other motion or text object, like cw, cE (vim-sexp), or even cif (vim-sexp). This turns your selection into a search-and-replace starting point, rather than the entire search pattern. It's also .-repeatable, but you probably need vim-repeat for some of them. This is super useful if, e.g., you have a bunch of similar forms that share a search pattern, and you'd like to replace all content in each of those forms.

When I do use cmd-mode :s (if there are many replacement sites), I usually still do visual selection first, and then insert it in cmd-mode from the / register with <C-r>/. This affords you the opportunity to edit customize the search pattern. Otherwise it's equivalent to :s//.