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

Odd behaviour with append_mode collapse_selection #9443

Closed
wmstack opened this issue Jan 27, 2024 · 11 comments · Fixed by #9448
Closed

Odd behaviour with append_mode collapse_selection #9443

wmstack opened this issue Jan 27, 2024 · 11 comments · Fixed by #9448
Labels
A-command Area: Commands C-bug Category: This is a bug

Comments

@wmstack
Copy link
Contributor

wmstack commented Jan 27, 2024

Summary

I use helix, and I map a to append_mode collapse_selection. There is an odd bug where the selection comes up again after pressing enter even though the last command collapsed the selection.

Reproduction Steps

# ~/.config/helix/config.toml
keys.normal.a = ["append_mode", "collapse_selection"]

image

Write some text and then add a left parenthesis to generate a pair
image

Then press esc then a (which is mapped as above)
image

Now press enter
image

I expected this to happen:
image

Instead, this happened:
image

Helix log

~/.cache/helix/helix.log
please provide a copy of `~/.cache/helix/helix.log` here if possible, you may need to redact some of the lines

Platform

Windows

Terminal Emulator

Windows Terminal

Installation Method

Scoop

Helix Version

helix 23.10 (f6021dd)

@wmstack wmstack added the C-bug Category: This is a bug label Jan 27, 2024
@the-mikedavis
Copy link
Member

This is intentional: appending with a will add any new text to the selection and the newline character is selectable in Helix.

@the-mikedavis the-mikedavis closed this as not planned Won't fix, can't repro, duplicate, stale Jan 27, 2024
@wmstack
Copy link
Contributor Author

wmstack commented Jan 27, 2024

This is intentional: appending with a will add any new text to the selection and the newline character is selectable in Helix.

There is no way this is intentional, because after the collapse_selection command, there is nothing that is selected, even if I use the mouse to move the cursor elsewhere, a selection forms when I press enter. No selection forms if I type normal characters though unless I press enter first.

If after pressing esc a you use the mouse to put the cursor in the middle and press enter, the selection will start again. Basically it looks as though there is hidden state that becomes visible when you press enter

@the-mikedavis
Copy link
Member

Oh I see, I skipped over the part about collapse_selection. I've added that to the reproduction steps. Yeah, insert_newline is uniquely trying to detect a here:

let new_range = if doc.restore_cursor {
// when appending, extend the range by local_offs
Range::new(
range.anchor + global_offs,
range.head + local_offs + global_offs,
)

Ideally it should not rely on that field and just figure out whether it needs to extend by looking only at the current selection.

@the-mikedavis the-mikedavis reopened this Jan 27, 2024
@the-mikedavis the-mikedavis added the A-command Area: Commands label Jan 27, 2024
@wmstack
Copy link
Contributor Author

wmstack commented Jan 27, 2024

Well, I don't know if this helps, but I have found a psuedo-fix by adding an insert_mode command after the collapse_selection. This makes it so one enter does not cause a selection but pressing it twice causes a selection.

@wmstack
Copy link
Contributor Author

wmstack commented Jan 27, 2024

I also want to add another odd behavior of the append_mode command. I don't actually dislike it because it is a really edge behaviour and it isn't clear it is a wrong decision but it causes the next escape to move backward if the cursor is selecting after the last character. It doesn't bother me that much but it is another one of these hidden state issues:

image

After pressing append mode

image

Now after escaping

image

If you instead use insert_mode to get to the second image, this doesn't happen (and you go back to stage 1 on escape). Finally, append mode when you are selecting the last character creates a new line, but if you are selecting after the last character it doesn't create a new line.

image

After append_mode

image

Escaping moves backwards so now you are selecting last newline character

image

append_mode

image

@the-mikedavis
Copy link
Member

That is also with the custom ["append_mode", "collapse_selection"] binding, right? With regular append_mode the cursor should go to the next line, and esc should return the cursor to its original position. That's also a consequence of the restore_cursor field (it's actually the intended purpose of that field and insert_newline is improperly using the field).

If you're trying to avoid the selection behavior of a then you should bind it to the equivalent of li instead of using collapse_selection. You should also consider not remapping a at all: the selection behavior is there by design and is useful when using multiple cursors.

@wmstack
Copy link
Contributor Author

wmstack commented Jan 27, 2024

Well, the cursor is not going to go to the next line because there is no next line. I should have expanded the screenshot to make it more clear. This is where both insert mode and append mode have the same behavior, which is to put the cursor after the last character. It doesn't seem to be affected by collapse_selection. Append mode will cause the next escape to move backward, while insert mode will cause the escape to return to the same position. I have tried it without and the behaviour is the same.

Also, the behavior with l and i is not entirely identical. For example, if you use b to go a word backward, append_mode will go to the end of that word. That makes more sense than putting the cursor after the first letter of the word. So if I go backwards twice then press a that would put me after the last word. Makes more sense right bba complements bbea

There was a helix configuration I saw a while ago where some Vim programmer recommended the bindings append_mode collapse_selection and insert_mode collapse_selection and I felt like they were in some sense optimal. So I adopted them.
https://github.com/LGUG2Z/helix-vim/blob/e0a80982f5297fb39da3695d615d391db3580893/config.toml#L44-L52

It isn't that I want to fully use it like vim, I just really thing that the selection looks jarring while I am typing.

@the-mikedavis
Copy link
Member

Oh I see, yeah if the buffer is empty then we can't move the selection over by one, and esc mistakenly moves you back one anyways. Kakoune solves this by adding the newline when you a at the end of the buffer and that seems reasonable to me - I may add a PR later to add that behavior.

the selection looks jarring while I am typing

Yeah, this is a common complaint. Other editors tend to punish you for having a selection (e.g. typing while you have a selection deletes the selection contents) but it's really important to the editing paradigm so I'd suggest trying it for a while (maybe a few weeks) and seeing if you can adjust.

@wmstack
Copy link
Contributor Author

wmstack commented Jan 27, 2024

Well I seem to have found the code for the behaviour of going to normal. To be honest it makes zero sense to me because this behaviour only manifests at the end of the buffer? It seems from the code that escape always moves the cursor back by 1?

helix/helix-view/src/editor.rs

Lines 1903 to 1915 in 2661e05

// if leaving append mode, move cursor back by 1
if doc.restore_cursor {
let text = doc.text().slice(..);
let selection = doc.selection(view.id).clone().transform(|range| {
Range::new(
range.from(),
graphemes::prev_grapheme_boundary(text, range.to()),
)
});
doc.set_selection(view.id, selection);
doc.restore_cursor = false;
}

@the-mikedavis
Copy link
Member

When you enter insert mode with append_mode the cursor gets moved one to the right, so moving back by one resets the positioning:

let selection = doc.selection(view.id).clone().transform(|range| {
Range::new(
range.from(),
graphemes::next_grapheme_boundary(doc.text().slice(..), range.to()),
)
});

@wmstack
Copy link
Contributor Author

wmstack commented Jan 27, 2024

I see, when using collapse_selection, pressing a and esc will just keep moving the cursor forward.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-command Area: Commands C-bug Category: This is a bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants