@@ -1,6 +1,7 @@
|
||||
import * as fs from "node:fs";
|
||||
import { createRequire } from "node:module";
|
||||
import * as path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { setKittyProtocolActive } from "./keys.ts";
|
||||
import { StdinBuffer } from "./stdin-buffer.ts";
|
||||
|
||||
@@ -210,23 +211,30 @@ export class ProcessTerminal implements Terminal {
|
||||
private enableWindowsVTInput(): void {
|
||||
if (process.platform !== "win32") return;
|
||||
try {
|
||||
// Dynamic require to avoid bundling koffi's 74MB of cross-platform
|
||||
// native binaries into every compiled binary. Koffi is only needed
|
||||
// on Windows for VT input support.
|
||||
const koffi = cjsRequire("koffi");
|
||||
const k32 = koffi.load("kernel32.dll");
|
||||
const GetStdHandle = k32.func("void* __stdcall GetStdHandle(int)");
|
||||
const GetConsoleMode = k32.func("bool __stdcall GetConsoleMode(void*, _Out_ uint32_t*)");
|
||||
const SetConsoleMode = k32.func("bool __stdcall SetConsoleMode(void*, uint32_t)");
|
||||
const arch = process.arch;
|
||||
if (arch !== "x64" && arch !== "arm64") return;
|
||||
|
||||
const STD_INPUT_HANDLE = -10;
|
||||
const ENABLE_VIRTUAL_TERMINAL_INPUT = 0x0200;
|
||||
const handle = GetStdHandle(STD_INPUT_HANDLE);
|
||||
const mode = new Uint32Array(1);
|
||||
GetConsoleMode(handle, mode);
|
||||
SetConsoleMode(handle, mode[0]! | ENABLE_VIRTUAL_TERMINAL_INPUT);
|
||||
// Dynamic require so non-Windows and bundled/browser paths never load the
|
||||
// native helper. In the npm package native/ is next to dist/; in compiled
|
||||
// binary archives native/ is copied next to the executable.
|
||||
const moduleDir = path.dirname(fileURLToPath(import.meta.url));
|
||||
const nativePath = path.join("native", "win32", "prebuilds", `win32-${arch}`, "win32-console-mode.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 { enableVirtualTerminalInput?: () => boolean };
|
||||
helper.enableVirtualTerminalInput?.();
|
||||
return;
|
||||
} catch {
|
||||
// Try the next possible packaging location.
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// koffi not available — Shift+Tab won't be distinguishable from Tab
|
||||
// Native helper not available — Shift+Tab won't be distinguishable from Tab.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user