mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-18 18:03:44 +00:00
Add Kitty keyboard protocol support for Shift+Enter and other modifier keys
Enable the Kitty keyboard protocol on terminal start to receive enhanced key sequences that include modifier information. This fixes Shift+Enter not working in Ghostty, Kitty, WezTerm, and other modern terminals. Changes: - Enable Kitty protocol on start (\x1b[>1u), disable on stop (\x1b[<u) - Add centralized key definitions in packages/tui/src/keys.ts - Support both legacy and Kitty sequences for all modifier+key combos: - Shift+Enter, Alt+Enter for newlines - Shift+Tab for thinking level cycling - Ctrl+C, Ctrl+A, Ctrl+E, Ctrl+K, Ctrl+U, Ctrl+W, Ctrl+O, Ctrl+P, Ctrl+T - Alt+Backspace for word deletion - Export Keys constants and helper functions from @mariozechner/pi-tui
This commit is contained in:
parent
2f86c8bc3c
commit
4a4531f887
10 changed files with 182 additions and 47 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import type { AutocompleteProvider, CombinedAutocompleteProvider } from "../autocomplete.js";
|
||||
import { Keys } from "../keys.js";
|
||||
import type { Component } from "../tui.js";
|
||||
import { visibleWidth } from "../utils.js";
|
||||
import { SelectList, type SelectListTheme } from "./select-list.js";
|
||||
|
|
@ -259,7 +260,8 @@ export class Editor implements Component {
|
|||
// Handle special key combinations first
|
||||
|
||||
// Ctrl+C - Exit (let parent handle this)
|
||||
if (data.charCodeAt(0) === 3) {
|
||||
// Handle both raw byte (\x03) and Kitty keyboard protocol
|
||||
if (data.charCodeAt(0) === 3 || data === Keys.CTRL_C) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -358,35 +360,37 @@ export class Editor implements Component {
|
|||
}
|
||||
|
||||
// Continue with rest of input handling
|
||||
// Ctrl+K - Delete to end of line
|
||||
if (data.charCodeAt(0) === 11) {
|
||||
// Ctrl+K - Delete to end of line (raw byte or Kitty protocol)
|
||||
if (data.charCodeAt(0) === 11 || data === Keys.CTRL_K) {
|
||||
this.deleteToEndOfLine();
|
||||
}
|
||||
// Ctrl+U - Delete to start of line
|
||||
else if (data.charCodeAt(0) === 21) {
|
||||
// Ctrl+U - Delete to start of line (raw byte or Kitty protocol)
|
||||
else if (data.charCodeAt(0) === 21 || data === Keys.CTRL_U) {
|
||||
this.deleteToStartOfLine();
|
||||
}
|
||||
// Ctrl+W - Delete word backwards
|
||||
else if (data.charCodeAt(0) === 23) {
|
||||
// Ctrl+W - Delete word backwards (raw byte or Kitty protocol)
|
||||
else if (data.charCodeAt(0) === 23 || data === Keys.CTRL_W) {
|
||||
this.deleteWordBackwards();
|
||||
}
|
||||
// Option/Alt+Backspace (e.g. Ghostty sends ESC + DEL)
|
||||
else if (data === "\x1b\x7f") {
|
||||
// Option/Alt+Backspace (e.g. Ghostty sends ESC + DEL, or Kitty protocol)
|
||||
else if (data === "\x1b\x7f" || data === Keys.ALT_BACKSPACE) {
|
||||
this.deleteWordBackwards();
|
||||
}
|
||||
// Ctrl+A - Move to start of line
|
||||
else if (data.charCodeAt(0) === 1) {
|
||||
// Ctrl+A - Move to start of line (raw byte or Kitty protocol)
|
||||
else if (data.charCodeAt(0) === 1 || data === Keys.CTRL_A) {
|
||||
this.moveToLineStart();
|
||||
}
|
||||
// Ctrl+E - Move to end of line
|
||||
else if (data.charCodeAt(0) === 5) {
|
||||
// Ctrl+E - Move to end of line (raw byte or Kitty protocol)
|
||||
else if (data.charCodeAt(0) === 5 || data === Keys.CTRL_E) {
|
||||
this.moveToLineEnd();
|
||||
}
|
||||
// New line shortcuts (but not plain LF/CR which should be submit)
|
||||
else if (
|
||||
(data.charCodeAt(0) === 10 && data.length > 1) || // Ctrl+Enter with modifiers
|
||||
data === "\x1b\r" || // Option+Enter in some terminals
|
||||
data === "\x1b[13;2~" || // Shift+Enter in some terminals
|
||||
data === "\x1b\r" || // Option+Enter in some terminals (legacy)
|
||||
data === "\x1b[13;2~" || // Shift+Enter in some terminals (legacy format)
|
||||
data === Keys.SHIFT_ENTER || // Shift+Enter in Kitty keyboard protocol
|
||||
data === Keys.ALT_ENTER || // Alt+Enter in Kitty keyboard protocol
|
||||
(data.length > 1 && data.includes("\x1b") && data.includes("\r")) ||
|
||||
(data === "\n" && data.length === 1) || // Shift+Enter from iTerm2 mapping
|
||||
data === "\\\r" // Shift+Enter in VS Code terminal
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue