hermes / ui-tui /src /lib /platform.ts
haochengsama's picture
Add files using upload-large-folder tool
04d8658 verified
Raw
History Blame Contribute Delete
2.34 kB
/** Platform-aware keybinding helpers.
*
* On macOS the "action" modifier is Cmd. Modern terminals that support kitty
* keyboard protocol report Cmd as `key.super`; legacy terminals often surface it
* as `key.meta`. Some macOS terminals also translate Cmd+Left/Right/Backspace
* into readline-style Ctrl+A/Ctrl+E/Ctrl+U before the app sees them.
* On other platforms the action modifier is Ctrl.
* Ctrl+C is ALWAYS the interrupt key regardless of platform — it must never be
* remapped to copy.
*/
export const isMac = process.platform === 'darwin'
/** True when the platform action-modifier is pressed (Cmd on macOS, Ctrl elsewhere). */
export const isActionMod = (key: { ctrl: boolean; meta: boolean; super?: boolean }): boolean =>
isMac ? key.meta || key.super === true : key.ctrl
/**
* Accept raw Ctrl+<letter> as an action shortcut on macOS, where `isActionMod`
* otherwise means Cmd. Two motivations:
* - Some macOS terminals rewrite Cmd navigation/deletion into readline control
* keys (Cmd+Left → Ctrl+A, Cmd+Right → Ctrl+E, Cmd+Backspace → Ctrl+U).
* - Ctrl+K (kill-to-end) and Ctrl+W (delete-word-back) are standard readline
* bindings that users expect to work regardless of platform, even though
* no terminal rewrites Cmd into them.
*/
export const isMacActionFallback = (
key: { ctrl: boolean; meta: boolean; super?: boolean },
ch: string,
target: 'a' | 'e' | 'u' | 'k' | 'w'
): boolean => isMac && key.ctrl && !key.meta && key.super !== true && ch.toLowerCase() === target
/** Match action-modifier + a single character (case-insensitive). */
export const isAction = (key: { ctrl: boolean; meta: boolean; super?: boolean }, ch: string, target: string): boolean =>
isActionMod(key) && ch.toLowerCase() === target
/**
* Voice recording toggle key (Ctrl+B).
*
* Documented as "Ctrl+B" everywhere: tips.py, config.yaml's voice.record_key
* default, and the Python CLI prompt_toolkit handler. We accept raw Ctrl+B on
* every platform so the TUI matches those docs. On macOS we additionally
* accept Cmd+B (the platform action modifier) so existing macOS muscle memory
* keeps working.
*/
export const isVoiceToggleKey = (
key: { ctrl: boolean; meta: boolean; super?: boolean },
ch: string
): boolean => (key.ctrl || isActionMod(key)) && ch.toLowerCase() === 'b'