Skip to content

feat: add configurable keybinds for slash commands#214

Closed
al4xdev wants to merge 7 commits into
lessweb:mainfrom
al4xdev:feat/keybinds
Closed

feat: add configurable keybinds for slash commands#214
al4xdev wants to merge 7 commits into
lessweb:mainfrom
al4xdev:feat/keybinds

Conversation

@al4xdev

@al4xdev al4xdev commented Jul 1, 2026

Copy link
Copy Markdown

feat: add configurable keybinds for slash commands

Summary

Add a keybinds settings field that maps keyboard shortcuts directly to slash command actions, so users can trigger commands like /exit, /new, /skills without typing /. Also adds a /keybind slash command for runtime management (add/remove/list).

Motivation

Currently, all slash commands require typing /command + Enter. For frequent operations (exiting, starting a new session, opening the skills list), a keyboard shortcut is faster and more ergonomic. This feature lets users configure their own shortcuts and manage them at runtime without editing JSON by hand.

Design

Configuration

New top-level field settings.keybinds:

{
  "keybinds": {
    "ctrl+e": "exit",
    "ctrl+n": "new",
    "ctrl+s": "skills",
    "ctrl+m": "model"
  }
}
  • Shortcut format: ctrl+key, ctrl+shift+key, or meta+key
  • Action value: any slash command name or skill name
  • Project settings override user settings per shortcut key
  • Custom keybinds only fire when no dropdown/menu is open (avoids conflicts)

Runtime management

The /keybind slash command supports three subcommands:

/keybind add ctrl+e exit
/keybind remove ctrl+e
/keybind list

Changes are persisted to settings.json immediately and take effect without restarting.

Architecture

The feature follows the same pattern as statusline and enabledSkills:

  • Core layer (packages/core/src/settings.ts): KeybindMap type, normalizeKeybinds(), mergeKeybinds(), integration into resolveSettingsSources()
  • Parser (packages/cli/src/ui/core/keybinds.ts): matchKeybind() converts shortcut strings (e.g. "ctrl+shift+g") into exact-modifier predicates against InputKey; buildKeybindMatchers() pre-compiles a map for fast per-keystroke lookup
  • Input integration (PromptInput.tsx): keybinds are checked before hardcoded shortcuts, resolving the action name to a SlashCommandItem and dispatching via handleSlashSelection()
  • Slash command (slash-commands.ts): new "keybind" kind with subcommand parsing in handleKeybindCommand(), reading/writing settings with project-over-user fallback

Files Changed

File Description
packages/core/src/settings.ts +26 — KeybindMap type, normalize/merge, resolved settings
packages/core/src/index.ts +1 — export KeybindMap
packages/core/src/tests/settings-and-notify.test.ts +47 — 4 keybind merge/normalize tests
packages/cli/src/ui/core/keybinds.ts New — parser module (42 lines)
packages/cli/src/ui/core/slash-commands.ts +7 — "keybind" kind + built-in command
packages/cli/src/ui/views/PromptInput.tsx +130 — keybind matchers memo, input integration, /keybind handler
packages/cli/src/ui/views/App.tsx +7 — pass keybinds prop + onKeybindsChanged callback
packages/cli/src/ui/index.ts +5 — barrel exports
packages/cli/src/tests/keybinds.test.ts New — 19 unit tests
packages/cli/src/tests/slash-commands.test.ts +1 — add "keybind" to built-in names
docs/configuration.md +21 — Chinese docs
docs/configuration_en.md +21 — English docs

Verification

npm run check     — typecheck 0 errors, lint 0 errors (1 pre-existing warning), format clean
npm test          — 269 tests, 0 fail
npm run build     — successful

al4xdev added 6 commits June 30, 2026 21:10
- Add KeybindMap type (Record<string, string>) for configurable keybinds
- Add keybinds field to DeepcodingSettings and ResolvedDeepcodingSettings
- Add normalizeKeybinds() to validate keybind entries
- Add mergeKeybinds() with project-over-user precedence
- Export KeybindMap from core public API
- Add matchKeybind() to match shortcut strings (e.g. "ctrl+shift+g")
  against raw input and InputKey with exact modifier matching
- Add buildKeybindMatchers() to pre-compile a KeybindMap into an array
  of matchers for fast per-keystroke lookup
…dling

- Add "keybind" to SlashCommandKind and BUILTIN_SLASH_COMMANDS with
  args hint (add <shortcut> <action>, remove <shortcut>, list)
- Implement /keybind handler with add/remove/list subcommands that
  read/write settings.json (project-level if present, user-level fallback)
- Integrate keybind checking in useTerminalInput callback: custom
  keybinds are matched before hardcoded shortcuts, only when no
  dropdown/menu is open to avoid conflicts
- Resolve keybind action to SlashCommandItem and dispatch via
  handleSlashSelection (supports all built-in commands and skills)
- Pass resolved settings keybinds from App to PromptInput
- Export matchKeybind, buildKeybindMatchers, and KeybindMatcher
  from the UI barrel
- Add 19 unit tests for matchKeybind covering ctrl, shift, meta modifiers,
  exact matching, case insensitivity, digit/non-alpha keys, and edge cases
- Add 4 integration tests for keybinds settings resolution: default empty,
  user-only, project-over-user merge, and invalid entry filtering
- Update slash-commands test to include "keybind" in built-in names
Document the keybinds settings field following the same format
as enabledSkills and mcpServers:

- Shortcut format: ctrl+key, ctrl+shift+key, meta+key
- Project-over-user merge precedence
- Runtime management via /keybind add|remove|list
Add onKeybindsChanged callback so that keybinds added or removed
via the /keybind slash command take effect immediately without
requiring a session restart. The callback re-resolves settings
from disk, matching the pattern used by handleModelConfigChange.
- Add /keybind slash command with add, remove, list subcommands
- Auto-complete partial matches (/key -> /keybind)
- Show usage hint on bare /keybind instead of opening view
- /keybind list opens KeybindsView showing all configured keybinds
- --global flag forces operations on user-level settings
- Cross-level duplicate detection (merged keybind lookup)
- KeybindsView shows [global]/[local] origin indicator
- Custom keybind matchers trigger slash actions on shortcut press
- Status message timeout increased to 8s for readability
@al4xdev al4xdev closed this Jul 1, 2026
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