@gajae-code/tui 0.18.9 → 0.18.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/package.json +3 -3
- package/src/tui.ts +23 -7
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.18.10] - 2026-10-12
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- TUI no longer goes blank after stop/restart cycles: `#hardwareCursorRow` is now properly reset during `stop()` to prevent stale cursor position state from corrupting viewport calculations on the next `start()`.
|
|
10
|
+
|
|
11
|
+
- With `clearOnShrink` enabled, a live block that shrinks after the transcript has scrolled into history no longer leaves blank spacer rows above the pinned composer until the next resize. The contraction now clears the screen and history and replays the frame, so the viewport is filled again and no row appears twice in history.
|
|
12
|
+
|
|
5
13
|
## [0.18.9] - 2026-10-11
|
|
6
14
|
|
|
7
15
|
### Added
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@gajae-code/tui",
|
|
4
|
-
"version": "0.18.
|
|
4
|
+
"version": "0.18.10",
|
|
5
5
|
"description": "Terminal User Interface library with differential rendering for efficient text-based applications",
|
|
6
6
|
"homepage": "https://gajae-code.com",
|
|
7
7
|
"author": "Yeachan-Heo and Gajae Code Contributors",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"fmt": "biome format --write ."
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@gajae-code/natives": "0.18.
|
|
40
|
-
"@gajae-code/utils": "0.18.
|
|
39
|
+
"@gajae-code/natives": "0.18.10",
|
|
40
|
+
"@gajae-code/utils": "0.18.10",
|
|
41
41
|
"lru-cache": "11.3.6",
|
|
42
42
|
"marked": "18.0.6"
|
|
43
43
|
},
|
package/src/tui.ts
CHANGED
|
@@ -1152,6 +1152,7 @@ export class TUI extends Container {
|
|
|
1152
1152
|
#fullRedrawCount = 0;
|
|
1153
1153
|
#stopped = false;
|
|
1154
1154
|
#terminalUnavailable = false;
|
|
1155
|
+
#restartNeedsClear = false; // Set when stop() resets viewport state
|
|
1155
1156
|
#bottomPinnedComponent: Component | null = null;
|
|
1156
1157
|
#pendingTerminalCleanup: Array<{ payload: string; onDelivered?: () => void }> = [];
|
|
1157
1158
|
#mouseSelectionStart: MouseSelectionPoint | null = null;
|
|
@@ -1432,6 +1433,11 @@ export class TUI extends Container {
|
|
|
1432
1433
|
this.#clearOnShrink = enabled;
|
|
1433
1434
|
}
|
|
1434
1435
|
|
|
1436
|
+
/** Overlays rely on padded rows, so contraction replays only without them. */
|
|
1437
|
+
#clearOnShrinkReplays(): boolean {
|
|
1438
|
+
return this.#clearOnShrink && this.overlayStack.length === 0;
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1435
1441
|
setFocus(component: Component | null): void {
|
|
1436
1442
|
// Clear focused flag on old component
|
|
1437
1443
|
if (isFocusable(this.#focusedComponent)) {
|
|
@@ -2981,6 +2987,12 @@ export class TUI extends Container {
|
|
|
2981
2987
|
this.#lineEmitWidthCache.clear();
|
|
2982
2988
|
this.#previousWidth = 0;
|
|
2983
2989
|
this.#previousHeight = 0;
|
|
2990
|
+
this.#cursorRow = 0;
|
|
2991
|
+
this.#hardwareCursorRow = 0;
|
|
2992
|
+
this.#viewportTopRow = 0;
|
|
2993
|
+
this.#maxLinesRendered = 0;
|
|
2994
|
+
// Mark that the next initial render needs to clear the screen after terminal reset
|
|
2995
|
+
this.#restartNeedsClear = true;
|
|
2984
2996
|
this.#forcedRenderPreviousWidth = 0;
|
|
2985
2997
|
this.#forcedRenderPreviousHeight = 0;
|
|
2986
2998
|
this.#transcriptRebuildPending = false;
|
|
@@ -5268,7 +5280,10 @@ export class TUI extends Container {
|
|
|
5268
5280
|
if (hasStickySuffix && height > 0 && this.#manualViewportTop === undefined) {
|
|
5269
5281
|
// Rebuilds start at their new transcript frontier. Forced redraws use the
|
|
5270
5282
|
// captured rendered dimensions rather than their -1 invalidation sentinels.
|
|
5283
|
+
// clearOnShrink replays the whole frame on contraction instead; spacer rows
|
|
5284
|
+
// would otherwise stay on screen as a blank gap above the pinned component.
|
|
5271
5285
|
const preserveLiveFrontier =
|
|
5286
|
+
!this.#clearOnShrinkReplays() &&
|
|
5272
5287
|
!transcriptIdentityReplaced &&
|
|
5273
5288
|
!transcriptRebuildPending &&
|
|
5274
5289
|
frontierPreviousWidth === width &&
|
|
@@ -5788,9 +5803,12 @@ export class TUI extends Container {
|
|
|
5788
5803
|
return;
|
|
5789
5804
|
}
|
|
5790
5805
|
// First render - just output everything without clearing (assumes clean screen)
|
|
5806
|
+
// unless we're restarting after a stop() which leaves stale content
|
|
5791
5807
|
if (initialRender) {
|
|
5792
5808
|
logRedraw("first render");
|
|
5793
|
-
|
|
5809
|
+
const shouldClear = this.#restartNeedsClear;
|
|
5810
|
+
this.#restartNeedsClear = false;
|
|
5811
|
+
fullRender(shouldClear, "first render");
|
|
5794
5812
|
return;
|
|
5795
5813
|
}
|
|
5796
5814
|
|
|
@@ -5848,13 +5866,11 @@ export class TUI extends Container {
|
|
|
5848
5866
|
// Content shrunk below the previous render and no overlays - re-render to clear empty rows
|
|
5849
5867
|
// (overlays need the padding, so only do this when no overlays are active)
|
|
5850
5868
|
// Configurable via setClearOnShrink() or GJC_CLEAR_ON_SHRINK=0 env var
|
|
5851
|
-
|
|
5869
|
+
// Erase native scrollback too: scrolled-off rows cannot be pulled back into the
|
|
5870
|
+
// viewport, and repainting them on screen would duplicate them in history.
|
|
5871
|
+
if (this.#clearOnShrinkReplays() && newLines.length < this.#previousLines.length) {
|
|
5852
5872
|
logRedraw(`clearOnShrink (prev=${this.#previousLines.length}, new=${newLines.length})`);
|
|
5853
|
-
|
|
5854
|
-
viewportRepaint(`clearOnShrink (prev=${this.#previousLines.length}, new=${newLines.length})`);
|
|
5855
|
-
} else {
|
|
5856
|
-
fullRender(true, "clearOnShrink");
|
|
5857
|
-
}
|
|
5873
|
+
fullRender(true, "clearOnShrink", true);
|
|
5858
5874
|
return;
|
|
5859
5875
|
}
|
|
5860
5876
|
|