mirror of
https://github.com/MoonshotAI/kimi-code.git
synced 2026-07-10 01:39:25 +00:00
fix(pi-tui): park cursor on exit under ledger renderer
This commit is contained in:
parent
ade7c0ef94
commit
7418b03506
3 changed files with 50 additions and 1 deletions
|
|
@ -688,4 +688,29 @@ export class LedgerTuiEngine {
|
|||
this.#preparedMeta = [];
|
||||
this.#preparedValidRows = 0;
|
||||
}
|
||||
|
||||
// Park the hardware cursor just past the last content row so the host's shell
|
||||
// prompt does not overwrite painted rows on exit. Mirrors TUI.stop()'s legacy
|
||||
// cursor-parking, but sourced from the ledger's own window/cursor state.
|
||||
public parkCursorForExit(): void {
|
||||
const window = this.#previousWindow;
|
||||
if (window.length === 0) return;
|
||||
let lastContentRow = -1;
|
||||
for (let i = window.length - 1; i >= 0; i--) {
|
||||
if ((window[i] ?? "").length > 0) {
|
||||
lastContentRow = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const targetRow = lastContentRow + 1;
|
||||
const height = this.terminal.rows;
|
||||
const rawCursorRow = this.#hardwareCursorRow - this.#windowTopRow;
|
||||
const cursorScreenRow = Math.max(0, Math.min(height - 1, rawCursorRow));
|
||||
let seq = "";
|
||||
const lineDiff = targetRow - cursorScreenRow;
|
||||
if (lineDiff > 0) seq += `\x1b[${lineDiff}B`;
|
||||
else if (lineDiff < 0) seq += `\x1b[${-lineDiff}A`;
|
||||
seq += "\r\n";
|
||||
this.terminal.write(seq);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -706,7 +706,9 @@ export class TUI extends Container {
|
|||
this.terminal.write("\x1b[?2031l");
|
||||
}
|
||||
// Move cursor to the end of the content to prevent overwriting/artifacts on exit
|
||||
if (this.previousLines.length > 0) {
|
||||
if (TUI.LEDGER_ENABLED && this.ledgerEngine) {
|
||||
this.ledgerEngine.parkCursorForExit();
|
||||
} else if (this.previousLines.length > 0) {
|
||||
const targetRow = this.previousLines.length; // Line after the last content
|
||||
const lineDiff = targetRow - this.hardwareCursorRow;
|
||||
if (lineDiff > 0) {
|
||||
|
|
|
|||
|
|
@ -96,4 +96,26 @@ describe("ledger engine golden", () => {
|
|||
tui.stop();
|
||||
});
|
||||
});
|
||||
|
||||
it("parks cursor past content on stop()", async () => {
|
||||
await withLedger(async () => {
|
||||
const terminal = new LoggingVirtualTerminal(40, 10);
|
||||
const tui = new TUI(terminal);
|
||||
const c = new TestComponent();
|
||||
tui.addChild(c);
|
||||
c.lines = ["Hello", "World"];
|
||||
tui.start();
|
||||
await terminal.waitForRender();
|
||||
terminal.clearWrites();
|
||||
tui.stop();
|
||||
const writes = terminal.getWrites();
|
||||
// stop() must emit a cursor-parking sequence ending with CRLF so the host
|
||||
// shell prompt lands on a fresh line below the painted content (not
|
||||
// overwriting it). This regresses the ledger-path exit artifact.
|
||||
assert.ok(
|
||||
writes.includes("\r\n"),
|
||||
`stop() should park cursor with a trailing CRLF; got: ${JSON.stringify(writes)}`,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue