fix(tui): reduce unnecessary full redraws for better performance

- Remove height change detection (only width changes trigger full redraw)
- Change clearOnShrink default to false (use PI_CLEAR_ON_SHRINK=1 to enable)
- Fix viewport check to use previousLines.length instead of maxLinesRendered
  (prevents false positive redraws when appending lines after content shrunk)
- Add clearOnShrink setting to /settings in coding-agent
- Remove line truncation in custom message component (always show full content)
This commit is contained in:
Mario Zechner 2026-02-02 08:10:08 +01:00
parent 419c07fb19
commit 0925fafe3b
8 changed files with 80 additions and 48 deletions

View file

@ -90,14 +90,6 @@ export class CustomMessageComponent extends Container {
.join("\n");
}
// Limit lines when collapsed
if (!this._expanded) {
const lines = text.split("\n");
if (lines.length > 5) {
text = `${lines.slice(0, 5).join("\n")}\n...`;
}
}
this.box.addChild(
new Markdown(text, 0, 0, this.markdownTheme, {
color: (text: string) => theme.fg("customMessageText", text),

View file

@ -40,6 +40,7 @@ export interface SettingsConfig {
editorPaddingX: number;
autocompleteMaxVisible: number;
quietStartup: boolean;
clearOnShrink: boolean;
}
export interface SettingsCallbacks {
@ -60,6 +61,7 @@ export interface SettingsCallbacks {
onEditorPaddingXChange: (padding: number) => void;
onAutocompleteMaxVisibleChange: (maxVisible: number) => void;
onQuietStartupChange: (enabled: boolean) => void;
onClearOnShrinkChange: (enabled: boolean) => void;
onCancel: () => void;
}
@ -312,6 +314,16 @@ export class SettingsSelectorComponent extends Container {
values: ["3", "5", "7", "10", "15", "20"],
});
// Clear on shrink toggle (insert after autocomplete-max-visible)
const autocompleteIndex = items.findIndex((item) => item.id === "autocomplete-max-visible");
items.splice(autocompleteIndex + 1, 0, {
id: "clear-on-shrink",
label: "Clear on shrink",
description: "Clear empty rows when content shrinks (may cause flicker)",
currentValue: config.clearOnShrink ? "true" : "false",
values: ["true", "false"],
});
// Add borders
this.addChild(new DynamicBorder());
@ -363,6 +375,9 @@ export class SettingsSelectorComponent extends Container {
case "autocomplete-max-visible":
callbacks.onAutocompleteMaxVisibleChange(parseInt(newValue, 10));
break;
case "clear-on-shrink":
callbacks.onClearOnShrinkChange(newValue === "true");
break;
}
},
callbacks.onCancel,

View file

@ -258,6 +258,7 @@ export class InteractiveMode {
this.session = session;
this.version = VERSION;
this.ui = new TUI(new ProcessTerminal(), this.settingsManager.getShowHardwareCursor());
this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink());
this.headerContainer = new Container();
this.chatContainer = new Container();
this.pendingMessagesContainer = new Container();
@ -2996,6 +2997,7 @@ export class InteractiveMode {
editorPaddingX: this.settingsManager.getEditorPaddingX(),
autocompleteMaxVisible: this.settingsManager.getAutocompleteMaxVisible(),
quietStartup: this.settingsManager.getQuietStartup(),
clearOnShrink: this.settingsManager.getClearOnShrink(),
},
{
onAutoCompactChange: (enabled) => {
@ -3084,6 +3086,10 @@ export class InteractiveMode {
this.editor.setAutocompleteMaxVisible(maxVisible);
}
},
onClearOnShrinkChange: (enabled) => {
this.settingsManager.setClearOnShrink(enabled);
this.ui.setClearOnShrink(enabled);
},
onCancel: () => {
done();
this.ui.requestRender();