fix: handle Shift+Space in Kitty keyboard protocol terminals (#15767)

This commit is contained in:
Tu Shaokun
2026-01-10 01:28:14 +08:00
committed by GitHub
parent 8bc3cfe29a
commit c1401682ed
2 changed files with 33 additions and 8 deletions

View File

@@ -224,40 +224,60 @@ describe('KeypressContext', () => {
});
});
describe('Tab and Backspace handling', () => {
describe('Tab, Backspace, and Space handling', () => {
it.each([
{
name: 'Tab key',
sequence: '\x1b[9u',
inputSequence: '\x1b[9u',
expected: { name: 'tab', shift: false },
},
{
name: 'Shift+Tab',
sequence: '\x1b[9;2u',
inputSequence: '\x1b[9;2u',
expected: { name: 'tab', shift: true },
},
{
name: 'Backspace',
sequence: '\x1b[127u',
inputSequence: '\x1b[127u',
expected: { name: 'backspace', meta: false },
},
{
name: 'Option+Backspace',
sequence: '\x1b[127;3u',
inputSequence: '\x1b[127;3u',
expected: { name: 'backspace', meta: true },
},
{
name: 'Ctrl+Backspace',
sequence: '\x1b[127;5u',
inputSequence: '\x1b[127;5u',
expected: { name: 'backspace', ctrl: true },
},
{
name: 'Shift+Space',
inputSequence: '\x1b[32;2u',
expected: {
name: 'space',
shift: true,
insertable: true,
sequence: ' ',
},
},
{
name: 'Ctrl+Space',
inputSequence: '\x1b[32;5u',
expected: {
name: 'space',
ctrl: true,
insertable: false,
sequence: '\x1b[32;5u',
},
},
])(
'should recognize $name in kitty protocol',
async ({ sequence, expected }) => {
async ({ inputSequence, expected }) => {
const { keyHandler } = setupKeypressTest();
act(() => {
stdin.write(sequence);
stdin.write(inputSequence);
});
expect(keyHandler).toHaveBeenCalledWith(

View File

@@ -84,6 +84,7 @@ const KEY_INFO_MAP: Record<
'[9u': { name: 'tab' },
'[13u': { name: 'return' },
'[27u': { name: 'escape' },
'[32u': { name: 'space' },
'[127u': { name: 'backspace' },
'[57414u': { name: 'return' }, // Numpad Enter
'[a': { name: 'up', shift: true },
@@ -479,6 +480,10 @@ function* emitKeys(
if (keyInfo.ctrl) {
ctrl = true;
}
if (name === 'space' && !ctrl && !meta) {
sequence = ' ';
insertable = true;
}
} else {
name = 'undefined';
if ((ctrl || meta) && (code.endsWith('u') || code.endsWith('~'))) {