feat(tui): removed cursor positioning and refactored TUI rendering with explicit env defaults
- Removed getCursorPosition() method from Component interface and implementations, eliminating hardware cursor positioning support. - Changed PI_HARDWARE_CURSOR environment variable default from implicit true to explicit '1' with fallback pattern. - Changed PI_CLEAR_ON_SHRINK environment variable default from implicit false to explicit '0' with fallback pattern. - Added screen clearing on TUI startup to prevent shell prompts from bleeding into first rendered frame. - Refactored full-render logic into reusable fullRender() helper function.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import * as Diff from "diff";
|
||||
import { theme } from "../../modes/theme/theme";
|
||||
import { replaceTabs } from "../../tools/render-utils";
|
||||
|
||||
/**
|
||||
* Parse diff line to extract prefix, line number, and content.
|
||||
@@ -11,13 +12,6 @@ function parseDiffLine(line: string): { prefix: string; lineNum: string; content
|
||||
return { prefix: match[1], lineNum: match[2] ?? "", content: match[3] };
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace tabs with spaces for consistent rendering.
|
||||
*/
|
||||
function replaceTabs(text: string): string {
|
||||
return text.replace(/\t/g, " ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute word-level diff and render with inverse on changed parts.
|
||||
* Uses diffWords which groups whitespace with adjacent words for cleaner highlighting.
|
||||
|
||||
@@ -84,7 +84,7 @@ export class SelectorController {
|
||||
},
|
||||
getStatusLinePreview: () => {
|
||||
// Return the rendered status line for inline preview
|
||||
const width = this.ctx.ui.getWidth();
|
||||
const width = this.ctx.ui.terminal.columns;
|
||||
return this.ctx.statusLine.getTopBorder(width).content;
|
||||
},
|
||||
onPluginsChanged: () => {
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
} from "@oh-my-pi/pi-tui";
|
||||
import { $env, isEnoent, logger, postmortem } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "chalk";
|
||||
import { APP_NAME } from "../config";
|
||||
import { KeybindingsManager } from "../config/keybindings";
|
||||
import { renderPromptTemplate } from "../config/prompt-templates";
|
||||
import { type Settings, settings } from "../config/settings";
|
||||
@@ -391,7 +392,7 @@ export class InteractiveMode implements InteractiveModeContext {
|
||||
}
|
||||
|
||||
updateEditorTopBorder(): void {
|
||||
const width = this.ui.getWidth();
|
||||
const width = this.ui.terminal.columns;
|
||||
const topBorder = this.statusLine.getTopBorder(width);
|
||||
this.editor.setTopBorder(topBorder);
|
||||
}
|
||||
@@ -726,14 +727,26 @@ export class InteractiveMode implements InteractiveModeContext {
|
||||
await this.session.emitCustomToolSessionEvent("shutdown");
|
||||
|
||||
if (this.isInitialized) {
|
||||
await this.ui.waitForRender();
|
||||
this.ui.requestRender(true);
|
||||
}
|
||||
|
||||
// Wait for any pending renders to complete
|
||||
// requestRender() uses process.nextTick(), so we wait one tick
|
||||
await new Promise(resolve => process.nextTick(resolve));
|
||||
|
||||
// Drain any in-flight Kitty key release events before stopping.
|
||||
// This prevents escape sequences from leaking to the parent shell over slow SSH.
|
||||
await this.ui.terminal.drainInput(1000);
|
||||
|
||||
this.stop();
|
||||
|
||||
// Print resumption hint if this is a persisted session
|
||||
const sessionId = this.sessionManager.getSessionId();
|
||||
const sessionFile = this.sessionManager.getSessionFile();
|
||||
if (sessionId && sessionFile) {
|
||||
process.stderr.write(`\n${chalk.dim(`Resume this session with ${APP_NAME} --resume ${sessionId}`)}\n`);
|
||||
}
|
||||
|
||||
await postmortem.quit(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -204,13 +204,6 @@ export class UiHelpers {
|
||||
// Render tool call components
|
||||
for (const content of message.content) {
|
||||
if (content.type !== "toolCall") {
|
||||
// Text/thinking blocks between tool calls break read grouping
|
||||
if (
|
||||
(content.type === "text" && content.text?.trim()) ||
|
||||
(content.type === "thinking" && (content as any).thinking?.trim())
|
||||
) {
|
||||
readGroup = null;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user