Skip to content

feat: add configurable keybinds for slash commands#217

Open
al4xdev wants to merge 9 commits into
lessweb:mainfrom
al4xdev:feat/keybinds
Open

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

Conversation

@al4xdev

@al4xdev al4xdev commented Jul 1, 2026

Copy link
Copy Markdown

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) with --global flag support.

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.

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
  • KeybindsView shows [local]/[global] badges per shortcut
  • 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 --global add ctrl+m mcp
/keybind remove ctrl+e
/keybind --global remove ctrl+e
/keybind list

--global flag forces write to user-level settings; without it, writes to project settings if they exist.

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

Files Changed

File Description
packages/core/src/settings.ts +29 -- KeybindMap type, normalize/merge, resolved settings
packages/core/src/index.ts +1 -- export KeybindMap
packages/core/src/tests/settings-and-notify.test.ts +54 -- keybind merge/normalize tests
packages/cli/src/ui/core/keybinds.ts New -- parser module (42 lines)
packages/cli/src/ui/core/slash-commands.ts +8 -- "keybind" kind + built-in command
packages/cli/src/ui/views/PromptInput.tsx +157 -- keybind matchers memo, input integration, /keybind handler with --global
packages/cli/src/ui/views/App.tsx +16 -- route /keybind, pass props to PromptInput
packages/cli/src/ui/views/KeybindsView.tsx New -- read-only view with local/global badges (72 lines)
packages/cli/src/ui/index.ts +1 -- barrel export
packages/cli/src/tests/keybinds.test.ts New -- unit tests (121 lines)
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, format clean
npm test          -- all tests pass
npm run build     -- successful

al4xdev added 9 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
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