* Simple key code logger component
| 8 | * Simple key code logger component |
| 9 | */ |
| 10 | class KeyLogger implements Component { |
| 11 | private log: string[] = []; |
| 12 | private maxLines = 20; |
| 13 | private tui: TUI; |
| 14 | private terminal: ProcessTerminal; |
| 15 | |
| 16 | constructor(tui: TUI, terminal: ProcessTerminal) { |
| 17 | this.tui = tui; |
| 18 | this.terminal = terminal; |
| 19 | } |
| 20 | |
| 21 | handleInput(data: string): void { |
| 22 | // Handle Ctrl+C (raw or Kitty protocol) for exit |
| 23 | if (matchesKey(data, "ctrl+c")) { |
| 24 | this.tui.stop(); |
| 25 | console.log("\nExiting..."); |
| 26 | process.exit(0); |
| 27 | } |
| 28 | |
| 29 | // Convert to various representations |
| 30 | const hex = Buffer.from(data).toString("hex"); |
| 31 | const charCodes = Array.from(data) |
| 32 | .map((c) => c.charCodeAt(0)) |
| 33 | .join(", "); |
| 34 | const repr = data |
| 35 | .replace(/\x1b/g, "\\x1b") |
| 36 | .replace(/\r/g, "\\r") |
| 37 | .replace(/\n/g, "\\n") |
| 38 | .replace(/\t/g, "\\t") |
| 39 | .replace(/\x7f/g, "\\x7f"); |
| 40 | |
| 41 | const logLine = `Hex: ${hex.padEnd(20)} | Chars: [${charCodes.padEnd(15)}] | Repr: "${repr}"`; |
| 42 | |
| 43 | this.log.push(logLine); |
| 44 | |
| 45 | // Keep only last N lines |
| 46 | if (this.log.length > this.maxLines) { |
| 47 | this.log.shift(); |
| 48 | } |
| 49 | |
| 50 | // Request re-render to show the new log entry |
| 51 | this.tui.requestRender(); |
| 52 | } |
| 53 | |
| 54 | invalidate(): void { |
| 55 | // No cached state to invalidate currently |
| 56 | } |
| 57 | |
| 58 | private protocolName(): string { |
| 59 | if (this.terminal.kittyProtocolActive) return "kitty"; |
| 60 | if (this.terminal.modifyOtherKeysActive) return "modifyOtherKeys"; |
| 61 | return "legacy"; |
| 62 | } |
| 63 | |
| 64 | private fit(line: string, width: number): string { |
| 65 | return truncateToWidth(line, width).padEnd(width); |
| 66 | } |
| 67 |
nothing calls this directly
no outgoing calls
no test coverage detected