@vincemakes/kiso-tui 0.16.0 → 0.16.1
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/dist/compositor.js +52 -7
- package/dist/editor.js +6 -0
- package/package.json +2 -2
package/dist/compositor.js
CHANGED
|
@@ -1473,7 +1473,11 @@ export class Body {
|
|
|
1473
1473
|
// frame, and the PTY gates that wait on the boot stream feel
|
|
1474
1474
|
// it; inside the frame it is four sequences and no new event.
|
|
1475
1475
|
this.#needsReset = false;
|
|
1476
|
-
|
|
1476
|
+
// REL-0161: the reset ESTABLISHES the hidden cursor (?25l) —
|
|
1477
|
+
// the steady state for the session's whole life. It repairs a
|
|
1478
|
+
// killed predecessor straight into the same state. The visible
|
|
1479
|
+
// cursor comes back exactly once, in editor.exit().
|
|
1480
|
+
out.push("\x1b[r\x1b[?69l\x1b[?7h\x1b[?25l");
|
|
1477
1481
|
// REL-0152-D20 — the mechanism is understood and the obvious fix
|
|
1478
1482
|
// is NOT taken here. See the finding.
|
|
1479
1483
|
//
|
|
@@ -1493,7 +1497,12 @@ export class Body {
|
|
|
1493
1497
|
// for stdin).
|
|
1494
1498
|
}
|
|
1495
1499
|
out.push("\x1b[?7l");
|
|
1496
|
-
|
|
1500
|
+
// REL-0161: ?25l is the STEADY state now, not a frame bracket —
|
|
1501
|
+
// re-asserted at every frame open as self-healing (a subprocess
|
|
1502
|
+
// or stray output that showed the cursor is corrected here), and
|
|
1503
|
+
// never paired with a ?25h. Sync (2026) still brackets the frame
|
|
1504
|
+
// where the terminal understands it.
|
|
1505
|
+
out.push(this.#conservative ? "\x1b[?25l" : "\x1b[?2026h\x1b[?25l");
|
|
1497
1506
|
// A8: the bottom-anchored window (the model's last H rows) shifts
|
|
1498
1507
|
// DOWN when the live region SHRINKS — the done-fold, the fold-hold
|
|
1499
1508
|
// release at the terminal event. The steady path's scroll syncs
|
|
@@ -1517,7 +1526,12 @@ export class Body {
|
|
|
1517
1526
|
// with it.
|
|
1518
1527
|
this.#drawFull(out, W, H, liveTop, liveLines, queueRows, menuRows, editor);
|
|
1519
1528
|
this.#fullRedraw = false;
|
|
1520
|
-
|
|
1529
|
+
// REL-0161: the frame close no longer shows the cursor — hidden IS
|
|
1530
|
+
// the steady state (Terminal.app infers "a prompt line" from
|
|
1531
|
+
// bracketed-paste + a visible cursor and decorates it with a Mark;
|
|
1532
|
+
// the composer draws its own cursor cell instead — #inputRowBytes).
|
|
1533
|
+
if (!this.#conservative)
|
|
1534
|
+
out.push("\x1b[?2026l");
|
|
1521
1535
|
out.push("\x1b[?7h"); // REL-0152-D14: autowrap back on for everything outside the frame
|
|
1522
1536
|
this.#inFrame = true;
|
|
1523
1537
|
try {
|
|
@@ -1902,16 +1916,47 @@ export class Body {
|
|
|
1902
1916
|
markerLine += CURSOR_MARKER;
|
|
1903
1917
|
markerCell = w;
|
|
1904
1918
|
}
|
|
1905
|
-
const stripped0 = markerLine.replace(CURSOR_MARKER, "");
|
|
1906
1919
|
if (W < 4) {
|
|
1907
1920
|
// the degenerate screen: the box cannot hold its walls — the
|
|
1908
1921
|
// bare row (the pre-W6 bytes; the fold probe's pass-through
|
|
1909
1922
|
// line still crashes invariant ① downstream, as before)
|
|
1910
|
-
return { stripped:
|
|
1923
|
+
return { stripped: markerLine.replace(CURSOR_MARKER, ""), markerCell };
|
|
1924
|
+
}
|
|
1925
|
+
// REL-0161 — the DRAWN cursor. The hardware cursor is hidden for
|
|
1926
|
+
// the session's life (Terminal.app infers "a prompt line" from
|
|
1927
|
+
// bracketed-paste + a visible cursor and Marks it), so the cell
|
|
1928
|
+
// at the marker renders inverse instead. The hardware cursor
|
|
1929
|
+
// still PARKS at the marker — the IME anchor is its position.
|
|
1930
|
+
const mi = markerLine.indexOf(CURSOR_MARKER);
|
|
1931
|
+
let stripped0;
|
|
1932
|
+
let cursorPad = 0; // 1 when the drawn cursor consumed a pad cell
|
|
1933
|
+
if (mi < 0) {
|
|
1934
|
+
stripped0 = markerLine; // a row that does not own the cursor
|
|
1935
|
+
}
|
|
1936
|
+
else {
|
|
1937
|
+
const before = markerLine.slice(0, mi);
|
|
1938
|
+
const after = markerLine.slice(mi + CURSOR_MARKER.length);
|
|
1939
|
+
if (after.length === 0) {
|
|
1940
|
+
// the cursor rests past the content — an inverse space,
|
|
1941
|
+
// taken OUT of the pad (the walk capped content at W−4,
|
|
1942
|
+
// so the pad is ≥ 1 and the row still totals W)
|
|
1943
|
+
stripped0 = `${before}\x1b[7m \x1b[27m`;
|
|
1944
|
+
cursorPad = 1;
|
|
1945
|
+
}
|
|
1946
|
+
else if (after[0] === "\x1b" || (after.codePointAt(0) >= 0xd800 && after.codePointAt(0) <= 0xdfff)) {
|
|
1947
|
+
// never wrap a sequence, never split a surrogate pair —
|
|
1948
|
+
// the cell keeps its bytes, the parked cursor still marks
|
|
1949
|
+
// the position for the terminal's own affordances
|
|
1950
|
+
stripped0 = before + after;
|
|
1951
|
+
}
|
|
1952
|
+
else {
|
|
1953
|
+
const glyph = String.fromCodePoint(after.codePointAt(0));
|
|
1954
|
+
stripped0 = `${before}\x1b[7m${glyph}\x1b[27m${after.slice(glyph.length)}`;
|
|
1955
|
+
}
|
|
1911
1956
|
}
|
|
1912
1957
|
// the pad completes the row to W — the content stopped at W−4,
|
|
1913
|
-
// so the pad is ≥ 1
|
|
1914
|
-
const padW = W - 3 - w;
|
|
1958
|
+
// so the pad is ≥ 1 (≥ 0 after the drawn cursor consumed one)
|
|
1959
|
+
const padW = W - 3 - w - cursorPad;
|
|
1915
1960
|
return { stripped: `\x1b[2m│ \x1b[0m${stripped0}\x1b[2m${" ".repeat(padW)}│\x1b[0m`, markerCell };
|
|
1916
1961
|
}
|
|
1917
1962
|
/** KC1 §6 — the focus component's input ROWS (N = 1 today's single
|
package/dist/editor.js
CHANGED
|
@@ -748,6 +748,12 @@ export class Editor {
|
|
|
748
748
|
process.stdout.write(MOUSE_OFF);
|
|
749
749
|
this.#mouseOn = false;
|
|
750
750
|
process.stdout.write("\x1b[?2004l"); // bracketed paste OFF
|
|
751
|
+
// REL-0161: the hardware cursor was hidden for the session's whole
|
|
752
|
+
// life (the compositor's entry reset); this is the one place kiso
|
|
753
|
+
// hands the terminal back. kill -9 skips it — the same exposure
|
|
754
|
+
// the reference implementation accepts; the entry repair covers
|
|
755
|
+
// the next kiso, and `reset` covers the shell.
|
|
756
|
+
process.stdout.write("\x1b[?25h");
|
|
751
757
|
process.stdin.setRawMode(false);
|
|
752
758
|
this.#closedResolve();
|
|
753
759
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vincemakes/kiso-tui",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.1",
|
|
4
4
|
"description": "kiso tui \u2014 the pure terminal layer (cell renderer, dock, raw editor, diff, palette). Zero runtime dependencies: input is data, output is bytes.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -35,6 +35,6 @@
|
|
|
35
35
|
},
|
|
36
36
|
"homepage": "https://github.com/vincemakes/kiso/tree/main/packages/tui#readme",
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@vincemakes/kiso-tui-cells": "0.16.
|
|
38
|
+
"@vincemakes/kiso-tui-cells": "0.16.1"
|
|
39
39
|
}
|
|
40
40
|
}
|