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

Keymap discussion #165

Closed
pickfire opened this issue Jun 7, 2021 · 245 comments
Closed

Keymap discussion #165

pickfire opened this issue Jun 7, 2021 · 245 comments
Labels
A-keymap Area: Keymap and keybindings A-plugin Area: Plugin system E-help-wanted Call for participation: Extra attention is needed

Comments

@pickfire
Copy link
Contributor

pickfire commented Jun 7, 2021

Since we take some keys from both vim and kakoune, we want to reduce the issues of taking the worse of both worse.

Currently I dumped some idea in https://github.com/helix-editor/helix/wiki/Keymap-brainstorm and will continue to update that for some time, putting in some painful edit operations in vim or kakoune or both. Then we may want to try addressing them in helix by picking the best of both worlds.

Maybe our next step is to move towards implementing some of the missing keys and re-iterate and see if we have any painful points while working with helix.

@pickfire pickfire added the E-help-wanted Call for participation: Extra attention is needed label Jun 7, 2021
@rieger-jared
Copy link

I've been using helix for a day now, and I'm finding some bindings or lack of bindings a bit frustrating. I guess what I think would be valuable to know is if this project is aiming to augment the vim mappings or is planning to write its own set of mappings. Furthermore, I think that this quite important for the adoption of the project that the key mapping interface is clear whether it's copying the vim interface or making its own as vim mappings for vim users are second nature to most.

I personally would hope that the project adopts the majority of the basic vim interface. I also understand that the project also has the potential to change some features where it's desirable for UX. By that I am referring to the multi cursor support.

However, perhaps we could also implement options for users? For example, Emacs users could set a configuration setting to select an Emacs key mapping. Likewise for vim. I would imagine that would be quite time-consuming to implement.

Does Helix want to be a post-modern vim? Or its own editor like atom or VS Code with its own key bindings? I personally believe building on top of vim is the better option as it would maintain portability in the keybinding interface for users.

@archseer
Copy link
Member

archseer commented Jun 8, 2021

We're basing the keymappings quite heavily on Kakoune, so you might find this helpful: https://github.com/mawww/kakoune/wiki/Migrating-from-Vim

The idea is that you always start by making a selection first (that way it's interactive and you see that you selected the right thing), then you operate on it.

We're currently diverging from kakoune by introducing a selection mode (I've also called it the "extend mode") which is similar to vim's visual mode: In this mode movements extend the selection instead of moving it. So wWW in Kakoune is vwww in Helix. This means that "reverse" bindings (eg. F instead of f in vim) can now live on shift again, instead of alt.

