-
Notifications
You must be signed in to change notification settings - Fork 8.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
Support "Key Chords" in keybindings #1334
Comments
Here’s a thought. What if we execute the keybinding when “CTRL” is released? So “CTRL-K, CTRL-D” is really just you hold CTRL, then press K, then press D. And it executes when you release CTRL. We could use a Trie data structure. Traverse the Trie as you press more keys. If you end on a leaf, execute the code. If an internal node has a command linked to it, execute ONLY when the first key pressed (in this case, CTRL) is released. |
Do you have already some idea how this could be structured in the |
@dnagl Yep 😄 I actually made the "keys" property an array when I first implemented keybindings, despite there only ever being one key combo, because I knew that this is something we'd want eventually. |
@zadjii-msft Seems obvious. The property contains an array. 😄 |
IMHO: chorded key binding shortcuts are generally useful when there are many possible actions/bindings, so you need a bigger space of possible inputs. A text editor / IDE is obviously one such scenario. It seems unlikely that a terminal would ever have so many shortcuts... does anyone know of another non-IDE terminal that implemented this? Per #2388 (comment) the array of "keys" might be a logical syntax to repurpose for multiple bindings to the same action. |
tmux and screen are both terminal emulators that have implemented chorded keys. 😄 |
Clearly I've massively underestimated your ambitions for this app! |
If you consider that iTerm2 can act as a tmux controller and turn tmux panes into physical terminal panes, the lines between the multiplexer and terminal emulator are already a bit blurry. We support panes, and we probably eventually want some higher-level concepts like pane selection, grouping, and movement that I don't think we should bind over the fairly limited set of level-1 keyboard characters. More to the point, though, I personally hold all the things that could be serialized in VT as sacred and "under the purview of the receiving application", so chording gives us an escape hatch to add a terminal control plane keyset. Ya know? |
## Summary of the Pull Request Adds warning messages for a pair of keybindings-related scenarios. This covers the following two bugs: * #4239 - If the user has supplied more than one key chord in their `"keys"` array. * #3522 - If a keybinding has a _required_ argument, then we'll display a message to the user - currently, the only required parameter is the `direction` parameter for both `resizePane` and `moveFocus` ## References When we get to #1334, we'll want to remove the `TooManyKeysForChord` warning. ## PR Checklist * [x] Closes #4239 * [x] Closes #3522 * [x] I work here * [x] Tests added/passed * [n/a] Requires documentation to be updated  ## Validation Steps Performed Tested manually, added tests.
FWIW, we're also implementing chords in enquirer, a prompt system, and this has turned out to be useful for not just traditional chords, but also multi-digit numbers. In general, one of the things that makes this challenging in the terminal (or at least limited in node.js) is there is no way to get key up/down events, so we can't determine when someone is holding down the
This is effectively what we're doing, and it seems to work well. Basically we store the first key if there is a non-chord key binding that should be used if the second key in the chord isn't pressed. If the second key is either a) not pressed before the timeout expires, or b) another key that does not match the second key in the chord is pressed, then we re-dispatch the stored key as a non-chord, then we dispatch the new (second) key. |
A terminal runs another application inside it, which also has keybindings of it's own. For example, this is why Ctrl+Shift+W closes tabs instead of Ctrl+W, since Ctrl+W is used in most shells to delete a word. Since the terminal can even run editors such as emacs/vim inside it, the need for more obscure keybindings arises very quickly. |
@0xabu terminal apps which support this feature already are https://github.com/Eugeny/tabby (formerly terminus) and https://github.com/vercel/hyper/ as well I'm not able to use these at work so looking forward to support with this terminal |
What is needed here to get this going/finished? |
Someone would need to figure out how to mechanically get a chorded keybinding to work with our TermControl right now. I left notes in the OP for things I would look into. I'd think the trick would be finding the way for Alas, I don't think this is something I'll have time to get to anytime soon, but if someone else would like to take a look I'd be happy to help in whatever way I can |
Dropping a note in here: Lib/_pyrepl/windows_eventqueue.py
|
Currently, we only support pressing a single key+modifiers to activate a keybinding action.
However, many text editors support "key chords" where the chord is a combination of multiple keys pressed in sequence. For example, in Visual Studio, the default keybinding for "Comment Code" is the chord
[ctrl+c, ctrl+k]
.We've already prepared for serializing these chords in the array of keybindings, but we don't support more than one key at a time. We'd have somehow check if a key is the start of a chord, and only dispatch the action when all keys for the chord have been pressed.
Lots of questions:
[ctrl+c, ctrl+k]
and another is bound to[ctrl+c]
?The text was updated successfully, but these errors were encountered: