Problem
The shared key-chord parser removes empty segments after splitting a chord on +. As a result, malformed bindings are silently interpreted as different valid shortcuts:
s+ → s
+s → s
ctrl++s → ctrl+s
ctrl+s+ → ctrl+s
For example, parseKeyChord("s+") currently returns the same parsed chord as parseKeyChord("s"), and the malformed chord matches a real s key event.
The behavior comes from filtering empty tokens before the parser validates the modifier and base-key structure in src/extension-api/keys.ts.
Why this matters
This grammar is shared by user [keybindings], extension registerCommand bindings, Hunk's own command table, and the public matchesKey helper. A typo can therefore claim and execute a real shortcut instead of being rejected and surfaced as an unusable chord.
This is also inconsistent with the parser's existing behavior for other malformed chords such as ctlr+s, f13, and ctrl+, which are rejected rather than normalized.
Expected behavior
Key chords with a missing component around + should be rejected. The intentional literal plus-key binding must remain valid:
+ → literal plus key
+ → literal plus key, with surrounding whitespace tolerated
Whitespace around valid components, such as ctrl + s, should also continue to work.
Acceptance criteria
s+, +s, ctrl++s, and ctrl+s+ are rejected by parseKeyChord.
- Literal
+ and whitespace-padded + continue to parse as the plus key.
- Valid spaced chords such as
ctrl + s continue to parse.
- A malformed user binding is reported and omitted without discarding valid sibling chords or claiming the normalized shortcut.
- Extension command registration inherits the stricter shared parser behavior.
- Add focused parser and keymap regression tests.
- Add a patch Changeset for
hunkdiff.
Implementation plan
implementation-plan.md
Problem
The shared key-chord parser removes empty segments after splitting a chord on
+. As a result, malformed bindings are silently interpreted as different valid shortcuts:For example,
parseKeyChord("s+")currently returns the same parsed chord asparseKeyChord("s"), and the malformed chord matches a realskey event.The behavior comes from filtering empty tokens before the parser validates the modifier and base-key structure in
src/extension-api/keys.ts.Why this matters
This grammar is shared by user
[keybindings], extensionregisterCommandbindings, Hunk's own command table, and the publicmatchesKeyhelper. A typo can therefore claim and execute a real shortcut instead of being rejected and surfaced as an unusable chord.This is also inconsistent with the parser's existing behavior for other malformed chords such as
ctlr+s,f13, andctrl+, which are rejected rather than normalized.Expected behavior
Key chords with a missing component around
+should be rejected. The intentional literal plus-key binding must remain valid:Whitespace around valid components, such as
ctrl + s, should also continue to work.Acceptance criteria
s+,+s,ctrl++s, andctrl+s+are rejected byparseKeyChord.+and whitespace-padded+continue to parse as the plus key.ctrl + scontinue to parse.hunkdiff.Implementation plan
implementation-plan.md