mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-19 09:33:53 +00:00
refactor(cli): Improve Kitty keycode handling and tests (#7046)
This commit is contained in:
@@ -14,16 +14,6 @@ import {
|
|||||||
} from './KeypressContext.js';
|
} from './KeypressContext.js';
|
||||||
import { useStdin } from 'ink';
|
import { useStdin } from 'ink';
|
||||||
import { EventEmitter } from 'node:events';
|
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
|
// Mock the 'ink' module to control stdin
|
||||||
vi.mock('ink', async (importOriginal) => {
|
vi.mock('ink', async (importOriginal) => {
|
||||||
@@ -103,7 +93,7 @@ describe('KeypressContext - Kitty Protocol', () => {
|
|||||||
|
|
||||||
// Send kitty protocol sequence for regular enter: ESC[13u
|
// Send kitty protocol sequence for regular enter: ESC[13u
|
||||||
act(() => {
|
act(() => {
|
||||||
stdin.sendKittySequence(`\x1b[${KITTY_KEYCODE_ENTER}u`);
|
stdin.sendKittySequence(`\x1b[13u`);
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(keyHandler).toHaveBeenCalledWith(
|
expect(keyHandler).toHaveBeenCalledWith(
|
||||||
@@ -131,7 +121,7 @@ describe('KeypressContext - Kitty Protocol', () => {
|
|||||||
|
|
||||||
// Send kitty protocol sequence for numpad enter: ESC[57414u
|
// Send kitty protocol sequence for numpad enter: ESC[57414u
|
||||||
act(() => {
|
act(() => {
|
||||||
stdin.sendKittySequence(`\x1b[${KITTY_KEYCODE_NUMPAD_ENTER}u`);
|
stdin.sendKittySequence(`\x1b[57414u`);
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(keyHandler).toHaveBeenCalledWith(
|
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
|
// Send kitty protocol sequence for numpad enter with Shift (modifier 2): ESC[57414;2u
|
||||||
act(() => {
|
act(() => {
|
||||||
stdin.sendKittySequence(`\x1b[${KITTY_KEYCODE_NUMPAD_ENTER};2u`);
|
stdin.sendKittySequence(`\x1b[57414;2u`);
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(keyHandler).toHaveBeenCalledWith(
|
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
|
// Send kitty protocol sequence for numpad enter with Ctrl (modifier 5): ESC[57414;5u
|
||||||
act(() => {
|
act(() => {
|
||||||
stdin.sendKittySequence(`\x1b[${KITTY_KEYCODE_NUMPAD_ENTER};5u`);
|
stdin.sendKittySequence(`\x1b[57414;5u`);
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(keyHandler).toHaveBeenCalledWith(
|
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
|
// Send kitty protocol sequence for numpad enter with Alt (modifier 3): ESC[57414;3u
|
||||||
act(() => {
|
act(() => {
|
||||||
stdin.sendKittySequence(`\x1b[${KITTY_KEYCODE_NUMPAD_ENTER};3u`);
|
stdin.sendKittySequence(`\x1b[57414;3u`);
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(keyHandler).toHaveBeenCalledWith(
|
expect(keyHandler).toHaveBeenCalledWith(
|
||||||
@@ -243,7 +233,7 @@ describe('KeypressContext - Kitty Protocol', () => {
|
|||||||
|
|
||||||
// Send kitty protocol sequence for numpad enter
|
// Send kitty protocol sequence for numpad enter
|
||||||
act(() => {
|
act(() => {
|
||||||
stdin.sendKittySequence(`\x1b[${KITTY_KEYCODE_NUMPAD_ENTER}u`);
|
stdin.sendKittySequence(`\x1b[57414u`);
|
||||||
});
|
});
|
||||||
|
|
||||||
// When kitty protocol is disabled, the sequence should be passed through
|
// 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(() => result.current.subscribe(keyHandler));
|
||||||
|
|
||||||
act(() => {
|
act(() => {
|
||||||
stdin.sendKittySequence(`\x1b[${KITTY_KEYCODE_TAB}u`);
|
stdin.sendKittySequence(`\x1b[9u`);
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(keyHandler).toHaveBeenCalledWith(
|
expect(keyHandler).toHaveBeenCalledWith(
|
||||||
@@ -310,7 +300,7 @@ describe('KeypressContext - Kitty Protocol', () => {
|
|||||||
|
|
||||||
// Modifier 2 is Shift
|
// Modifier 2 is Shift
|
||||||
act(() => {
|
act(() => {
|
||||||
stdin.sendKittySequence(`\x1b[${KITTY_KEYCODE_TAB};2u`);
|
stdin.sendKittySequence(`\x1b[9;2u`);
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(keyHandler).toHaveBeenCalledWith(
|
expect(keyHandler).toHaveBeenCalledWith(
|
||||||
@@ -328,7 +318,7 @@ describe('KeypressContext - Kitty Protocol', () => {
|
|||||||
act(() => result.current.subscribe(keyHandler));
|
act(() => result.current.subscribe(keyHandler));
|
||||||
|
|
||||||
act(() => {
|
act(() => {
|
||||||
stdin.sendKittySequence(`\x1b[${KITTY_KEYCODE_BACKSPACE}u`);
|
stdin.sendKittySequence(`\x1b[127u`);
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(keyHandler).toHaveBeenCalledWith(
|
expect(keyHandler).toHaveBeenCalledWith(
|
||||||
@@ -347,7 +337,7 @@ describe('KeypressContext - Kitty Protocol', () => {
|
|||||||
|
|
||||||
// Modifier 3 is Alt/Option
|
// Modifier 3 is Alt/Option
|
||||||
act(() => {
|
act(() => {
|
||||||
stdin.sendKittySequence(`\x1b[${KITTY_KEYCODE_BACKSPACE};3u`);
|
stdin.sendKittySequence(`\x1b[127;3u`);
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(keyHandler).toHaveBeenCalledWith(
|
expect(keyHandler).toHaveBeenCalledWith(
|
||||||
@@ -592,7 +582,7 @@ describe('KeypressContext - Kitty Protocol', () => {
|
|||||||
// Verify warning for char codes
|
// Verify warning for char codes
|
||||||
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
||||||
'Kitty sequence buffer has char codes:',
|
'Kitty sequence buffer has char codes:',
|
||||||
[CHAR_CODE_ESC, CHAR_CODE_LEFT_BRACKET, CHAR_CODE_1, CHAR_CODE_2],
|
[27, 91, 49, 50],
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import readline from 'node:readline';
|
|||||||
import { PassThrough } from 'node:stream';
|
import { PassThrough } from 'node:stream';
|
||||||
import {
|
import {
|
||||||
BACKSLASH_ENTER_DETECTION_WINDOW_MS,
|
BACKSLASH_ENTER_DETECTION_WINDOW_MS,
|
||||||
|
CHAR_CODE_ESC,
|
||||||
KITTY_CTRL_C,
|
KITTY_CTRL_C,
|
||||||
KITTY_KEYCODE_BACKSPACE,
|
KITTY_KEYCODE_BACKSPACE,
|
||||||
KITTY_KEYCODE_ENTER,
|
KITTY_KEYCODE_ENTER,
|
||||||
@@ -126,48 +127,17 @@ export function KeypressProvider({
|
|||||||
const alt = (modifierBits & 2) === 2;
|
const alt = (modifierBits & 2) === 2;
|
||||||
const ctrl = (modifierBits & 4) === 4;
|
const ctrl = (modifierBits & 4) === 4;
|
||||||
|
|
||||||
if (keyCode === 27) {
|
const keyNameMap: Record<number, string> = {
|
||||||
return {
|
[CHAR_CODE_ESC]: 'escape',
|
||||||
name: 'escape',
|
[KITTY_KEYCODE_TAB]: 'tab',
|
||||||
ctrl,
|
[KITTY_KEYCODE_BACKSPACE]: 'backspace',
|
||||||
meta: alt,
|
[KITTY_KEYCODE_ENTER]: 'return',
|
||||||
shift,
|
[KITTY_KEYCODE_NUMPAD_ENTER]: 'return',
|
||||||
paste: false,
|
};
|
||||||
sequence,
|
|
||||||
kittyProtocol: true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keyCode === KITTY_KEYCODE_TAB) {
|
if (keyCode in keyNameMap) {
|
||||||
return {
|
return {
|
||||||
name: 'tab',
|
name: keyNameMap[keyCode],
|
||||||
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',
|
|
||||||
ctrl,
|
ctrl,
|
||||||
meta: alt,
|
meta: alt,
|
||||||
shift,
|
shift,
|
||||||
|
|||||||
Reference in New Issue
Block a user