Kakoune: w and <a-w> do not work as expected when end of selection falls on end of word.

Created on 12 Oct 2019  Â·  16Comments  Â·  Source: mawww/kakoune

Steps

Put the following text in a buffer:

c ccc ccc ccc
cc ccc ccc ccc

Move to the second line and do \ Now, try the same thing on the first line.

Outcome

The first "c" is not included in the resulting selection.

Expected

The first "c" should be in the selection.

Edit: A more refined test case:

    [   abcd]e     abc a                  w
       abc[de     ]abc a

OK, fine...

    [   abcde]     abc a                  w
       abcde[     ]abc a

...wait, what?

    [   abcde ]    abc a                  w
       abcde[     ]abc a

OK, I declare shenanigans.

Most helpful comment

OK, good, I'm glad I'm not going insane, here.

w and <a-w> badly need to get unfucked. I also tried doing it the kakoune way, and found the same inconsistencies and more.

Why are these:

       ab[c]d    a abc ab        w
       ab[cd    ]a abc ab        
       abcd[ ]   a abc ab        w
       abcd[    ]a abc ab        



md5-202d919ea20e685d5066b1af518d547d



       abc[d]    a abc ab        w
       abcd[    ]a abc ab        

Please tell me you can see this glaring irregularity in how the rules are enforced.

All 16 comments

This is not wrong. <a-w> is select to the next word start. If you have just "c" there is a word-start just there.

If you do <a-w>yp you see that the space between the words was selected, as documented.

If you want to select a word use <a-a>w or <a-i>w.

(I'm just now gave my first try to kakoune.)

Documentation as suggested:

w: select the word and following whitespaces on the right of selection end
l: select the character on the right of selection end

(It means [selected text].)

How l works? [a]bc -> a[b]c. So selection doesn't include the current character.

How w works? [a]bc -> [abc]. Identical word usage in documentation but selection includes the current character.

One more thing:

ab a abc abc
^  ^ ^   ^   where words beginning
  ^ ^   ^    whitespaces
^^ ^ ^^^ ^^^ word characters
             (there is nothing more here)

Now try it out in practice:

[a]b abc a abc        w
[ab ]abc a abc        d
[a]bc a abc           w
[abc ]a abc           d
[a] abc               w
a[ ]abc               d
a[a]bc                w
a[abc]                d
a[-]                  w
“no selections remaining”

It must be black magic because “a” is a word character that was simply skipped. I really want to know what's the explanation of this, just please don't tell it's “documented” or “it works right”. Because it doesn't... or if yes, I won't thinking anymore whether I should switch to kakoune or not.


[...] If you have just "c" there is a word-start just there.

So you say w skips the current gray block, that's why “c” didn't become selected? Then it doesn't work well in the 100-ε percent of cases.

[...] you see that the space between the words was selected, as documented.

Between? So you say too that space is surrounded by word characters? I can also confirm from several sources that “a” is classified as a word character.

If you want to select a word use w or w.

No. Sometimes people just simply need to “select the word and following whitespaces on the right of selection end” and they want to do it using w as documented.

OK, good, I'm glad I'm not going insane, here.

w and <a-w> badly need to get unfucked. I also tried doing it the kakoune way, and found the same inconsistencies and more.

Why are these:

       ab[c]d    a abc ab        w
       ab[cd    ]a abc ab        
       abcd[ ]   a abc ab        w
       abcd[    ]a abc ab        



md5-202d919ea20e685d5066b1af518d547d



       abc[d]    a abc ab        w
       abcd[    ]a abc ab        

Please tell me you can see this glaring irregularity in how the rules are enforced.

You're outside the document. Your problem is not that w or is not correct, but that you don't expect the way kakounes cursor works.

a[-]      w -> can't select anything

no selections remaining

but if you have a next line:

a[-]              w
something

a
[something]

There is an additional cursor position at the end of every line. The cursor becomes darker. If you come from vim, it is strange, but it is actually very consistent. I currently fail to find the documentation about that, maybe an longtime user can explain or point to the documentation? @Delapouite @lenormf

You maybe misunderstood, but my issue wasn't with “no selections remaining”, but the remaining “a” before it. How the hell can it happen that I start deleting words one after another and something remains?

As I noticed “w” selection always includes the character I'm standing on(*), so in this case:

[a] abc               w
a[ ]abc               d

“a” should be remain selected, like this:

[a ]abc               d

*: That I think is against documentation if I compare the wording to “l”.

I'm a bit wondered why this thread didn't get more (any) activity for months. I've read another inconsistency around x that skips empty lines in some circumstances... These basic things, that nobody thinks can be messed up and yet still not working after years, can took the mood of people. I'm unable to understand what are the priority tasks if not to fix these flaws as soon as possible.

Have you considered that these things might be carefully-chosen, and not accidental? Just because you personally don't understand why a thing behaves a certain way, doesn't mean that it happened by accident.

I'm not exactly sure what inconsistency around x you're talking about, but you might want to read #2206 and #2590. I don't happen to recall any previous discussion of w or <a-w>, but there's probably one around if you search.

w is not inconsistent, it moves to the next word start, selecting from the cursor position. W does the same, with the anchor fixed.

As a general rule, SelectMode::Replace moves and selects from the cursor position, while SelectMode::Extend applies with the anchor fixed.

You can check [normal.cc] and try the commands. They are very consistent, but it seems you expected that w moves by word instead of word start. I developed [word-select.kak] for that.

For “x on empty lines”, it is not that it is inconsistent, but context dependent. It selects the full line, and if satisfied the next line. Contrarily to other editors, the newline character is nothing special: you can select it like any other character. It means technically, you are not on an empty line: you are on a line with the newline selected, which is the full line, so pressing x will select the next line. If you do not want that extra behavior, you have the non smart version on Alt + x. You can map it to x if you want, and experiment if you like it.

As a general rule, when providing a smart or context dependent command, Kakoune provides the non smart version on Alt. It is a compromise between ease of interactivity and predictability for non interactive use, such as scripting.

Kakoune normal mode is very expressive, and while trying to be orthogonal, compromises have been made for pragmatism. You can see more in the [design.asciidoc] document.

Just because you personally don't understand why a thing behaves a certain way, doesn't mean that it happened by accident.

I found the behavior rather inconsistent. That's why I don't understand how it works.

w is not inconsistent, it moves to the next word start, selecting from the cursor position.

I feel myself _really-really_ stupid, but you say this. No?

abc ab a abc
^   ^  ^ ^ word starts. w stops before them

From my previous example:

[a] abc               w
a[ ]abc               d

If cursor moved from the first column to the second column, why “a” is not selected if “selecting from the cursor position”?

Kakoune provides the non smart version on Alt.

I tried Alt+w but it behaved the same. (Maybe it's just a terminal issue though.)

I feel like the defenders of kakoune's current behaviour aren't paying enough attention to the stated problem. Please read "Edit: a more refined test case" in the OP more carefully.

off-topic, @zsugabubus actually, the behaviour of x is consistent. It highlights the current line, unless the current line is already highlighted, in which case it highlights the next line. When there's a one-character selection (i.e. the newline character) on an empty line, the current line is already highlighted, so it selects the next line.

Personally, I find the behaviour of x jumping to the next line if the current is already highlighted totally useless, and it really should just highlight the current line, but that point's debatable. Also, <a-x> does that, so if that's what you want, you can pretty safely remap x to <a-x>.

You're right, the behavior of w is quite complex and hard to decipher.

As I'm often myself confused about how it works, let's try to understand the code behind the select_next_word function: https://github.com/mawww/kakoune/blob/master/src/selectors.cc#L49

Especially this condition:

if (categorize<word_type>(*begin, extra_word_chars) !=
        categorize<word_type>(*(begin+1), extra_word_chars))
        ++begin;

which in my mind reads something like this: "before doing anything, let's adjust the starting point of the future selection, by observing the current character and its right neighbor. If it's not from the same family, let's move 1 char to the right first".

Let's reuse the previous examples:

First scenario. begin is on c, a letter. Right to it is d is also a letter. Same family we do not do ++begin.

   ab[c]d    a abc ab        w
   ab[cd    ]a abc ab

Second scenario. begin is a space. Right to it is also a space. Same family, we do not do ++begin.

   abcd[ ]   a abc ab        w
   abcd[    ]a abc ab

Third scenario. begin is on d, a letter. Right to it is a space. Not the same family, so let's do a ++begin.

   abc[d]    a abc ab        w
   abcd[    ]a abc ab

Looks like we're onto something. So the question is: why does this strange rule exist in the first place? There's not better way to find out, that just removing it from the source code and recompiling an experimental Kakoune!

I've just did it and here's what happens: if you press w several times, you'll get "stuck":

   ab[c]d    a abc ab        w
   ab[cd    ]a abc ab        w
   abcd  [  ]a abc ab        w
   abcd  [  ]a abc ab        w

So in the end the problematic is quite similar to the one expressed about the repeatability of the t command. See https://github.com/mawww/kakoune/issues/1637

Then–the obvious question–why not ++begin only when standing on whitespace followed by non-whitespace? It means that we have completely selected the word + whitespaces after it, so we can jump to the next word. It seems logical and repeatable.

But what does ++begin on a non-white -> white transition would want to mean? We are on a one-length word and now we should continue with selecting the whitespace after it. It would be great if a comment before ++begin could explain the behavior for the reader. (So you could avoid deleting something crucial.)

After all, it seems a bug to me.

I'll try to deepen my reflection on the subject soon.

Meanwhile, after a bit of research, it turns out that the question was asked a while ago: https://github.com/mawww/kakoune/issues/752 but mawww explanation was pretty light.

I didn't even realize it was inconsistent until now. I remember something similar in vim. Running commands dw should have the same result as cw<esc> but it doesn't. Similarly, vwd should behave like dw but it also doesn't. (Similarly I would expect Y to do a y$ but it does a yy.)

I guess that's one of those things that I just lived with without questioning it. But I think your point is valid.

Running commands dw should have the same result as cw but it doesn't.

The explanation why. (You can switch it off in nvim.)

Similarly, vwd should behave like dw but it also doesn't.

In Vim there are inclusive and exclusive motions and motions with v become inclusive.

Was this page helpful?
0 / 5 - 0 ratings