diff --git a/src/cli.ts b/src/cli.ts index cc2fe9f..45e06b7 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,14 +1,22 @@ #!/usr/bin/env node -import { exitAlternateScreenBuffer } from "./utils/screen.js"; +import { + exitAlternateScreenBuffer, + isInAlternateScreenBuffer, +} from "./utils/screen.js"; import { processUtils } from "./utils/processUtils.js"; import { createProgram } from "./utils/commands.js"; import { getApiKeyErrorMessage, checkBaseDomain } from "./utils/config.js"; // Global Ctrl+C handler to ensure it always exits processUtils.on("SIGINT", () => { - // Force exit immediately, clearing alternate screen buffer - exitAlternateScreenBuffer(); + // Only restore the alternate screen buffer if we actually entered it. + // Unconditionally sending the exit sequence when no TUI is active causes + // the terminal to restore a stale saved-cursor position, jumping the + // cursor and garbling any plain-text output (e.g. `rli d ssh` wait loop). + if (isInAlternateScreenBuffer()) { + exitAlternateScreenBuffer(); + } processUtils.stdout.write("\n"); processUtils.exit(130); // Standard exit code for SIGINT }); diff --git a/src/utils/screen.ts b/src/utils/screen.ts index e89a93d..18cae86 100644 --- a/src/utils/screen.ts +++ b/src/utils/screen.ts @@ -9,12 +9,20 @@ import { processUtils } from "./processUtils.js"; +let _inAlternateScreenBuffer = false; + +/** Returns true if the alternate screen buffer is currently active. */ +export function isInAlternateScreenBuffer(): boolean { + return _inAlternateScreenBuffer; +} + /** * Enter the alternate screen buffer. * This provides a fullscreen experience where content won't mix with * previous terminal output. Like vim or top. */ export function enterAlternateScreenBuffer(): void { + _inAlternateScreenBuffer = true; processUtils.stdout.write("\x1b[?1049h"); } @@ -23,6 +31,7 @@ export function enterAlternateScreenBuffer(): void { * This returns the terminal to its original state before enterAlternateScreen() was called. */ export function exitAlternateScreenBuffer(): void { + _inAlternateScreenBuffer = false; processUtils.stdout.write("\x1b[?1049l"); }