mirror of
https://github.com/codeaashu/claude-code.git
synced 2026-04-08 22:28:48 +03:00
claude-code
This commit is contained in:
87
web/lib/keyParser.ts
Normal file
87
web/lib/keyParser.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
// Detects Mac at module load time (safe to call on client, returns false on server)
|
||||
export const isMac =
|
||||
typeof navigator !== "undefined" && /Mac|iPhone|iPad/i.test(navigator.platform);
|
||||
|
||||
export interface ParsedKey {
|
||||
mod: boolean;
|
||||
ctrl: boolean;
|
||||
shift: boolean;
|
||||
alt: boolean;
|
||||
key: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a shortcut string like "mod+shift+k" into a structured object.
|
||||
* Supports modifiers: mod, ctrl, shift, alt
|
||||
* `mod` = Cmd on Mac, Ctrl on Win/Linux
|
||||
*/
|
||||
export function parseKey(keyString: string): ParsedKey {
|
||||
const parts = keyString.toLowerCase().split("+");
|
||||
const key = parts[parts.length - 1];
|
||||
return {
|
||||
mod: parts.includes("mod"),
|
||||
ctrl: parts.includes("ctrl"),
|
||||
shift: parts.includes("shift"),
|
||||
alt: parts.includes("alt"),
|
||||
key,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether a KeyboardEvent matches a parsed key definition.
|
||||
*/
|
||||
export function matchesEvent(parsed: ParsedKey, e: KeyboardEvent): boolean {
|
||||
// On Mac, `mod` maps to metaKey; on Win/Linux it maps to ctrlKey
|
||||
const expectedMeta = isMac ? parsed.mod : false;
|
||||
const expectedCtrl = isMac ? parsed.ctrl : parsed.mod || parsed.ctrl;
|
||||
|
||||
if (e.metaKey !== expectedMeta) return false;
|
||||
if (e.ctrlKey !== expectedCtrl) return false;
|
||||
if (e.altKey !== parsed.alt) return false;
|
||||
|
||||
// For alphanumeric keys, enforce the shift modifier check explicitly.
|
||||
// For symbol characters (?, /, comma, etc.) shift is implicit in the key value,
|
||||
// so we skip the shift check and just match on e.key.
|
||||
const keyIsAlphanumeric = /^[a-z0-9]$/.test(parsed.key);
|
||||
if (keyIsAlphanumeric && e.shiftKey !== parsed.shift) return false;
|
||||
|
||||
return e.key.toLowerCase() === parsed.key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a key combo string for display.
|
||||
* Returns an array of display segments, e.g. ["⌘", "K"] or ["Ctrl", "K"].
|
||||
*/
|
||||
export function formatKeyCombo(keyString: string): string[] {
|
||||
const parts = keyString.split("+");
|
||||
return parts.map((part) => {
|
||||
switch (part.toLowerCase()) {
|
||||
case "mod":
|
||||
return isMac ? "⌘" : "Ctrl";
|
||||
case "shift":
|
||||
return isMac ? "⇧" : "Shift";
|
||||
case "alt":
|
||||
return isMac ? "⌥" : "Alt";
|
||||
case "ctrl":
|
||||
return isMac ? "⌃" : "Ctrl";
|
||||
case "enter":
|
||||
return "↵";
|
||||
case "escape":
|
||||
return "Esc";
|
||||
case "backspace":
|
||||
return "⌫";
|
||||
case "tab":
|
||||
return "Tab";
|
||||
case "arrowup":
|
||||
return "↑";
|
||||
case "arrowdown":
|
||||
return "↓";
|
||||
case "arrowleft":
|
||||
return "←";
|
||||
case "arrowright":
|
||||
return "→";
|
||||
default:
|
||||
return part.toUpperCase();
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user