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

Line-wise extend mode #356

Closed
CBenoit opened this issue Jun 23, 2021 · 19 comments
Closed

Line-wise extend mode #356

CBenoit opened this issue Jun 23, 2021 · 19 comments
Labels
A-keymap Area: Keymap and keybindings C-enhancement Category: Improvements E-medium Call for participation: Experience needed to fix: Medium / intermediate

Comments

@CBenoit
Copy link
Member

CBenoit commented Jun 23, 2021

Description

A new line-wise extend mode similar to (neo)vim's line-wise visual mode that we can enter by pressing V.

Aside

As mentioned in this issue I would like it to replace current line selection using x.

Current x (kakoune's x) has a few pain points:

  • An empty line is always fully selected (selection is at least one character, in this case the newline character), so when pressing x the next line is selected in addition to the current line. This totally makes sense, but makes the behavior somewhat feeling weird. We could use a new state just for that, but that's not very elegant.
  • It can only be used to extend down (we could still have X to extend up though).

For more background, see this kakoune issue.

Line-wise extend mode fixes the above pain points and can also do more:

  • V switch to line-wise extend mode and only makes sure the current line is fully selected whether current line is empty or not. Vy would effectively be vim's "yank current line" (yy) while kakoune's xy is "yank current line if it is not empty, yank both current and next line othewise".
  • Once in line-wise extend mode one can extend in any direction using usual movement commands (down, up, find, … just name it!).
@CBenoit CBenoit added C-enhancement Category: Improvements A-keymap Area: Keymap and keybindings E-medium Call for participation: Experience needed to fix: Medium / intermediate labels Jun 23, 2021
@cessen
Copy link
Contributor

cessen commented Jun 23, 2021

An empty line is always fully selected (selection is at least one character, in this case the newline character), so when pressing x the next line is selected in addition to the current line. This totally makes sense, but makes the behavior somewhat feeling weird. We could use a new state just for that, but that's not very elegant.

I discuss that as one of the motivating examples in #362. IMO it's potentially solvable in an elegant way that doesn't involve any special state, depending on your definitions.

Having said that, I also like vim's line-wise extend mode, ha ha. :-)

@CBenoit
Copy link
Member Author

CBenoit commented Jun 24, 2021

Very good points you made in #362! 😄

I see the current plan is to keep the current behavior but get an internal refactoring to use gap indexing instead:

I'm a bit unsure on the approach to cursors, so I think we should start by enforcing that ranges are always at least 1-width. I don't think there's a good approach to solve this in the terminal (it makes i/a behavior a bit more confusing because it looks like you're over a character but you're positioned right before it, both i and a will insert in the same spot), but it would be interesting in a proper UI because we could render 0-width cursors.

So I guess this wouldn't fix x immediately, right?

@cessen
Copy link
Contributor

cessen commented Jun 24, 2021

Correct, it won't fix x immediately, but it will open the door to possibly fixing it later, depending on how we decide we want Helix to work in general around cursors/selections.

(Edit: I'm personally pretty optimistic. I think there are very likely to be good ways to make everything work intuitively with zero-width cursors, even in a terminal. But I think it will be easier to demonstrate and convince people with a prototype, which will be a lot easier to whip up after switching to gap indexing anyway.)

@CBenoit
Copy link
Member Author

CBenoit commented Jun 25, 2021

(Edit: I'm personally pretty optimistic. I think there are very likely to be good ways to make everything work intuitively with zero-width cursors, even in a terminal. But I think it will be easier to demonstrate and convince people with a prototype, which will be a lot easier to whip up after switching to gap indexing anyway.)

(I'm very enthusiastic about this approach, I'll will be following that!)

@archseer
Copy link
Member

I wonder if simply implementing X as "extend selection to line bounds" might be enough? You could make a selection then press X to have it cover all the selected lines.

@pickfire
Copy link
Contributor

Or vx if we don't want to hold shift for X.

@CBenoit
Copy link
Member Author

CBenoit commented Jun 30, 2021

I wonder if simply implementing X as "extend selection to line bounds" might be enough? You could make a selection then press X to have it cover all the selected lines.

I think it's enough albeit a bit less efficient

@archseer
Copy link
Member

archseer commented Jul 5, 2021

I've implemented X in a4e28c6

https://asciinema.org/a/THZeT7YLA2izb9lNviGuMg5PL

@CBenoit
Copy link
Member Author

CBenoit commented Jul 5, 2021

Looks good, thank you! 🙂
It seems to me the issue can be closed so I'll go ahead!

Possible plugin-provided implementation for VIM-like line-wise extend mode : add a hook on selection change to call extend_to_line_bounds

@CBenoit CBenoit closed this as completed Jul 5, 2021
@dpc
Copy link
Contributor

dpc commented Aug 6, 2021

Hi, I've been trying hx and I've been one of the vocal kakoune users in mawww/kakoune#2590 , the the point where I still use my custom fork that changes x behavior.

I was also prototyping https://github.com/dpc/breeze , which is kakoune inspired editor with 0-width cursor as a base mode of operation, also in Rust. Since you kind of work on a very similar thing though far more featureful already I thought I might point to it just as an inspiration.

In it I used gap-cursor from the start, and I represent an unselected empty line as []\n and selected one as [\n] (where [] is the selection/cursor). Note: since in breeze, the cursor (the vertical line is displayed separately from the selection), that means there's the difference looks like this:

line NOT considered fully selected:

Screenshot from 2021-08-05 23-47-59

line considered fully selected:

Screenshot from 2021-08-05 23-48-05

That little arrow is a marker of a selected newline. You might want to try it yourself, run breeze, open some file and see how it feels.

@cessen
Copy link
Contributor

cessen commented Aug 6, 2021

@dpc
Although I would certainly prefer vertical-line cursors, there are a couple of hurdles:

  1. Many terminals don't support vertical-line cursors, so it's not very portable.
  2. Even terminals that do support vertical-line cursors only support a single such cursor, but Helix is a multi-cursor editor. So even in those terminals we still can't display our cursors that way.

I would still like to experiment with approaches to indicate/visualize zero-width cursors within the limitations of terminals, but I don't think vertical-line cursors is a workable solution in the current terminal landscape, unfortunately.

@sudormrfbin
Copy link
Member

FWIW I made a working prototype some time ago to change cursor shape on mode change (#323) and this is what I ended up with:

We can show an I beam for the primary cursor (given that the terminal supports it) but that's about it. For multiple cursors we'll have to fall back to block cursors in the terminal.

@dpc
Copy link
Contributor

dpc commented Aug 6, 2021

(...) I don't think vertical-line cursors is a workable solution in the current terminal landscape, unfortunately.

I thought about it myself, and my conclusion was:

Why would anyone go so out of their way to use some super niche text editor... and then plan to use it with some legacy underpowered terminal emulator, instead of one of the fast modern featureful ones?

And:

Given such a dominance of "mainstream" CLI modal text editors like Neovim Emacs, why would anyone bother with some weird new one? An editor like this MUST do something far, far better than existing ones and provide substantially better experience to have people stick around and suffer through some other pain points like smaller ecosystem.

For both legacy & multi-cursor, I was planing to display a normal 1-width cursor fallback.

@cessen
Copy link
Contributor

cessen commented Aug 6, 2021

(Before I go any further, I just want to make sure anyone stumbling on this understands: I am not the primary author of Helix. I sometimes write with an authoritative voice, but I'm only speaking for myself here.)

Why would anyone go so out of their way to use some super niche text editor... and then plan to use it with some legacy underpowered terminal emulator, instead of one of the fast modern featureful ones?

I mostly agree with you here (with some minor quibbles). But the main issue still remains: even the modern terminal emulators don't support multiple vertical-line cursors. If it were a reasonably common feature among modern terminal emulators I think I'd be right there with you. But I don't know of any terminal emulator that supports this, even among modern ones. That doesn't mean one doesn't exist, of course. But the point is that it's definitely not something we can rely on, even on a modern system.

I think our best option for accommodating vertical-line cursors is to support them in a GUI version of Helix. Then we can draw things however we want.

Okay... so having said all of that, I want to come back to what I think is the more pertinent point: editor behavior.

Even if we can't display vertical-line cursors, that doesn't necessarily mean we can't support zero-width cursor behavior. I had some ideas about that in #362. Basically, if we make a distinction between "cursors" and "selections" (the former being zero-width, the latter being anything > zero-width), then we can make a visual distinction between the two by e.g. display cursors with a different color. I think as long as we made this a front-and-center concept in Helix, it could work well.

But I also think it needs some prototyping and experimentation to see if it actually works well in practice, and to explore/discover other possible solutions that might work even better. Since implementing #376 that kind of experimentation should be much easier to do.

Given such a dominance of "mainstream" CLI modal text editors like Neovim Emacs, why would anyone bother with some weird new one? An editor like this MUST do something far, far better than existing ones and provide substantially better experience to have people stick around and suffer through some other pain points like smaller ecosystem.

Independent of the substance of this discussion, I see people making this kind of argument a lot when trying to convince open source projects to change what they're doing. For some projects that's reasonable, due to their nature. But for many others (I think including Helix) I find this kind of reasoning odd, and it kind of comes across as "Cm'on kid, don'cha wanna be famous?"

I don't think many of us are developing Helix specifically because we're trying to make it popular. We're developing Helix because we personally want to use it as our editor. So I think it's best to focus the discussion on the actual pros and cons of the available approaches rather than on what would attract more people to the project.

@dpc
Copy link
Contributor

dpc commented Aug 6, 2021

even the modern terminal emulators don't support multiple vertical-line cursors

As a kakoune user, I find that I rarely use multiple selections and usually miss the simplicity of :g/foo/bar/. When I do use them, 90% of the time the edits I'm making are so far apart that I still see only one at the time anyway, so I have completely different problems. So I while agree that some handling of it is needed, I am confidence it will be good enough in practice.

then we can make a visual distinction between the two by e.g. display cursors with a different color.

👍

@cessen
Copy link
Contributor

cessen commented Aug 6, 2021

As a kakoune user, I find that I rarely use multiple selections and usually miss the simplicity of :g/foo/bar/.

Ah, interesting. Coming from Sublime, it's a primary workflow for me. It's certainly a little trickier to use effectively in Helix right now with the available selection commands (and I suspect that's true in Kakoune as well...?). But after higher priority things have been addressed, that's something I want to tackle. Assuming no one else gets to it first.

@musjj
Copy link

musjj commented Oct 9, 2023

Can this issue potentially be re-opened? The OP seems satisfied with the current solution, but IMO extend_to_line_bounds is not really a true line-wise mode. You can test this by pressing vX, then k. You can see that the previous line is now no longer fully selected.

@kladd
Copy link

kladd commented Oct 30, 2023

Second.

@pascalkuthe
Copy link
Member

You just got it the wrong way around. You enter insertmode with v and move around, then you can press X last to extend to linebounds.

Just like kakoune we have no plan to add a linewise selection mode.

@helix-editor helix-editor locked as resolved and limited conversation to collaborators Oct 30, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A-keymap Area: Keymap and keybindings C-enhancement Category: Improvements E-medium Call for participation: Experience needed to fix: Medium / intermediate
Projects
None yet
Development

No branches or pull requests

9 participants