fix(tui): normalize keypad functional keys closes #2650

This commit is contained in:
Mario Zechner
2026-03-29 21:53:31 +02:00
parent 86d9220dfe
commit 8c64058809
4 changed files with 89 additions and 8 deletions

View File

@@ -4,7 +4,7 @@
import assert from "node:assert";
import { describe, it } from "node:test";
import { matchesKey, parseKey, setKittyProtocolActive } from "../src/keys.js";
import { decodeKittyPrintable, matchesKey, parseKey, setKittyProtocolActive } from "../src/keys.js";
function withEnv(name: string, value: string | undefined, fn: () => void): void {
const previous = process.env[name];
@@ -76,6 +76,29 @@ describe("matchesKey", () => {
setKittyProtocolActive(false);
});
it("should normalize Kitty keypad functional keys to logical digits, symbols, and navigation", () => {
setKittyProtocolActive(true);
assert.strictEqual(matchesKey("\x1b[57400u", "1"), true);
assert.strictEqual(matchesKey("\x1b[57410u", "/"), true);
assert.strictEqual(matchesKey("\x1b[57417u", "left"), true);
assert.strictEqual(matchesKey("\x1b[57426u", "delete"), true);
assert.strictEqual(parseKey("\x1b[57399u"), "0");
assert.strictEqual(parseKey("\x1b[57409u"), ".");
assert.strictEqual(parseKey("\x1b[57413u"), "+");
assert.strictEqual(parseKey("\x1b[57416u"), ",");
assert.strictEqual(parseKey("\x1b[57417u"), "left");
assert.strictEqual(parseKey("\x1b[57418u"), "right");
assert.strictEqual(parseKey("\x1b[57419u"), "up");
assert.strictEqual(parseKey("\x1b[57420u"), "down");
assert.strictEqual(parseKey("\x1b[57421u"), "pageUp");
assert.strictEqual(parseKey("\x1b[57422u"), "pageDown");
assert.strictEqual(parseKey("\x1b[57423u"), "home");
assert.strictEqual(parseKey("\x1b[57424u"), "end");
assert.strictEqual(parseKey("\x1b[57425u"), "insert");
assert.strictEqual(parseKey("\x1b[57426u"), "delete");
setKittyProtocolActive(false);
});
it("should handle shifted key in format", () => {
setKittyProtocolActive(true);
// Format with shifted key: CSI codepoint:shifted:base;modifier u
@@ -389,6 +412,21 @@ describe("matchesKey", () => {
});
});
describe("decodeKittyPrintable", () => {
it("should decode Kitty keypad functional keys to printable characters", () => {
assert.strictEqual(decodeKittyPrintable("\x1b[57399u"), "0");
assert.strictEqual(decodeKittyPrintable("\x1b[57400u"), "1");
assert.strictEqual(decodeKittyPrintable("\x1b[57409u"), ".");
assert.strictEqual(decodeKittyPrintable("\x1b[57410u"), "/");
assert.strictEqual(decodeKittyPrintable("\x1b[57411u"), "*");
assert.strictEqual(decodeKittyPrintable("\x1b[57412u"), "-");
assert.strictEqual(decodeKittyPrintable("\x1b[57413u"), "+");
assert.strictEqual(decodeKittyPrintable("\x1b[57415u"), "=");
assert.strictEqual(decodeKittyPrintable("\x1b[57416u"), ",");
assert.strictEqual(decodeKittyPrintable("\x1b[57417u"), undefined);
});
});
describe("parseKey", () => {
describe("Kitty protocol with alternate keys", () => {
it("should return Latin key name when base layout key is present", () => {