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
NAP 7: Key Binding Dispatch #200
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow this is very nicely written @kne42! I've left a couple of minor suggestions, but as per the NAP process, I think this can be merged very soon.
|
||
### Finding a match | ||
|
||
When checking if an active key binding matches the entered key sequence, the resolver will fetch the pre-sorted list of direct conflicts and check if the last entry is active using its `when` property, moving to the next entry if it is not. When it encounters a blocking rule, it will return no match, and for a negate rule, it will store the affected command in an ignore list and continue to the next entry. If no special rules are present, it will return a match if the command is not in an ignore list, otherwise continuing to the next entry, and so on, until no more entries remain. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know what blocking or negate rules are... Could you add a paragraph on these?
docs/naps/7-key-binding-dispatch.md
Outdated
```python | ||
def has_shift(key: int) -> bool: | ||
return bool(key & KeyMod.Shift) | ||
|
||
def starts_with_ctrl_cmd_x(key: int) -> bool: | ||
return key & 0x0000FFFF == (KeyMod.CtrlCmd | KeyCode.KeyX) | ||
|
||
def multi_part(key: int) -> bool: | ||
return key > 0x0000FFFF | ||
|
||
> list(filter(has_shift, keymap)) | ||
[<KeyCombo.CtrlCmd|Shift|KeyZ: 3115>, <KeyMod.Shift: 1024>] | ||
|
||
> list(filter(starts_with_ctrl_cmd_x, keymap)) | ||
[ | ||
<KeyCombo.CtrlCmd|KeyX: 2089>, | ||
KeyChord(<KeyCombo.CtrlCmd|KeyX: 2089>, <KeyCode.KeyC: 20>), | ||
KeyChord(<KeyCombo.CtrlCmd|KeyX: 2089>, <KeyCode.KeyV: 39>), | ||
] | ||
|
||
> list(filter(multi_part, keymap)) | ||
[ | ||
KeyChord(<KeyCombo.CtrlCmd|KeyX: 2089>, <KeyCode.KeyC: 20>), | ||
KeyChord(<KeyCombo.CtrlCmd|KeyX: 2089>, <KeyCode.KeyV: 39>), | ||
] | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The formatting here is a bit weird... I suggest not mixing pure Python cells and cells containing prompts and outputs.
docs/naps/7-key-binding-dispatch.md
Outdated
] | ||
``` | ||
|
||
Note that because of the spec, querying for modifiers will only check the first part: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"because of the spec" — maybe be more precise about which part of the spec?
The docs build is erroring out because MyST (and reST) tries to add a "transition" (a horizontal bar) before the footnotes, but you also have a section name for it (
to |
Co-authored-by: Juan Nunez-Iglesias <jni@fastmail.com>
|
||
a **key combination** is a base key pressed with one or more modifier keys, e.g. `ctrl+c` or `ctrl+shift+z` | ||
|
||
a **key chord** consists of two parts, of which each can be either a base key or a key combination, e.g, `ctrl+x v` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean by two parts? A key combo represents simultaneously pressing several keys, but a chord represents a sequence? Must each part be pressed separately? Do they need to within a certain time gap?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, each part needs to be pressed separately. they do not need to be within a certain time gap, although that was a consideration for indirect conflicts (e.g. ctrl+x
is both its own kb and also part of the chord ctrl+x m
)
docs/naps/7-key-binding-dispatch.md
Outdated
|
||
There are two ways indirect conflicts can exist: | ||
|
||
A. the provided key sequence is a single modifier that is a modifier in another key binding's key combination or is a modifier in the first key combination of a key binding's key chord |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I don't have the right kind of brain to think about key bindings, but an example for each case would help a lot!
Overall, the document is beautiful. I haven't kept up with the key binding discussion, so some of the details are a little lost on me, but I got the gist. I had some (hopefully) simple clarifying questions. Will leave more detailed discussion and questions for those with more context and stronger opinions here.
The mapping for similar reasons as given in the NAP itself - because it's simpler and the prefix tree doesn't perform much better in a fairly large/complex case. |
docs/naps/7-key-binding-dispatch.md
Outdated
- `f1-f12`, `a-z`, `0-9` | ||
- `` ` ``, `-`, `=`, `[`, `]`, `\`, `;`, `'`, `,`, `.`, `/` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is a US centric view. Many of those are characters, not keys, that might be present on the same key. 6
and -
are the same key on french keyboard for example.
I'm fine having a US centric implementation, but I just want to underline that the nomenclature is important at otherwise it can lead to confusion.
I would suggest pulling a-z0-9 into their own category, and saying something along "keys that support one or more of the following character are base keys".
As far as I understand for the other ones, they may be on the same physical button, (eg, pageupdown, and arrow keys), but needs the fn button button to be pressed, so at keyboard level they register as a different key.
I believe vocabulary and definitions are important otherwise we will talk pass each other, and defining say button/key/characters may help us express things we couldn't do otherwise.
In practice keys/character distinction might be important for the physical layout of where the shortcuts are. Typically games can use wasd
for moving character, those are key bindings and not character binding, as on other non-english keyboard, you want the positions of the button to be the same, but the character ends up being zqsd
on say french keyboard.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, that's interesting. I find that explanation confusing as well, so I put down "a base key is a key that when pressed without a modifier key, produces one of the following key codes".
Do you find that satisfactory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that' better, and thank for your link, it is interesting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work! Should merge asap as per NAP rules :)
This is really clear, but I have just one comment: |
So have special casing for if a modifier is pressed and held vs pressed and immediately released? I think this adds too much complexity for my liking. Advanced users could start a timer when the key is first "pressed" (this signal can be delayed due to dispatching) and then check on release if they should execute different logic based on the time. I don't really want to support/encourage the usage of modifier keys as keybindings outside of changing the GUI (e.g. press |
Sorry if I wasn't clear, I meant a (keyboard) modifier (held) for a mouse action—exactly like your case of alt to modify a select/cursor! |
I still don't quite follow. Could you give me an example of the two different use cases someone might have and how we want to handle each? My current understanding is that you want to have an additional registration system (outside of key bindings) for mouse bindings that similarly captures conditionals, modifiers, etc. Some examples with most selection tools include click to change selection to an element, shift+click to add multiple to selection, and control+click to toggle selection of an element. |
hi @melissawm im still getting this error, any ideas? |
ok, i found the issue, for some reason, it initially correctly installs |
hi @jni could you give a re-review if possible? starting a merge countdown if no one has additional feedback at this time |
NAP for how key bindings will be handled --------- Co-authored-by: Juan Nunez-Iglesias <jni@fastmail.com>
NAP for how key bindings will be handled
specific areas I would appreciate feedback on:
Ctrl+A S
is active,Ctrl+A
would not activate)