From db0bf2b71f85500729d83d0940ebb399dd80c764 Mon Sep 17 00:00:00 2001 From: Abhi <43648792+abhipatel12@users.noreply.github.com> Date: Mon, 25 Aug 2025 17:14:07 -0400 Subject: [PATCH] refactor(cli): Improve Kitty keycode handling and tests (#7046) --- .../src/ui/contexts/KeypressContext.test.tsx | 32 ++++-------- .../cli/src/ui/contexts/KeypressContext.tsx | 50 ++++--------------- 2 files changed, 21 insertions(+), 61 deletions(-) diff --git a/packages/cli/src/ui/contexts/KeypressContext.test.tsx b/packages/cli/src/ui/contexts/KeypressContext.test.tsx index 53ba98f4..e60f6db2 100644 --- a/packages/cli/src/ui/contexts/KeypressContext.test.tsx +++ b/packages/cli/src/ui/contexts/KeypressContext.test.tsx @@ -14,16 +14,6 @@ import { } from './KeypressContext.js'; import { useStdin } from 'ink'; import { EventEmitter } from 'node:events'; -import { - KITTY_KEYCODE_ENTER, - KITTY_KEYCODE_NUMPAD_ENTER, - KITTY_KEYCODE_TAB, - KITTY_KEYCODE_BACKSPACE, - CHAR_CODE_ESC, - CHAR_CODE_LEFT_BRACKET, - CHAR_CODE_1, - CHAR_CODE_2, -} from '../utils/platformConstants.js'; // Mock the 'ink' module to control stdin vi.mock('ink', async (importOriginal) => { @@ -103,7 +93,7 @@ describe('KeypressContext - Kitty Protocol', () => { // Send kitty protocol sequence for regular enter: ESC[13u act(() => { - stdin.sendKittySequence(`\x1b[${KITTY_KEYCODE_ENTER}u`); + stdin.sendKittySequence(`\x1b[13u`); }); expect(keyHandler).toHaveBeenCalledWith( @@ -131,7 +121,7 @@ describe('KeypressContext - Kitty Protocol', () => { // Send kitty protocol sequence for numpad enter: ESC[57414u act(() => { - stdin.sendKittySequence(`\x1b[${KITTY_KEYCODE_NUMPAD_ENTER}u`); + stdin.sendKittySequence(`\x1b[57414u`); }); expect(keyHandler).toHaveBeenCalledWith( @@ -159,7 +149,7 @@ describe('KeypressContext - Kitty Protocol', () => { // Send kitty protocol sequence for numpad enter with Shift (modifier 2): ESC[57414;2u act(() => { - stdin.sendKittySequence(`\x1b[${KITTY_KEYCODE_NUMPAD_ENTER};2u`); + stdin.sendKittySequence(`\x1b[57414;2u`); }); expect(keyHandler).toHaveBeenCalledWith( @@ -187,7 +177,7 @@ describe('KeypressContext - Kitty Protocol', () => { // Send kitty protocol sequence for numpad enter with Ctrl (modifier 5): ESC[57414;5u act(() => { - stdin.sendKittySequence(`\x1b[${KITTY_KEYCODE_NUMPAD_ENTER};5u`); + stdin.sendKittySequence(`\x1b[57414;5u`); }); expect(keyHandler).toHaveBeenCalledWith( @@ -215,7 +205,7 @@ describe('KeypressContext - Kitty Protocol', () => { // Send kitty protocol sequence for numpad enter with Alt (modifier 3): ESC[57414;3u act(() => { - stdin.sendKittySequence(`\x1b[${KITTY_KEYCODE_NUMPAD_ENTER};3u`); + stdin.sendKittySequence(`\x1b[57414;3u`); }); expect(keyHandler).toHaveBeenCalledWith( @@ -243,7 +233,7 @@ describe('KeypressContext - Kitty Protocol', () => { // Send kitty protocol sequence for numpad enter act(() => { - stdin.sendKittySequence(`\x1b[${KITTY_KEYCODE_NUMPAD_ENTER}u`); + stdin.sendKittySequence(`\x1b[57414u`); }); // When kitty protocol is disabled, the sequence should be passed through @@ -291,7 +281,7 @@ describe('KeypressContext - Kitty Protocol', () => { act(() => result.current.subscribe(keyHandler)); act(() => { - stdin.sendKittySequence(`\x1b[${KITTY_KEYCODE_TAB}u`); + stdin.sendKittySequence(`\x1b[9u`); }); expect(keyHandler).toHaveBeenCalledWith( @@ -310,7 +300,7 @@ describe('KeypressContext - Kitty Protocol', () => { // Modifier 2 is Shift act(() => { - stdin.sendKittySequence(`\x1b[${KITTY_KEYCODE_TAB};2u`); + stdin.sendKittySequence(`\x1b[9;2u`); }); expect(keyHandler).toHaveBeenCalledWith( @@ -328,7 +318,7 @@ describe('KeypressContext - Kitty Protocol', () => { act(() => result.current.subscribe(keyHandler)); act(() => { - stdin.sendKittySequence(`\x1b[${KITTY_KEYCODE_BACKSPACE}u`); + stdin.sendKittySequence(`\x1b[127u`); }); expect(keyHandler).toHaveBeenCalledWith( @@ -347,7 +337,7 @@ describe('KeypressContext - Kitty Protocol', () => { // Modifier 3 is Alt/Option act(() => { - stdin.sendKittySequence(`\x1b[${KITTY_KEYCODE_BACKSPACE};3u`); + stdin.sendKittySequence(`\x1b[127;3u`); }); expect(keyHandler).toHaveBeenCalledWith( @@ -592,7 +582,7 @@ describe('KeypressContext - Kitty Protocol', () => { // Verify warning for char codes expect(consoleWarnSpy).toHaveBeenCalledWith( 'Kitty sequence buffer has char codes:', - [CHAR_CODE_ESC, CHAR_CODE_LEFT_BRACKET, CHAR_CODE_1, CHAR_CODE_2], + [27, 91, 49, 50], ); }); }); diff --git a/packages/cli/src/ui/contexts/KeypressContext.tsx b/packages/cli/src/ui/contexts/KeypressContext.tsx index 4e980af8..d898f781 100644 --- a/packages/cli/src/ui/contexts/KeypressContext.tsx +++ b/packages/cli/src/ui/contexts/KeypressContext.tsx @@ -21,6 +21,7 @@ import readline from 'node:readline'; import { PassThrough } from 'node:stream'; import { BACKSLASH_ENTER_DETECTION_WINDOW_MS, + CHAR_CODE_ESC, KITTY_CTRL_C, KITTY_KEYCODE_BACKSPACE, KITTY_KEYCODE_ENTER, @@ -126,48 +127,17 @@ export function KeypressProvider({ const alt = (modifierBits & 2) === 2; const ctrl = (modifierBits & 4) === 4; - if (keyCode === 27) { - return { - name: 'escape', - ctrl, - meta: alt, - shift, - paste: false, - sequence, - kittyProtocol: true, - }; - } + const keyNameMap: Record = { + [CHAR_CODE_ESC]: 'escape', + [KITTY_KEYCODE_TAB]: 'tab', + [KITTY_KEYCODE_BACKSPACE]: 'backspace', + [KITTY_KEYCODE_ENTER]: 'return', + [KITTY_KEYCODE_NUMPAD_ENTER]: 'return', + }; - if (keyCode === KITTY_KEYCODE_TAB) { + if (keyCode in keyNameMap) { return { - name: 'tab', - ctrl, - meta: alt, - shift, - paste: false, - sequence, - kittyProtocol: true, - }; - } - - if (keyCode === KITTY_KEYCODE_BACKSPACE) { - return { - name: 'backspace', - ctrl, - meta: alt, - shift, - paste: false, - sequence, - kittyProtocol: true, - }; - } - - if ( - keyCode === KITTY_KEYCODE_ENTER || - keyCode === KITTY_KEYCODE_NUMPAD_ENTER - ) { - return { - name: 'return', + name: keyNameMap[keyCode], ctrl, meta: alt, shift,