-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Allow multi key remappings in config file #454
Conversation
6255d6e
to
e14ed08
Compare
So I presume you would do this for 3 keys?: |
@kirawi Exactly, it can be arbitrarily nested to any level. An alternative syntax (supported by the toml spec): [keys.insert.e.s]
"c" = "normal_mode" |
[keys.insert.e.s]
"c" = "normal_mode" This does seemed better, is it possible to switch to this? Either way, the current configuration mechanism is just temporary. |
Both methods are supported by the parser, it's in the defined toml spec :) |
e14ed08
to
da83e46
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is better to integrate this with infobox to kill two birds with one stone.
- able to change infobox keys
- able to show infobox for user custom keys
But with that we need additional information in the settings.
Maybe you can look at how infobox is implemented, I have this in mind so I parse the keys the same way the config is currently being parsed.
helix/helix-term/src/commands.rs
Lines 3691 to 3714 in e2bcef7
mode_info! { | |
/// space mode | |
space_mode, SPACE_MODE, | |
/// file picker | |
"f" => file_picker, | |
/// buffer picker | |
"b" => buffer_picker, | |
/// symbol picker | |
"s" => symbol_picker, | |
/// window mode | |
"w" => window_mode, | |
/// yank joined to clipboard | |
"y" => yank_joined_to_clipboard, | |
/// yank main selection to clipboard | |
"Y" => yank_main_selection_to_clipboard, | |
/// paste system clipboard after selections | |
"p" => paste_clipboard_after, | |
/// paste system clipboard before selections | |
"P" => paste_clipboard_before, | |
/// replace selections with clipboard | |
"R" => replace_selections_with_clipboard, | |
/// keep primary selection | |
"space" => keep_primary_selection, | |
} |
Do you want to give it a try? If anything can ping me.
The infobox was one of the reasons I went with a tree to represent the keys since it would be easy to get the next set of possible keys after a keypress; this is how I was thinking of doing it: --- a/helix-term/src/keymap.rs
+++ b/helix-term/src/keymap.rs
@@ -195,7 +195,18 @@ impl Default for Keymaps {
ctrl!('o') => KeyCommand(Command::jump_backward),
// ctrl!('s') KeyCommand(ommand)::save_selection,
- key!(' ') => KeyCommand(Command::space_mode),
+ key!(' ') => SubKeymap(hashmap!(
+ key!('f') => KeyCommand(Command::file_picker),
+ key!('b') => KeyCommand(Command::buffer_picker),
+ key!('s') => KeyCommand(Command::symbol_picker),
+ key!('w') => KeyCommand(Command::window_mode),
+ key!('y') => KeyCommand(Command::yank_joined_to_clipboard),
+ key!('Y') => KeyCommand(Command::yank_main_selection_to_clipboard),
+ key!('p') => KeyCommand(Command::paste_clipboard_after),
+ key!('P') => KeyCommand(Command::paste_clipboard_before),
+ key!('R') => KeyCommand(Command::replace_selections_with_clipboard),
+ key!(' ') => KeyCommand(Command::keep_primary_selection)
+ )), So instead of using the |
I don't think tree is the issue, I think both specifying the message during compile-time works but I think we should reuse the But there is a benefit to let user specify their message, because we don't know how the user structure their keys so it is better to let users override the description for the infobox as well, which is why I think the description should be in runtime config, because we don't know how user want to structure the stuff, and the infobox should depends on how it is structured to have custom text. Although infobox integration is not necessary now but at the very least I would like to see the replacement of |
I think this is a good feature, but it shouldn't be bolted onto the current data structures. We should implement a custom trie structure for keys, and then fetching the value either returns a final node (a command) or a node with more branches, which can then be used to render the autoinfo in a generic way for any subcommand. |
@pickfire I think we can start with non-configurable infobox descriptions since the user cannot make custom commands yet, and if the default descriptions need changing they should probably be changed in the repo itself. I'll look into replacing @archseer You mean storing the state within |
That said, I took a look and the trie in iota looks a lot like what we have now (a bunch of hashmaps) :) so we can probably just tweak the current implementation. Yeah I think the way to go is improve the In order for the descriptions to work we'll have to define them per command (instead of within the |
This PR is heading in a direction that I'm really excited about, but I think can potentially go even further. I'm not sure if we want to tackle this in this PR, but here's what I was thinking: The keymap tree wouldn't just handle sequential key presses, but also modes. Basically, if you think of normal mode as being the "root", then the keymap tree branches off from there, and that tree can have both:
This would allow nearly complete customization of Helix's interaction model. The main question I'm still unsure of with the above idea is how insert mode fits into all of this. Possible each sticky node has a boolean flag that specifies whether it's an "insert-like" mode or a "normal-like" mode. Not sure. (Sorry if this is off-topic for the PR... I'm just really excited about getting the Helix interaction model super customizable, ha ha.) |
b00a23a
to
5af6890
Compare
5af6890
to
f427e6b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can just defer infobox integration but I would like to see hashmap!
macro being updated to add the Leaf
.
helix-term/src/keymap.rs
Outdated
"E" => move_next_long_word_end, | ||
|
||
"v" => select_mode, | ||
"g" => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Goto line number doesn't work now since there is no separate function for goto mode. Adding a function for goto mode only will require treating it as a special case especially for handling the infobox and user remappings. A solution is to add it to gg
(keybind would change from 82g
to 82gg
, like in vim).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we add hooks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But that would make it impossible to have any other key under g
to take a count, and the user might remap some function to it that takes a count.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The keys under g from what I see all does not need a count.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default ones don't, I meant the case as a user remapping some other function that takes count to a key under g
. I will probably do this myself with ge
to be vim-like (go to end of previous word) and it would take a count.
@cessen That's a neat idea; I suppose it's similar to emacs major modes (I don't use emacs so not sure) ?
@pickfire I moved the keys from
I made |
I don't use emacs either, so no idea, ha ha. I just have a hope for modes themselves to also be fully customizable in Helix, and that's one idea for how to accomplish that in a relatively coherent way. But maybe another approach would be better. |
Great work! I think this is looking much nicer than what we have on
Yeah signature help is incomplete and will likely be auto triggered by a hook when a trigger character is used (defined by lsp, usually Expand selection used to be |
Tested it out on local, it works! Just a few things:
|
helix-term/src/keymap.rs
Outdated
"E" => move_next_long_word_end, | ||
|
||
"v" => select_mode, | ||
"g" => { "Goto mode" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please reuse the old titles that you removed rather than creating new ones? Like the following.
"g" => { "Goto mode" | |
/// goto | |
/// | |
/// When specified with a count, it will go to that line without entering the mode. | |
"g" => { |
The extra description will only be shown in the rustdoc but the "goto" word will be shown in both rustdoc and infobox.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reusing the old titles seem better since they are shorter 👍🏾. But specifying it as a doc comment and then having an additional description would be hard to parse since the macro is recursive (also writing descriptions for rustdoc seem redundant since they are not user facing and only developers will see it)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I will take a look at this later myself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But can you please keep them as normal comments here? So later I can just change it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the descriptions themselves to use the ones from mode_info
in ad7e412
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the docs and macro can be improved. "m" => { "Match mode"
looks weird. But at least for now the docs should take from the old one for those that was writtten, I tuned them specifically for the infobox.
Thank you ! Making the macro recursive was quite fun :)
@archseer BTreeMap sorts itself by keys, so it won't remember insertion order. I think we can keep a private
I'll try a hand at it :)
@pickfire My initial preference for the syntax was |
Ah right! I guess we'd need https://github.com/bluss/indexmap but I'm not sure if it's worth pulling in another dependency, a Vec of keys to sort by would work yeah. |
Yeah pulling a dependency seems overkill, I went ahead and added it with a Vec :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work!
Regression from helix-editor#454. Go to line 10 with `10gg` or `10G`.
Regression from #454. Go to line 10 with `10gg` or `10G`.
@sudormrfbin Would it be possible to serialze the default keymap from a I need to rebind almost all keys because I'm on a workman layout sometimes, so this is really annoying to do as a partial With a Edit: to keep the
|
Even aside from keyboard layouts, I think it would be good to support starting from a blank slate anyway, for building totally custom keymaps. |
@blaggacao Moving the default keys to Other than that I don't see a problem with it, though using scancodes as mentioned in #165 and #133 would be a more elegant solution to the problem. |
Allows configuration like this:
Or alternatively in inline table syntax:
We can't use something like
"jk" = "normal_mode"
since that will collide with key names like"backspace"
and"esc"
.Key mappings are represented in a tree like structure, which can be useful in the future to dynamically show infobox contents (currently the keys are hardcoded, and user mappings cannot be shown).