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 the atom.keymaps API, 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.
Two related issues here:
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
ccommand to change text,awmotion to select a whole word, and3for repeating, meaning thatc3awshould 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 wand so on. Instead, we have Atom key bindings forc,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
ca3winstead ofc3awneeds to recognize thata 3is not valid (it does) and cancel the whole combination ofc 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
cand fire the change command, seeaand wait for the next key stroke among many possible motions starting witha(a word isaw, a paragraph isapand so on); then Atom will see3, realize that's not supported, and here it departs from what we need: it will try to matchaon its own (which isn't available there, so it's ignored) and then it will replay3. In the end, vim-mode seesc3w, which is different fromc3aw.To cancel
ca3in atom/vim-mode#764, I'm subscribing toatom.keymaps.onDidFailToMatchBinding. In vim-mode, I can cancel the waitingcchange command easily, but to cancel thei 3combination and prevent replaying of3, I'm using the private functionatom.keymaps.cancelPendingState()within theonDidFailToMatchBindingcallback. 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 withshiftbeing thekeystrokes. I understand why that happens and ignore it as harmless, not cancelling thecchange operation in vim-mode. For that, I've copiedisAtomModifier()from atom-keymap'ssrc/helpers.coffee, but I'd prefer to call something likeatom.keymaps.isAtomModifier()instead, if that was made available. That's issue 2.