We're copying kakoune's goto mode (It's a lot easier to memorize gt than H) and moving the view mode under z (similar to vim) to make space for v. This will also help with discoverability by introducing kakoune's auto-info popups (e.g. g would show a menu).

Are there any specific keymaps you're missing?

@bczsalba
Copy link

bczsalba commented Jun 8, 2021

I heavily rely on the ci and vi bindings from vim, but if I'm reading you correctly they go against the "always start by making a selection first" policy. Are there any good alternatives to them in helix?

@archseer
Copy link
Member

archseer commented Jun 8, 2021

Yeah so the equivalent of vim's textobjects would be an object selection mode. Something like si{d for "select inside { delete", but with a different key than s since we're using it for other things.

This still needs to be implemented but it's important so I'd like to focus on it soon.

We're also looking at structural matching via tree-sitter so that you'd be able to select / move entire functions, etc. In the same vein as https://github.com/nvim-treesitter/nvim-treesitter-textobjects and similar libraries.

@pickfire
Copy link
Contributor Author

pickfire commented Jun 8, 2021

@rieger-jared Maybe you should try out kakoune first to understand some of the concepts helix is based on.

Helix currently is in a very weird keybinding state I would say, some is there some is not there, which I start writing and updating the wiki for stuff I find difficult.

One issue I see helix have is we don't have the <operation> <movement> method like in vim but at the same time we only partially taken kakoune <movement> <operation> so in certain situations may be more troublesome to type it out.

@CBenoit
Copy link
Member

CBenoit commented Jun 9, 2021

Quick opinion on x/X. On kakoune the behavior is a bit weird (mawww/kakoune#2590).
I think we could just remove it because it's superseded by the "extend mode".
V being the line-wise extend mode, pressing it would be roughly equivalent to pressing x selection-wise (in current helix and kakoune if line is not empty).
To delete a line: Vd instead of xd. I think the kakoune x exists because of lack of post-movement (dd) combined to lack of extend mode.

And we get x for text object selection mode: xi{d.

@archseer archseer changed the title Think about keymap Keymap discussion Jun 10, 2021
@archseer archseer pinned this issue Jun 10, 2021
@ashkitten
Copy link

discussed on matrix (edited slightly to depend less on context):

here's an interesting edge case i encounter in kakoune a lot: say you have a word, and you want to select to the end of the word and extend that backwards to the beginning of the line. you intuitively want to do evgi, right? but that doesn't work because when you use e the anchor of the selection is at the beginning of the word, and vgi doesn't modify the anchor... you end up selecting from the first character of the word to the beginning of the line, so instead you have to do e;vgi. i find myself using ; in a lot of places i feel are unintuitive with kakoune because of the anchor position.
i feel like there has to be a better way than to treat ; as an escape hatch for unintuitive behavior...
(and of course the same movement works fine in vim, with ev0... it's only because of normal-mode e selecting the word that this is a problem)
hmm, i wonder if we could treat e, b, w, etc. as "temporary" selections that don't actually affect a visual selection?
so if you do evgi the anchor gets reset when you enter visual mode
but ed still works
that's essentially how they already work, since ee overwrites the first e selection without extending it
it would make vwwd different than wvwd but i think that's probably okay
i'm trying to think if it would be valuable to treat movement selections as a special-cased temporary type of selection, or if v should just reset the anchor... i think it becomes more important when you get into multiple selections, and i'm not sure what the right answer is

@pickfire
Copy link
Contributor Author

I think we could just remove it because it's superseded by the "extend mode".

No, we can't really do that. x/X is one of the most used keys. Try check the wiki on the examples, I think most of them I put need to use x, if we removed that try and see if it could be replaced by V, I think most of the case we can't. Usually X is used on extend, we can't do V since we are already in visual mode, if we remove X, we need to do jgl to extend a full line.

@CBenoit
Copy link
Member

CBenoit commented Jun 11, 2021

I think we could just remove it because it's superseded by the "extend mode".

No, we can't really do that. x/X is one of the most used keys. Try check the wiki on the examples, I think most of them I put need to use x, if we removed that try and see if it could be replaced by V, I think most of the case we can't. Usually X is used on extend, we can't do V since we are already in visual mode, if we remove X, we need to do jgl to extend a full line.

In line-wise extend mode you should not use gl and gh stuff. You don't need to extend a full line, since you're always on a full line (same as vim's V). I updated the wiki examples with what I think V should be.

@ashkitten
Copy link

i'd like to add that in my week or so using kakoune i've definitely missed <c-v> in a lot of places (like commenting out a block of code, for instance... though i know :comment-line exists). i think helix would do well to have a real rectangle selection mode and not depend solely on multiple cursors like kakoune

@pickfire pickfire added the A-keymap Area: Keymap and keybindings label Jun 15, 2021
@DrZingo
Copy link
Contributor

DrZingo commented Jun 18, 2021

I would like to see a plan for keybindings. To change editor is a big time investment, and adopters need to see if it is worth it in the end.

@cessen
Copy link
Contributor

cessen commented Jun 18, 2021

@DrZingo

I would like to see a plan for keybindings. To change editor is a big time investment, and adopters need to see if it is worth it in the end.

Can you expand on your concerns about the keymap in more detail? You had a lot to say in the matrix chat, and I think it would be good to capture those specific concerns here.

@DrZingo
Copy link
Contributor

DrZingo commented Jun 18, 2021

@DrZingo

I would like to see a plan for keybindings. To change editor is a big time investment, and adopters need to see if it is worth it in the end.

Can you expand on your concerns about the keymap in more detail? You had a lot to say in the matrix chat, and I think it would be good to capture those specific concerns here.

It all boils down to: I (and other adopters) want to know how all extra object bindings will end up without involving non intuitive non mnemonic characters and or alt/ctrl. If early adopters end up with bad bindings along the road, time and effort will be a bit wasted.
There are already binding clashes according to the keymap docs, and feature wise an estimate of 10-20% is implemented fully or to some degree.
Together with "We don't want alt/ctrl", "I think we will...", is not reassuring that the object->verb is the way to go. Especially as some verbs anyway will end up as first (Add, add, Insert, insert, paste, Paste etc.)

@CBenoit
Copy link
Member

CBenoit commented Jun 18, 2021

If it's alright for you, I would really appreciate if you could provide additional samples and use cases on the wiki page. Especially, as you appears to be advocating for vim keybindings, I'm interested in samples where you think kakoune performs badly and VIM is good.

@pickfire
Copy link
Contributor Author

pickfire commented Jun 19, 2021

I have an idea. What if we can make use of 0 and 1 as inner and outer like kakoune alt-i and alt-a, since currently the count 0 and 1 will be useless anyway, but to do this we need to know if user pressed any number and if the number is 0 or 1 then we do stuff differently. Example, 0w select inner word. The downside is it's a bit further. The upside is it is just a single key and we repurpose the count to do it, we then get a lower key count compared to vim and kakoune for this frequent key (and don't need to hold any key). What do you all think? thums up or down?

@sudormrfbin
Copy link
Member

That's a very clever way to do it; the main issue I see with it is that they are harder to reach and selecting inside and around are very common operations.

@CBenoit
Copy link
Member

CBenoit commented Jun 20, 2021

While not a bad alternative, I'm not very happy with 0 ad 1.
Several reasons :

  • as mentioned, harder to reach
  • on french layouts (azerty, bépo), shift is used to type numbers
  • when pressing 0 if no other number has been entered before, we know for sure this is text object inner selection mode. However, 1 could be either the beginning of a bigger number (e.g.: 10) or the text object outer selection mode. This is not cool if we intend to show help windows like in kakoune because we can't be sure whether help should be displayed or not
  • no mnemonic for it

I may repeat myself, but I would map x to inner (text object) and X to outer (text object "more") assuming V is line-wise extend mode and we don't need current x/X anymore.

@DrZingo
Copy link
Contributor

DrZingo commented Jun 21, 2021

These are quite similar in action, how about have them on the same keybinding, as they are in different modes. If they are frequently used - on m - otherwise something less short. (I don't use matching bracket particularly often myself, and flip selection I don't know yet).

m | Jump to matching bracket
Alt-; | Flip selection cursor and anchor

@CBenoit
Copy link
Member

CBenoit commented Jun 23, 2021

Alternatives to my text object inner x and text object outer X mapping suggestion from matrix:

@teenjuna

Why not si/sa for select inner / select around? As I understand, it will be used from normal mode, so s.. is free. Correct me if I'm wrong.
I can see how [current] s may be replaced with ss for select inside selections

@CBenoit

xi / xa for text object inner and text object around would be fine as well

@pickfire
Copy link
Contributor Author

pickfire commented Jun 24, 2021

I just realized that helix is hard to change till end of line. C or c$ in vim and alt-lc or Glc in kakoune but in helix we need to vglhc. I wish gl can exclude the newline so we can just Glc in helix.

@DrZingo
Copy link
Contributor

DrZingo commented Jun 24, 2021

It may be of interest to take a look at different keyboard layouts before deciding on a particular key. As an example the ; key is located to the left of 1 on some layouts, and is shifted on many European and Spanish-writing languages. This results in Alt-Shift-; for these.
Maybe a peek at this page before can justify/stop a choice of key:
https://keyshorts.com/blogs/blog/44712961-how-to-identify-laptop-keyboard-localization

@valpackett
Copy link
Contributor

As someone who switched from vim to kakoune, my config includes a "vim habits" section that includes: $ to go to end of line, 0 to go to beginning of line, ^ to go to non-whitespace beginning of the line, and most importantly bare { } for paragraph navigation.

One pain point in kakoune is that binding 0 like that means you can't even enter e.g. a 10 prefix anymore, as that zero would trigger the binding. There are workarounds for this, but this really shouldn't require workarounds. Hopefully helix can avoid this problem.

@pickfire
Copy link
Contributor Author

pickfire commented Jul 11, 2021

One pain point in kakoune is that binding 0 like that means you can't even enter e.g. a 10 prefix anymore, as that zero would trigger the binding. There are workarounds for this, but this really shouldn't require workarounds. Hopefully helix can avoid this problem.

I think plugin should have the ability to fix this if the keymap and commands is part of the plugin. I just add a tag for plugin because I think it is slightly related to plugin.

@pickfire pickfire added the A-plugin Area: Plugin system label Jul 11, 2021
@EmiOnGit
Copy link
Contributor

I want to bring up a change to the x and X key.
Personally I don't use the X key very often, it also seem to be rather confusing for other people starting out.

What I currently miss is a convenient way to extend the selection up as well as shrink the selection by one line up/down.

This could be achievable with redefining the x slightly and using the X key as a counter part.
Suggestion:
x:

Select current line, if already selected, extend to next line
if selection anchor is flipped (cursor above), remove the first line of the selection.

Current behavior is to disable the flip, and extend the selection by one line regardless.


X:

If selection starts in the same line, shrink to start, else shrink to previous line.
If selection anchor is flipped, extend by line above.

@chtenb
Copy link
Contributor

chtenb commented Nov 19, 2023

RE: all the posts about linewise selections.

The x/X mappings, as well as C and Alt-, come up frequently in discussions.
I thought I'd share a minor reshuffle of keys that has made these a lot better for me.

[keys.normal]
J = ["extend_to_line_bounds", "select_mode"]                      # Select whole line, then select lines downwards
K = ["extend_to_line_bounds", "select_mode", "flip_selections"]   # Select whole line, then select lines upwards

"A-j" = "join_selections"          # Join lines
"A-J" = "join_selections_space"    # Join lines, selecting the space in between

X = "remove_primary_selection"    # Remove primary selection
x = "keep_selections"             # Keep selections that match regex
"A-x" = "remove_selections"       # Remove selections that match regex

[keys.select]
J = ["extend_line_down", "extend_to_line_bounds"]
K = ["extend_line_up", "extend_to_line_bounds"]

"A-j" = "join_selections"
"A-J" = "join_selections_space"

X = "remove_primary_selection"
x = "keep_selections"
"A-x" = "remove_selections"

In short, J/K selects the current whole line first on the first key press, and then extends linewise up or down. This is similar to how j/k behaves, but instead it selects whole lines.
X now removes the primary selection.

Upsides:

  1. Easily select lines up and down using J/K. When you selected one line to far with J, no worries, just press K :)
  2. Easily remove cursors with X
    • X pairs very ergonomically with C for adding cursors below and removing them again. The fact that you can hold shift feels very natural. I found C an unintuitive key for adding cursors before, but this change has made me appreciate it.
    • Same for when iterating through the selections with ( / ). Holding shift and pressing X on the selections you want removed is a lot easier than letting shift loose to reach for Alt-,
  3. Apart from the ergnomic upsides, I find them also easier to remember. X has nothing to do with lines in my mind, while I CAN relate it to discarding things, in this case selections. J/K need no explanation here.

Downsides:

  1. Joining lines is now Alt-j, which is slightly different from Vim.
  2. J/K could do with dedicated commands, that do not need the hack with the select mode and would work in more edge cases.

Side note: I've never used the keep_selections command (bound to K by default), so I was happy to move it to x/Alt-x, which are somewhat in an awkward spot to reach.
(When the need would arise for another first-class function, this would probably be the first command I would ditch in favor of something else.)

@EmiOnGit
Copy link
Contributor

After testing with your config, I can agree :)

J/K feels very natural, my only nitpick is that it feels very odd (maybe just unfamiliar?) to be put in visual mode.
X for removing the primary selection seems natural, though personally I don't think I'd have a need for removing only one selection very often :)

After all I'd love these changes!

@chtenb
Copy link
Contributor

chtenb commented Nov 19, 2023

J/K feels very natural, my only nitpick is that it feels very odd (maybe just unfamiliar?) to be put in visual mode.

Yes, that is one of the things I meant with downside no 2. I think it would be beneficial to have commands which do something like this but stay in normal mode. I.e. more like how the current x command works, but WITH a proper inverse and a sensitivity to the orientation of the selection.

@EmiOnGit
Copy link
Contributor

@chtenb So what's the common procedure in this community?
I assume that this would not be seen by to many people here. Do we make it more public as a issue and hope for further discussion? (I'd love these changes for everyone to enjoy)

@chtenb
Copy link
Contributor

chtenb commented Nov 24, 2023

I think the first step would be to introduce proper commands for J/K, as outlined in the previous post, such that people can use a good version of these bindings. After that I don't know. People generally don't like change they didn't ask for, but in the end it's up to the maintainers opinion. If enough people seem to like it, we can at least document the option somewhere more visible then, perhaps in a wiki entry or something.

@firasuke
Copy link

firasuke commented Dec 8, 2023

Is there a keymap for selecting an entire line then going upwards? Pressing x multiple times selects multiple lines downwards, but there's no way to select a line then go upwards (the behavior I am talking about here is Shift + v)?

Also trying to replicate block selection Ctrl + v from vim, with multiple cursors have not been convenient. Is there a way around it? Or a better way to do it?

@chtenb
Copy link
Contributor

chtenb commented Dec 8, 2023

Is there a keymap for selecting an entire line then going upwards? Pressing x multiple times selects multiple lines downwards, but there's no way to select a line then go upwards (the behavior I am talking about here is Shift + v)?

Also trying to replicate block selection Ctrl + v from vim, with multiple cursors have not been convenient. Is there a way around it? Or a better way to do it?

If you look 5 comments up, you'll read an entire post dedicated to this.

@firasuke
Copy link

firasuke commented Dec 8, 2023

Is there a keymap for selecting an entire line then going upwards? Pressing x multiple times selects multiple lines downwards, but there's no way to select a line then go upwards (the behavior I am talking about here is Shift + v)?
Also trying to replicate block selection Ctrl + v from vim, with multiple cursors have not been convenient. Is there a way around it? Or a better way to do it?

If you look 5 comments up, you'll read an entire post dedicated to this.

Thanks, though I did check, and I only noticed the J/K mentioned for flipping the selection. It just does not feel ergonomic, as one would expect X to do that by default.

@oredaze
Copy link

oredaze commented Dec 27, 2023

Hi, I have been checking helix for the first time as a [neo]vim lover.
I notice that ma and mi feel nicer to me on va and vi, because v is the selection key, and the action they invoke is selection. But then again the v is a stronger selection, unlike the regular one (i don't know the terms).
So I was wondering isn't it smart to have va and vi as an alternative to the m ones by default. It won't be a duplicate, because they are slightly different. Maybe someone can suggest something even better?

@mostafaqanbaryan
Copy link

mostafaqanbaryan commented Jan 6, 2024

Hi.
So, lots of us use Helix/Vim inside Zellij or Tmux.
And mapped their keys around Alt.
So now that I want to use Helix as my main editor, it has a lot of conflicts with my Zellij config.
I tried to remap alt keys of Helix to something else, but some of alt keys are needed a lot and this is making me slow (like Alt+. to '+. for example).
It would be great if this was not the default behavior (of course, I know it's hard to find a good replacement)
Any suggestions?

@dead10ck
Copy link
Member

dead10ck commented Jan 7, 2024

@mostafaqanbaryan I think this is kind of tangential to the issue of Helix's default key map. Zellij purposefully uses lots of key combos that conflict with many terminal applications, not just helix. It's a known issue which even the author is not happy with.

zellij-org/zellij#1399

Tmux does not have this problem with its default key binds because of the way it uses leader sequences (Ctrl+b + key), and so from the perspective of any given terminal app, there is only a single potential conflict on Ctrl+b.

@EmiOnGit

This comment has been minimized.

@Zoybean
Copy link
Contributor

Zoybean commented Jan 23, 2024

I've had some weird issues with tabbing in insert mode, that I just realised is caused by smart-tab (which I have now disabled). Is there some explanation of why smart-tab does what it does, or what its use case is? I want to understand it rather than disabling something I don't understand.

@7ombie
Copy link
Contributor

7ombie commented Feb 2, 2024

The hardcoded bindings are the biggest problem (IMO), and the easiest to fix. After all, if the user can change the bindings, suboptimal defaults are far less of an issue.

For example, we cannot configure Helix to use v for View Mode (with V for the sticky variant), as there's no view_mode command to bind v to. This was to reserve v for Select Mode (??).

Personally, I use Escape to switch to Normal Mode, except in Normal Mode, where it switches to Select Mode instead (toggling between Normal and Select modes). This leaves v spare, so naturally, I'd prefer to use that for View Mode.

Likewise, I use Enter to move focus to the command line (so I don't need to hold Shift and enter a colon). This also allows me to double tap Enter to rerun the last command. This makes the colon redundant, as it cannot be rebound.

I'd also like to rebind the comma and dot keys (along with their angle brackets), as it'll allow me to manage multiple cursors far more intuitively, but the dot key cannot be rebound.

I could provide more examples, but you get the point. I can't see any reason to special-case and hardcode certain bindings.

@crazyoptimist
Copy link

Why not adopt VIM's keymaps as they are.

I tried hx today and it's really frustrating when I perform:

  • redo
  • delete

I believe there will be more to find myself.

I strongly recommend to adopt VIM's default keymaps as they are, at least for the most frequently used ones for minimalist users. That way migrating from VIM to HX would be seamless for the future adopters.

@archseer
Copy link
Member

archseer commented Mar 7, 2024

@crazyoptimist This has been discussed to death already and we've explained several times on why that won't happen. Helix is a different editor and the internals would have to be rewritten for this to work (in which case we're just rewriting vim). It's modal but that doesn't imply identical to vim. If you just want vim, why not use vim?

This thread is very generic and various changes have been intermixed here. For a general discussion, github discussions are a better option. For an individual, actionable change or proposal a new issue should be created.

@archseer archseer closed this as not planned Won't fix, can't repro, duplicate, stale Mar 7, 2024
@robclancy

This comment was marked as abuse.

@archseer
Copy link
Member

archseer commented Mar 8, 2024

@robclancy PR welcome! Let's see how easy it is to implement

@robclancy

This comment was marked as abuse.

@archseer
Copy link
Member

archseer commented Mar 8, 2024

I closed the issue because "keymap discussion" is not an actionable issue with a resolution. Feel free to open a "vim keybindings" issue and I'll give you the same douchey response there giving you the opportunity to prove me wrong and show how easy it is to implement in helix ;)

@robclancy

This comment was marked as abuse.

@archseer
Copy link
Member

archseer commented Mar 8, 2024

Alright then, please use a different editor.

@robclancy

This comment was marked as abuse.

@archseer
Copy link
Member

archseer commented Mar 8, 2024

Yes and my point was we had 239 comments that weren't closely related and should be opened as separate issues. Again, I don't appreciate your tone and you're welcome to stop using helix and use something else.

@helix-editor helix-editor locked as too heated and limited conversation to collaborators Mar 8, 2024
@the-mikedavis the-mikedavis unpinned this issue Mar 17, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A-keymap Area: Keymap and keybindings A-plugin Area: Plugin system E-help-wanted Call for participation: Extra attention is needed
Projects
None yet
Development

No branches or pull requests