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

Unexpected behavior because of newline characters being selectable #2956

Closed
Nughm3 opened this issue Jul 4, 2022 · 10 comments
Closed

Unexpected behavior because of newline characters being selectable #2956

Nughm3 opened this issue Jul 4, 2022 · 10 comments
Labels
C-bug Category: This is a bug

Comments

@Nughm3
Copy link

Nughm3 commented Jul 4, 2022

Summary

This is a small nitpick I have with Helix, coming from Neovim. Helix counts the last newline character \n as a selectable character.

Helix:
image

Neovim:
image

As seen above, the last character you can select in Neovim is the semicolon, but in Helix you can select the newline. This causes some keys, such as a or xc to work differently than I would expect. See "reproduction steps" below.

I recognize that this issue is a bit opinionated. If this is behavior is intentional, I'd like to know why. Thanks!

Reproduction Steps

Case 1

image
After pressing a, Helix recognizes that the next character after \n is the } on the next line, and inserts there instead.
image
Normally, I would intend to append text at the end of line 2 instead of inserting at the start of line 3. This always annoys me, as I would have to go back up or just use A instead, whereas in other editors like Neovim I'm used to it appending text at the end of the line.

Case 2

I often find myself having to change the whole line. In Vim this would be cc, and in Helix it intuitively should be xc.
image
However, x selects the whole line including the newline character, so when I press c it deletes that too and shoves the next line onto the current one:
image

By the way, gl doesn't select the newline, which is inconsistent with x. (Correction: see 2nd comment - there's a reason for the inconsistency)

Suggestions:

  • Don't let the user select \n
  • Change a to stop at line boundaries
  • Change x to be like ghvgl (go to line start, select mode, go to line end not including \n)

Helix log

No response

Platform

Linux (Arch x86-64)

Terminal Emulator

wezterm 20220624-141144-bd1b7c5d

Helix Version

22.05

@Nughm3 Nughm3 added the C-bug Category: This is a bug label Jul 4, 2022
@poliorcetics
Copy link
Contributor

I have the same problem with the kitty terminal emulator, it notably affects how URLs are recognized and copied/pasted:

Screenshot 2022-07-04 at 13 09 18

@CptPotato
Copy link
Contributor

CptPotato commented Jul 4, 2022

One issue with this is that for some commands it's necessary for x/X to select the new-line character as well (like xd for example).

For changing lines you could use a similar command as I do for selecting the line's content (minus leading and trailing whitespace): #2503

@Nughm3
Copy link
Author

Nughm3 commented Jul 4, 2022

One issue with this is that for some commands it's necessary for x/X to select the new-line character as well (like xd for example).

That makes sense - in that case vim/nvim probably are not a reasonable comparison due to their different editing model. dd in vim will remove the newline but cc won't. I'll just use x_c.

For a, would it be reasonable to confine it to line boundaries?

@archseer
Copy link
Member

archseer commented Jul 4, 2022

This is expected behaviour. We treat newlines like any other character which makes operations more consistent. We actually used to stop before EOL but this was changed to match kakoune's behaviour.

Either:

  • use A to append
  • put your cursor in the same spot as vim (last character on the line) and use a
  • use i to insert before the selection

@archseer
Copy link
Member

archseer commented Jul 4, 2022

There's some considerations around case 2 to add a C type binding that would change a single line. For now the easiest is t<Enter>c which will select until newline then change

@Nughm3
Copy link
Author

Nughm3 commented Jul 4, 2022

Thanks for clearing that up. I'll close the issue.

@Nughm3 Nughm3 closed this as completed Jul 4, 2022
@CptPotato
Copy link
Contributor

There's some considerations around case 2 to add a C type binding that would change a single line. For now the easiest is t<Enter>c which will select until newline then change

I think [ "extend_to_line_bounds", "trim_selections", "change_selection" ] could work pretty well, but right now it seems that change_selection can't be mapped together with other commands, yet (#2051).

@linde12
Copy link

linde12 commented Jan 9, 2023

Man, i wish xc would just be more natural - there is really little point to it deleting the newline, and makes xc kind of useless since you always have to do x_c or ghvglc, ght<ret> or similar workarounds to actually change the line (not remove the line it and go into insert mode on the line below)

Sure, one can bind it, but if i wanted keybinds i would use vscode or some other non-modal editor instead. Unfortunately this is one of the primary reasons im sticking to nvim and i am sad about it since i really love how simple it is to configure helix. Hoping you will reconsider one day - i want to like this editor, i really do!

@tsujp
Copy link

tsujp commented Jul 19, 2023

Man, i wish xc would just be more natural - there is really little point to it deleting the newline, and makes xc kind of useless since you always have to do x_c or ghvglc, ght<ret> or similar workarounds to actually change the line (not remove the line it and go into insert mode on the line below)

Sure, one can bind it, but if i wanted keybinds i would use vscode or some other non-modal editor instead. Unfortunately this is one of the primary reasons im sticking to nvim and i am sad about it since i really love how simple it is to configure helix. Hoping you will reconsider one day - i want to like this editor, i really do!

Having read this thread after finding it due the exact same gripe... I now disagree. If the intention is to make behaviour consistent then I'd rather have the consistent behaviour because that affords less internal logic in Helix to deal with the edge cases created by inconsistent behaviour.

Yes adding a keybinding can suck but x_c is already a lot shorter than ghvglc (and x_c is still quite easy to type) but also the increase in configuration complexity is next to nothing compared to Emacs, (N)Vim, VSCode etc. My Emacs configuration for less functionality than Helix provides out of the box is hundreds of lines of elisp over multiple files; for (N)Vim it's the same in either Lua or VimScript; and for VSCode it's a large JSON object with multiple 3rd party (sometimes abandoned) plugins. My Helix configuration is a dozen lines of TOML.

I was in the camp of "I want this behaviour changed" 10 minutes ago but now I don't.

  1. The intentional design of this behaviour keeps Helix's internals simpler; less complexity there = easier maintenance and more predictable behaviour (i.e. less potential for bugs).
  2. The small "penalty" of a custom keybinding is nothing when you consider the configuration simplicity in Helix compared to the configuration complexity (and the mental burden, debugging burden etc) of other popular editors with modal capabilities.

@ethanmsl
Copy link

@tsujp
The behavior is consistent in the domain of character representations in text.
The behavior is inconsistent in the domain of human activity.

Pretty much every program that works with texts gives newline representations (the many that there are) special treatment. Because they are an implementation detail separate from the dynamics of the text as it is intended to be interacted with.

Having also come from the fragile and often laborious Neovim ecosystem what I am also finding frustrating about Helix is that it is very interested in consistency on the mechanical-editor action level, and not on the level of actual use. Which is to say that Helix demands you be very aware of it's select state and location -- forcing a much more implementation-based interaction. I'm finding that it 'gets in the way' much more often than it assists, where it differs from vim.

(Heavy remapping helps, but it seems inherent in the model -- as it's designed to be mechanically consistent and not allow conditional actions based on edgecase scenarios.)

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

No branches or pull requests

7 participants