@react-x11/components 0.10.0 → 0.11.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.
Files changed (90) hide show
  1. package/dist/code/index.d.ts.map +1 -1
  2. package/dist/code/index.js +25 -24
  3. package/dist/code/index.js.map +1 -1
  4. package/dist/code-language/index.d.ts +1 -1
  5. package/dist/code-language/index.d.ts.map +1 -1
  6. package/dist/code-language/index.js +1 -1
  7. package/dist/code-language/index.js.map +1 -1
  8. package/dist/code-language/runs.d.ts +31 -0
  9. package/dist/code-language/runs.d.ts.map +1 -1
  10. package/dist/code-language/runs.js +105 -0
  11. package/dist/code-language/runs.js.map +1 -1
  12. package/dist/codeblock/index.d.ts +13 -0
  13. package/dist/codeblock/index.d.ts.map +1 -1
  14. package/dist/codeblock/index.js +37 -1
  15. package/dist/codeblock/index.js.map +1 -1
  16. package/dist/html/css/cascade.d.ts +32 -10
  17. package/dist/html/css/cascade.d.ts.map +1 -1
  18. package/dist/html/css/cascade.js +72 -27
  19. package/dist/html/css/cascade.js.map +1 -1
  20. package/dist/html/css/style.d.ts +7 -4
  21. package/dist/html/css/style.d.ts.map +1 -1
  22. package/dist/html/css/style.js +37 -6
  23. package/dist/html/css/style.js.map +1 -1
  24. package/dist/html/css/ua.js +8 -5
  25. package/dist/html/css/ua.js.map +1 -1
  26. package/dist/html/layout/block.d.ts.map +1 -1
  27. package/dist/html/layout/block.js +127 -9
  28. package/dist/html/layout/block.js.map +1 -1
  29. package/dist/html/layout/boxes.d.ts +27 -0
  30. package/dist/html/layout/boxes.d.ts.map +1 -1
  31. package/dist/html/layout/boxes.js +30 -2
  32. package/dist/html/layout/boxes.js.map +1 -1
  33. package/dist/html/layout/inline.d.ts +3 -0
  34. package/dist/html/layout/inline.d.ts.map +1 -1
  35. package/dist/html/layout/inline.js +236 -14
  36. package/dist/html/layout/inline.js.map +1 -1
  37. package/dist/html/node.d.ts.map +1 -1
  38. package/dist/html/node.js +118 -57
  39. package/dist/html/node.js.map +1 -1
  40. package/dist/html/paint.d.ts.map +1 -1
  41. package/dist/html/paint.js +203 -37
  42. package/dist/html/paint.js.map +1 -1
  43. package/dist/html/svg.d.ts.map +1 -1
  44. package/dist/html/svg.js +27 -20
  45. package/dist/html/svg.js.map +1 -1
  46. package/dist/internal/codelines.d.ts +42 -0
  47. package/dist/internal/codelines.d.ts.map +1 -0
  48. package/dist/internal/codelines.js +170 -0
  49. package/dist/internal/codelines.js.map +1 -0
  50. package/dist/markdown/index.d.ts.map +1 -1
  51. package/dist/markdown/index.js +98 -26
  52. package/dist/markdown/index.js.map +1 -1
  53. package/dist/rich-text-editor/index.d.ts.map +1 -1
  54. package/dist/rich-text-editor/index.js +3 -8
  55. package/dist/rich-text-editor/index.js.map +1 -1
  56. package/dist/rich-text-editor/markdown.d.ts.map +1 -1
  57. package/dist/rich-text-editor/markdown.js +30 -1
  58. package/dist/rich-text-editor/markdown.js.map +1 -1
  59. package/dist/rich-text-editor/replace.d.ts +13 -0
  60. package/dist/rich-text-editor/replace.d.ts.map +1 -0
  61. package/dist/rich-text-editor/replace.js +64 -0
  62. package/dist/rich-text-editor/replace.js.map +1 -0
  63. package/dist/terminal-output/index.d.ts.map +1 -1
  64. package/dist/terminal-output/index.js +100 -25
  65. package/dist/terminal-output/index.js.map +1 -1
  66. package/dist/terminal-output/runs.d.ts +4 -1
  67. package/dist/terminal-output/runs.d.ts.map +1 -1
  68. package/dist/terminal-output/runs.js +5 -1
  69. package/dist/terminal-output/runs.js.map +1 -1
  70. package/package.json +1 -1
  71. package/src/code/index.ts +34 -32
  72. package/src/code-language/index.ts +1 -1
  73. package/src/code-language/runs.ts +111 -1
  74. package/src/codeblock/index.ts +48 -1
  75. package/src/html/css/cascade.ts +117 -39
  76. package/src/html/css/style.ts +43 -15
  77. package/src/html/css/ua.ts +8 -5
  78. package/src/html/layout/block.ts +134 -8
  79. package/src/html/layout/boxes.ts +43 -2
  80. package/src/html/layout/inline.ts +257 -13
  81. package/src/html/node.ts +145 -79
  82. package/src/html/paint.ts +236 -45
  83. package/src/html/svg.ts +30 -19
  84. package/src/internal/codelines.ts +200 -0
  85. package/src/markdown/index.ts +145 -26
  86. package/src/rich-text-editor/index.ts +3 -11
  87. package/src/rich-text-editor/markdown.ts +36 -1
  88. package/src/rich-text-editor/replace.ts +85 -0
  89. package/src/terminal-output/index.ts +127 -34
  90. package/src/terminal-output/runs.ts +16 -2
@@ -27,13 +27,26 @@ import { useTheme } from 'react-x11';
27
27
  import { ansiPalette, parseAnsi } from '../ansi/index.js';
28
28
  import { registerRichText, RICHTEXT_ELEMENT, useLinkClicks, useSelectionMenu, } from '../richtext/index.js';
29
29
  import { codeBlockLook, codeBlockStyle, codeTextStyle, } from '../codeblock/index.js';
30
- import { documentRuns } from './runs.js';
30
+ import { linesRuns } from './runs.js';
31
31
  import { hx } from './hx.js';
32
32
  import { useFontPrewarm } from '../internal/prewarm.js';
33
33
  const h = React.createElement;
34
34
  // The shared-module registration, at this component's own module scope — see
35
35
  // the note in `../richtext/node.ts`.
36
36
  registerRichText();
37
+ /**
38
+ * Lines a block of output holds.
39
+ *
40
+ * The output is a column of blocks rather than one element, so an append
41
+ * lays out again the block it lands in and not the whole capture: one
42
+ * `<richtext>` for all of it was laid out whole for every line appended,
43
+ * 0.9 s an append at 20,000 lines. A block keeps its element while its lines
44
+ * are the same objects, which the parser shares from one snapshot to the
45
+ * next. Blocks start at multiples of this in the capture's own numbering,
46
+ * `truncated` counted in, so `maxLines` dropping lines off the top changes
47
+ * only the first block.
48
+ */
49
+ const BLOCK_LINES = 256;
37
50
  function isDocument(source) {
38
51
  return (typeof source === 'object' &&
39
52
  source !== null &&
@@ -128,35 +141,88 @@ export function TerminalOutput(props) {
128
141
  foreground: colors?.foreground ?? look.color,
129
142
  background: colors?.background ?? String(theme.background ?? '#ffffff'),
130
143
  }), [colors, look.color, theme.background]);
