fix(tui): detect Apple Terminal Shift+Enter

This commit is contained in:
Armin Ronacher
2026-05-23 15:09:01 +02:00
parent 4a98f748bb
commit c5181a266e
10 changed files with 204 additions and 3 deletions

View File

@@ -0,0 +1,60 @@
import { createRequire } from "node:module";
import * as path from "node:path";
import { fileURLToPath } from "node:url";
const cjsRequire = createRequire(import.meta.url);
export type ModifierKey = "shift" | "command" | "control" | "option";
type NativeModifiersHelper = {
isModifierPressed: (name: ModifierKey) => boolean;
};
let nativeModifiersHelper: NativeModifiersHelper | null | undefined;
function isNativeModifiersHelper(value: unknown): value is NativeModifiersHelper {
if (typeof value !== "object" || value === null) return false;
const candidate = (value as { isModifierPressed?: unknown }).isModifierPressed;
return typeof candidate === "function";
}
function loadNativeModifiersHelper(): NativeModifiersHelper | undefined {
if (nativeModifiersHelper !== undefined) return nativeModifiersHelper ?? undefined;
nativeModifiersHelper = null;
if (process.platform !== "darwin") return undefined;
const arch = process.arch;
if (arch !== "x64" && arch !== "arm64") return undefined;
const moduleDir = path.dirname(fileURLToPath(import.meta.url));
const nativePath = path.join("native", "darwin", "prebuilds", `darwin-${arch}`, "darwin-modifiers.node");
const candidates = [
path.join(moduleDir, "..", nativePath),
path.join(moduleDir, nativePath),
path.join(path.dirname(process.execPath), nativePath),
];
for (const modulePath of candidates) {
try {
const helper = cjsRequire(modulePath) as unknown;
if (isNativeModifiersHelper(helper)) {
nativeModifiersHelper = helper;
return helper;
}
} catch {
// Try the next possible packaging location.
}
}
return undefined;
}
export function isNativeModifierPressed(key: ModifierKey): boolean {
if (process.env.PI_TUI_DISABLE_NATIVE_MODIFIERS === "1") return false;
const helper = loadNativeModifiersHelper();
if (!helper) return false;
try {
return helper.isModifierPressed(key) === true;
} catch {
return false;
}
}