@textui/core 0.3.0 → 0.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/dist/app/app.d.ts CHANGED
@@ -54,6 +54,8 @@ export declare class App implements TextUIApp {
54
54
  private frameScheduled;
55
55
  private frameTimer;
56
56
  private running_;
57
+ /** What `start` acquired, so `suspend` can put the same thing back. */
58
+ private session;
57
59
  private disposed;
58
60
  private themeId;
59
61
  private shellId;
@@ -105,6 +107,23 @@ export declare class App implements TextUIApp {
105
107
  activeShell(): string;
106
108
  setCapabilityOverrides(overrides: CapabilityOverrides): void;
107
109
  start(): Promise<void>;
110
+ /**
111
+ * Hand the terminal to something else, and take it back.
112
+ *
113
+ * For a program that draws for itself - an editor, a pager, a shell. The
114
+ * session is released, so the alt screen is left, raw mode is off and the
115
+ * child inherits a terminal in the state it expects; then it is acquired
116
+ * again exactly as it was.
117
+ *
118
+ * The frame buffer is invalidated on the way back rather than merely
119
+ * redrawn. The renderer writes the difference between what it painted last
120
+ * and what it paints now, and after another program has been on the screen
121
+ * that difference is against something no longer there - so a plain redraw
122
+ * puts back only the cells this application happened to change.
123
+ *
124
+ * `run` rejecting still gives the terminal back.
125
+ */
126
+ suspend<T>(run: () => Promise<T>): Promise<T>;
108
127
  stop(): Promise<void>;
109
128
  dispose(): void;
110
129
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/app/app.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/app/app.ts"],"names":[],"mappings":"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"}
package/dist/app/app.js CHANGED
@@ -70,6 +70,8 @@ export class App {
70
70
  frameScheduled = false;
71
71
  frameTimer = null;
72
72
  running_ = false;
73
+ /** What `start` acquired, so `suspend` can put the same thing back. */
74
+ session = null;
73
75
  disposed = false;
74
76
  themeId;
75
77
  shellId;
@@ -307,7 +309,10 @@ export class App {
307
309
  this.setTheme(shellTheme);
308
310
  }
309
311
  const caps = this.terminal.capabilities();
310
- await this.terminal.acquire({
312
+ // Kept, because `suspend` has to put back exactly what was taken: a
313
+ // session re-acquired from defaults would come back without the mouse, or
314
+ // with an alt screen the caller had asked not to have.
315
+ this.session = {
311
316
  managed: true,
312
317
  altScreen: true,
313
318
  hideCursor: true,
@@ -317,7 +322,8 @@ export class App {
317
322
  focusEvents: caps.focusEvents,
318
323
  enhancedKeys: caps.kittyKeyboard,
319
324
  ...this.options.session,
320
- });
325
+ };
326
+ await this.terminal.acquire(this.session);
321
327
  // After `acquire`, never before: with no session there is nothing to put
322
328
  // the shape back, so an early call is dropped rather than leaked.
323
329
  this.applyCursorShape();
@@ -327,6 +333,36 @@ export class App {
327
333
  this.publishEnvironment();
328
334
  this.renderFrame();
329
335
  }
336
+ /**
337
+ * Hand the terminal to something else, and take it back.
338
+ *
339
+ * For a program that draws for itself - an editor, a pager, a shell. The
340
+ * session is released, so the alt screen is left, raw mode is off and the
341
+ * child inherits a terminal in the state it expects; then it is acquired
342
+ * again exactly as it was.
343
+ *
344
+ * The frame buffer is invalidated on the way back rather than merely
345
+ * redrawn. The renderer writes the difference between what it painted last
346
+ * and what it paints now, and after another program has been on the screen
347
+ * that difference is against something no longer there - so a plain redraw
348
+ * puts back only the cells this application happened to change.
349
+ *
350
+ * `run` rejecting still gives the terminal back.
351
+ */
352
+ async suspend(run) {
353
+ if (!this.running_ || !this.session)
354
+ return run();
355
+ await this.terminal.release();
356
+ try {
357
+ return await run();
358
+ }
359
+ finally {
360
+ await this.terminal.acquire(this.session);
361
+ this.applyCursorShape();
362
+ this.buffer_.invalidate();
363
+ this.renderFrame();
364
+ }
365
+ }
330
366
  async stop() {
331
367
  if (!this.running_)
332
368
  return;
@@ -727,7 +763,21 @@ export class App {
727
763
  if (position)
728
764
  return;
729
765
  const cursor = instance.props.cursor;
730
- if (!cursor || !instance.box)
766
+ /*
767
+ * Absent, not falsy.
768
+ *
769
+ * `cursor` is a column, and column 0 is a real one - it is where the
770
+ * caret sits in an empty field, and where it sits at the start of any
771
+ * field. `!cursor` treated that as "no caret here", so a text input
772
+ * published no cursor position at all until its first character was
773
+ * typed: the terminal cursor stayed hidden, and the only thing marking
774
+ * the focused control was its border colour.
775
+ *
776
+ * `true` still means "here, at offset 0", which is what the `typeof`
777
+ * below is for - so this rejects the three ways of saying nothing and
778
+ * nothing else.
779
+ */
780
+ if (cursor === undefined || cursor === null || cursor === false || !instance.box)
731
781
  return;
732
782
  const id = typeof instance.props.id === 'string' ? instance.props.id : instance.id;
733
783
  if (id !== focused && `${instance.id}:focus` !== focused)
@@ -846,6 +896,32 @@ export class App {
846
896
  catch (err) {
847
897
  this.handleError(err, `input:${event.type}`);
848
898
  }
899
+ /*
900
+ * Pointer motion and the wheel are streams, and only where they got to
901
+ * means anything.
902
+ *
903
+ * A terminal reports every cell the pointer crosses and every notch of the
904
+ * wheel, and one read can carry twenty of them - so rendering per event
905
+ * lays out and paints the whole tree twenty times to draw one gesture. The
906
+ * cost is the size of the tree, which is why it is invisible on a short
907
+ * screen and, on a long transcript, is the thing being dragged trailing
908
+ * seconds behind the pointer and a wheel that goes on scrolling after the
909
+ * hand has stopped. That second one is the tell: it is not momentum, it is
910
+ * a backlog of events still being drawn one frame each.
911
+ *
912
+ * Only the drawing is coalesced. Every event is still dispatched, so the
913
+ * notches still add up and the pointer still ends where it ended; what
914
+ * they share is the one frame `handleMouse` asked for, at the animation
915
+ * ceiling rather than at whatever rate the terminal felt like reporting.
916
+ *
917
+ * Keys are the opposite and stay synchronous: every one of them is a
918
+ * separate thing a person did, and a handler closes over the props from
919
+ * its last render, so typing "ab" without a frame in between makes the
920
+ * handler for "b" see the state from before "a".
921
+ */
922
+ if (event.type === 'mouse'
923
+ && (event.action === 'move' || event.action === 'drag' || event.action === 'wheel'))
924
+ return;
849
925
  if (this.running_ && this.isDirty())
850
926
  this.renderFrame();
851
927
  }
@@ -1,4 +1,4 @@
1
- import type { Style, StyleInput } from '../types/style.js';
1
+ import type { Style, StyleColor, StyleInput } from '../types/style.js';
2
2
  import type { SemanticRole } from '../types/component-registry.js';
3
3
  import type { KeyEvent, MouseEvent } from '../types/input.js';
4
4
  import type { PaintSurface, RenderContext } from '../types/render.js';
@@ -94,6 +94,19 @@ export interface TextProps extends BaseProps {
94
94
  /** Where to cut when the text does not fit. */
95
95
  truncate?: 'end' | 'start' | 'middle' | false;
96
96
  ellipsis?: string;
97
+ /**
98
+ * Text to pick out wherever it appears, case-insensitively.
99
+ *
100
+ * For search: the caller passes what it is looking for and the rows are
101
+ * coloured where they hold it. It is applied after wrapping and truncation,
102
+ * to the text as drawn - so nothing about how a paragraph is broken into
103
+ * lines has to change to mark a hit in it, and a match split across a wrap
104
+ * is simply not on either row to colour.
105
+ */
106
+ match?: string;
107
+ /** The match's colours. Accent on its own foreground by default. */
108
+ matchFg?: StyleColor;
109
+ matchBg?: StyleColor;
97
110
  }
98
111
  export interface CanvasProps extends BaseProps {
99
112
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"intrinsics.d.ts","sourceRoot":"","sources":["../../src/jsx/intrinsics.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"intrinsics.d.ts","sourceRoot":"","sources":["../../src/jsx/intrinsics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD;;;;;;;GAOG;AACH,MAAM,WAAW,SAAU,SAAQ,KAAK;IACtC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,UAAU,CAAC;IAEnB,wEAAwE;IACxE,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,iEAAiE;IACjE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,4CAA4C;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB,KAAK,CAAC,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,GAAG,IAAI,CAAC;IACxC,OAAO,CAAC,IAAI,IAAI,CAAC;IACjB,MAAM,CAAC,IAAI,IAAI,CAAC;IAChB;;;;;;;;OAQG;IACH,OAAO,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,GAAG,IAAI,CAAC;IAC5C,iFAAiF;IACjF,OAAO,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC,CAAC;IACjD;;;;;;;OAOG;IACH,OAAO,CAAC,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IAElC,iEAAiE;IACjE,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,0EAA0E;IAC1E,WAAW,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACtD;AAED,MAAM,WAAW,QAAS,SAAQ,SAAS;IACzC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IACzC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IAC1C,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,SAAU,SAAQ,SAAS;IAC1C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB;AAED,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C;;;OAGG;IACH,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,aAAa,GAAG,IAAI,CAAC;IACtD,sDAAsD;IACtD,SAAS,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACjD;AAED,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
@@ -69,7 +69,22 @@ export declare class Buffer implements CellBuffer {
69
69
  cellChanged(i: number): boolean;
70
70
  dirtyRows(): number[];
71
71
  commit(): void;
72
- /** Force the next diff to repaint everything. After a resize or a redraw. */
72
+ /**
73
+ * Force the next diff to repaint everything. After a resize or a redraw.
74
+ *
75
+ * Both halves, and the second one is the one that was missing. Clearing
76
+ * `committed` makes `dirtyRows` return every row, but `diffFrame` still
77
+ * skips each cell that matches the previous frame - and a blank cell in the
78
+ * new frame matched the reset previous frame exactly, so it was never
79
+ * written. Under a theme with an opaque canvas nothing showed, because every
80
+ * cell carries a background colour and therefore differs anyway. Under a
81
+ * theme with a transparent one the blanks are default-on-default, and the
82
+ * terminal kept whatever the old layout had left in them: a resize scattered
83
+ * the previous frame across the new one and it never cleared.
84
+ *
85
+ * So the previous frame is filled with a character no cell can hold, which
86
+ * is a comparison that cannot come out equal.
87
+ */
73
88
  invalidate(): void;
74
89
  toText(rect?: Rect): string;
75
90
  }
@@ -1 +1 @@
1
- {"version":3,"file":"buffer.d.ts","sourceRoot":"","sources":["../../src/render/buffer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAA4B,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAExE,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,WAAW,CAAC;IAChB,EAAE,EAAE,WAAW,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B;AAGD,kEAAkE;AAClE,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC;;;;;;GAMG;AACH,qBAAa,MAAO,YAAW,UAAU;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IAEf,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,EAAE,EAAE,UAAU,CAAC;IACf,EAAE,EAAE,UAAU,CAAC;IACf,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;IAE9B,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,SAAS,CAAyB;IAC1C,OAAO,CAAC,SAAS,CAAS;gBAEd,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAkBzC,8EAA8E;IAC9E,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAa3C;;;;;;;OAOG;IACH,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAYtD,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI;IAO3C,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM;IAInC,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO;IAIvC;;;;OAIG;IACH,GAAG,CACD,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,IAAI,EAAE,MAAM,EACZ,EAAE,GAAE,WAA2B,EAC/B,EAAE,GAAE,WAA2B,EAC/B,KAAK,SAAI,EACT,IAAI,CAAC,EAAE,MAAM,GACZ,IAAI;IAqDP;;;;;;;;OAQG;IACH,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,GAAE,WAA2B,GAAG,IAAI;IAmBzD,OAAO,CAAC,QAAQ;IAShB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAoC3C,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO;IAU/B,SAAS,IAAI,MAAM,EAAE;IAiBrB,MAAM,IAAI,IAAI;IASd,6EAA6E;IAC7E,UAAU,IAAI,IAAI;IAIlB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,MAAM;CAgB5B;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAElE"}
1
+ {"version":3,"file":"buffer.d.ts","sourceRoot":"","sources":["../../src/render/buffer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAA4B,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAYxE,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,WAAW,CAAC;IAChB,EAAE,EAAE,WAAW,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B;AAGD,kEAAkE;AAClE,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC;;;;;;GAMG;AACH,qBAAa,MAAO,YAAW,UAAU;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IAEf,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,EAAE,EAAE,UAAU,CAAC;IACf,EAAE,EAAE,UAAU,CAAC;IACf,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;IAE9B,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,SAAS,CAAyB;IAC1C,OAAO,CAAC,SAAS,CAAS;gBAEd,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAkBzC,8EAA8E;IAC9E,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAa3C;;;;;;;OAOG;IACH,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAYtD,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI;IAO3C,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM;IAInC,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO;IAIvC;;;;OAIG;IACH,GAAG,CACD,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,IAAI,EAAE,MAAM,EACZ,EAAE,GAAE,WAA2B,EAC/B,EAAE,GAAE,WAA2B,EAC/B,KAAK,SAAI,EACT,IAAI,CAAC,EAAE,MAAM,GACZ,IAAI;IAqDP;;;;;;;;OAQG;IACH,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,GAAE,WAA2B,GAAG,IAAI;IAmBzD,OAAO,CAAC,QAAQ;IAShB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAoC3C,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO;IAU/B,SAAS,IAAI,MAAM,EAAE;IAiBrB,MAAM,IAAI,IAAI;IASd;;;;;;;;;;;;;;;OAeG;IACH,UAAU,IAAI,IAAI;IAKlB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,MAAM;CAgB5B;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAElE"}
@@ -1,4 +1,13 @@
1
1
  import { COLOR_DEFAULT, packColor } from './color.js';
2
+ /**
3
+ * A character no cell can hold, for the previous frame when it must not match.
4
+ *
5
+ * `put` refuses the empty string and every real glyph is one the terminal can
6
+ * print, so NUL is a value that never arrives from a render and never leaves
7
+ * one: `diffFrame` reads `chars`, never `prevChars`, so this is only ever a
8
+ * comparison and is never written out.
9
+ */
10
+ const NEVER = '\u0000';
2
11
  import { graphemeWidth } from '../util/text.js';
3
12
  /** Internal cell flags, kept out of the public attrs bitfield. */
4
13
  export const FLAG_CONTINUATION = 1;
@@ -200,7 +209,7 @@ export class Buffer {
200
209
  this.links = next.links;
201
210
  // A resize invalidates the previous frame entirely.
202
211
  const n = width * height;
203
- this.prevChars = new Array(n).fill(' ');
212
+ this.prevChars = new Array(n).fill(NEVER);
204
213
  this.prevFg = new Int32Array(n).fill(COLOR_DEFAULT);
205
214
  this.prevBg = new Int32Array(n).fill(COLOR_DEFAULT);
206
215
  this.prevAttrs = new Uint16Array(n);
@@ -238,9 +247,25 @@ export class Buffer {
238
247
  this.prevLinks = this.links.slice();
239
248
  this.committed = true;
240
249
  }
241
- /** Force the next diff to repaint everything. After a resize or a redraw. */
250
+ /**
251
+ * Force the next diff to repaint everything. After a resize or a redraw.
252
+ *
253
+ * Both halves, and the second one is the one that was missing. Clearing
254
+ * `committed` makes `dirtyRows` return every row, but `diffFrame` still
255
+ * skips each cell that matches the previous frame - and a blank cell in the
256
+ * new frame matched the reset previous frame exactly, so it was never
257
+ * written. Under a theme with an opaque canvas nothing showed, because every
258
+ * cell carries a background colour and therefore differs anyway. Under a
259
+ * theme with a transparent one the blanks are default-on-default, and the
260
+ * terminal kept whatever the old layout had left in them: a resize scattered
261
+ * the previous frame across the new one and it never cleared.
262
+ *
263
+ * So the previous frame is filled with a character no cell can hold, which
264
+ * is a comparison that cannot come out equal.
265
+ */
242
266
  invalidate() {
243
267
  this.committed = false;
268
+ this.prevChars.fill(NEVER);
244
269
  }
245
270
  toText(rect) {
246
271
  const r = rect ?? { x: 0, y: 0, width: this.width, height: this.height };
@@ -34,6 +34,24 @@ export interface LayoutBox {
34
34
  content: Rect;
35
35
  /** Content larger than `content`, when overflow is 'scroll'. */
36
36
  scrollSize?: Size;
37
+ /**
38
+ * Frame and gaps, worked out once for this box.
39
+ *
40
+ * Neither depends on the space being offered - they are the box's own
41
+ * margin, border, padding and gap - and the box is measured about four
42
+ * times a frame at different bounds, each of which was rebuilding both and
43
+ * allocating three objects to do it. Same lifetime as `measured` below, and
44
+ * for the same reason: a layout box is rebuilt from the instance tree every
45
+ * frame, so nothing here can go stale.
46
+ */
47
+ frame?: {
48
+ margin: Edges;
49
+ inset: Edges;
50
+ };
51
+ gaps?: {
52
+ main: number;
53
+ cross: number;
54
+ };
37
55
  /**
38
56
  * The last answer `measureBox` gave for this box, and what it was asked.
39
57
  *
@@ -1 +1 @@
1
- {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/render/layout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,KAAK,EAA6B,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAGpF;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,KAAK,CAAC;IACb,yEAAyE;IACzE,WAAW,EAAE,KAAK,CAAC;IACnB,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,yEAAyE;IACzE,OAAO,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACpD,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,IAAI,EAAE,IAAI,CAAC;IACX,8DAA8D;IAC9D,OAAO,EAAE,IAAI,CAAC;IACd,gEAAgE;IAChE,UAAU,CAAC,EAAE,IAAI,CAAC;IAElB;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,IAAI,CAAA;KAAE,CAAC;CACjD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,KAAK,CAuB9D;AA0CD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,GAAG,GAAG,GAAG,QAAQ,CAElE;AAkED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAsJ/E;AA0FD,6EAA6E;AAC7E,wBAAgB,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,GAAG,IAAI,CAE5D"}
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/render/layout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,KAAK,EAA6B,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAGpF;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,KAAK,CAAC;IACb,yEAAyE;IACzE,WAAW,EAAE,KAAK,CAAC;IACnB,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,yEAAyE;IACzE,OAAO,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACpD,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,IAAI,EAAE,IAAI,CAAC;IACX,8DAA8D;IAC9D,OAAO,EAAE,IAAI,CAAC;IACd,gEAAgE;IAChE,UAAU,CAAC,EAAE,IAAI,CAAC;IAElB;;;;;;;;;OASG;IACH,KAAK,CAAC,EAAE;QAAE,MAAM,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC;IACxC,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAEvC;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,IAAI,CAAA;KAAE,CAAC;CACjD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,KAAK,CAuB9D;AA0CD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,GAAG,GAAG,GAAG,QAAQ,CAElE;AA0ED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAsJ/E;AA0FD,6EAA6E;AAC7E,wBAAgB,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,GAAG,IAAI,CAE5D"}
@@ -82,11 +82,16 @@ function mainOverflow(box) {
82
82
  * that sets both reads the same either way round.
83
83
  */
84
84
  function gapsOf(box) {
85
+ const seen = box.gaps;
86
+ if (seen !== undefined)
87
+ return seen;
85
88
  const vertical = box.style.rowGap ?? box.style.gap ?? 0;
86
89
  const horizontal = box.style.columnGap ?? box.style.gap ?? 0;
87
- return isColumn(box)
90
+ const gaps = isColumn(box)
88
91
  ? { main: vertical, cross: horizontal }
89
92
  : { main: horizontal, cross: vertical };
93
+ box.gaps = gaps;
94
+ return gaps;
90
95
  }
91
96
  /**
92
97
  * Cut a run of main-axis sizes into lines that each fit `limit`.
@@ -115,10 +120,13 @@ function splitLines(mains, gap, limit) {
115
120
  }
116
121
  /** Space this box consumes outside its content: margin, border, padding. */
117
122
  function frameOf(box) {
123
+ const seen = box.frame;
124
+ if (seen !== undefined)
125
+ return seen;
118
126
  const margin = resolveEdges(box.style.margin);
119
127
  const padding = resolveEdges(box.style.padding);
120
128
  const b = box.borderEdges;
121
- return {
129
+ const frame = {
122
130
  margin,
123
131
  inset: {
124
132
  top: b.top + padding.top,
@@ -127,6 +135,8 @@ function frameOf(box) {
127
135
  left: b.left + padding.left,
128
136
  },
129
137
  };
138
+ box.frame = frame;
139
+ return frame;
130
140
  }
131
141
  /**
132
142
  * Intrinsic size, ignoring grow. Containers ask their children; leaves are
@@ -178,7 +188,7 @@ export function measureBox(box, availW, availH) {
178
188
  continue;
179
189
  count++;
180
190
  const m = measureBox(child, innerAvailW, innerAvailH);
181
- const cm = resolveEdges(child.style.margin);
191
+ const cm = frameOf(child).margin;
182
192
  mains.push(column ? m.height + edgeV(cm) : m.width + edgeH(cm));
183
193
  crosses.push(column ? m.width + edgeH(cm) : m.height + edgeV(cm));
184
194
  }
@@ -222,7 +232,7 @@ export function measureBox(box, availW, availH) {
222
232
  continue;
223
233
  const flex = Math.max(0, child.style.flex ?? 0);
224
234
  if (flex > 0) {
225
- const cm = resolveEdges(child.style.margin);
235
+ const cm = frameOf(child).margin;
226
236
  const share = Math.max(0, Math.floor((room * flex) / totalFlex) - edgeH(cm));
227
237
  const m = measureBox(child, share, innerAvailH);
228
238
  crosses[index] = m.height + edgeV(cm);
@@ -439,7 +449,7 @@ function layoutWrapped(box, flow) {
439
449
  const mains = [];
440
450
  const crosses = [];
441
451
  for (const child of flow) {
442
- const margin = resolveEdges(child.style.margin);
452
+ const margin = frameOf(child).margin;
443
453
  const basis = child.style.basis ?? (column ? child.style.height : child.style.width);
444
454
  const fixed = resolveDimension(basis, mainAvail);
445
455
  const m = measureBox(child, column ? crossAvail : mainAvail, column ? mainAvail : crossAvail);
@@ -480,7 +490,7 @@ function layoutLine(box, flow, content, scrollOffset) {
480
490
  const crossAvail = column ? content.width : content.height;
481
491
  const gapTotal = flow.length > 1 ? gap * (flow.length - 1) : 0;
482
492
  // 1. base sizes
483
- const margins = flow.map((c) => resolveEdges(c.style.margin));
493
+ const margins = flow.map((c) => frameOf(c).margin);
484
494
  const bases = [];
485
495
  for (let i = 0; i < flow.length; i++) {
486
496
  const child = flow[i];
@@ -1 +1 @@
1
- {"version":3,"file":"paint.d.ts","sourceRoot":"","sources":["../../src/runtime/paint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAEjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAGrE,OAAO,KAAK,EAA2B,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAiC,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAMrF,OAAO,EAES,KAAK,gBAAgB,EACpC,MAAM,YAAY,CAAC;AAwHpB,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,aAAa,EACpB,YAAY,EAAE,oBAAoB,EAClC,KAAK,GAAE,gBAAiC,GACvC,aAAa,CAiBf;AAID,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,aAAa,CAAC;IACrB,YAAY,EAAE,oBAAoB,CAAC;IACnC,kEAAkE;IAClE,OAAO,CAAC,QAAQ,EAAE,QAAQ,GAAG,gBAAgB,CAAC;CAC/C;AAeD,6DAA6D;AAC7D,UAAU,SAAS;IACjB,EAAE,EAAE,WAAW,CAAC;IAChB,EAAE,EAAE,WAAW,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AA4DD,6EAA6E;AAC7E,wBAAgB,UAAU,CACxB,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,QAAQ,EACb,SAAS,GAAE,SAA0B,GACpC,SAAS,EAAE,CAwDb;AA4DD,wBAAgB,SAAS,CACvB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,IAAI,GACT,IAAI,CA4FN"}
1
+ {"version":3,"file":"paint.d.ts","sourceRoot":"","sources":["../../src/runtime/paint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAEjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAGrE,OAAO,KAAK,EAA2B,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAiC,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAMrF,OAAO,EAES,KAAK,gBAAgB,EACpC,MAAM,YAAY,CAAC;AAuIpB,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,aAAa,EACpB,YAAY,EAAE,oBAAoB,EAClC,KAAK,GAAE,gBAAiC,GACvC,aAAa,CAiBf;AAID,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,aAAa,CAAC;IACrB,YAAY,EAAE,oBAAoB,CAAC;IACnC,kEAAkE;IAClE,OAAO,CAAC,QAAQ,EAAE,QAAQ,GAAG,gBAAgB,CAAC;CAC/C;AAeD,6DAA6D;AAC7D,UAAU,SAAS;IACjB,EAAE,EAAE,WAAW,CAAC;IAChB,EAAE,EAAE,WAAW,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AA4DD,6EAA6E;AAC7E,wBAAgB,UAAU,CACxB,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,QAAQ,EACb,SAAS,GAAE,SAA0B,GACpC,SAAS,EAAE,CAwDb;AAsFD,wBAAgB,SAAS,CACvB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,IAAI,GACT,IAAI,CA4FN"}
@@ -2,7 +2,7 @@ import { ATTR_DIM } from '../types/cells.js';
2
2
  import { overflowOn } from '../render/layout.js';
3
3
  import { COLOR_DEFAULT, mix, packColor } from '../render/color.js';
4
4
  import { rectIntersect } from '../types/geometry.js';
5
- import { graphemes, graphemeWidth, sanitize, stringWidth, truncate, truncateSideOf, wrapModeOf, wrapText, } from '../util/text.js';
5
+ import { graphemes, graphemeWidth, isAscii, sanitize, stringWidth, truncate, truncateSideOf, wrapModeOf, wrapText, } from '../util/text.js';
6
6
  import { attrsFromStyle, NO_INTERACTION, packStyleColor, resolveBorder, resolveStyle, } from './style.js';
7
7
  /**
8
8
  * Painting.
@@ -62,8 +62,22 @@ class Surface {
62
62
  const attrs = style?.attrs ?? 0;
63
63
  const link = style?.link;
64
64
  const oy = this.rect.y + y;
65
+ const clean = sanitize(text);
66
+ // Plain ASCII is one cell per character and needs none of the clustering
67
+ // machinery - and it is nearly every string a terminal ever draws. The
68
+ // general path allocates an array of one-character strings for the whole
69
+ // run before writing any of it.
65
70
  let cx = x;
66
- for (const g of graphemes(sanitize(text))) {
71
+ if (isAscii(clean)) {
72
+ for (let i = 0; i < clean.length; i++) {
73
+ const ax = this.rect.x + cx;
74
+ if (this.visible(ax, oy))
75
+ this.buffer.put(ax, oy, clean[i], fg, bg, attrs, link);
76
+ cx += 1;
77
+ }
78
+ return cx - x;
79
+ }
80
+ for (const g of graphemes(clean)) {
67
81
  const w = graphemeWidth(g);
68
82
  if (w === 0)
69
83
  continue;
@@ -246,31 +260,56 @@ function textContent(instance) {
246
260
  function oneLine(text) {
247
261
  return text.includes('\n') ? text.split('\n').join(' ') : text;
248
262
  }
263
+ /**
264
+ * Text measurements already taken.
265
+ *
266
+ * A measurement is a pure function of the string, how it wraps and the width
267
+ * it is offered - and a layout asks for the same three several times in a
268
+ * frame, then the next frame asks for all of them again. The text in a
269
+ * transcript does not change; only the one line somebody is typing does.
270
+ */
271
+ const measurements = new Map();
272
+ const MEASURE_CACHE = 4096;
249
273
  function textMeasure(instance, style) {
250
274
  return (maxWidth) => {
251
275
  const text = sanitize(textContent(instance));
252
276
  if (text === '')
253
277
  return { width: 0, height: text.includes('\n') ? 1 : 1 };
254
278
  const wrap = style.wrap ?? 'none';
279
+ const key = `${wrap}\u0000${String(maxWidth)}\u0000${text}`;
280
+ const seen = measurements.get(key);
281
+ if (seen !== undefined)
282
+ return seen;
255
283
  // A truncating text is one row, always. It still asks for the width it
256
284
  // would like - a box sizing itself around it gets the whole string when
257
285
  // there is room, and only cuts when there is not.
258
- if (truncateSideOf(wrap) !== undefined) {
259
- return { width: stringWidth(oneLine(text)), height: 1 };
260
- }
261
- if (wrap === 'none') {
262
- const lines = text.split('\n');
263
- return {
264
- width: Math.max(...lines.map(stringWidth)),
265
- height: lines.length,
266
- };
267
- }
268
- const limit = Number.isFinite(maxWidth) && maxWidth > 0 ? maxWidth : stringWidth(text);
269
- const lines = wrapText(text, limit, wrapModeOf(wrap));
286
+ const size = measure(text, wrap, maxWidth);
287
+ if (measurements.size >= MEASURE_CACHE)
288
+ measurements.clear();
289
+ measurements.set(key, size);
290
+ return size;
291
+ };
292
+ }
293
+ /** The measurement itself, with nothing remembered. */
294
+ function measure(text, wrap, maxWidth) {
295
+ // A truncating text is one row, always. It still asks for the width it
296
+ // would like - a box sizing itself around it gets the whole string when
297
+ // there is room, and only cuts when there is not.
298
+ if (truncateSideOf(wrap) !== undefined) {
299
+ return { width: stringWidth(oneLine(text)), height: 1 };
300
+ }
301
+ if (wrap === 'none') {
302
+ const lines = text.split('\n');
270
303
  return {
271
- width: Math.min(limit, Math.max(0, ...lines.map(stringWidth))),
272
- height: Math.max(1, lines.length),
304
+ width: Math.max(...lines.map(stringWidth)),
305
+ height: lines.length,
273
306
  };
307
+ }
308
+ const limit = Number.isFinite(maxWidth) && maxWidth > 0 ? maxWidth : stringWidth(text);
309
+ const lines = wrapText(text, limit, wrapModeOf(wrap));
310
+ return {
311
+ width: Math.min(limit, Math.max(0, ...lines.map(stringWidth))),
312
+ height: Math.max(1, lines.length),
274
313
  };
275
314
  }
276
315
  // ------------------------------------------------------------------- paint
@@ -512,6 +551,22 @@ function paintText(surface, box, visual, instance, env) {
512
551
  attrs: visual.attrs,
513
552
  link: typeof instance.props.link === 'string' ? instance.props.link : undefined,
514
553
  };
554
+ /*
555
+ * Text to pick out of this one, and how to draw it where it appears.
556
+ *
557
+ * Search highlighting is a paint-time concern and not a content one: the
558
+ * caller passes the same string it is searching for and the wrapped rows
559
+ * are coloured where they hold it, so nothing about how the text is broken
560
+ * into lines has to change to mark a hit in it.
561
+ */
562
+ const match = typeof instance.props.match === 'string'
563
+ ? instance.props.match.toLowerCase()
564
+ : '';
565
+ const matchStyle = {
566
+ ...style,
567
+ fg: colorOf(packStyleColor(instance.props.matchFg ?? 'onAccent', env.theme)),
568
+ bg: colorOf(packStyleColor(instance.props.matchBg ?? 'accent', env.theme)),
569
+ };
515
570
  const wrap = visual.style.wrap ?? 'none';
516
571
  const align = visual.style.textAlign ?? 'left';
517
572
  // The ellipsis is a glyph like any other: on an ascii terminal it is '...'.
@@ -539,8 +594,40 @@ function paintText(surface, box, visual, instance, env) {
539
594
  const offset = align === 'center' ? Math.max(0, Math.floor((area.width - w) / 2))
540
595
  : align === 'right' ? Math.max(0, area.width - w)
541
596
  : 0;
542
- surface.text(area.x + offset, area.y + i, line, style);
597
+ if (match === '') {
598
+ surface.text(area.x + offset, area.y + i, line, style);
599
+ continue;
600
+ }
601
+ for (const run of split(line, match)) {
602
+ surface.text(area.x + offset + stringWidth(line.slice(0, run.at)), area.y + i, run.text, run.hit ? matchStyle : style);
603
+ }
604
+ }
605
+ }
606
+ /**
607
+ * A line cut into the parts that match a needle and the parts that do not.
608
+ *
609
+ * Case-insensitive, and over the line as it will be drawn - so a match broken
610
+ * across a wrap is two lines with no match in either, which is the honest
611
+ * answer: there is nothing on one row to put a colour on.
612
+ */
613
+ function split(line, needle) {
614
+ const runs = [];
615
+ const haystack = line.toLowerCase();
616
+ let from = 0;
617
+ for (;;) {
618
+ const at = haystack.indexOf(needle, from);
619
+ if (at === -1)
620
+ break;
621
+ if (at > from)
622
+ runs.push({ at: from, text: line.slice(from, at), hit: false });
623
+ runs.push({ at, text: line.slice(at, at + needle.length), hit: true });
624
+ from = at + needle.length;
543
625
  }
626
+ if (runs.length === 0)
627
+ return [{ at: 0, text: line, hit: false }];
628
+ if (from < line.length)
629
+ runs.push({ at: from, text: line.slice(from), hit: false });
630
+ return runs;
544
631
  }
545
632
  /**
546
633
  * The escape hatch. A canvas draws in its own coordinate space starting at
@@ -62,6 +62,17 @@ export interface TextUIApp extends Disposable {
62
62
  start(): Promise<void>;
63
63
  /** Release exactly what was acquired, then stop. */
64
64
  stop(): Promise<void>;
65
+ /**
66
+ * Hand the terminal to something that draws for itself, and take it back.
67
+ *
68
+ * For an editor, a pager, a shell. The session is released so the child
69
+ * inherits a terminal in the state it expects - no alt screen, no raw mode -
70
+ * and is acquired again afterwards exactly as it was, with the frame
71
+ * repainted whole rather than diffed against what another program left.
72
+ *
73
+ * `run` rejecting still gives the terminal back.
74
+ */
75
+ suspend<T>(run: () => Promise<T>): Promise<T>;
65
76
  /** Force a frame now, outside the scheduler. Tests and screenshots use it. */
66
77
  flush(): void;
67
78
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/types/app.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/types/app.ts"],"names":[],"mappings":"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"}