Replies: 7 comments 20 replies
-
Coincidentally, just this week I pushed an update to I'll share more on what that might look like when I get time later today. |
Beta Was this translation helpful? Give feedback.
-
Sorry for going quiet. It's been a busy week at work and home. Anyhow, the topic at hand. The solution I'm proposing is this one, instead of having a flat and rigid config file, instead having it a native part of Murex's event system. For example:
yeah that's verbose, but it doesn't create yet another different way of configuring the shell. Plus it means you can get a little more clever, for example, if you want this hotkey to also apply a message to the hint text:
You can also chain actions, eg
|
Beta Was this translation helpful? Give feedback.
-
I've been thinking about your "modes" comment quite a bit this week. Murex does have a concept of modes, but several different modes can be true in parallel: Line editing mode
Autocompletion mode
Preview mode
There are some limitations, like fuzzy search doesn't support VIM keys, but by and large any of those 3 modes could be in any of their respective states at any one time. So I'm not sure the best way to surface to complexity to the event in a way that doesn't create burden on the individual writing their event. The initial thought was I can surface a JSON structure that's easy to inspect, looking something like:
So you could inspect it like:
|
Beta Was this translation helpful? Give feedback.
-
Thanks for the detailed response! So if I'm understanding right, in this example you gave with a list of actions,
the content of $.Actions is a list that can contain functions from
Would the readline/cursor actions only be available in the context of the keypress event? Also, when I was playing around with what's on IMO in that case it might be a good idea to print some kind of warning to stderr about redefining an existing key? |
Beta Was this translation helpful? Give feedback.
-
I like your approach to adding modes as a meta variable -- it adds a lot of configuration power to the event without being overly complex. My only question would be are onKeyPress events able to change the mode themselves, and if so would that be done by manipulating the meta variable? e.g. |
Beta Was this translation helpful? Give feedback.
-
First working prototype has been pushed to No documentation yet |
Beta Was this translation helpful? Give feedback.
-
I'm having second thoughts about using This could lead to some unexpected edge cases like in the following contrived example:
An easy solution to this is to use a different variable name, eg You can workaround the above problem with something like
...basically assigning Plus if I'm expecting users to do that then I might as well just make that variable special to begin with. eg The other option is to scrap using variables entirely and write to a named pipe. But I think that just creates new problems too. |
Beta Was this translation helpful? Give feedback.
-
Hi all,
I'd like to kick some ideas around and solicit feedback on the topic of supporting the ability to configure custom keybinds in Murex. I started looking into writing a PR to do this, but it quickly became clear that there are a lot of high-level questions that don't necessarily have clear answers.
Background
Currently, Murex supports a number of keybinds. These can do everything from modifying the text and cursor in the command prompt to navigating and controlling Murex's features and utilities. Unless I've missed it, there's currently no mechanism by which these keybinds can be customized by the user.
The existing keybinds do seem to do a good job of making users accustomed to Bash/Readline comfortable. But no configuration will work for all users. Subjectively, having to learn new keybinds when you switch software rather than being able to reuse the ones you're already comfortable with can be a big source of friction. Speaking personally, the first ever issue I opened in this repo was a request to add keybinds I was used to in other shells.
Survey of Other Shells
While Bash/Readline might be familiar, I was curious how others handle keybinds, so I took a look at some more recent shells. Of course, these shells may have communities, use cases, and design philosophies that differ from Murex's, but they can still provide us with some ideas. I don't claim to be an expert on any of these shells, I just gathered this information from a quick look at their docs.
Fish
Fish provides a bind command that supports mode-aware keybindings.
The key that triggers a binding is defined by a fish escape sequence.
Additionally, fish provides a neat builtin called
fish_key_reader
that captures a key sequence and tells you how it's represented as a fish escape sequence, and what bindings (if any) are currently mapped to that sequence.Key sequences can be mapped to normal shell commands/functions, but also to a special set of functions mostly relating to manipulating the cursor/text in the prompt, analogous to Murex's
hotkey_functions.go
.Reference
Elvish
Elvish comes with a
readline-binding
module providing readline keybinds which is not turned on by default but can be enabled with the commanduse readline-binding
.Keys may be mapped to code blocks.
Keys are expressed as a character (e.g.
k
) or function key (e.g.F1
,Right
,PageUp
), optionally prefixed by a modifier (e.g.A-
,Alt-
,S-
,Shift-
).Keybindings can be edited with a command of the following form (where "insert" is the mode in which the keybinding should apply)
set edit:insert:binding[Alt-x] = { exit }
Keybinds can be made across all modes as well in
$edit:global-binding
.Reference
Nushell
Keybindings in Nushell can be set in a config file, also with per-mode specificity. Each keybinding contains the following elements
control
,alt_shift
,none
, etc.emacs
,vi_insert
, andvi_normal
Reference
Oil
Oil appears to use Readline.
Zsh
Okay, although I said I was looking at shells newer than Bash, this still technically counts, having been released one year later! 😆
Zsh key bindings can be managed with the
bindkey
builtin.Keys can be described in multiple notations (e.g. caret notation, escape sequences, Unicode).
Keys can be bound to ZLE (ZSH's Readline equivalent) widgets or strings. ZLE provides widgets to manipulate the cursor/text in the prompt (e.g.
backward-kill-word
,up-line-or-history
), and supports user-defined widgets to run shell commands. Binding a key to a string can also be used to run commands, e.g. by making the string the name of a command followed by a newline character.Reference 1
Reference 2
Questions About Murex Keybinds
With these other implementations in mind, we can now turn to how some of these features might be implemented in Murex.
In my opinion, the
config
builtin seems to be a natural way to implement custom keybinds in Murex. Maybe a new app in config calledkeys
could be added. If we were to take this approach, though, I'm not entirely sure how the JSON would be structured.One approach would be to have an object with some kind of representation of the key+modifier as its keys, and code blocks to execute as its values.
Another would be some kind of list, e.g.
but this seems like it would have the disadvantage of being more difficult to query. If you're looking for a specific keybind using the first format, it's just a lookup for the key. But using the second format, you'd have to iterate over the list checking each object to see if the key matches.
Another wrinkle is modes, or the ability for a keybind to do different things in different contexts. Using the first format, you'd have to bake the mode into the key somehow, whereas with the second format you could just add a "mode" key to each object to specify the mode(s) for which the keybind is active. While Murex doesn't seem to use the term
mode
in the same was as most of the other shells we looked at, it does have different contexts where we might want keybinds to do different things. For example, we might wantTab
to do one thing while autocompleting a command, and another when the F9 command line preview is open.Still another question is what do we want to allow users to do when a keybind is pressed. Presumably they could bind a key to a code block or function, but it also seems desirable for them to have some ability to access the functions in
hotkey_functions.go
. Is there any other functionality we want to expose to them?Conclusion
This turned out much longer than expected but I hope it might provoke some thought and discussion about keybinds. Thanks for reading!
Beta Was this translation helpful? Give feedback.
All reactions