131
- const runs = React.useMemo(() => documentRuns(document, { family: look.family, size: look.size }, palette), [document, look.family, look.size, palette]);
132
- const outputProps = {
133
- runs,
134
- style: codeTextStyle(look, wrap),
144
+ // Kept across renders while what a block is drawn with holds.
145
+ const blocks = React.useRef(null);
146
+ if (blocks.current?.look !== look ||
147
+ blocks.current.palette !== palette ||
148
+ blocks.current.wrap !== wrap ||
149
+ blocks.current.lineNumbers !== lineNumbers) {
150
+ blocks.current = { look, palette, wrap, lineNumbers, byIndex: new Map() };
151
+ }
152
+ const byIndex = blocks.current.byIndex;
153
+ const font = { family: look.family, size: look.size };
154
+ const outputStyle = codeTextStyle(look, wrap);
155
+ const gutterStyle = {
156
+ lineHeight: look.lineHeight,
157
+ textAlign: 'right',
135
158
  };
136
- if (!wrap)
137
- outputProps.wrap = false;
138
- const lineCount = document.lines.length;
159
+ // The capture's own numbering: the first line shown is the one after
160
+ // every line `maxLines` has dropped.
161
+ const first = document.truncated;
162
+ const end = first + document.lines.length;
163
+ const outputs = [];
164
+ const gutters = [];
165
+ const kept = new Set();
166
+ for (let start = first - (first % BLOCK_LINES); start < end || outputs.length === 0; start += BLOCK_LINES) {
167
+ const index = start / BLOCK_LINES;
168
+ const from = Math.max(start, first) - first;
169
+ const to = Math.min(start + BLOCK_LINES, end) - first;
170
+ const lines = document.lines.slice(from, to);
171
+ let block = byIndex.get(index);
172
+ if (!block || !sameLines(block.lines, lines)) {
173
+ const outputProps = {
174
+ runs: linesRuns(lines, font, palette),
175
+ style: outputStyle,
176
+ };
177
+ if (!wrap)
178
+ outputProps.wrap = false;
179
+ block = {
180
+ lines,
181
+ output: h(RICHTEXT_ELEMENT, {
182
+ key: index,
183
+ ...outputProps,
184
+ }),
185
+ gutter: lineNumbers
186
+ ? h(RICHTEXT_ELEMENT, {
187
+ key: index,
188
+ // The numbers are chrome, not text: `selectable={false}` keeps
189
+ // them out of a drag and out of the copied text.
190
+ selectable: false,
191
+ runs: lines.map((_, i) => ({
192
+ text: i === lines.length - 1
193
+ ? `${first + from + i + 1}`
194
+ : `${first + from + i + 1}\n`,
195
+ family: look.family,
196
+ size: look.size,
197
+ color: look.dim,
198
+ })),
199
+ wrap: false,
200
+ style: gutterStyle,
201
+ })
202
+ : null,
203
+ };
204
+ byIndex.set(index, block);
205
+ }
206
+ kept.add(index);
207
+ outputs.push(block.output);
208
+ if (block.gutter)
209
+ gutters.push(block.gutter);
210
+ }
211
+ for (const index of byIndex.keys()) {
212
+ if (!kept.has(index))
213
+ byIndex.delete(index);
214
+ }
215
+ // One column of numbers per column of output, block beside block: the
216
+ // same font and line height keep them in register.
139
217
  const gutter = lineNumbers
140
- ? h(RICHTEXT_ELEMENT, {
141
- // One richtext for all the numbers: same font, same line height, so
142
- // it stays in register with the output beside it. `selectable={false}`
143
- // is what keeps it out of a drag and out of the copied text.
144
- selectable: false,
145
- runs: Array.from({ length: lineCount }, (_, i) => ({
146
- text: i === lineCount - 1 ? `${i + 1}` : `${i + 1}\n`,
147
- family: look.family,
148
- size: look.size,
149
- color: look.dim,
150
- })),
151
- wrap: false,
218
+ ? hx('box', {
152
219
  style: {
153
- lineHeight: look.lineHeight,
154
- textAlign: 'right',
155
- minWidth: Math.max(String(lineCount).length, 2) * Math.ceil(look.size * 0.62),
220
+ flexDirection: 'column',
221
+ minWidth: Math.max(String(end).length, 2) * Math.ceil(look.size * 0.62),
156
222
  marginRight: look.padding,
157
223
  flexShrink: 0,
158
224
  },
159
- })
225
+ }, ...gutters)
160
226
  : null;
161
227
  const rootStyle = {
162
228
  ...codeBlockStyle(look),
@@ -179,6 +245,15 @@ export function TerminalOutput(props) {
179
245
  ...menu,
180
246
  ...links,
181
247
  'data-testname': props['data-testname'],
182
- }, gutter, hx('box', { style: { overflow: 'scroll', flexDirection: 'column', flexGrow: 1 } }, h(RICHTEXT_ELEMENT, outputProps)));
248
+ }, gutter, hx('box', { style: { overflow: 'scroll', flexDirection: 'column', flexGrow: 1 } }, ...outputs));
249
+ }
250
+ /** Whether two runs of lines are the same objects, one for one. */
251
+ function sameLines(a, b) {
252
+ if (a.length !== b.length)
253
+ return false;
254
+ for (let i = 0; i < a.length; i++)
255
+ if (a[i] !== b[i])
256
+ return false;
257
+ return true;
183
258
  }
184
259
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/terminal-output/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/terminal-output/index.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { AnsiDocument, AnsiPalette, AnsiSpan } from '../ansi/index.js';
1
+ import type { AnsiDocument, AnsiLine, AnsiPalette, AnsiSpan } from '../ansi/index.js';
2
2
  import type { TextRun } from '../richtext/index.js';
3
3
  /** The font a capture is set in. The palette is separate because it changes
4
4
  * for a different reason — a theme flip rather than a size prop. */
@@ -24,4 +24,7 @@ export declare function spanRun(span: AnsiSpan, font: OutputFont, palette: AnsiP
24
24
  * terminal never drew.
25
25
  */
26
26
  export declare function documentRuns(document: AnsiDocument, font: OutputFont, palette: AnsiPalette): TextRun[];
27
+ /** Some of a document's lines as runs, the way {@link documentRuns} makes
28
+ * all of them: a block of `<TerminalOutput>`'s output. */
29
+ export declare function linesRuns(lines: readonly AnsiLine[], font: OutputFont, palette: AnsiPalette): TextRun[];
27
30
  //# sourceMappingURL=runs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runs.d.ts","sourceRoot":"","sources":["../../src/terminal-output/runs.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD;qEACqE;AACrE,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CACrB,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,WAAW,GACnB,OAAO,CAuBT;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,WAAW,GACnB,OAAO,EAAE,CAYX"}
1
+ {"version":3,"file":"runs.d.ts","sourceRoot":"","sources":["../../src/terminal-output/runs.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,QAAQ,EACT,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD;qEACqE;AACrE,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CACrB,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,WAAW,GACnB,OAAO,CAuBT;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,WAAW,GACnB,OAAO,EAAE,CAEX;AAED;2DAC2D;AAC3D,wBAAgB,SAAS,CACvB,KAAK,EAAE,SAAS,QAAQ,EAAE,EAC1B,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,WAAW,GACnB,OAAO,EAAE,CAWX"}
@@ -50,8 +50,12 @@ export function spanRun(span, font, palette) {
50
50
  * terminal never drew.
51
51
  */
52
52
  export function documentRuns(document, font, palette) {
53
+ return linesRuns(document.lines, font, palette);
54
+ }
55
+ /** Some of a document's lines as runs, the way {@link documentRuns} makes
56
+ * all of them: a block of `<TerminalOutput>`'s output. */
57
+ export function linesRuns(lines, font, palette) {
53
58
  const runs = [];
54
- const { lines } = document;
55
59
  for (let i = 0; i < lines.length; i++) {
56
60
  for (const span of lines[i].spans) {
57
61
  if (span.text)
@@ -1 +1 @@
1
- {"version":3,"file":"runs.js","sourceRoot":"","sources":["../../src/terminal-output/runs.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,4DAA4D;AAC5D,EAAE;AACF,2EAA2E;AAC3E,4EAA4E;AAC5E,kDAAkD;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAWrD;;;;;;;GAOG;AACH,MAAM,UAAU,OAAO,CACrB,IAAc,EACd,IAAgB,EAChB,OAAoB;IAEpB,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACpD,MAAM,GAAG,GAAY;QACnB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,EAAE;KACV,CAAC;IACF,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;QACrB,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC;QACZ,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IACD,IAAI,IAAI,CAAC,IAAI;QAAE,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;IACnC,IAAI,IAAI,CAAC,MAAM;QAAE,GAAG,CAAC,KAAK,GAAG,QAAQ,CAAC;IACtC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,cAAc;YACjC,CAAC,CAAC,iBAAiB,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,cAAc,EAAE,EAAE,OAAO,CAAC,CAAC,EAAE;YAC5D,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC;IACtC,CAAC;IACD,IAAI,IAAI,CAAC,MAAM;QAAE,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC;IACjC,IAAI,IAAI,CAAC,IAAI;QAAE,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IACpC,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAC1B,QAAsB,EACtB,IAAgB,EAChB,OAAoB;IAEpB,MAAM,IAAI,GAAc,EAAE,CAAC;IAC3B,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,CAAC,CAAE,CAAC,KAAK,EAAE,CAAC;YACnC,IAAI,IAAI,CAAC,IAAI;gBAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QACzD,CAAC;QACD,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"runs.js","sourceRoot":"","sources":["../../src/terminal-output/runs.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,4DAA4D;AAC5D,EAAE;AACF,2EAA2E;AAC3E,4EAA4E;AAC5E,kDAAkD;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAgBrD;;;;;;;GAOG;AACH,MAAM,UAAU,OAAO,CACrB,IAAc,EACd,IAAgB,EAChB,OAAoB;IAEpB,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACpD,MAAM,GAAG,GAAY;QACnB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,EAAE;KACV,CAAC;IACF,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;QACrB,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC;QACZ,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IACD,IAAI,IAAI,CAAC,IAAI;QAAE,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;IACnC,IAAI,IAAI,CAAC,MAAM;QAAE,GAAG,CAAC,KAAK,GAAG,QAAQ,CAAC;IACtC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,cAAc;YACjC,CAAC,CAAC,iBAAiB,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,cAAc,EAAE,EAAE,OAAO,CAAC,CAAC,EAAE;YAC5D,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC;IACtC,CAAC;IACD,IAAI,IAAI,CAAC,MAAM;QAAE,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC;IACjC,IAAI,IAAI,CAAC,IAAI;QAAE,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IACpC,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAC1B,QAAsB,EACtB,IAAgB,EAChB,OAAoB;IAEpB,OAAO,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AAClD,CAAC;AAED;2DAC2D;AAC3D,MAAM,UAAU,SAAS,CACvB,KAA0B,EAC1B,IAAgB,EAChB,OAAoB;IAEpB,MAAM,IAAI,GAAc,EAAE,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,CAAC,CAAE,CAAC,KAAK,EAAE,CAAC;YACnC,IAAI,IAAI,CAAC,IAAI;gBAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QACzD,CAAC;QACD,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-x11/components",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "Components for react-x11 that do not belong in the core package",
5
5
  "keywords": [
6
6
  "react",
package/src/code/index.ts CHANGED
@@ -17,21 +17,18 @@ import type { ReactElement } from 'react';
17
17
  import { useTheme } from 'react-x11';
18
18
  import type { Style } from 'react-x11/style';
19
19
 
20
- import {
21
- registerRichText,
22
- RICHTEXT_ELEMENT,
23
- useSelectionMenu,
24
- } from '../richtext/index.js';
25
- import type { RichTextProps, TextRun } from '../richtext/index.js';
20
+ import { registerRichText, useSelectionMenu } from '../richtext/index.js';
21
+ import type { TextRun } from '../richtext/index.js';
26
22
  import {
27
23
  codeBlockLook,
28
- codeBlockRuns,
24
+ CodeBlockRunCache,
29
25
  codeBlockStyle,
30
26
  codeTextStyle,
31
27
  } from '../codeblock/index.js';
32
28
  import type { Language, TokenStyles } from '../code-language/index.js';
33
29
  import { hx } from './hx.js';
34
30
  import { useFontPrewarm } from '../internal/prewarm.js';
31
+ import { CodeGutter, CodeLines } from '../internal/codelines.js';
35
32
 
36
33
  const h = React.createElement;
37
34
 
@@ -107,39 +104,44 @@ export function Code(props: CodeProps): ReactElement {
107
104
  );
108
105
  useFontPrewarm(look.family);
109
106
 
107
+ // Kept between renders, so a source that changes at its end is tokenized
108
+ // again from the line that changed (`CodeBlockRunCache`).
109
+ const runCache = React.useRef<CodeBlockRunCache | null>(null);
110
+ runCache.current ??= new CodeBlockRunCache();
111
+ React.useEffect(() => () => runCache.current?.dispose(), []);
110
112
  const runs: TextRun[] = React.useMemo(
111
- () => codeBlockRuns(source, look, { lang, language, resolveLanguage }),
113
+ () =>
114
+ runCache.current!.runs(source, look, { lang, language, resolveLanguage }),
112
115
  [source, lang, language, resolveLanguage, look],
113
116
  );
114
117
 
115
118
  const lineCount = React.useMemo(() => source.split('\n').length, [source]);
116
119
 
117
- const codeProps: RichTextProps = { runs, style: codeTextStyle(look, wrap) };
118
- if (!wrap) codeProps.wrap = false;
120
+ // In blocks of lines, so a change lays out the blocks it touches
121
+ // (`../internal/codelines.ts`).
122
+ const code = h(CodeLines, { runs, style: codeTextStyle(look, wrap), wrap });
119
123
 
120
124
  const gutter = lineNumbers
121
- ? h(RICHTEXT_ELEMENT, {
122
- // one richtext for all the numbers: same font, same line height, so
123
- // it stays in register with the code beside it. `selectable={false}`
124
- // is what keeps it out of a drag and out of the copied text — the
125
- // numbering is chrome, and CSS spells that `user-select: none`.
126
- selectable: false,
127
- runs: Array.from({ length: lineCount }, (_, i) => ({
128
- text: `${i + 1}\n`,
129
- family: look.family,
130
- size: look.size,
131
- color: look.dim,
132
- })),
133
- wrap: false,
134
- style: {
135
- lineHeight: look.lineHeight,
136
- textAlign: 'right',
137
- minWidth:
138
- Math.max(String(lineCount).length, 2) * Math.ceil(look.size * 0.62),
139
- marginRight: look.padding,
140
- flexShrink: 0,
125
+ ? hx(
126
+ 'box',
127
+ {
128
+ style: {
129
+ flexDirection: 'column',
130
+ minWidth:
131
+ Math.max(String(lineCount).length, 2) *
132
+ Math.ceil(look.size * 0.62),
133
+ marginRight: look.padding,
134
+ flexShrink: 0,
135
+ },
141
136
  },
142
- } as Record<string, unknown>)
137
+ // numbers in the same font and line height as the code, blocked the
138
+ // same way, so the two stay in register
139
+ h(CodeGutter, {
140
+ lines: lineCount,
141
+ run: { family: look.family, size: look.size, color: look.dim },
142
+ style: { lineHeight: look.lineHeight, textAlign: 'right' },
143
+ }),
144
+ )
143
145
  : null;
144
146
 
145
147
  const rootStyle: Style = {
@@ -170,7 +172,7 @@ export function Code(props: CodeProps): ReactElement {
170
172
  hx(
171
173
  'box',
172
174
  { style: { overflow: 'scroll', flexDirection: 'column', flexGrow: 1 } },
173
- h(RICHTEXT_ELEMENT, codeProps as unknown as Record<string, unknown>),
175
+ code,
174
176
  ),
175
177
  );
176
178
  }
@@ -34,7 +34,7 @@ export {
34
34
  } from './theme.js';
35
35
 
36
36
  export { languageForTag, tokenizeText } from './registry.js';
37
- export { codeRuns } from './runs.js';
37
+ export { codeRuns, CodeRunCache } from './runs.js';
38
38
  export type { CodeRun, CodeRunOptions } from './runs.js';
39
39
 
40
40
  export { TOKEN_FALLBACK } from './types.js';
@@ -23,7 +23,7 @@
23
23
  // AGENTS.md on tree-shaking, and `textmate.ts` for the same shape.
24
24
  import { languageForTag, tokenizeText } from './registry.js';
25
25
  import { tokenStyleFor } from './theme.js';
26
- import type { Language, TokenStyles } from './types.js';
26
+ import type { Language, Token, Tokenizer, TokenStyles } from './types.js';
27
27
 
28
28
  /** One styled run of code. Structurally a `<richtext>` run. */
29
29
  export interface CodeRun {
@@ -126,3 +126,113 @@ function push(
126
126
  out.push(run);
127
127
  }
128
128
  }
129
+
130
+ /**
131
+ * `codeRuns`, kept between calls for a text that changes a little at a
132
+ * time: a fence being streamed, a source being appended to.
133
+ *
134
+ * One tokenizer lives as long as the cache. It is told which lines changed
135
+ * (`Tokenizer.edit`, the interface `<CodeEditor>` already drives) and asked
136
+ * again only for those and the lines after them its state has to walk
137
+ * through, and every other line keeps the runs it had. `codeRuns` tokenized
138
+ * the whole text afresh: at 5,000 lines, most of the time an appended line
139
+ * took on the client.
140
+ *
141
+ * The runs are the same text in the same colours `codeRuns` gives, cut a
142
+ * little differently: a line's runs never reach into the next, and each
143
+ * newline is a run of its own, so that a line keeps its runs while others
144
+ * change. `decorate` is applied to every run once, when it is made — the
145
+ * family and size a block of code is set in, say.
146
+ *
147
+ * Call `dispose()` when done with it: an engine may keep timers.
148
+ */
149
+ export class CodeRunCache<R = CodeRun> {
150
+ private key: readonly unknown[] | null = null;
151
+ private tokenizer: Tokenizer | null = null;
152
+ private lines: string[] = [];
153
+ private tokens: (readonly Token[] | undefined)[] = [];
154
+ private lineRuns: (R[] | undefined)[] = [];
155
+ private newline: R | null = null;
156
+
157
+ constructor(
158
+ private readonly decorate: (run: CodeRun) => R = (run) => run as R,
159
+ ) {}
160
+
161
+ runs(text: string, tag: string, opts: CodeRunOptions): R[] {
162
+ if (text.length === 0)
163
+ return [this.decorate({ text: '', color: opts.color })];
164
+ const language =
165
+ opts.language ??
166
+ (tag ? (opts.resolveLanguage?.(tag) ?? languageForTag(tag)) : null);
167
+ if (!language) return [this.decorate({ text, color: opts.color })];
168
+
169
+ const key = [language, opts.styles, opts.color, opts.resolveToken];
170
+ if (!this.key || key.some((part, i) => part !== this.key![i])) {
171
+ this.dispose();
172
+ this.key = key;
173
+ this.lines = [];
174
+ this.tokens = [];
175
+ this.lineRuns = [];
176
+ this.newline = this.decorate({ text: '\n', color: opts.color });
177
+ this.tokenizer = language.createTokenizer({ invalidate: () => {} });
178
+ this.tokenizer.setLines(this.lines);
179
+ }
180
+ const tokenizer = this.tokenizer!;
181
+
182
+ // the lines the text shares with the last one, from the top: the edit
183
+ // is everything after them
184
+ const next = text.split('\n');
185
+ const lines = this.lines;
186
+ const shared = Math.min(lines.length, next.length);
187
+ let from = 0;
188
+ while (from < shared && lines[from] === next[from]) from++;
189
+ if (from < lines.length || from < next.length) {
190
+ const removed = lines.length - from;
191
+ const inserted = next.length - from;
192
+ lines.length = from;
193
+ for (let i = from; i < next.length; i++) lines.push(next[i]!);
194
+ tokenizer.edit({ fromLine: from, removed, inserted });
195
+ this.tokens.length = from;
196
+ this.lineRuns.length = from;
197
+ }
198
+
199
+ // Asked in order from the top, so a stream engine walks its frontier
200
+ // line by line and answers each exactly, never from a guess.
201
+ const out: R[] = [];
202
+ for (let i = 0; i < lines.length; i++) {
203
+ if (i > 0) out.push(this.newline!);
204
+ const tokens = tokenizer.lineTokens(i);
205
+ let runs = this.lineRuns[i];
206
+ if (!runs || this.tokens[i] !== tokens) {
207
+ runs = lineRuns(lines[i]!, tokens, opts).map(this.decorate);
208
+ this.lineRuns[i] = runs;
209
+ this.tokens[i] = tokens;
210
+ }
211
+ for (const run of runs) out.push(run);
212
+ }
213
+ return out;
214
+ }
215
+
216
+ dispose(): void {
217
+ this.tokenizer?.dispose?.();
218
+ this.tokenizer = null;
219
+ this.key = null;
220
+ }
221
+ }
222
+
223
+ /** One line's runs, as `codeRuns` makes them, up to its end. */
224
+ function lineRuns(
225
+ line: string,
226
+ tokens: readonly Token[],
227
+ opts: CodeRunOptions,
228
+ ): CodeRun[] {
229
+ const out: CodeRun[] = [];
230
+ let at = 0;
231
+ for (const t of tokens) {
232
+ if (t.from > at) push(out, line.slice(at, t.from), undefined, opts);
233
+ push(out, line.slice(t.from, t.to), t.type, opts);
234
+ at = t.to;
235
+ }
236
+ if (at < line.length) push(out, line.slice(at), undefined, opts);
237
+ return out;
238
+ }
@@ -15,7 +15,11 @@
15
15
  // A shared module, not a component: no element registration, no React, and
16
16
  // nothing imported from either of its consumers (a component never imports
17
17
  // another component).
18
- import { codeRuns, autoTokenStyles } from '../code-language/index.js';
18
+ import {
19
+ codeRuns,
20
+ autoTokenStyles,
21
+ CodeRunCache,
22
+ } from '../code-language/index.js';
19
23
  import type { Language, TokenStyles } from '../code-language/index.js';
20
24
  import type { TextRun } from '../richtext/index.js';
21
25
  import { tint } from 'react-x11/style';
@@ -130,6 +134,49 @@ export function codeBlockRuns(
130
134
  }).map((run) => ({ ...run, family: look.family, size: look.size }));
131
135
  }
132
136
 
137
+ /**
138
+ * `codeBlockRuns` kept between calls, for a block of code that changes a
139
+ * little at a time — a fence being streamed, a source being appended to:
140
+ * the tokenizer is told which lines changed and the rest keep their runs
141
+ * (`CodeRunCache`). Call `dispose()` when done with it.
142
+ */
143
+ export class CodeBlockRunCache {
144
+ private cache: CodeRunCache<TextRun> | null = null;
145
+ private family: string | undefined;
146
+ private size: number | undefined;
147
+
148
+ runs(
149
+ source: string,
150
+ look: CodeBlockLook,
151
+ options: CodeBlockRunOptions = {},
152
+ ): TextRun[] {
153
+ if (!this.cache || this.family !== look.family || this.size !== look.size) {
154
+ this.cache?.dispose();
155
+ const { family, size } = look;
156
+ this.family = family;
157
+ this.size = size;
158
+ this.cache = new CodeRunCache<TextRun>((run) => ({
159
+ ...run,
160
+ family,
161
+ size,
162
+ }));
163
+ }
164
+ const { lang = '', language, resolveLanguage, highlight = true } = options;
165
+ return this.cache.runs(source, highlight ? lang : '', {
166
+ styles: look.styles,
167
+ color: look.color,
168
+ ...(highlight && language ? { language } : null),
169
+ ...(highlight && resolveLanguage ? { resolveLanguage } : null),
170
+ resolveToken: look.resolveToken,
171
+ });
172
+ }
173
+
174
+ dispose(): void {
175
+ this.cache?.dispose();
176
+ this.cache = null;
177
+ }
178
+ }
179
+
133
180
  /** The block's own box: fill, radius, padding. What surrounds it — a row
134
181
  * with a gutter, a column in a document — is the component's. */
135
182
  export function codeBlockStyle(look: CodeBlockLook): Style {