@oh-my-pi/pi-tui 12.11.1 → 12.11.2
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/package.json +3 -3
- package/src/tui.ts +34 -32
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-tui",
|
|
3
|
-
"version": "12.11.
|
|
3
|
+
"version": "12.11.2",
|
|
4
4
|
"description": "Terminal User Interface library with differential rendering for efficient text-based applications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
"bun": ">=1.3.7"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@oh-my-pi/pi-natives": "12.11.
|
|
56
|
-
"@oh-my-pi/pi-utils": "12.11.
|
|
55
|
+
"@oh-my-pi/pi-natives": "12.11.2",
|
|
56
|
+
"@oh-my-pi/pi-utils": "12.11.2",
|
|
57
57
|
"@types/mime-types": "^3.0.1",
|
|
58
58
|
"chalk": "^5.6.2",
|
|
59
59
|
"marked": "^17.0.2",
|
package/src/tui.ts
CHANGED
|
@@ -886,11 +886,12 @@ export class TUI extends Container {
|
|
|
886
886
|
buffer += newLines[i];
|
|
887
887
|
}
|
|
888
888
|
const renderCursorRow = Math.max(0, newLines.length - 1);
|
|
889
|
+
const cursorUpdate = this.#buildHardwareCursorSequence(cursorPos, newLines.length, renderCursorRow);
|
|
890
|
+
buffer += cursorUpdate.sequence;
|
|
889
891
|
buffer += "\x1b[?2026l"; // End synchronized output
|
|
890
892
|
this.terminal.write(buffer);
|
|
891
893
|
this.#cursorRow = renderCursorRow;
|
|
892
|
-
this.#hardwareCursorRow =
|
|
893
|
-
this.#positionHardwareCursor(cursorPos, newLines.length);
|
|
894
|
+
this.#hardwareCursorRow = cursorUpdate.row;
|
|
894
895
|
// Reset max lines when clearing, otherwise track growth
|
|
895
896
|
if (clear) {
|
|
896
897
|
this.#maxLinesRendered = newLines.length;
|
|
@@ -967,37 +968,36 @@ export class TUI extends Container {
|
|
|
967
968
|
// All changes are in deleted lines (nothing to render, just clear)
|
|
968
969
|
if (firstChanged >= newLines.length) {
|
|
969
970
|
const targetRow = Math.max(0, newLines.length - 1);
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
if (i < extraLines - 1) buffer += "\x1b[1B";
|
|
989
|
-
}
|
|
990
|
-
if (extraLines > 0) {
|
|
991
|
-
buffer += `\x1b[${extraLines}A`;
|
|
992
|
-
}
|
|
993
|
-
buffer += "\x1b8\x1b[?2026l";
|
|
994
|
-
this.terminal.write(buffer);
|
|
995
|
-
// Cursor restored to pre-render position by \x1b8; keep tracked row unchanged here.
|
|
971
|
+
let buffer = "\x1b[?2026h";
|
|
972
|
+
const lineDiff = computeLineDiff(targetRow);
|
|
973
|
+
if (lineDiff > 0) buffer += `\x1b[${lineDiff}B`;
|
|
974
|
+
else if (lineDiff < 0) buffer += `\x1b[${-lineDiff}A`;
|
|
975
|
+
buffer += "\r";
|
|
976
|
+
// Clear extra lines without scrolling
|
|
977
|
+
const extraLines = this.#previousLines.length - newLines.length;
|
|
978
|
+
if (extraLines > height) {
|
|
979
|
+
logRedraw(`extraLines > height (${extraLines} > ${height})`);
|
|
980
|
+
fullRender(true);
|
|
981
|
+
return;
|
|
982
|
+
}
|
|
983
|
+
if (extraLines > 0) {
|
|
984
|
+
buffer += "\x1b[1B";
|
|
985
|
+
}
|
|
986
|
+
for (let i = 0; i < extraLines; i++) {
|
|
987
|
+
buffer += "\r\x1b[2K";
|
|
988
|
+
if (i < extraLines - 1) buffer += "\x1b[1B";
|
|
996
989
|
}
|
|
990
|
+
if (extraLines > 0) {
|
|
991
|
+
buffer += `\x1b[${extraLines}A`;
|
|
992
|
+
}
|
|
993
|
+
const cursorUpdate = this.#buildHardwareCursorSequence(cursorPos, newLines.length, targetRow);
|
|
994
|
+
buffer += cursorUpdate.sequence;
|
|
995
|
+
buffer += "\x1b[?2026l";
|
|
996
|
+
this.terminal.write(buffer);
|
|
997
|
+
this.#hardwareCursorRow = cursorUpdate.row;
|
|
997
998
|
this.#cursorRow = targetRow;
|
|
998
999
|
this.#previousLines = newLines;
|
|
999
1000
|
this.#previousWidth = width;
|
|
1000
|
-
this.#positionHardwareCursor(cursorPos, newLines.length);
|
|
1001
1001
|
this.#previousViewportTop = Math.max(0, this.#maxLinesRendered - height);
|
|
1002
1002
|
return;
|
|
1003
1003
|
}
|
|
@@ -1014,7 +1014,7 @@ export class TUI extends Container {
|
|
|
1014
1014
|
|
|
1015
1015
|
// Render from first changed line to end
|
|
1016
1016
|
// Build buffer with all updates wrapped in synchronized output
|
|
1017
|
-
let buffer = "\x1b[?2026h
|
|
1017
|
+
let buffer = "\x1b[?2026h"; // Begin synchronized output
|
|
1018
1018
|
const prevViewportBottom = prevViewportTop + height - 1;
|
|
1019
1019
|
const moveTargetRow = appendStart ? firstChanged - 1 : firstChanged;
|
|
1020
1020
|
if (moveTargetRow > prevViewportBottom) {
|
|
@@ -1098,7 +1098,9 @@ export class TUI extends Container {
|
|
|
1098
1098
|
buffer += `\x1b[${extraLines}A`;
|
|
1099
1099
|
}
|
|
1100
1100
|
|
|
1101
|
-
|
|
1101
|
+
const cursorUpdate = this.#buildHardwareCursorSequence(cursorPos, newLines.length, finalCursorRow);
|
|
1102
|
+
buffer += cursorUpdate.sequence;
|
|
1103
|
+
buffer += "\x1b[?2026l"; // End synchronized output
|
|
1102
1104
|
if (process.env.PI_TUI_DEBUG === "1") {
|
|
1103
1105
|
const debugDir = "/tmp/tui";
|
|
1104
1106
|
fs.mkdirSync(debugDir, { recursive: true });
|
|
@@ -1132,7 +1134,7 @@ export class TUI extends Container {
|
|
|
1132
1134
|
// cursorRow tracks end of content (for viewport calculation)
|
|
1133
1135
|
// hardwareCursorRow tracks actual terminal cursor position (for movement)
|
|
1134
1136
|
this.#cursorRow = Math.max(0, newLines.length - 1);
|
|
1135
|
-
this.#
|
|
1137
|
+
this.#hardwareCursorRow = cursorUpdate.row;
|
|
1136
1138
|
// Track terminal's working area (grows but doesn't shrink unless cleared)
|
|
1137
1139
|
this.#maxLinesRendered = Math.max(this.#maxLinesRendered, newLines.length);
|
|
1138
1140
|
this.#previousViewportTop = Math.max(0, this.#maxLinesRendered - height);
|