Harden keybinding parsing, modes/conflicts, and chord coverage#68
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 01764395cf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const keyResult = routeKeyEvent(routeInputState, ev, keyCtx); | ||
| applyRoutedKeybindingState(routeInputState, keyResult.nextState); | ||
| if (keyResult.consumed) { |
There was a problem hiding this comment.
Propagate keybinding handler failures before consuming input
This routing path applies keyResult.nextState and consumes the event without checking keyResult.handlerError, so handler exceptions are silently dropped in app runtime. That became user-visible in this commit because setMode() now throws for unknown modes: a typo like app.setMode("inert") inside a keybinding handler is swallowed here, the key is still treated as consumed, and no fatal/error is surfaced, making mode bugs hard to diagnose.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 220d04c.
createApp now checks keyResult.handlerError after keybinding routing (for both raw key events and synthetic key events from text input), enqueues ZRUI_USER_CODE_THROW, and stops processing the batch.
Added regression test: unknown mode switch inside keybinding handler surfaces fatal error in packages/core/src/keybindings/__tests__/keybinding.mode-switch.test.ts.
Summary
This PR hardens the existing keybinding system without adding new syntax/features. It audits and tightens parsing, chord/mode behavior, and conflict resolution, then adds deterministic regression coverage and updates docs.
Fixes
ctrl+ctrl+a).setMode()throw for unknown/unregistered modes (clear error).Tests Added
New deterministic suites under
packages/core/src/keybindings/__tests__/:keybinding.parse.test.tskeybinding.chord.test.tskeybinding.modes.test.tskeybinding.conflicts.test.tskeybinding.mode-switch.test.tsThe new suites cover parser edge cases, chord matching/timeout semantics, mode inheritance/switching, routing/conflict precedence, and integration behavior around handler-triggered mode switches.
Documentation
docs/guide/input-and-focus.mdwith a consolidated Keybinding System section documenting syntax, chord behavior, mode rules, conflict resolution, and routing order.Validation
npm run lintnpm run buildnpm run typechecknode scripts/run-tests.mjsAll commands pass on this branch.