Intercept keyboard events via xterm's custom key handler and emit readline/zle escape sequences so bindings work regardless of terminfo: - Alt/Option + Left/Right: word-wise cursor move - Alt/Option + Backspace: delete previous word - macOS Cmd + Left/Right: jump to line start/end - macOS Cmd + Backspace: clear to line start Uses `e.code` to stay correct on dead-key layouts, skips IME composition, and excludes AltGr (ctrl+alt) on Windows/Linux.
52 lines
1.1 KiB
TypeScript
52 lines
1.1 KiB
TypeScript
"use client"
|
|
|
|
import { useEffect, useState } from "react"
|
|
|
|
export type PlatformType = "macos" | "windows" | "linux" | "unknown"
|
|
|
|
export function detectPlatform(): PlatformType {
|
|
if (typeof navigator === "undefined") return "unknown"
|
|
|
|
const platform = navigator.platform.toLowerCase()
|
|
const userAgent = navigator.userAgent.toLowerCase()
|
|
|
|
if (platform.includes("mac") || userAgent.includes("mac os")) {
|
|
return "macos"
|
|
}
|
|
|
|
if (platform.includes("win") || userAgent.includes("windows")) {
|
|
return "windows"
|
|
}
|
|
|
|
if (
|
|
platform.includes("linux") ||
|
|
userAgent.includes("linux") ||
|
|
userAgent.includes("x11")
|
|
) {
|
|
return "linux"
|
|
}
|
|
|
|
return "unknown"
|
|
}
|
|
|
|
export function usePlatform() {
|
|
const [platform, setPlatform] = useState<PlatformType>("unknown")
|
|
|
|
useEffect(() => {
|
|
const frame = window.requestAnimationFrame(() => {
|
|
setPlatform(detectPlatform())
|
|
})
|
|
|
|
return () => {
|
|
window.cancelAnimationFrame(frame)
|
|
}
|
|
}, [])
|
|
|
|
return {
|
|
platform,
|
|
isMac: platform === "macos",
|
|
isWindows: platform === "windows",
|
|
isLinux: platform === "linux",
|
|
}
|
|
}
|