mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-29 14:34:55 -07:00
Add kitty support for function keys. (#12415)
This commit is contained in:
committed by
GitHub
parent
f8ce3585eb
commit
caf2ca1438
@@ -469,6 +469,10 @@ describe('KeypressContext - Kitty Protocol', () => {
|
|||||||
{ sequence: `\x1b[1~`, expected: { name: 'home' } },
|
{ sequence: `\x1b[1~`, expected: { name: 'home' } },
|
||||||
{ sequence: `\x1b[4~`, expected: { name: 'end' } },
|
{ sequence: `\x1b[4~`, expected: { name: 'end' } },
|
||||||
{ sequence: `\x1b[2~`, expected: { name: 'insert' } },
|
{ sequence: `\x1b[2~`, expected: { name: 'insert' } },
|
||||||
|
{ sequence: `\x1b[11~`, expected: { name: 'f1' } },
|
||||||
|
{ sequence: `\x1b[17~`, expected: { name: 'f6' } },
|
||||||
|
{ sequence: `\x1b[23~`, expected: { name: 'f11' } },
|
||||||
|
{ sequence: `\x1b[24~`, expected: { name: 'f12' } },
|
||||||
// Reverse tabs
|
// Reverse tabs
|
||||||
{ sequence: `\x1b[Z`, expected: { name: 'tab', shift: true } },
|
{ sequence: `\x1b[Z`, expected: { name: 'tab', shift: true } },
|
||||||
{ sequence: `\x1b[1;2Z`, expected: { name: 'tab', shift: true } },
|
{ sequence: `\x1b[1;2Z`, expected: { name: 'tab', shift: true } },
|
||||||
|
|||||||
@@ -56,6 +56,48 @@ const MAC_ALT_KEY_CHARACTER_MAP: Record<string, string> = {
|
|||||||
'\u00B5': 'm', // "µ" toggle markup view
|
'\u00B5': 'm', // "µ" toggle markup view
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps symbols from parameterized functional keys `\x1b[1;1<letter>`
|
||||||
|
* to their corresponding key names (e.g., 'up', 'f1').
|
||||||
|
*/
|
||||||
|
const LEGACY_FUNC_TO_NAME: { [k: string]: string } = {
|
||||||
|
A: 'up',
|
||||||
|
B: 'down',
|
||||||
|
C: 'right',
|
||||||
|
D: 'left',
|
||||||
|
H: 'home',
|
||||||
|
F: 'end',
|
||||||
|
P: 'f1',
|
||||||
|
Q: 'f2',
|
||||||
|
R: 'f3',
|
||||||
|
S: 'f4',
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps key codes from tilde-coded functional keys `\x1b[<code>~`
|
||||||
|
* to their corresponding key names.
|
||||||
|
*/
|
||||||
|
const TILDE_KEYCODE_TO_NAME: Record<number, string> = {
|
||||||
|
1: 'home',
|
||||||
|
2: 'insert',
|
||||||
|
3: 'delete',
|
||||||
|
4: 'end',
|
||||||
|
5: 'pageup',
|
||||||
|
6: 'pagedown',
|
||||||
|
11: 'f1',
|
||||||
|
12: 'f2',
|
||||||
|
13: 'f3',
|
||||||
|
14: 'f4',
|
||||||
|
15: 'f5',
|
||||||
|
17: 'f6', // skipping 16 is intentional
|
||||||
|
18: 'f7',
|
||||||
|
19: 'f8',
|
||||||
|
20: 'f9',
|
||||||
|
21: 'f10',
|
||||||
|
23: 'f11', // skipping 22 is intentional
|
||||||
|
24: 'f12',
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a buffer could potentially be a valid kitty sequence or its prefix.
|
* Check if a buffer could potentially be a valid kitty sequence or its prefix.
|
||||||
*/
|
*/
|
||||||
@@ -169,19 +211,7 @@ function parseKittyPrefix(buffer: string): { key: Key; length: number } | null {
|
|||||||
const alt = (bits & MODIFIER_ALT_BIT) === MODIFIER_ALT_BIT;
|
const alt = (bits & MODIFIER_ALT_BIT) === MODIFIER_ALT_BIT;
|
||||||
const ctrl = (bits & MODIFIER_CTRL_BIT) === MODIFIER_CTRL_BIT;
|
const ctrl = (bits & MODIFIER_CTRL_BIT) === MODIFIER_CTRL_BIT;
|
||||||
const sym = m[2];
|
const sym = m[2];
|
||||||
const symbolToName: { [k: string]: string } = {
|
const name = LEGACY_FUNC_TO_NAME[sym] || '';
|
||||||
A: 'up',
|
|
||||||
B: 'down',
|
|
||||||
C: 'right',
|
|
||||||
D: 'left',
|
|
||||||
H: 'home',
|
|
||||||
F: 'end',
|
|
||||||
P: 'f1',
|
|
||||||
Q: 'f2',
|
|
||||||
R: 'f3',
|
|
||||||
S: 'f4',
|
|
||||||
};
|
|
||||||
const name = symbolToName[sym] || '';
|
|
||||||
if (!name) return null;
|
if (!name) return null;
|
||||||
return {
|
return {
|
||||||
key: {
|
key: {
|
||||||
@@ -216,29 +246,7 @@ function parseKittyPrefix(buffer: string): { key: Key; length: number } | null {
|
|||||||
|
|
||||||
// Tilde-coded functional keys (Delete, Insert, PageUp/Down, Home/End)
|
// Tilde-coded functional keys (Delete, Insert, PageUp/Down, Home/End)
|
||||||
if (terminator === '~') {
|
if (terminator === '~') {
|
||||||
let name: string | null = null;
|
const name = TILDE_KEYCODE_TO_NAME[keyCode];
|
||||||
switch (keyCode) {
|
|
||||||
case 1:
|
|
||||||
name = 'home';
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
name = 'insert';
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
name = 'delete';
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
name = 'end';
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
name = 'pageup';
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
name = 'pagedown';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (name) {
|
if (name) {
|
||||||
return {
|
return {
|
||||||
key: {
|
key: {
|
||||||
@@ -307,15 +315,7 @@ function parseKittyPrefix(buffer: string): { key: Key; length: number } | null {
|
|||||||
m = buffer.match(legacyFuncKey);
|
m = buffer.match(legacyFuncKey);
|
||||||
if (m) {
|
if (m) {
|
||||||
const sym = m[1];
|
const sym = m[1];
|
||||||
const nameMap: { [key: string]: string } = {
|
const name = LEGACY_FUNC_TO_NAME[sym]!;
|
||||||
A: 'up',
|
|
||||||
B: 'down',
|
|
||||||
C: 'right',
|
|
||||||
D: 'left',
|
|
||||||
H: 'home',
|
|
||||||
F: 'end',
|
|
||||||
};
|
|
||||||
const name = nameMap[sym]!;
|
|
||||||
return {
|
return {
|
||||||
key: {
|
key: {
|
||||||
name,
|
name,
|
||||||
|
|||||||
Reference in New Issue
Block a user