co-mono/packages/tui/test/key-tester.ts
Mario Zechner a686f61c1d feat(tui): improve editor Ctrl/Alt word and line deletion shortcuts
- Add Ctrl+W for word deletion (stops at whitespace/punctuation)
- Add Ctrl+U for delete to start of line (merges with previous line at col 0)
- Change Ctrl+K from delete entire line to delete to end of line (merges with next line at EOL)
- Add Option+Backspace support in Ghostty (maps to Ctrl+W via ESC+DEL sequence)
- Cmd+Backspace in Ghostty works as Ctrl+U (terminal sends same control code)
- Update README and CHANGELOG with new keyboard shortcuts

Fixes #2, Fixes #3
2025-11-14 23:19:24 +01:00

91 lines
2.1 KiB
JavaScript
Executable file

#!/usr/bin/env node
import { ProcessTerminal } from "../src/terminal.js";
import { type Component, TUI } from "../src/tui.js";
/**
* Simple key code logger component
*/
class KeyLogger implements Component {
private log: string[] = [];
private maxLines = 20;
private tui: TUI;
constructor(tui: TUI) {
this.tui = tui;
}
handleInput(data: string): void {
// Convert to various representations
const hex = Buffer.from(data).toString("hex");
const charCodes = Array.from(data)
.map((c) => c.charCodeAt(0))
.join(", ");
const repr = data
.replace(/\x1b/g, "\\x1b")
.replace(/\r/g, "\\r")
.replace(/\n/g, "\\n")
.replace(/\t/g, "\\t")
.replace(/\x7f/g, "\\x7f");
const logLine = `Hex: ${hex.padEnd(20)} | Chars: [${charCodes.padEnd(15)}] | Repr: "${repr}"`;
this.log.push(logLine);
// Keep only last N lines
if (this.log.length > this.maxLines) {
this.log.shift();
}
// Request re-render to show the new log entry
this.tui.requestRender();
}
render(width: number): string[] {
const lines: string[] = [];
// Title
lines.push("=".repeat(width));
lines.push("Key Code Tester - Press keys to see their codes (Ctrl+C to exit)".padEnd(width));
lines.push("=".repeat(width));
lines.push("");
// Log entries
for (const entry of this.log) {
lines.push(entry.padEnd(width));
}
// Fill remaining space
const remaining = Math.max(0, 25 - lines.length);
for (let i = 0; i < remaining; i++) {
lines.push("".padEnd(width));
}
// Footer
lines.push("=".repeat(width));
lines.push("Test these:".padEnd(width));
lines.push(" - Option/Alt + Backspace".padEnd(width));
lines.push(" - Cmd/Ctrl + Backspace".padEnd(width));
lines.push(" - Regular Backspace".padEnd(width));
lines.push("=".repeat(width));
return lines;
}
}
// Set up TUI
const terminal = new ProcessTerminal();
const tui = new TUI(terminal);
const logger = new KeyLogger(tui);
tui.addChild(logger);
tui.setFocus(logger);
// Handle Ctrl+C for clean exit
process.on("SIGINT", () => {
tui.stop();
console.log("\nExiting...");
process.exit(0);
});
// Start the TUI
tui.start();