RobertWHurst / Keystrokes

Keystrokes as an easy to use library for binding functions to keys and key combos. It can be used with any TypeScript or JavaScript project, even in non-browser environments.
MIT License
158 stars 6 forks source link

Enhancements to sequential key combos #4

Closed pilliq closed 1 year ago

pilliq commented 1 year ago

Hi @RobertWHurst!

Is your feature request related to a problem? Please describe. For context, I want to build "vim-like" shortcuts into a web app. That means working a lot with sequential key combos (e.g. useKeyCombo('g,o') where g is pressed and released, and then o is pressed and release). Keystrokes supports sequential key combos (which is great!), but there are a few usecases that I did not immediately see Keystrokes support.

Describe the solution you'd like Specifically:

  1. I'd like to be able to "peek" into the current sequential key combos that Keystrokes has partially matched, e.g. using the useKeyCombo('g,o') example again, if I press and release g, I'd like to be able to ask Keystrokes "what sequential key combos have been partially matched?" and it would return a list of registered sequential key combos that begin with g.
    • Ideally, it would also be able to return the keys actually matched, e.g. if I had useKeyCombo('g,o,t') and pressed/released g and then pressed/released o, then asking for partially matched sequential key combos would return the currently matched keys (g,o) along with the list of registered sequential combos that partially match (useKeyCombo('g,o,t'))

Why I want to be able to display the currently accumulated/matched key sequence the user has typed somewhere on the page (kind of how vim does at the bottom of the editor).

  1. I'd also like to have the ability to cancel sequential key combo matching midway. Specifically, I'd like to map the Esc key to clear the currently accumulated key sequence. Using Keystrokes, I seem to be able to type g, then any number of keys, and finally o and Keystrokes still happily executes the key combo. e.g. if I registered g,o and I type g,t,w,r,o, Keystrokes still interprets that as if I typed g,o (aside: not sure if this was intended, or if this is a bug).
    • Ideally, there would be a setting that allows for an optional timeout for when Keystrokes should stop listening for an accumulated key sequence. This is not completely necessary as long as there's some facility for Keystrokes to "cancel" the currently accumulated key sequence.

These features may already exist in Keystrokes, but I wasn't able to find them with a cursory look.

Thanks for the help and for your work on this lib!

RobertWHurst commented 1 year ago

Yeah that sounds like a great idea. Let me mull on this a bit and circle around with you in a day or so. Glad to hear you like the library šŸ»

RobertWHurst commented 1 year ago

Well it's been more than a day or so šŸ˜….

I've been thinking about how to do this and I think I'm going to add a new method to keystrokes called checkKeyComboSequenceIndex. It will return the sequence index of the combo - 0 if the combo is not active at all. For each sequence active within the combo the returned value will be incremented. So for a combo like g,o if g is pressed then the returned index will be 1. If then g is released and o is pressed the index will be 2. Once o is released the index will be 0 again.

If get a string representation of what parts of the combo are pressed simply use string split

const myCombo = 'g,o'
const myComboSquenceIndex = keystrokes.checkKeyComboSequenceIndex(myCombo)
const activePartOfCombo = myCombo.split(',').slice(0, myComboSequenceIndex).join(',')
RobertWHurst commented 1 year ago

Closing as checkKeyComboSequenceIndex was landed in v1.1.0. That said we can continue with this discussion still.