mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-15 23:01:30 +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,4 @@
|
|||
import { Editor } from "@mariozechner/pi-tui";
|
||||
import { Editor, isShiftTab, Keys } from "@mariozechner/pi-tui";
|
||||
|
||||
/**
|
||||
* Custom editor that handles Escape and Ctrl+C keys for coding-agent
|
||||
|
|
@ -12,26 +12,26 @@ export class CustomEditor extends Editor {
|
|||
public onCtrlT?: () => void;
|
||||
|
||||
handleInput(data: string): void {
|
||||
// Intercept Ctrl+T for thinking block visibility toggle
|
||||
if (data === "\x14" && this.onCtrlT) {
|
||||
// Intercept Ctrl+T for thinking block visibility toggle (raw byte or Kitty protocol)
|
||||
if ((data === "\x14" || data === Keys.CTRL_T) && this.onCtrlT) {
|
||||
this.onCtrlT();
|
||||
return;
|
||||
}
|
||||
|
||||
// Intercept Ctrl+O for tool output expansion
|
||||
if (data === "\x0f" && this.onCtrlO) {
|
||||
// Intercept Ctrl+O for tool output expansion (raw byte or Kitty protocol)
|
||||
if ((data === "\x0f" || data === Keys.CTRL_O) && this.onCtrlO) {
|
||||
this.onCtrlO();
|
||||
return;
|
||||
}
|
||||
|
||||
// Intercept Ctrl+P for model cycling
|
||||
if (data === "\x10" && this.onCtrlP) {
|
||||
// Intercept Ctrl+P for model cycling (raw byte or Kitty protocol)
|
||||
if ((data === "\x10" || data === Keys.CTRL_P) && this.onCtrlP) {
|
||||
this.onCtrlP();
|
||||
return;
|
||||
}
|
||||
|
||||
// Intercept Shift+Tab for thinking level cycling
|
||||
if (data === "\x1b[Z" && this.onShiftTab) {
|
||||
// Intercept Shift+Tab for thinking level cycling (legacy or Kitty protocol)
|
||||
if (isShiftTab(data) && this.onShiftTab) {
|
||||
this.onShiftTab();
|
||||
return;
|
||||
}
|
||||
|
|
@ -43,8 +43,8 @@ export class CustomEditor extends Editor {
|
|||
return;
|
||||
}
|
||||
|
||||
// Intercept Ctrl+C
|
||||
if (data === "\x03" && this.onCtrlC) {
|
||||
// Intercept Ctrl+C (raw byte or Kitty keyboard protocol)
|
||||
if ((data === "\x03" || data === Keys.CTRL_C) && this.onCtrlC) {
|
||||
this.onCtrlC();
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { type Component, Container, Input, Spacer, Text, truncateToWidth } from "@mariozechner/pi-tui";
|
||||
import { type Component, Container, Input, Keys, Spacer, Text, truncateToWidth } from "@mariozechner/pi-tui";
|
||||
import type { SessionManager } from "../../../core/session-manager.js";
|
||||
import { fuzzyFilter } from "../../../utils/fuzzy.js";
|
||||
import { theme } from "../theme/theme.js";
|
||||
|
|
@ -144,8 +144,8 @@ class SessionList implements Component {
|
|||
this.onCancel();
|
||||
}
|
||||
}
|
||||
// Ctrl+C - exit process
|
||||
else if (keyData === "\x03") {
|
||||
// Ctrl+C - exit process (raw byte or Kitty keyboard protocol)
|
||||
else if (keyData === "\x03" || keyData === Keys.CTRL_C) {
|
||||
process.exit(0);
|
||||
}
|
||||
// Pass everything else to search input
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { type Component, Container, Spacer, Text, truncateToWidth } from "@mariozechner/pi-tui";
|
||||
import { type Component, Container, Keys, Spacer, Text, truncateToWidth } from "@mariozechner/pi-tui";
|
||||
import { theme } from "../theme/theme.js";
|
||||
import { DynamicBorder } from "./dynamic-border.js";
|
||||
|
||||
|
|
@ -99,8 +99,8 @@ class UserMessageList implements Component {
|
|||
this.onCancel();
|
||||
}
|
||||
}
|
||||
// Ctrl+C - cancel
|
||||
else if (keyData === "\x03") {
|
||||
// Ctrl+C - cancel (raw byte or Kitty keyboard protocol)
|
||||
else if (keyData === "\x03" || keyData === Keys.CTRL_C) {
|
||||
if (this.onCancel) {
|
||||
this.onCancel();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue