@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.
Files changed (2) hide show
  1. package/package.json +3 -3
  2. 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.1",
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.1",
56
- "@oh-my-pi/pi-utils": "12.11.1",
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 = renderCursorRow;
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
- if (this.#previousLines.length > newLines.length) {
971
- let buffer = "\x1b[?2026h\x1b7";
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";
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\x1b7"; // Begin synchronized output + save cursor
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
- buffer += "\x1b8\x1b[?2026l"; // Restore cursor, then end synchronized output
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.#positionHardwareCursor(cursorPos, newLines.length);
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);