mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-21 16:01:05 +00:00
feat: add type-safe KeyId for matchesKey function
- Add KeyId union type covering all valid key combinations
- Add Key helper object for autocomplete (Key.ctrl('c'), Key.escape, etc.)
- Update matchesKey signature to use KeyId instead of string
- Catches typos like 'esacpe' at compile time
This commit is contained in:
parent
f79256ac3b
commit
38b7f21e01
3 changed files with 123 additions and 9 deletions
|
|
@ -27,11 +27,10 @@ export {
|
||||||
type EditorKeybindingsConfig,
|
type EditorKeybindingsConfig,
|
||||||
EditorKeybindingsManager,
|
EditorKeybindingsManager,
|
||||||
getEditorKeybindings,
|
getEditorKeybindings,
|
||||||
type KeyId,
|
|
||||||
setEditorKeybindings,
|
setEditorKeybindings,
|
||||||
} from "./keybindings.js";
|
} from "./keybindings.js";
|
||||||
// Keyboard input handling
|
// Keyboard input handling
|
||||||
export { matchesKey, parseKey } from "./keys.js";
|
export { Key, type KeyId, matchesKey, parseKey } from "./keys.js";
|
||||||
// Terminal interface and implementations
|
// Terminal interface and implementations
|
||||||
export { ProcessTerminal, type Terminal } from "./terminal.js";
|
export { ProcessTerminal, type Terminal } from "./terminal.js";
|
||||||
// Terminal image support
|
// Terminal image support
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { matchesKey } from "./keys.js";
|
import { type KeyId, matchesKey } from "./keys.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Editor actions that can be bound to keys.
|
* Editor actions that can be bound to keys.
|
||||||
|
|
@ -31,10 +31,8 @@ export type EditorAction =
|
||||||
// Clipboard
|
// Clipboard
|
||||||
| "copy";
|
| "copy";
|
||||||
|
|
||||||
/**
|
// Re-export KeyId from keys.ts
|
||||||
* Key identifier string (e.g., "ctrl+c", "shift+ctrl+p", "escape").
|
export type { KeyId };
|
||||||
*/
|
|
||||||
export type KeyId = string;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Editor keybindings configuration.
|
* Editor keybindings configuration.
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,123 @@
|
||||||
* API:
|
* API:
|
||||||
* - matchesKey(data, keyId) - Check if input matches a key identifier
|
* - matchesKey(data, keyId) - Check if input matches a key identifier
|
||||||
* - parseKey(data) - Parse input and return the key identifier
|
* - parseKey(data) - Parse input and return the key identifier
|
||||||
|
* - Key - Helper object for creating typed key identifiers
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Type-Safe Key Identifiers
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
type Letter =
|
||||||
|
| "a"
|
||||||
|
| "b"
|
||||||
|
| "c"
|
||||||
|
| "d"
|
||||||
|
| "e"
|
||||||
|
| "f"
|
||||||
|
| "g"
|
||||||
|
| "h"
|
||||||
|
| "i"
|
||||||
|
| "j"
|
||||||
|
| "k"
|
||||||
|
| "l"
|
||||||
|
| "m"
|
||||||
|
| "n"
|
||||||
|
| "o"
|
||||||
|
| "p"
|
||||||
|
| "q"
|
||||||
|
| "r"
|
||||||
|
| "s"
|
||||||
|
| "t"
|
||||||
|
| "u"
|
||||||
|
| "v"
|
||||||
|
| "w"
|
||||||
|
| "x"
|
||||||
|
| "y"
|
||||||
|
| "z";
|
||||||
|
|
||||||
|
type SpecialKey =
|
||||||
|
| "escape"
|
||||||
|
| "esc"
|
||||||
|
| "enter"
|
||||||
|
| "return"
|
||||||
|
| "tab"
|
||||||
|
| "space"
|
||||||
|
| "backspace"
|
||||||
|
| "delete"
|
||||||
|
| "home"
|
||||||
|
| "end"
|
||||||
|
| "up"
|
||||||
|
| "down"
|
||||||
|
| "left"
|
||||||
|
| "right";
|
||||||
|
|
||||||
|
type BaseKey = Letter | SpecialKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Union type of all valid key identifiers.
|
||||||
|
* Provides autocomplete and catches typos at compile time.
|
||||||
|
*/
|
||||||
|
export type KeyId =
|
||||||
|
| BaseKey
|
||||||
|
| `ctrl+${BaseKey}`
|
||||||
|
| `shift+${BaseKey}`
|
||||||
|
| `alt+${BaseKey}`
|
||||||
|
| `ctrl+shift+${BaseKey}`
|
||||||
|
| `shift+ctrl+${BaseKey}`
|
||||||
|
| `ctrl+alt+${BaseKey}`
|
||||||
|
| `alt+ctrl+${BaseKey}`
|
||||||
|
| `shift+alt+${BaseKey}`
|
||||||
|
| `alt+shift+${BaseKey}`
|
||||||
|
| `ctrl+shift+alt+${BaseKey}`
|
||||||
|
| `ctrl+alt+shift+${BaseKey}`
|
||||||
|
| `shift+ctrl+alt+${BaseKey}`
|
||||||
|
| `shift+alt+ctrl+${BaseKey}`
|
||||||
|
| `alt+ctrl+shift+${BaseKey}`
|
||||||
|
| `alt+shift+ctrl+${BaseKey}`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper object for creating typed key identifiers with autocomplete.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* - Key.escape, Key.enter, Key.tab, etc. for special keys
|
||||||
|
* - Key.ctrl("c"), Key.alt("x") for single modifier
|
||||||
|
* - Key.ctrlShift("p"), Key.ctrlAlt("x") for combined modifiers
|
||||||
|
*/
|
||||||
|
export const Key = {
|
||||||
|
// Special keys
|
||||||
|
escape: "escape" as const,
|
||||||
|
esc: "esc" as const,
|
||||||
|
enter: "enter" as const,
|
||||||
|
return: "return" as const,
|
||||||
|
tab: "tab" as const,
|
||||||
|
space: "space" as const,
|
||||||
|
backspace: "backspace" as const,
|
||||||
|
delete: "delete" as const,
|
||||||
|
home: "home" as const,
|
||||||
|
end: "end" as const,
|
||||||
|
up: "up" as const,
|
||||||
|
down: "down" as const,
|
||||||
|
left: "left" as const,
|
||||||
|
right: "right" as const,
|
||||||
|
|
||||||
|
// Single modifiers
|
||||||
|
ctrl: <K extends BaseKey>(key: K): `ctrl+${K}` => `ctrl+${key}`,
|
||||||
|
shift: <K extends BaseKey>(key: K): `shift+${K}` => `shift+${key}`,
|
||||||
|
alt: <K extends BaseKey>(key: K): `alt+${K}` => `alt+${key}`,
|
||||||
|
|
||||||
|
// Combined modifiers
|
||||||
|
ctrlShift: <K extends BaseKey>(key: K): `ctrl+shift+${K}` => `ctrl+shift+${key}`,
|
||||||
|
shiftCtrl: <K extends BaseKey>(key: K): `shift+ctrl+${K}` => `shift+ctrl+${key}`,
|
||||||
|
ctrlAlt: <K extends BaseKey>(key: K): `ctrl+alt+${K}` => `ctrl+alt+${key}`,
|
||||||
|
altCtrl: <K extends BaseKey>(key: K): `alt+ctrl+${K}` => `alt+ctrl+${key}`,
|
||||||
|
shiftAlt: <K extends BaseKey>(key: K): `shift+alt+${K}` => `shift+alt+${key}`,
|
||||||
|
altShift: <K extends BaseKey>(key: K): `alt+shift+${K}` => `alt+shift+${key}`,
|
||||||
|
|
||||||
|
// Triple modifiers
|
||||||
|
ctrlShiftAlt: <K extends BaseKey>(key: K): `ctrl+shift+alt+${K}` => `ctrl+shift+alt+${key}`,
|
||||||
|
} as const;
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Constants
|
// Constants
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
@ -142,10 +257,12 @@ function parseKeyId(keyId: string): { key: string; ctrl: boolean; shift: boolean
|
||||||
* - Alt combinations: "alt+enter", "alt+backspace"
|
* - Alt combinations: "alt+enter", "alt+backspace"
|
||||||
* - Combined modifiers: "shift+ctrl+p", "ctrl+alt+x"
|
* - Combined modifiers: "shift+ctrl+p", "ctrl+alt+x"
|
||||||
*
|
*
|
||||||
|
* Use the Key helper for autocomplete: Key.ctrl("c"), Key.escape, Key.ctrlShift("p")
|
||||||
|
*
|
||||||
* @param data - Raw input data from terminal
|
* @param data - Raw input data from terminal
|
||||||
* @param keyId - Key identifier string (e.g., "ctrl+c", "escape")
|
* @param keyId - Key identifier (e.g., "ctrl+c", "escape", Key.ctrl("c"))
|
||||||
*/
|
*/
|
||||||
export function matchesKey(data: string, keyId: string): boolean {
|
export function matchesKey(data: string, keyId: KeyId): boolean {
|
||||||
const parsed = parseKeyId(keyId);
|
const parsed = parseKeyId(keyId);
|
||||||
if (!parsed) return false;
|
if (!parsed) return false;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue