Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
ewtoombs opened this issue Oct 12, 2019 · 16 comments

Comments

@ewtoombs
Copy link

ewtoombs commented Oct 12, 2019

Steps

Put the following text in a buffer:

c ccc ccc ccc
cc ccc ccc ccc

Move to the second line and do <a-h> to get your grey cursor to the beginning. If you do one <a-w>, the text "cc " at the beginning of the line will be selected. That's what is supposed to happen.
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.

@rhizoome
Copy link
Contributor

rhizoome commented Oct 22, 2019

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.

@zsugabubus
Copy link

(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.

@ewtoombs
Copy link
Author

ewtoombs commented Jan 16, 2020

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        

different from this:

       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.

@ewtoombs ewtoombs changed the title <a-w> does not work as expected for one letter long Words at the beginning of a line. w and <a-w> do not work as expected when end of selection falls on end of word. Jan 17, 2020
@rhizoome
Copy link
Contributor

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

@zsugabubus
Copy link

zsugabubus commented Jan 18, 2020

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”.

@zsugabubus
Copy link

zsugabubus commented Jan 18, 2020

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.

@Screwtapello
Copy link
Contributor

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.

@alexherbo2
Copy link
Contributor

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.

@zsugabubus
Copy link

zsugabubus commented Jan 18, 2020

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.)

@ewtoombs
Copy link
Author

ewtoombs commented Jan 20, 2020

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.

@ewtoombs
Copy link
Author

ewtoombs commented Jan 20, 2020

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>.

@Delapouite
Copy link
Contributor

Delapouite commented Feb 20, 2020

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 #1637

@zsugabubus
Copy link

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.

@Delapouite
Copy link
Contributor

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: #752 but mawww explanation was pretty light.

@toddyamakawa
Copy link

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.

@zsugabubus
Copy link

zsugabubus commented Jan 12, 2021

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants