I think vim's search&replace is a better deal

#1

Kakoune: %sWORDTOREPLACEcREPLACEMENT
vim: :s/WORDTOREPLACE/REPLACEMENT/gc

And I mean ‘c’. I use it all the time except when the entire file or selection fits on the screen. Which is not often in larger files. For non-vimmers, c causes an old-school confirmation prompt with yes/no/all/abort.


I understand kakoune is an experiment much like vis was (it looks inactive). I value kak for this because it’s high time other editors started learning from vim, and vim does have some poorly designed features. IDEs are learning from Emacs. I use neovim myself.

Color me skeptical about the whole multi-selection thingy. I think it works spectacularly (and ‘spectacular’ is the keyword here) for simple cases, but poorly for bigger ones, let alone advanced ones. I’m talking about a file with a few hundred lines of fairly unstructured code (not over 4000 of crap I deal with at work). There’s just no sensible way to deal with multi-selections that don’t fit on a screen!

Confirmation is very useful because it’s common to not get it perfectly right at the first time in a file that had a few authors. And there may be something you haven’t thought about. Confirmation prompt lets me skip a search&replace match or completely abort if I realize I made a terrible mistake. Kakoune effectively forces you to get it absolutely right the first time. And if you use regex, you better look at all your matches immediately because as soon as you press c they’re completely gone and you can’t see what was there.

The only way I found to re-view my search results before I nuke them is select first, then loop over with )(. I think this is putting the cart before the horse and more error-prone.

You can have great screenhots and trailers for a poor game. I think there are many games optimized for screenshots, not for playing. I think multi-selections are one of those things. It’s the same reason I take vimcasts.org with a grain of salt. Many of that guy’s tips seem optimized for showing off, not for practical work. I mean, whyYy would I want to move some lines up 1 line at a time instead of pasting them right where they belong. And pollute change history at the same time.

Another - in my eyes - advantage of vim’s approach is that it’s trivially repeatable by default, and trivial to edit as well. The problem with overly interactive programs is that you can’t script them easily, and vim sorta hits a good compromise between interactive and scriptable. When I type a comand, I don’t see selections as they change, but I see ahead what will happen later. Sometimes it works well, sometimes not so much. Either way having easily editable and reviewable commands encourages editor users to do just that, instead of using a “good enough” combination of keys that requires manual fixing afterwards.

Bonus: I have this in my .inputrc:

# This modifies UPARROW and DOWNARROW keys to supply commands from
# bash history file using INCREMENTAL SEARCH.
"\e[A": history-search-backward
"\e[B": history-search-forward
set show-all-if-ambiguous on
set completion-ignore-case on

This is for readline, not for vim. It works in Bash, in vim command mode, in python interpreter. Note this is not a nice way editor pieces fit together, just a nice way an operating system pieces fit together. And a couple of keys shorter than kakoune too.

Vim commands combined with search history mean that :command (ex?) mode is a bit like my spellbook. Usually I only have to type the first few characters of a command, uparrow, enter.

I’ll post more complaining in next threads, but this was a low hanging fruit (and I’m quite sure I know this part of kak well enough not to make a fool of myself).

#2

I noticed that too.
Just to compare, in Spacemacs, the evil mode (which allow to use it as in vim) is graphically well done from my point of view. Words to be replaced are “strikethrough” and you can see your new replacement on the side. By this way you confirm when all is well done. It’s seems even better that in vim itself.

#3

As you’ve mentioned later, you can jump between selections with ) (forward) and ( (backward).

About:

and

  • Search for match with /
  • Replace selection with c
  • Go to next match with n
  • Repeat replace with .
  • Repeat n. until you satisfied

You can slelect whole buffer with %, select a regexp with s, then cycle through each selection and skip remove some of those Alt+Space before replacing if you really need to. Or you can use search and replace as I’ve suggested above as a more granular way to control replacement.

You always use regexes in Kakoune, uless you explicitly tell it not to with \Q in front of query.

set inccommand=nosplit

Kakoune has this ootb.

#4
set inccommand=split

This is neovim feature though. There are plugins for Vim to acheive that: https://github.com/osyo-manga/vim-over

#5

I can not add this line in kakrc ?
I get

sh: line 6: [: next-2: integer expression expected
/.config/kak/kakrc:132:8958: ‘set’ wrong argument count
/kakoune/share/kak/kakrc:5:853: ‘evaluate-commands’ 97:17497: ‘source’ 132:8958: ‘set’ wrong argument count
error while parsing kakrc:
1:1: ‘source’ 5:853: ‘evaluate-commands’ 97:17497: ‘source’ 132:8958: ‘set’ wrong argument count

#6

this is neovim configuration option

#7

How do you vet that your changes do not affect unwanted parts of the code though?
Cycling with ( and ) in kakoune is not ideal, but it seems like a good compromise considering that you cannot always show everything that will be modified in just one screen.

#8

neovim has a nice feature: inccommand (no)split which opens a new window and shows all replacements that are being done like so:
image

I’ve proposed a similar behavior for Kakoune but with folding, that will hide all lines that have no cursors.

#9

You can move with the mouse to check everything is as you want before to apply the change.

#10

for me it is less convenient than moving with n or )

#11

Also, if we comparing equivalent Kakoune and Vim commands, a proper variant of Vim command would be:

%sWORDTOREPLACEcREPLACEMENT     - Kakoune
:%s/WORDTOREPLACE/REPLACEMENT/g - Vim

If you want this c behavior from Vim, just use search and replace as I’ve described:

  • Search for match with /
  • Replace selection with c
  • Go to next match with n
  • Repeat replace with .
  • Repeat n. until you satisfied

You also can emulate query replace with small prompt command:

define-command -docstring "Ask before repeating last command (with `.' (dot)) for next search match" \
query-repeat %{ try %{
    execute-keys n
    prompt "confirm? [yn]: " -on-change %{ execute-keys %sh{
        case ${kak_text} in
            y) printf "%s\n" "<esc>.: query-repeat<ret>";;
            n) printf "%s\n" "<esc>: query-repeat<ret>" ;;
            *) ;;
        esac
    }} nop
} catch %{
    fail "no search pattern"
}}

