@oh-my-pi/pi-tui 15.5.10 → 15.5.11
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.
|
@@ -31,6 +31,10 @@ export declare class Editor implements Component, Focusable {
|
|
|
31
31
|
cursorOverride: string | undefined;
|
|
32
32
|
/** Display width of the cursorOverride glyph (needed because override may contain ANSI escapes). */
|
|
33
33
|
cursorOverrideWidth: number | undefined;
|
|
34
|
+
/** Optional hook that styles displayed input text with zero-width ANSI escapes.
|
|
35
|
+
* MUST preserve visible width (may only add SGR codes, never glyphs). Applied per
|
|
36
|
+
* layout line to the user-text segments — never to the cursor glyph or inline hint. */
|
|
37
|
+
decorateText: ((text: string) => string) | undefined;
|
|
34
38
|
borderColor: (str: string) => string;
|
|
35
39
|
onAutocompleteUpdate?: () => void;
|
|
36
40
|
onSubmit?: (text: string) => void;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-tui",
|
|
4
|
-
"version": "15.5.
|
|
4
|
+
"version": "15.5.11",
|
|
5
5
|
"description": "Terminal User Interface library with differential rendering for efficient text-based applications",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"fmt": "biome format --write ."
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@oh-my-pi/pi-natives": "15.5.
|
|
41
|
-
"@oh-my-pi/pi-utils": "15.5.
|
|
40
|
+
"@oh-my-pi/pi-natives": "15.5.11",
|
|
41
|
+
"@oh-my-pi/pi-utils": "15.5.11",
|
|
42
42
|
"lru-cache": "11.3.6",
|
|
43
43
|
"marked": "^18.0.3"
|
|
44
44
|
},
|
package/src/components/editor.ts
CHANGED
|
@@ -325,6 +325,10 @@ export class Editor implements Component, Focusable {
|
|
|
325
325
|
cursorOverride: string | undefined;
|
|
326
326
|
/** Display width of the cursorOverride glyph (needed because override may contain ANSI escapes). */
|
|
327
327
|
cursorOverrideWidth: number | undefined;
|
|
328
|
+
/** Optional hook that styles displayed input text with zero-width ANSI escapes.
|
|
329
|
+
* MUST preserve visible width (may only add SGR codes, never glyphs). Applied per
|
|
330
|
+
* layout line to the user-text segments — never to the cursor glyph or inline hint. */
|
|
331
|
+
decorateText: ((text: string) => string) | undefined;
|
|
328
332
|
#promptGutter: string | undefined;
|
|
329
333
|
|
|
330
334
|
// Store last layout width for cursor navigation
|
|
@@ -583,6 +587,13 @@ export class Editor implements Component, Focusable {
|
|
|
583
587
|
return Math.max(1, this.#maxHeight - verticalChrome);
|
|
584
588
|
}
|
|
585
589
|
|
|
590
|
+
/** Apply the optional input decorator to a plain (ANSI-free) text segment.
|
|
591
|
+
* Decoration only adds zero-width SGR codes, so visible width is unchanged. */
|
|
592
|
+
#decorate(text: string): string {
|
|
593
|
+
const decorate = this.decorateText;
|
|
594
|
+
return decorate !== undefined && text.length > 0 ? decorate(text) : text;
|
|
595
|
+
}
|
|
596
|
+
|
|
586
597
|
#getStyledInputCursor(): { text: string; width: number } {
|
|
587
598
|
const cursorChar = this.#theme.symbols.inputCursor;
|
|
588
599
|
return { text: `\x1b[5m${cursorChar}\x1b[0m`, width: visibleWidth(cursorChar) };
|
|
@@ -732,6 +743,7 @@ export class Editor implements Component, Focusable {
|
|
|
732
743
|
let displayText = layoutLine.text;
|
|
733
744
|
let displayWidth = visibleWidth(layoutLine.text);
|
|
734
745
|
let cursorInPadding = false;
|
|
746
|
+
let decorated = false;
|
|
735
747
|
const showPromptGutter = promptGutter !== undefined && visibleIndex === 0;
|
|
736
748
|
const gutterText =
|
|
737
749
|
promptGutter === undefined ? "" : showPromptGutter ? promptGutter.firstLine : promptGutter.continuation;
|
|
@@ -809,7 +821,11 @@ export class Editor implements Component, Focusable {
|
|
|
809
821
|
const firstGrapheme = afterGraphemes[0]?.segment || "";
|
|
810
822
|
const restAfter = after.slice(firstGrapheme.length);
|
|
811
823
|
const cursor = `\x1b[7m${firstGrapheme}\x1b[0m`;
|
|
812
|
-
|
|
824
|
+
// Decorate the plain text on each side of the cursor glyph. The reverse-video
|
|
825
|
+
// reset (\x1b[0m) ends in "m" (a word char), so a boundary match on restAfter
|
|
826
|
+
// would fail in the whole-line fallback below — decorate the segments here.
|
|
827
|
+
displayText = this.#decorate(before) + marker + cursor + this.#decorate(restAfter);
|
|
828
|
+
decorated = true;
|
|
813
829
|
// displayWidth stays the same - we're replacing, not adding
|
|
814
830
|
} else if (this.cursorOverride) {
|
|
815
831
|
// Cursor override replaces the normal end-of-text cursor glyph
|
|
@@ -856,6 +872,13 @@ export class Editor implements Component, Focusable {
|
|
|
856
872
|
}
|
|
857
873
|
}
|
|
858
874
|
|
|
875
|
+
// No cursor on this line, or a branch that left the user text intact: decorate the
|
|
876
|
+
// whole line. CURSOR_MARKER and cursor glyphs begin with ESC, so word boundaries
|
|
877
|
+
// around a decorated keyword stay intact when matched against the assembled line.
|
|
878
|
+
if (!decorated) {
|
|
879
|
+
displayText = this.#decorate(displayText);
|
|
880
|
+
}
|
|
881
|
+
|
|
859
882
|
const linePad = padding(Math.max(0, lineContentWidth - displayWidth));
|
|
860
883
|
|
|
861
884
|
if (!borderVisible) {
|