fix(tui): dropped stale hidden-lines footer on expanded output
Expanded `!` bash and `eval` execution output kept rendering the `… N more lines (ctrl+o to expand)` footer after Ctrl+O revealed every line, because `hiddenLineCount` was computed from the collapsed preview window regardless of the `#expanded` (or sixel-passthrough) state. Zero the hidden count whenever the full output is shown so `buildStatusFooter()` stops advertising hidden lines and ctrl+o. Fixes #5842
This commit is contained in:
@@ -2,6 +2,10 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed expanded `!` bash and `eval` output keeping a stale `… N more lines (ctrl+o to expand)` footer after Ctrl+O revealed every line ([#5842](https://github.com/can1357/oh-my-pi/issues/5842)).
|
||||
|
||||
## [17.0.2] - 2026-07-17
|
||||
|
||||
### Added
|
||||
|
||||
@@ -146,14 +146,18 @@ export class BashExecutionComponent extends Container {
|
||||
#updateDisplay(): void {
|
||||
const availableLines = this.#outputLines;
|
||||
|
||||
// Apply preview truncation based on expanded state
|
||||
// Full output is shown when expanded or when sixel passthrough renders
|
||||
// the raw payload; the collapsed preview shows only the tail window.
|
||||
const previewLogicalLines = availableLines.slice(-PREVIEW_LINES);
|
||||
const hiddenLineCount = availableLines.length - previewLogicalLines.length;
|
||||
const sixelLineMask =
|
||||
TERMINAL.imageProtocol === ImageProtocol.Sixel && isSixelPassthroughEnabled()
|
||||
? getSixelLineMask(availableLines)
|
||||
: undefined;
|
||||
const hasSixelOutput = sixelLineMask?.some(Boolean) ?? false;
|
||||
const showingAllLines = this.#expanded || hasSixelOutput;
|
||||
// Only the collapsed preview hides lines; when the full output is shown
|
||||
// the footer must not keep advertising hidden lines / ctrl+o.
|
||||
const hiddenLineCount = showingAllLines ? 0 : availableLines.length - previewLogicalLines.length;
|
||||
|
||||
// Rebuild content container
|
||||
this.#contentContainer.clear();
|
||||
@@ -163,7 +167,7 @@ export class BashExecutionComponent extends Container {
|
||||
|
||||
// Output
|
||||
if (availableLines.length > 0) {
|
||||
if (this.#expanded || hasSixelOutput) {
|
||||
if (showingAllLines) {
|
||||
const displayText = availableLines
|
||||
.map((line, index) => (sixelLineMask?.[index] ? line : theme.fg("muted", line)))
|
||||
.join("\n");
|
||||
|
||||
@@ -114,7 +114,9 @@ export class EvalExecutionComponent extends Container {
|
||||
#updateDisplay(): void {
|
||||
const availableLines = this.#outputLines;
|
||||
const previewLogicalLines = availableLines.slice(-PREVIEW_LINES);
|
||||
const hiddenLineCount = availableLines.length - previewLogicalLines.length;
|
||||
// Only the collapsed preview hides lines; when expanded the footer must
|
||||
// not keep advertising hidden lines / ctrl+o.
|
||||
const hiddenLineCount = this.#expanded ? 0 : availableLines.length - previewLogicalLines.length;
|
||||
|
||||
this.#contentContainer.clear();
|
||||
|
||||
|
||||
@@ -141,3 +141,47 @@ describe("BashExecutionComponent streaming throttle", () => {
|
||||
expect(output).not.toContain("streaming_line");
|
||||
});
|
||||
});
|
||||
|
||||
describe("BashExecutionComponent expand footer", () => {
|
||||
const ui = { requestRender: () => {}, requestComponentRender: () => {} } as unknown as TUI;
|
||||
|
||||
beforeEach(async () => {
|
||||
const theme = await getThemeByName("dark");
|
||||
expect(theme).toBeDefined();
|
||||
setThemeInstance(theme!);
|
||||
});
|
||||
|
||||
// PREVIEW_LINES is 20: 27 lines leaves 7 hidden in the collapsed preview.
|
||||
const makeComponent = () => {
|
||||
const component = new BashExecutionComponent("ls", ui, false);
|
||||
const lines = Array.from({ length: 27 }, (_, i) => `entry${i}`);
|
||||
component.setComplete(0, false, { output: lines.join("\n") });
|
||||
return component;
|
||||
};
|
||||
|
||||
it("advertises hidden lines while collapsed", () => {
|
||||
const rendered = makeComponent().render(120).join("\n");
|
||||
expect(rendered).toContain("more lines");
|
||||
expect(rendered).toContain("ctrl+o to expand");
|
||||
});
|
||||
|
||||
it("drops the hidden-lines footer once expanded", () => {
|
||||
const component = makeComponent();
|
||||
component.setExpanded(true);
|
||||
const rendered = component.render(120).join("\n");
|
||||
expect(rendered).not.toContain("more lines");
|
||||
expect(rendered).not.toContain("ctrl+o to expand");
|
||||
// Every line is now present, including the previously hidden prefix.
|
||||
expect(rendered).toContain("entry0");
|
||||
expect(rendered).toContain("entry26");
|
||||
});
|
||||
|
||||
it("restores the footer when collapsed again", () => {
|
||||
const component = makeComponent();
|
||||
component.setExpanded(true);
|
||||
component.setExpanded(false);
|
||||
const rendered = component.render(120).join("\n");
|
||||
expect(rendered).toContain("more lines");
|
||||
expect(rendered).toContain("ctrl+o to expand");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user