map global normal <c-n> ': query-repeat<ret>'
1 Like
#12

Yup I figured out most of things you recommended:
() in normavisual mode do work, but you have to opt in to do the right thing (so is putting g at the end of substitution command in vim, but I still think it’s more robust). That’s why I don’t consider it a “sensible” option in kakoune - you have to remember to do it every time.

More generally, bigger emphasis on interactive operations instead of commands means less ways to add options. Especially with kakoune’s apparent distaste for leader keys.

/ Search + n. does work, but it does little to showcase the power of multple selections.

I found out about set incommand=split (VIM option) today at work. It’s a very nice solution to my issues, but I’d prefer it didn’t immediately preview with replacement text. I usually know what I’m replacing with, it’s the "what’ that can go too far. I’m going to file a request at neovim github page.

I think this is an area that shows a good use of vim windows, and something that would be difficult to replicate in kakoune given its single window approach. I wonder how kakoune will handle this. (I use the i3 tiling window manager, so i totally don’t mind lack of split windows in kakoune).


Haha, that would be an interesting use of folding. Yes I agree folding mostly hides bad code, but sometimes you have no choice because it’s not your hobby project and the management won’t allow you to clean up. No value for shareholders blah blah. According to a book I own - “Working Effectively With Legacy Code” - only about 20% code is clean code, the rest is a sorry mess.

Also, folding can act as a makeshift tagbar. In vim, you can’t really use stock javascript parser with universal-ctags because it won’t understand all javascript frameworks and their custom syntax. You have to write your own parser using regexes, and that unfortunately can’t understand tag nesting. That’s where code folding comes in. You can mass-fold code at certain level and see the outline of the code.

#13

while I agree with most of what you’ve said, this statement is weird. Correct, but weird. It is correct, but only because the task, described by you in the initial comment, has nothing to do with multiple selections. It is simply not a multiple selection task because you want to granularly replace one piece of text with another – you have to do one by one replacement. It is equal for any other editor, and for those with multiple cursors too (emacs, sublime, atom, vscode) – they all have search n replace and replace all commands for this purpose. Kakoune doesn’t, because it’s easy to emulate with search replace repeat.

