More generic composite key escape method (e.g. for jj/jk/kj etc)
See original GitHub issueThe problem
Currently the composite key system is a little strange. In order to handle the case where the two letters are the same (eg jj
), the first composite key has to trigger an escape if it sees its bound key again. This means handling the case where they are different (eg kj
) will always also handle the case where they are the same (i.e. kk
as well as kj
). Also, it only allows for one combination, so would not allow order-independent mapping of the kj
chord (i.e. trigger on both kj
and jk
Proposed solution (WIP)
Have a single function to be mapped to, something like compositeEscNotifyKeyPressed
. All keys within the chord, whether just j
or both k
and j
should be mapped to this individually, so you might end up with something like:
{
"key": "j",
"args": "j",
"command": "vscode-neovim.compositeEscNotifyKeyPressed",
"when": "neovim.mode == insert && editorTextFocus"
},
{
"key": "k",
"args": "k",
"command": "vscode-neovim.compositeEscNotifyKeyPressed",
"when": "neovim.mode == insert && editorTextFocus"
}
This would be accompanied with a separate option (say, “compositeEscKeyChords
”), a dictionary holding each chord you want to bind, for example:
{
"k": "v",
"v": "k",
"j": "j"
// Not supported with this algorithm because of the duplicate key:
// "v": "k"
}
Then the callback function should store as a variable the pressed key (passed as an arg) if it is in compositeEscKeyChords
as a key. If that variable already has something in it, and the current press is within the timeout, check to see if the current press is a value in the map for the stored previous key. If so, do the backspace and esc. If not, send the character.
What do you think about this setup? As far as I can see it would solve the problems above, and do so in a more elegant way than the current solution.
(I think the timeout should also be provided as an option, because people can get quite sensitive about their timeoutlen
in vim.)
Issue Analytics
- State:
- Created 3 years ago
- Reactions:6
- Comments:6 (2 by maintainers)
Ok I implemented a version of this, updated tests, etc. It’s general enough to map any key, or just one if you include
escOnDoubleTap: true
in the args list inkeybindings.json
. Also addedtimeoutLen
arg!Ah, I see what you mean. In the tests I had been using it for, I hadn’t needed to type those keys so I didn’t notice the delay 😕
Bother