This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-11-03
Channels
- # announcements (17)
- # asami (17)
- # babashka (20)
- # beginners (110)
- # calva (1)
- # cherry (3)
- # cider (1)
- # clj-kondo (21)
- # clj-on-windows (1)
- # cljsrn (5)
- # clojure (142)
- # clojure-austin (1)
- # clojure-europe (72)
- # clojure-france (28)
- # clojure-hungary (2)
- # clojure-nl (2)
- # clojure-norway (38)
- # clojure-poland (2)
- # clojure-uk (3)
- # clojurescript (4)
- # cursive (33)
- # data-science (3)
- # datahike (5)
- # datomic (1)
- # emacs (27)
- # events (3)
- # fulcro (15)
- # graalvm (4)
- # gratitude (2)
- # honeysql (7)
- # humbleui (8)
- # introduce-yourself (11)
- # jobs-discuss (9)
- # lambdaisland (3)
- # lsp (18)
- # malli (62)
- # music (1)
- # nbb (3)
- # off-topic (10)
- # pathom (3)
- # pedestal (6)
- # polylith (5)
- # re-frame (7)
- # releases (2)
- # shadow-cljs (33)
- # sql (1)
- # test-check (23)
- # vim (20)
- # xtdb (9)
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
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 *
)
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 @U076FM90B’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]
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 @U7ERLH6JX 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. v<movement>
- select the text I'd like to replace
2. *
- search for selection (with the "advanced mappings" that @U0510902N 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.