1 Like
#14

Kakoune can show this in separate client, windows doesn’t matter here. Windows are handled with external tools, but window is just window – a frame where the client sits, so this shouldn’t be a problem for Kakoune.

#15

It is correct, but only because the task, described by you in the initial comment, has nothing to do with multiple selections. It is simply not a multiple selection task because you want to granularly replace one piece of text with another

Good point.

By the way, I came up with a third way to deal with off-screen replacement targets: pagination ! It would work fine in vim, too.

Instead of answering y/n for every single match, you’d anwer y/n for each page worth of code. Another way of looking at this:

  • folding code except matches is good for previewing and seeing if you have false positives - phrases that match but souldn’t.
  • my suggestion with pagination is essentially viewing matches in context - more verbose, but much better at preventing false negatives - phrases that didn’t match but should.

Kakoune can show stuff in a separate client, but can it dynamically spawn separate client windows? Is that a thing?

By the way folding non-matching code would be a bit tricky. In vim, every fold takes 1 line, so you’d get 1 line divider between every group of folds. Not practical. But with no diving lines, how to show there’s folded ode between 2 matches? Something like git-gutter perhaps (sign column)

#16

another great option for global search/replace is kakoune-find - assuming you don’t need more than one line of context

#17

I’m using this extension quite heavily to do some sort of refactoring of several buffers, but I didn’t thought about it as a way to do replacement for single buffer, lol :smiley:

#18

sure. You can use toolsclient and jumpclient. You can set a specific client to be your client for any kind of tools, like grep, or make. You also can make any client a jump client – if you jump from any other client to definition of something the jumpcilent will be used. Plugins can also define their own tool client ans spawn clients, check out my tagbar.kak plugin, that creates tagbarclient as a separate panel like split (tmux) or separate window (X).

Basically any plugin can create clients that it needs for any kind of thing.

In case of such folding we can hide unneeded code completely (I guess it wont be a problem for Kakoune).

#19

About the OP’s original query: up to a few days ago (when I started to learn about multiple selections in kak), I would have agreed that multiple cursors are gimmicky. I don’t agree any more, however, because I now see how powerful they can be. But to feel the power you need to go beyond search-and-replace tasks (which are bad examples of multiple-cursor advocacy). The real power comes from combining a regex-search task with kak’s movements. E.g., imagine a list of

Name: first-name family-name

You can select the whole buffer, filter for ^Name with a regex search, then press ESC, then move 2 words to the right to skip the first-name fields, and set the family-name to uppercase with a single key.

This would be very awkward to do without multiple cursors (perhaps a more complex regex with capture of the 3rd word? or a macro?).

My tentative conclusions: 1) search-and-replace is not the best way to advertise multiple cursors, and 2) considering the whole kak package (= regex search + multiple-cursor movement commands), vim’s search-is-replace is not a better deal.

1 Like
#20

The only way I found to re-view my search results before I nuke them is select first, then loop over with )(. I think this is putting the cart before the horse and more error-prone.

And that’s exactly what you did by inserting a % on Kakoune with

Kakoune: %sWORDTOREPLACEcREPLACEMENT
vim: :s/WORDTOREPLACE/REPLACEMENT/gc

The confirmation prompt is a confirmation bias on your part, as long as you allow it to.

replace with (y/n/a/q/l/^E/^Y)? is redundant , because if you need a message reminding you what to do next, you could probably accomplish the same as long you retrain your muscle memory on Kakoune, while doing a search-replace. After all, we’re all creatures of habit. Then again, why %?

take for example the following:

foo bar. foo bar. foo bar

I just want to capitalize the beginning of the sentences, not the paragraph, and if you want to call that a sentence, on Emacs this would be

 M-x replace-regexp
 \(\. \w\)
 \,(capitalize \1)

but i seems a stretch after all.

With vim things improved but not much really.

 :%s/\. [a-z]/\U&/gc