Skip to content

feat: configurable keybinding system with agent presets#56

Open
IShaalan wants to merge 15 commits intojohannesjo:mainfrom
IShaalan:feature/configurable-keybindings
Open

feat: configurable keybinding system with agent presets#56
IShaalan wants to merge 15 commits intojohannesjo:mainfrom
IShaalan:feature/configurable-keybindings

Conversation

@IShaalan
Copy link
Copy Markdown

@IShaalan IShaalan commented Apr 4, 2026

Summary

  • Replace all hardcoded shortcuts with a configurable two-layer system (App + Terminal)
  • Ship agent presets (Default, Claude Code) that resolve keybinding conflicts with terminal-based coding agents
  • Transform the Help dialog into an interactive keybinding editor with recording mode, conflict detection, and reset
  • Add Cmd+Backspace terminal mapping for kill-line-backward
  • Persist configuration in a dedicated keybindings.json

Problem

Parallel Code's shortcuts conflict with coding agents running inside its terminals. Option+Left/Right (word movement), Cmd+B (background task), and Cmd+Backspace (kill line) are intercepted or ignored, with no way to discover or fix these conflicts.

Claude Code preset resolves

Conflict Default Claude Code Preset
Option+Left/Right Column navigation Unbound (word movement passes through)
Cmd+B Toggle sidebar Reassigned to Cmd+Shift+B
Cmd+Backspace Nothing Kill line backward (Ctrl+U)

Test plan

  • Default preset: all existing shortcuts work identically
  • Claude Code preset: Option+Left/Right, Cmd+Shift+B, Cmd+Backspace all work
  • Rebinding with conflict detection (Override/Swap/Cancel)
  • Per-preset isolation: customizing one preset doesn't affect another
  • Reset (per-binding and Reset All)
  • Persistence survives app restart
  • Migration banner appears once, dismissible

🤖 Generated with Claude Code

IShaalan and others added 15 commits April 3, 2026 20:06
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add cmdOrCtrl to Modifiers interface and update all platform:both app-layer
bindings to use cmdOrCtrl instead of meta, so shortcuts work on Linux (Ctrl)
as well as macOS (Cmd). Add a test to enforce this constraint going forward.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ection

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…lback

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rsistence

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace ~20 hardcoded registerShortcut() calls in App.tsx with a
registry-driven approach. Add registerFromRegistry() to shortcuts.ts
that reads KeyBinding objects and maps action strings to handlers.
Shortcuts are now registered via a reactive createEffect that reads
resolvedBindings(), enabling automatic re-registration when the user
changes keybinding presets or overrides.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace hardcoded if/else key handler in TerminalView with a
registry-driven loop over terminal-layer bindings from resolvedBindings().
Adds Cmd+Backspace → \x15 (kill-line) as a new behavior from the defaults.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…flict detection

Rewrite HelpDialog from a static shortcut cheat sheet into a full keybinding
editor with preset selector, per-binding recording mode, conflict warnings
(with override/swap/cancel), and per-binding reset functionality.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Unbound bindings (e.g., column navigation in Claude Code preset) now
appear in the keybinding editor as rows with a muted em-dash instead
of disappearing entirely. This ensures consistent layout across
presets and lets users click to rebind unbound shortcuts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…e docs

1. Fix SolidJS reactivity: replace produce() with full object replacement
   in setUserOverride/clearUserOverride so memos recompute correctly
2. Add "dismiss" text link to migration banner alongside the x button
3. Remove accidentally committed PRD, gitignore docs/ directory

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
User overrides are now stored per-preset instead of globally. Changing
a binding on Claude Code preset no longer affects Default, and vice
versa. Reset correctly clears only the active preset's overrides.

Persistence format updated to { preset, overridesByPreset: { ... } }
with backward compatibility for the old flat { userOverrides } format.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previously, pressing Escape while in recording mode stopped event
propagation, so the Dialog's own Escape handler never fired. Now
Escape cancels recording without stopping propagation, allowing the
dialog to close in a single keypress.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. Fix modifiersMatch to treat cmdOrCtrl and meta as equivalent on
   macOS (and cmdOrCtrl/ctrl on Linux) so conflict detection works
   across app and terminal layers

2. Extract terminal binding filter into a function — avoids module-level
   createMemo (SolidJS lint) while keeping the hot path clean

3. Extract shared matchesKeyEvent utility (src/lib/keybindings/match.ts)
   used by both shortcuts.ts and TerminalView.tsx, removing duplicate
   key-matching logic

4. Replace native confirm() with app's styled dialog in Reset All

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant