diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index fb1e9c8d..b27f6bb1 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Added + +- Configurable keybindings via `~/.pi/agent/keybindings.json`. All keyboard shortcuts (editor navigation, deletion, app actions like model cycling, etc.) can now be customized. Supports multiple bindings per action. ([#405](https://github.com/badlogic/pi-mono/pull/405) by [@hjanuschka](https://github.com/hjanuschka)) + ## [0.32.1] - 2026-01-03 ### Added diff --git a/packages/coding-agent/README.md b/packages/coding-agent/README.md index 277131b6..994660ca 100644 --- a/packages/coding-agent/README.md +++ b/packages/coding-agent/README.md @@ -15,6 +15,7 @@ Works on Linux, macOS, and Windows (requires bash; see [Windows Setup](#windows- - [Slash Commands](#slash-commands) - [Editor Features](#editor-features) - [Keyboard Shortcuts](#keyboard-shortcuts) + - [Custom Keybindings](#custom-keybindings) - [Bash Mode](#bash-mode) - [Image Support](#image-support) - [Sessions](#sessions) @@ -257,6 +258,61 @@ Both modes are configurable via `/settings`: "one-at-a-time" delivers messages o | Ctrl+T | Toggle thinking block visibility | | Ctrl+G | Edit message in external editor (`$VISUAL` or `$EDITOR`) | +### Custom Keybindings + +All keyboard shortcuts can be customized via `~/.pi/agent/keybindings.json`. Each action can be bound to one or more keys. + +**Key format:** `modifier+key` where modifiers are `ctrl`, `shift`, `alt` and keys are `a-z`, `0-9`, `escape`, `tab`, `enter`, `space`, `backspace`, `delete`, `home`, `end`, `up`, `down`, `left`, `right`. + +**Configurable actions:** + +| Action | Default | Description | +|--------|---------|-------------| +| `cursorUp` | `up` | Move cursor up | +| `cursorDown` | `down` | Move cursor down | +| `cursorLeft` | `left` | Move cursor left | +| `cursorRight` | `right` | Move cursor right | +| `cursorWordLeft` | `alt+left`, `ctrl+left` | Move cursor word left | +| `cursorWordRight` | `alt+right`, `ctrl+right` | Move cursor word right | +| `cursorLineStart` | `home`, `ctrl+a` | Move to line start | +| `cursorLineEnd` | `end`, `ctrl+e` | Move to line end | +| `deleteCharBackward` | `backspace` | Delete char backward | +| `deleteCharForward` | `delete` | Delete char forward | +| `deleteWordBackward` | `ctrl+w`, `alt+backspace` | Delete word backward | +| `deleteToLineStart` | `ctrl+u` | Delete to line start | +| `deleteToLineEnd` | `ctrl+k` | Delete to line end | +| `newLine` | `shift+enter`, `alt+enter` | Insert new line | +| `submit` | `enter` | Submit input | +| `tab` | `tab` | Tab/autocomplete | +| `interrupt` | `escape` | Interrupt operation | +| `clear` | `ctrl+c` | Clear editor | +| `exit` | `ctrl+d` | Exit (when empty) | +| `suspend` | `ctrl+z` | Suspend process | +| `cycleThinkingLevel` | `shift+tab` | Cycle thinking level | +| `cycleModelForward` | `ctrl+p` | Next model | +| `cycleModelBackward` | `shift+ctrl+p` | Previous model | +| `selectModel` | `ctrl+l` | Open model selector | +| `expandTools` | `ctrl+o` | Expand tool output | +| `toggleThinking` | `ctrl+t` | Toggle thinking | +| `externalEditor` | `ctrl+g` | Open external editor | +| `followUp` | `alt+enter` | Queue follow-up message | + +**Example (Emacs-style):** + +```json +{ + "cursorUp": ["up", "ctrl+p"], + "cursorDown": ["down", "ctrl+n"], + "cursorLeft": ["left", "ctrl+b"], + "cursorRight": ["right", "ctrl+f"], + "cursorWordLeft": ["alt+left", "alt+b"], + "cursorWordRight": ["alt+right", "alt+f"], + "deleteCharForward": ["delete", "ctrl+d"], + "deleteCharBackward": ["backspace", "ctrl+h"], + "newLine": ["shift+enter", "ctrl+j"] +} +``` + ### Bash Mode Prefix commands with `!` to execute them and add output to context: diff --git a/packages/tui/CHANGELOG.md b/packages/tui/CHANGELOG.md index 7a5b3028..459f7c2d 100644 --- a/packages/tui/CHANGELOG.md +++ b/packages/tui/CHANGELOG.md @@ -2,6 +2,18 @@ ## [Unreleased] +### Breaking Changes + +- **Key detection functions removed**: All `isXxx()` key detection functions (`isEnter()`, `isEscape()`, `isCtrlC()`, etc.) have been removed. Use `matchesKey(data, keyId)` instead (e.g., `matchesKey(data, "enter")`, `matchesKey(data, "ctrl+c")`). This affects hooks and custom tools that use `ctx.ui.custom()` with keyboard input handling. ([#405](https://github.com/badlogic/pi-mono/pull/405)) + +### Added + +- `EditorKeybindingsManager` for configurable editor keybindings. Components now use `matchesKey()` and keybindings manager instead of individual `isXxx()` functions. ([#405](https://github.com/badlogic/pi-mono/pull/405) by [@hjanuschka](https://github.com/hjanuschka)) + +### Changed + +- Key detection refactored: consolidated `is*()` functions into generic `matchesKey(data, keyId)` function that accepts key identifiers like `"ctrl+c"`, `"shift+enter"`, `"alt+left"`, etc. + ## [0.32.1] - 2026-01-03 ## [0.32.0] - 2026-01-03