-
Notifications
You must be signed in to change notification settings - Fork 57
API for cancelling of key binding #92
Description
Two related issues here:
- is there a way of cancelling of failed key strokes without any propagation or replay of key strokes?
- and can
isAtomModifier()be made part of theatom.keymapsAPI, please?
Now I'll give some background for why this is an issue:
In vim-mode, we have commands, motions, prefixes and other things that can be combined together. For example, we have the c command to change text, aw motion to select a whole word, and 3 for repeating, meaning that c3aw should change three words.
We do not have an exhaustive keymap that would define all possible combinations because that would be quite a long list. In fact, a number prefix can be any integer number, so we'd need to define key bindings for c a w, c 1 a w, c 2 a w, ..., c 1 0 a w and so on. Instead, we have Atom key bindings for c, a w, and numbers, and we do the composing of commands in the package logic.
However, that presents us with the challenge of invalid combinations. Typing ca3w instead of c3aw needs to recognize that a 3 is not valid (it does) and cancel the whole combination of c a 3 (at which point we may beep to tell the user they've made a mistake). I'm trying to do that in atom/vim-mode#764.
By default, Atom Keymap will see c and fire the change command, see a and wait for the next key stroke among many possible motions starting with a (a word is aw, a paragraph is ap and so on); then Atom will see 3, realize that's not supported, and here it departs from what we need: it will try to match a on its own (which isn't available there, so it's ignored) and then it will replay 3. In the end, vim-mode sees c3w, which is different from c3aw.
To cancel ca3 in atom/vim-mode#764, I'm subscribing to atom.keymaps.onDidFailToMatchBinding. In vim-mode, I can cancel the waiting c change command easily, but to cancel the i 3 combination and prevent replaying of 3, I'm using the private function atom.keymaps.cancelPendingState() within the onDidFailToMatchBinding callback. Is there some public way of doing this? That's issue 1.
However, in commands like c%, which is quite valid, Atom Keymap gives me a did-fail-to-match-binding event with shift being the keystrokes. I understand why that happens and ignore it as harmless, not cancelling the c change operation in vim-mode. For that, I've copied isAtomModifier() from atom-keymap's src/helpers.coffee, but I'd prefer to call something like atom.keymaps.isAtomModifier() instead, if that was made available. That's issue 2.