@ashx-j/lunr-tui 0.2.0 → 0.2.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/components/box.d.ts +5 -1
- package/dist/components/box.d.ts.map +1 -1
- package/dist/components/box.js +20 -4
- package/dist/components/box.js.map +1 -1
- package/dist/tui.d.ts +8 -0
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +69 -14
- package/dist/tui.js.map +1 -1
- package/package.json +1 -1
package/dist/tui.js
CHANGED
|
@@ -146,6 +146,11 @@ export class TUI extends Container {
|
|
|
146
146
|
chatScrollOffset = 0;
|
|
147
147
|
lastChatViewportHeight = 1;
|
|
148
148
|
lastChatScrollMax = 0;
|
|
149
|
+
chatLaidOut = false;
|
|
150
|
+
chatUsesGutter = false;
|
|
151
|
+
/** Bumped on non-scroll `requestRender` so offset-only paints can reuse chat layout. */
|
|
152
|
+
contentEpoch = 0;
|
|
153
|
+
chatLayoutCache;
|
|
149
154
|
alternateScreen = false;
|
|
150
155
|
alternateScreenActive = false;
|
|
151
156
|
mouseTrackingActive = false;
|
|
@@ -192,6 +197,9 @@ export class TUI extends Container {
|
|
|
192
197
|
*/
|
|
193
198
|
pinFrom(component) {
|
|
194
199
|
this.pinComponent = component;
|
|
200
|
+
this.chatLayoutCache = undefined;
|
|
201
|
+
this.chatUsesGutter = false;
|
|
202
|
+
this.chatLaidOut = false;
|
|
195
203
|
if (!component) {
|
|
196
204
|
this.chatScrollOffset = 0;
|
|
197
205
|
this.lastChatViewportHeight = Math.max(1, this.terminal.rows);
|
|
@@ -207,16 +215,20 @@ export class TUI extends Container {
|
|
|
207
215
|
/** `0` follows the latest chat. Larger values scroll up into history. */
|
|
208
216
|
setChatScroll(offset) {
|
|
209
217
|
const next = Number.isFinite(offset) ? Math.max(0, Math.floor(offset)) : 0;
|
|
210
|
-
this.
|
|
211
|
-
|
|
212
|
-
this.render(this.terminal.columns);
|
|
213
|
-
}
|
|
214
|
-
else {
|
|
218
|
+
if (this.getPinIndex() < 0) {
|
|
219
|
+
const changed = this.chatScrollOffset !== 0 || this.lastChatScrollMax !== 0;
|
|
215
220
|
this.chatScrollOffset = 0;
|
|
216
221
|
this.lastChatScrollMax = 0;
|
|
222
|
+
if (changed && this.started)
|
|
223
|
+
this.requestRender();
|
|
224
|
+
return;
|
|
217
225
|
}
|
|
226
|
+
const clamped = this.chatLaidOut ? Math.min(next, this.lastChatScrollMax) : next;
|
|
227
|
+
if (clamped === this.chatScrollOffset)
|
|
228
|
+
return;
|
|
229
|
+
this.chatScrollOffset = clamped;
|
|
218
230
|
if (this.started)
|
|
219
|
-
this.
|
|
231
|
+
this.requestRenderFromScroll();
|
|
220
232
|
}
|
|
221
233
|
/** Positive delta scrolls up (older). Negative scrolls toward the latest. */
|
|
222
234
|
scrollChat(deltaLines) {
|
|
@@ -424,6 +436,9 @@ export class TUI extends Container {
|
|
|
424
436
|
if (pinIndex < 0) {
|
|
425
437
|
this.chatHitRegions = [];
|
|
426
438
|
this.chatScrollbar = undefined;
|
|
439
|
+
this.chatLayoutCache = undefined;
|
|
440
|
+
this.chatUsesGutter = false;
|
|
441
|
+
this.chatLaidOut = false;
|
|
427
442
|
return super.render(width);
|
|
428
443
|
}
|
|
429
444
|
const rows = Math.max(1, this.terminal.rows);
|
|
@@ -435,15 +450,44 @@ export class TUI extends Container {
|
|
|
435
450
|
}
|
|
436
451
|
const viewH = Math.max(minView, rows - dockLines.length);
|
|
437
452
|
this.lastChatViewportHeight = viewH;
|
|
438
|
-
this.
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
if (
|
|
453
|
+
this.chatLaidOut = true;
|
|
454
|
+
let chatWidth = this.chatUsesGutter ? Math.max(1, width - 1) : width;
|
|
455
|
+
let scrollLines;
|
|
456
|
+
let fromCache = false;
|
|
457
|
+
const cache = this.chatLayoutCache;
|
|
458
|
+
if (cache && cache.epoch === this.contentEpoch && cache.chatWidth === chatWidth) {
|
|
459
|
+
scrollLines = cache.scrollLines;
|
|
460
|
+
this.chatHitRegions = this.copyHitRegions(cache.hitRegionsUnshifted);
|
|
461
|
+
fromCache = true;
|
|
462
|
+
}
|
|
463
|
+
else {
|
|
444
464
|
this.chatHitRegions = [];
|
|
445
465
|
scrollLines = this.collectChildLines(0, pinIndex, chatWidth);
|
|
446
466
|
}
|
|
467
|
+
if (this.chatUsesGutter) {
|
|
468
|
+
if (scrollLines.length <= viewH) {
|
|
469
|
+
this.chatUsesGutter = false;
|
|
470
|
+
chatWidth = width;
|
|
471
|
+
this.chatHitRegions = [];
|
|
472
|
+
scrollLines = this.collectChildLines(0, pinIndex, chatWidth);
|
|
473
|
+
fromCache = false;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
else if (scrollLines.length > viewH) {
|
|
477
|
+
this.chatUsesGutter = true;
|
|
478
|
+
chatWidth = Math.max(1, width - 1);
|
|
479
|
+
this.chatHitRegions = [];
|
|
480
|
+
scrollLines = this.collectChildLines(0, pinIndex, chatWidth);
|
|
481
|
+
fromCache = false;
|
|
482
|
+
}
|
|
483
|
+
if (!fromCache) {
|
|
484
|
+
this.chatLayoutCache = {
|
|
485
|
+
epoch: this.contentEpoch,
|
|
486
|
+
chatWidth,
|
|
487
|
+
scrollLines,
|
|
488
|
+
hitRegionsUnshifted: this.copyHitRegions(this.chatHitRegions),
|
|
489
|
+
};
|
|
490
|
+
}
|
|
447
491
|
let chatSlice;
|
|
448
492
|
let start = 0;
|
|
449
493
|
if (scrollLines.length <= viewH) {
|
|
@@ -451,7 +495,7 @@ export class TUI extends Container {
|
|
|
451
495
|
this.chatScrollOffset = 0;
|
|
452
496
|
this.lastChatScrollMax = 0;
|
|
453
497
|
this.chatScrollbar = undefined;
|
|
454
|
-
chatSlice = scrollLines;
|
|
498
|
+
chatSlice = scrollLines.slice();
|
|
455
499
|
}
|
|
456
500
|
else {
|
|
457
501
|
this.lastChatScrollMax = scrollLines.length - viewH;
|
|
@@ -480,15 +524,19 @@ export class TUI extends Container {
|
|
|
480
524
|
if (this.selection) {
|
|
481
525
|
const lo = Math.min(this.selection.anchorY, this.selection.focusY);
|
|
482
526
|
const hi = Math.max(this.selection.anchorY, this.selection.focusY);
|
|
527
|
+
const highlightWidth = this.chatUsesGutter ? chatWidth : width;
|
|
483
528
|
for (let y = lo; y <= hi; y++) {
|
|
484
529
|
const idx = y - 1;
|
|
485
530
|
if (idx < 0 || idx >= chatSlice.length)
|
|
486
531
|
continue;
|
|
487
|
-
chatSlice[idx] = applySelectionHighlight(chatSlice[idx] ?? "",
|
|
532
|
+
chatSlice[idx] = applySelectionHighlight(chatSlice[idx] ?? "", highlightWidth);
|
|
488
533
|
}
|
|
489
534
|
}
|
|
490
535
|
return [...chatSlice, ...dockLines];
|
|
491
536
|
}
|
|
537
|
+
copyHitRegions(regions) {
|
|
538
|
+
return regions.map((region) => ({ y0: region.y0, y1: region.y1, lines: region.lines }));
|
|
539
|
+
}
|
|
492
540
|
shiftHitRegions(delta) {
|
|
493
541
|
for (const region of this.chatHitRegions) {
|
|
494
542
|
region.y0 += delta;
|
|
@@ -723,6 +771,13 @@ export class TUI extends Container {
|
|
|
723
771
|
this.terminal.stop();
|
|
724
772
|
}
|
|
725
773
|
requestRender(force = false) {
|
|
774
|
+
this.contentEpoch++;
|
|
775
|
+
this.queueRender(force);
|
|
776
|
+
}
|
|
777
|
+
requestRenderFromScroll() {
|
|
778
|
+
this.queueRender(false);
|
|
779
|
+
}
|
|
780
|
+
queueRender(force) {
|
|
726
781
|
if (force) {
|
|
727
782
|
this.previousLines = [];
|
|
728
783
|
this.previousWidth = -1; // -1 triggers widthChanged, forcing a full clear
|