mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-17 16:51:15 -07:00
Restore keyboard mode when exiting the editor (#13350)
This commit is contained in:
committed by
GitHub
parent
3f8d636501
commit
84573992b4
@@ -5,8 +5,11 @@
|
||||
*/
|
||||
|
||||
let detectionComplete = false;
|
||||
let protocolSupported = false;
|
||||
let protocolEnabled = false;
|
||||
|
||||
let kittySupported = false;
|
||||
let sgrMouseSupported = false;
|
||||
|
||||
let kittyEnabled = false;
|
||||
let sgrMouseEnabled = false;
|
||||
|
||||
/**
|
||||
@@ -14,15 +17,15 @@ let sgrMouseEnabled = false;
|
||||
* Definitive document about this protocol lives at https://sw.kovidgoyal.net/kitty/keyboard-protocol/
|
||||
* This function should be called once at app startup.
|
||||
*/
|
||||
export async function detectAndEnableKittyProtocol(): Promise<boolean> {
|
||||
export async function detectAndEnableKittyProtocol(): Promise<void> {
|
||||
if (detectionComplete) {
|
||||
return protocolSupported;
|
||||
return;
|
||||
}
|
||||
|
||||
return new Promise((resolve) => {
|
||||
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
||||
detectionComplete = true;
|
||||
resolve(false);
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -35,14 +38,24 @@ export async function detectAndEnableKittyProtocol(): Promise<boolean> {
|
||||
let progressiveEnhancementReceived = false;
|
||||
let timeoutId: NodeJS.Timeout | undefined;
|
||||
|
||||
const onTimeout = () => {
|
||||
timeoutId = undefined;
|
||||
const finish = () => {
|
||||
if (timeoutId !== undefined) {
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = undefined;
|
||||
}
|
||||
process.stdin.removeListener('data', handleData);
|
||||
if (!originalRawMode) {
|
||||
process.stdin.setRawMode(false);
|
||||
}
|
||||
|
||||
if (kittySupported || sgrMouseSupported) {
|
||||
enableSupportedProtocol();
|
||||
process.on('exit', disableAllProtocols);
|
||||
process.on('SIGTERM', disableAllProtocols);
|
||||
}
|
||||
|
||||
detectionComplete = true;
|
||||
resolve(false);
|
||||
resolve();
|
||||
};
|
||||
|
||||
const handleData = (data: Buffer) => {
|
||||
@@ -59,37 +72,20 @@ export async function detectAndEnableKittyProtocol(): Promise<boolean> {
|
||||
// indication the terminal probably supports kitty and we just need to
|
||||
// wait a bit longer for a response.
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = setTimeout(onTimeout, 1000);
|
||||
timeoutId = setTimeout(finish, 1000);
|
||||
}
|
||||
|
||||
// Check for device attributes response (CSI ? <attrs> c)
|
||||
if (responseBuffer.includes('\x1b[?') && responseBuffer.includes('c')) {
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = undefined;
|
||||
process.stdin.removeListener('data', handleData);
|
||||
|
||||
if (!originalRawMode) {
|
||||
process.stdin.setRawMode(false);
|
||||
}
|
||||
|
||||
if (progressiveEnhancementReceived) {
|
||||
// Enable the protocol
|
||||
process.stdout.write('\x1b[>1u');
|
||||
protocolSupported = true;
|
||||
protocolEnabled = true;
|
||||
kittySupported = true;
|
||||
}
|
||||
|
||||
// Broaden mouse support by enabling SGR mode if we get any device
|
||||
// attribute response, which is a strong signal of a modern terminal.
|
||||
process.stdout.write('\x1b[?1006h');
|
||||
sgrMouseEnabled = true;
|
||||
sgrMouseSupported = true;
|
||||
|
||||
// Set up cleanup on exit for all enabled protocols
|
||||
process.on('exit', disableAllProtocols);
|
||||
process.on('SIGTERM', disableAllProtocols);
|
||||
|
||||
detectionComplete = true;
|
||||
resolve(protocolSupported);
|
||||
finish();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -102,14 +98,18 @@ export async function detectAndEnableKittyProtocol(): Promise<boolean> {
|
||||
// Timeout after 200ms
|
||||
// When a iterm2 terminal does not have focus this can take over 90s on a
|
||||
// fast macbook so we need a somewhat longer threshold than would be ideal.
|
||||
timeoutId = setTimeout(onTimeout, 200);
|
||||
timeoutId = setTimeout(finish, 200);
|
||||
});
|
||||
}
|
||||
|
||||
export function isKittyProtocolEnabled(): boolean {
|
||||
return kittyEnabled;
|
||||
}
|
||||
|
||||
function disableAllProtocols() {
|
||||
if (protocolEnabled) {
|
||||
if (kittyEnabled) {
|
||||
process.stdout.write('\x1b[<u');
|
||||
protocolEnabled = false;
|
||||
kittyEnabled = false;
|
||||
}
|
||||
if (sgrMouseEnabled) {
|
||||
process.stdout.write('\x1b[?1006l'); // Disable SGR Mouse
|
||||
@@ -117,10 +117,17 @@ function disableAllProtocols() {
|
||||
}
|
||||
}
|
||||
|
||||
export function isKittyProtocolEnabled(): boolean {
|
||||
return protocolEnabled;
|
||||
}
|
||||
|
||||
export function isKittyProtocolSupported(): boolean {
|
||||
return protocolSupported;
|
||||
/**
|
||||
* This is exported so we can reenable this after exiting an editor which might
|
||||
* change the mode.
|
||||
*/
|
||||
export function enableSupportedProtocol(): void {
|
||||
if (kittySupported) {
|
||||
process.stdout.write('\x1b[>1u');
|
||||
kittyEnabled = true;
|
||||
}
|
||||
if (sgrMouseSupported) {
|
||||
process.stdout.write('\x1b[?1006h');
|
||||
sgrMouseEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user