@f5xc-salesdemos/pi-tui 14.4.0 → 14.5.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@f5xc-salesdemos/pi-tui",
4
- "version": "14.4.0",
4
+ "version": "14.5.0",
5
5
  "description": "Terminal User Interface library with differential rendering for efficient text-based applications",
6
6
  "homepage": "https://github.com/f5xc-salesdemos/xcsh",
7
7
  "author": "Can Boluk",
@@ -32,13 +32,13 @@
32
32
  "check": "biome check . && bun run check:types",
33
33
  "check:types": "tsgo -p tsconfig.json --noEmit",
34
34
  "lint": "biome lint .",
35
- "test": "bun test test/*.test.ts",
35
+ "test": "bun test --preload ./test/preload.ts test/*.test.ts",
36
36
  "fix": "biome check --write --unsafe .",
37
37
  "fmt": "biome format --write ."
38
38
  },
39
39
  "dependencies": {
40
- "@f5xc-salesdemos/pi-natives": "14.4.0",
41
- "@f5xc-salesdemos/pi-utils": "14.4.0",
40
+ "@f5xc-salesdemos/pi-natives": "14.5.0",
41
+ "@f5xc-salesdemos/pi-utils": "14.5.0",
42
42
  "marked": "^17.0"
43
43
  },
44
44
  "devDependencies": {
@@ -421,7 +421,10 @@ export class Editor implements Component, Focusable {
421
421
  getTopBorderAvailableWidth(terminalWidth: number): number {
422
422
  const paddingX = this.#getEditorPaddingX();
423
423
  const borderWidth = this.#getHorizontalChromeWidth(paddingX);
424
- return Math.max(0, terminalWidth - borderWidth * 2);
424
+ // When status content is present: left corner loses 1 dash, frame is 1 char narrower (gutter)
425
+ const topLeftWidth = this.#topBorderContent ? Math.max(1, borderWidth - 1) : borderWidth;
426
+ const gutter = this.#topBorderContent ? 1 : 0;
427
+ return Math.max(0, terminalWidth - gutter - topLeftWidth - borderWidth);
425
428
  }
426
429
 
427
430
  /**
@@ -676,18 +679,22 @@ export class Editor implements Component, Focusable {
676
679
  }
677
680
 
678
681
  render(width: number): string[] {
682
+ // When powerline status bar is present, reserve 1-char trailing gutter to match zsh
683
+ const effectiveWidth = this.#topBorderContent ? width - 1 : width;
679
684
  const paddingX = this.#getEditorPaddingX();
680
685
  const borderVisible = this.#borderVisible;
681
- const promptGutter = this.#getPromptGutter(width, paddingX);
682
- const contentAreaWidth = this.#getContentWidth(width, paddingX);
683
- const layoutWidth = this.#getLayoutWidth(width, paddingX);
686
+ const promptGutter = this.#getPromptGutter(effectiveWidth, paddingX);
687
+ const contentAreaWidth = this.#getContentWidth(effectiveWidth, paddingX);
688
+ const layoutWidth = this.#getLayoutWidth(effectiveWidth, paddingX);
684
689
  this.#lastLayoutWidth = layoutWidth;
685
690
 
686
691
  // Box-drawing characters for rounded corners
687
692
  const box = this.#theme.symbols.boxRound;
688
693
  const borderWidth = this.#getHorizontalChromeWidth(paddingX);
689
- const topLeft = this.borderColor(`${box.topLeft}${box.horizontal.repeat(paddingX)}`);
690
- const topRight = this.borderColor(`${box.horizontal.repeat(paddingX)}${box.topRight}`);
694
+ const topPad = this.#topBorderContent ? Math.max(0, paddingX - 1) : paddingX;
695
+ const topLeft = this.borderColor(`${box.topLeft}${box.horizontal.repeat(topPad)}`);
696
+ const topRightPad = this.#topBorderContent ? paddingX : paddingX;
697
+ const topRight = this.borderColor(`${box.horizontal.repeat(topRightPad)}${box.topRight}`);
691
698
  const bottomLeft = this.borderColor(`${box.bottomLeft}${box.horizontal}${padding(Math.max(0, paddingX - 1))}`);
692
699
  const horizontal = this.borderColor(box.horizontal);
693
700
 
@@ -700,8 +707,12 @@ export class Editor implements Component, Focusable {
700
707
  const result: string[] = [];
701
708
 
702
709
  if (borderVisible) {
703
- // Render top border: ╭─ [status content] ────────────────╮
704
- const topFillWidth = Math.max(0, width - borderWidth * 2);
710
+ // Render top border: [status content]───────────────── ──╮
711
+ // When status content is present, topLeft has no padding (just ╭)
712
+ // but topRight still has paddingX dashes (──╮)
713
+ const topLeftWidth = this.#topBorderContent ? Math.max(1, borderWidth - 1) : borderWidth;
714
+ const topRightWidth = borderWidth;
715
+ const topFillWidth = Math.max(0, effectiveWidth - topLeftWidth - topRightWidth);
705
716
  if (this.#topBorderContent) {
706
717
  const { content, width: statusWidth } = this.#topBorderContent;
707
718
  if (statusWidth <= topFillWidth) {
@@ -883,7 +894,7 @@ export class Editor implements Component, Focusable {
883
894
 
884
895
  // Add autocomplete list if active
885
896
  if (this.#autocompleteState && this.#autocompleteList) {
886
- const autocompleteResult = this.#autocompleteList.render(width);
897
+ const autocompleteResult = this.#autocompleteList.render(effectiveWidth);
887
898
  result.push(...autocompleteResult);
888
899
  }
889
900
 
package/src/tui.ts CHANGED
@@ -385,7 +385,7 @@ export class TUI extends Container {
385
385
  for (const overlay of this.overlayStack) overlay.component.invalidate?.();
386
386
  }
387
387
 
388
- start(): void {
388
+ start(clearScreen = true): void {
389
389
  this.#stopped = false;
390
390
  this.terminal.start(
391
391
  data => this.#handleInput(data),
@@ -394,7 +394,7 @@ export class TUI extends Container {
394
394
  this.terminal.hideCursor();
395
395
  this.#querySixelSupport();
396
396
  this.#queryCellSize();
397
- this.requestRender(true);
397
+ this.requestRender(clearScreen);
398
398
  }
399
399
 
400
400
  addInputListener(listener: InputListener): () => void {