textInput treated the platform action-mod (Cmd on macOS, Ctrl on Linux) as the sole word-boundary modifier. On Linux that meant: - Ctrl+A selected all instead of jumping to line start (contra standard readline and the hotkey doc in README.md which says `Ctrl+A` = Start of line). - Alt+B / Alt+F / Alt+Backspace / Alt+Delete were dropped, because `key.meta` was never consulted — the README already documented `Meta+B` / `Meta+F` as word nav. Gate select-all to macOS Cmd+A (`isMac && mod && inp === 'a'`), route Linux Ctrl+A through `actionHome`, and broaden every word-boundary predicate (b/f/Backspace/Delete and the modified arrow keys) from `mod` to `wordMod = mod || k.meta` so Alt chords work on Linux and Mac while existing Ctrl/Cmd chords keep working.
79 lines
2.1 KiB
TypeScript
79 lines
2.1 KiB
TypeScript
import {
|
|
detectVSCodeLikeTerminal,
|
|
type FileOps,
|
|
isRemoteShellSession,
|
|
shouldPromptForTerminalSetup
|
|
} from './terminalSetup.js'
|
|
|
|
export type MacTerminalHint = {
|
|
key: string
|
|
message: string
|
|
tone: 'info' | 'warn'
|
|
}
|
|
|
|
export type MacTerminalContext = {
|
|
isAppleTerminal: boolean
|
|
isRemote: boolean
|
|
isTmux: boolean
|
|
vscodeLike: null | 'cursor' | 'vscode' | 'windsurf'
|
|
}
|
|
|
|
export function detectMacTerminalContext(env: NodeJS.ProcessEnv = process.env): MacTerminalContext {
|
|
const termProgram = env['TERM_PROGRAM'] ?? ''
|
|
|
|
return {
|
|
isAppleTerminal: termProgram === 'Apple_Terminal' || !!env['TERM_SESSION_ID'],
|
|
isRemote: isRemoteShellSession(env),
|
|
isTmux: !!env['TMUX'],
|
|
vscodeLike: detectVSCodeLikeTerminal(env)
|
|
}
|
|
}
|
|
|
|
export async function terminalParityHints(
|
|
env: NodeJS.ProcessEnv = process.env,
|
|
options?: { fileOps?: Partial<FileOps>; homeDir?: string }
|
|
): Promise<MacTerminalHint[]> {
|
|
const ctx = detectMacTerminalContext(env)
|
|
const hints: MacTerminalHint[] = []
|
|
|
|
if (
|
|
ctx.vscodeLike &&
|
|
(await shouldPromptForTerminalSetup({ env, fileOps: options?.fileOps, homeDir: options?.homeDir }))
|
|
) {
|
|
hints.push({
|
|
key: 'ide-setup',
|
|
tone: 'info',
|
|
message: `Detected ${ctx.vscodeLike} terminal · run /terminal-setup for best Cmd+Enter / undo parity`
|
|
})
|
|
}
|
|
|
|
if (ctx.isAppleTerminal) {
|
|
hints.push({
|
|
key: 'apple-terminal',
|
|
tone: 'warn',
|
|
message:
|
|
'Apple Terminal detected · use /paste for image-only clipboard fallback, and try Ctrl+A / Ctrl+E / Ctrl+U if Cmd+←/→/⌫ gets rewritten'
|
|
})
|
|
}
|
|
|
|
if (ctx.isTmux) {
|
|
hints.push({
|
|
key: 'tmux',
|
|
tone: 'warn',
|
|
message:
|
|
'tmux detected · clipboard copy/paste uses passthrough when available; allow-passthrough improves OSC52 reliability'
|
|
})
|
|
}
|
|
|
|
if (ctx.isRemote) {
|
|
hints.push({
|
|
key: 'remote',
|
|
tone: 'warn',
|
|
message:
|
|
'SSH session detected · text clipboard can bridge via OSC52, but image clipboard and local screenshot paths still depend on the machine running Hermes'
|
|
})
|
|
}
|
|
|
|
return hints
|
|
}
|