mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-17 09:02:08 +00:00
feat(tui): query Kitty keyboard protocol support before enabling
- Query terminal with CSI ? u before enabling Kitty protocol - Only enable protocol if terminal responds (100ms timeout) - Mode-aware key parsing: when Kitty active, interpret legacy sequences as custom terminal mappings (e.g. \x1b\r = shift+enter) - Add Terminal Setup section to README with Ghostty/wezterm config fixes #439
This commit is contained in:
parent
0b9e3ada0c
commit
c5d54a8413
5 changed files with 186 additions and 18 deletions
|
|
@ -13,8 +13,31 @@
|
|||
* - matchesKey(data, keyId) - Check if input matches a key identifier
|
||||
* - parseKey(data) - Parse input and return the key identifier
|
||||
* - Key - Helper object for creating typed key identifiers
|
||||
* - setKittyProtocolActive(active) - Set global Kitty protocol state
|
||||
* - isKittyProtocolActive() - Query global Kitty protocol state
|
||||
*/
|
||||
|
||||
// =============================================================================
|
||||
// Global Kitty Protocol State
|
||||
// =============================================================================
|
||||
|
||||
let _kittyProtocolActive = false;
|
||||
|
||||
/**
|
||||
* Set the global Kitty keyboard protocol state.
|
||||
* Called by ProcessTerminal after detecting protocol support.
|
||||
*/
|
||||
export function setKittyProtocolActive(active: boolean): void {
|
||||
_kittyProtocolActive = active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query whether Kitty keyboard protocol is currently active.
|
||||
*/
|
||||
export function isKittyProtocolActive(): boolean {
|
||||
return _kittyProtocolActive;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Type-Safe Key Identifiers
|
||||
// =============================================================================
|
||||
|
|
@ -402,17 +425,35 @@ export function matchesKey(data: string, keyId: KeyId): boolean {
|
|||
case "enter":
|
||||
case "return":
|
||||
if (shift && !ctrl && !alt) {
|
||||
return (
|
||||
// CSI u sequences (standard Kitty protocol)
|
||||
if (
|
||||
matchesKittySequence(data, CODEPOINTS.enter, MODIFIERS.shift) ||
|
||||
matchesKittySequence(data, CODEPOINTS.kpEnter, MODIFIERS.shift)
|
||||
);
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
// When Kitty protocol is active, legacy sequences are custom terminal mappings
|
||||
// \x1b\r = Kitty's "map shift+enter send_text all \e\r"
|
||||
// \n = Ghostty's "keybind = shift+enter=text:\n"
|
||||
if (_kittyProtocolActive) {
|
||||
return data === "\x1b\r" || data === "\n";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (alt && !ctrl && !shift) {
|
||||
return (
|
||||
data === "\x1b\r" ||
|
||||
// CSI u sequences (standard Kitty protocol)
|
||||
if (
|
||||
matchesKittySequence(data, CODEPOINTS.enter, MODIFIERS.alt) ||
|
||||
matchesKittySequence(data, CODEPOINTS.kpEnter, MODIFIERS.alt)
|
||||
);
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
// \x1b\r is alt+enter only in legacy mode (no Kitty protocol)
|
||||
// When Kitty protocol is active, alt+enter comes as CSI u sequence
|
||||
if (!_kittyProtocolActive) {
|
||||
return data === "\x1b\r";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (modifier === 0) {
|
||||
return (
|
||||
|
|
@ -577,14 +618,22 @@ export function parseKey(data: string): string | undefined {
|
|||
}
|
||||
}
|
||||
|
||||
// Legacy sequences
|
||||
// Mode-aware legacy sequences
|
||||
// When Kitty protocol is active, ambiguous sequences are interpreted as custom terminal mappings:
|
||||
// - \x1b\r = shift+enter (Kitty mapping), not alt+enter
|
||||
// - \n = shift+enter (Ghostty mapping)
|
||||
if (_kittyProtocolActive) {
|
||||
if (data === "\x1b\r" || data === "\n") return "shift+enter";
|
||||
}
|
||||
|
||||
// Legacy sequences (used when Kitty protocol is not active, or for unambiguous sequences)
|
||||
if (data === "\x1b") return "escape";
|
||||
if (data === "\t") return "tab";
|
||||
if (data === "\r" || data === "\x1bOM") return "enter";
|
||||
if (data === " ") return "space";
|
||||
if (data === "\x7f" || data === "\x08") return "backspace";
|
||||
if (data === "\x1b[Z") return "shift+tab";
|
||||
if (data === "\x1b\r") return "alt+enter";
|
||||
if (!_kittyProtocolActive && data === "\x1b\r") return "alt+enter";
|
||||
if (data === "\x1b\x7f") return "alt+backspace";
|
||||
if (data === "\x1b[A") return "up";
|
||||
if (data === "\x1b[B") return "down";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue