@jitl/opentui-core 0.1.97 → 0.2.15
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/NativeSpanFeed.d.ts +2 -2
- package/README.md +2 -1
- package/Renderable.d.ts +12 -1
- package/audio.d.ts +89 -0
- package/buffer.d.ts +6 -5
- package/console.d.ts +3 -1
- package/edit-buffer.d.ts +1 -1
- package/editor-view.d.ts +1 -1
- package/{index-yxe6e14n.js → index-46f5e8m6.js} +1388 -1721
- package/index-46f5e8m6.js.map +36 -0
- package/index-5zwezmgj.js +639 -0
- package/index-5zwezmgj.js.map +11 -0
- package/index-axv7cw60.js +44 -0
- package/index-axv7cw60.js.map +10 -0
- package/{index-rhfjv9c1.js → index-g9agybj3.js} +4626 -984
- package/index-g9agybj3.js.map +82 -0
- package/index-k18nf2r7.js +21 -0
- package/{ffi-x3zvcksd.js.map → index-k18nf2r7.js.map} +1 -1
- package/{index-tkk6cmr2.js → index-rp7vz5rh.js} +125 -23
- package/index-rp7vz5rh.js.map +10 -0
- package/{index-kcpn1hka.js → index-xwsdfq5x.js} +16 -6
- package/index-xwsdfq5x.js.map +10 -0
- package/index.d.ts +1 -0
- package/index.js +37 -17
- package/index.js.map +1 -1
- package/lib/RGBA.d.ts +22 -6
- package/lib/clipboard.d.ts +1 -1
- package/lib/{keymapping.d.ts → keybinding.internal.d.ts} +10 -2
- package/lib/objects-in-viewport.d.ts +4 -4
- package/lib/parse.keypress-kitty.d.ts +1 -0
- package/lib/parse.keypress.d.ts +1 -0
- package/lib/render-geometry.d.ts +8 -0
- package/lib/stdin-parser.d.ts +4 -1
- package/lib/terminal-capability-detection.d.ts +2 -0
- package/lib/terminal-palette.d.ts +20 -5
- package/lib/tree-sitter/assets/update.d.ts +1 -0
- package/lib/tree-sitter/client.d.ts +2 -0
- package/lib/tree-sitter/default-parsers.d.ts +1 -1
- package/lib/tree-sitter/index.d.ts +0 -2
- package/lib/tree-sitter/update-assets.d.ts +3 -0
- package/lib/tree-sitter/update-assets.js +377 -0
- package/lib/tree-sitter/update-assets.js.map +12 -0
- package/lib/tree-sitter-styled-text.d.ts +6 -4
- package/node22-bun-ffi-structs-ha8fmzzb.js +396 -0
- package/node22-bun-ffi-structs-ha8fmzzb.js.map +10 -0
- package/package.json +23 -22
- package/parser.worker.js +161 -24
- package/parser.worker.js.map +12 -5
- package/platform/bun-ffi-structs.d.ts +2 -0
- package/platform/ffi.d.ts +126 -0
- package/platform/node22-bun-ffi-structs.d.ts +33 -0
- package/platform/node22-ffi.d.ts +33 -0
- package/{compat → platform}/runtime.d.ts +6 -0
- package/platform/worker.d.ts +4 -0
- package/renderables/Code.d.ts +4 -0
- package/renderables/Markdown.d.ts +62 -0
- package/renderables/ScrollBox.d.ts +1 -0
- package/renderables/Select.d.ts +3 -1
- package/renderables/TabSelect.d.ts +3 -1
- package/renderables/TextBufferRenderable.d.ts +1 -0
- package/renderables/TextTable.d.ts +15 -1
- package/renderables/Textarea.d.ts +5 -3
- package/renderables/markdown-parser.d.ts +1 -0
- package/renderer-theme-mode.d.ts +29 -0
- package/renderer.d.ts +142 -16
- package/runtime-plugin-support-configure.d.ts +4 -0
- package/runtime-plugin-support-configure.js +20 -0
- package/{index-re3ntm60.js.map → runtime-plugin-support-configure.js.map} +1 -1
- package/runtime-plugin-support.d.ts +3 -3
- package/runtime-plugin-support.js +9 -18
- package/runtime-plugin-support.js.map +3 -3
- package/runtime-plugin.d.ts +1 -4
- package/runtime-plugin.js +5 -5
- package/syntax-style.d.ts +11 -3
- package/testing/terminal-capabilities.d.ts +7 -0
- package/testing/test-recorder.d.ts +6 -6
- package/testing/test-renderer.d.ts +34 -2
- package/testing.d.ts +2 -0
- package/testing.js +329 -23
- package/testing.js.map +7 -5
- package/text-buffer-view.d.ts +2 -1
- package/text-buffer.d.ts +1 -1
- package/types.d.ts +33 -1
- package/zig-structs.d.ts +111 -20
- package/zig.d.ts +57 -7
- package/3d/SpriteResourceManager.d.ts +0 -74
- package/3d/SpriteUtils.d.ts +0 -13
- package/3d/TextureUtils.d.ts +0 -24
- package/3d/ThreeRenderable.d.ts +0 -40
- package/3d/WGPURenderer.d.ts +0 -61
- package/3d/animation/ExplodingSpriteEffect.d.ts +0 -71
- package/3d/animation/PhysicsExplodingSpriteEffect.d.ts +0 -76
- package/3d/animation/SpriteAnimator.d.ts +0 -124
- package/3d/animation/SpriteParticleGenerator.d.ts +0 -62
- package/3d/canvas.d.ts +0 -44
- package/3d/index.d.ts +0 -12
- package/3d/physics/PlanckPhysicsAdapter.d.ts +0 -19
- package/3d/physics/RapierPhysicsAdapter.d.ts +0 -19
- package/3d/physics/physics-interface.d.ts +0 -27
- package/3d.d.ts +0 -2
- package/3d.js +0 -33843
- package/3d.js.map +0 -155
- package/Worker-vajwjk0s.js +0 -94
- package/Worker-vajwjk0s.js.map +0 -10
- package/compat/FFIType.d.ts +0 -304
- package/compat/Worker.d.ts +0 -1
- package/compat/bun-ffi-structs.d.ts +0 -2
- package/compat/ffi.d.ts +0 -86
- package/compat/nodejs/Worker.d.ts +0 -16
- package/compat/nodejs/bun-ffi-structs/index.d.ts +0 -46
- package/compat/nodejs/ffi.d.ts +0 -21
- package/compat/nodejs/registerResolveJs.d.ts +0 -1
- package/compat/nodejs/runtime.d.ts +0 -7
- package/compat/nodejs/test.d.ts +0 -4
- package/compat/nodejs/trampoline.worker.d.ts +0 -1
- package/compat/test.d.ts +0 -1
- package/compat/testHelpers.d.ts +0 -18
- package/ffi-x3zvcksd.js +0 -25
- package/index-5yqvbmcz.js +0 -220
- package/index-5yqvbmcz.js.map +0 -10
- package/index-bnfz2g63.js +0 -654
- package/index-bnfz2g63.js.map +0 -10
- package/index-cbvybypy.js +0 -43
- package/index-cbvybypy.js.map +0 -10
- package/index-kcpn1hka.js.map +0 -10
- package/index-re3ntm60.js +0 -51
- package/index-rhfjv9c1.js.map +0 -70
- package/index-tkk6cmr2.js.map +0 -10
- package/index-yxe6e14n.js.map +0 -42
- package/runtime-hdpkc6qf.js +0 -220
- package/runtime-hdpkc6qf.js.map +0 -17
- /package/{compat/nodejs/registerBun.d.ts → native-event-worker-repro.worker.d.ts} +0 -0
|
@@ -6,18 +6,20 @@ import {
|
|
|
6
6
|
BaseRenderable,
|
|
7
7
|
BorderCharArrays,
|
|
8
8
|
BorderChars,
|
|
9
|
+
BoxRenderable,
|
|
9
10
|
CliRenderEvents,
|
|
10
11
|
CliRenderer,
|
|
12
|
+
CodeRenderable,
|
|
11
13
|
ConsolePosition,
|
|
14
|
+
DEFAULT_BACKGROUND_RGB,
|
|
15
|
+
DEFAULT_FOREGROUND_RGB,
|
|
12
16
|
DataPathsManager,
|
|
13
17
|
DebugOverlayCorner,
|
|
14
|
-
Edge,
|
|
15
18
|
EditBuffer,
|
|
16
19
|
EditBufferRenderable,
|
|
17
20
|
EditBufferRenderableEvents,
|
|
18
21
|
EditorView,
|
|
19
22
|
ExtmarksController,
|
|
20
|
-
Gutter,
|
|
21
23
|
InternalKeyHandler,
|
|
22
24
|
KeyEvent,
|
|
23
25
|
KeyHandler,
|
|
@@ -36,18 +38,25 @@ import {
|
|
|
36
38
|
RenderableEvents,
|
|
37
39
|
RendererControlState,
|
|
38
40
|
RootRenderable,
|
|
41
|
+
RootTextNodeRenderable,
|
|
39
42
|
Selection,
|
|
40
43
|
SpanInfoStruct,
|
|
41
44
|
StdinParser,
|
|
42
45
|
StyledText,
|
|
46
|
+
SyntaxStyle,
|
|
43
47
|
SystemClock,
|
|
44
48
|
TargetChannel,
|
|
45
49
|
TerminalConsole,
|
|
46
50
|
TerminalPalette,
|
|
47
51
|
TextAttributes,
|
|
48
52
|
TextBuffer,
|
|
53
|
+
TextBufferRenderable,
|
|
54
|
+
TextBufferView,
|
|
55
|
+
TextNodeRenderable,
|
|
56
|
+
TextRenderable,
|
|
49
57
|
TreeSitterClient,
|
|
50
58
|
addDefaultParsers,
|
|
59
|
+
ansi256IndexToRgb,
|
|
51
60
|
attributesWithLink,
|
|
52
61
|
basenameToFiletype,
|
|
53
62
|
bg,
|
|
@@ -74,9 +83,11 @@ import {
|
|
|
74
83
|
brightYellow,
|
|
75
84
|
buildKeyBindingsMap,
|
|
76
85
|
buildKittyKeyboardFlags,
|
|
86
|
+
buildTerminalPaletteSignature,
|
|
77
87
|
capture,
|
|
78
88
|
clearEnvCache,
|
|
79
89
|
convertGlobalToLocalSelection,
|
|
90
|
+
convertThemeToStyles,
|
|
80
91
|
coordinateToCharacterIndex,
|
|
81
92
|
createCliRenderer,
|
|
82
93
|
createExtmarksController,
|
|
@@ -102,7 +113,7 @@ import {
|
|
|
102
113
|
getBorderSides,
|
|
103
114
|
getCharacterPositions,
|
|
104
115
|
getDataPaths,
|
|
105
|
-
|
|
116
|
+
getKeyBindingAction,
|
|
106
117
|
getLinkId,
|
|
107
118
|
getObjectsInViewport,
|
|
108
119
|
getTreeSitterClient,
|
|
@@ -116,18 +127,20 @@ import {
|
|
|
116
127
|
isEditBufferRenderable,
|
|
117
128
|
isRenderable,
|
|
118
129
|
isStyledText,
|
|
130
|
+
isTextNodeRenderable,
|
|
119
131
|
isVNode,
|
|
120
132
|
isValidBorderStyle,
|
|
121
|
-
isValidPercentage,
|
|
122
133
|
italic,
|
|
123
134
|
link,
|
|
124
135
|
magenta,
|
|
125
|
-
main,
|
|
126
136
|
maybeMakeRenderable,
|
|
127
137
|
measureText,
|
|
128
138
|
mergeKeyAliases,
|
|
129
139
|
mergeKeyBindings,
|
|
130
140
|
nonAlphanumericKeys,
|
|
141
|
+
normalizeColorValue,
|
|
142
|
+
normalizeIndexedColorIndex,
|
|
143
|
+
normalizeTerminalPalette,
|
|
131
144
|
parseAlign,
|
|
132
145
|
parseAlignItems,
|
|
133
146
|
parseBorderStyle,
|
|
@@ -160,7 +173,7 @@ import {
|
|
|
160
173
|
stringWidth,
|
|
161
174
|
stripAnsiSequences,
|
|
162
175
|
t,
|
|
163
|
-
|
|
176
|
+
terminalNamedSingleStrokeKeys,
|
|
164
177
|
treeSitterToStyledText,
|
|
165
178
|
treeSitterToTextChunks,
|
|
166
179
|
underline,
|
|
@@ -168,10 +181,13 @@ import {
|
|
|
168
181
|
white,
|
|
169
182
|
wrapWithDelegates,
|
|
170
183
|
yellow
|
|
171
|
-
} from "./index-
|
|
184
|
+
} from "./index-g9agybj3.js";
|
|
185
|
+
import {
|
|
186
|
+
toArrayBuffer
|
|
187
|
+
} from "./index-5zwezmgj.js";
|
|
172
188
|
import {
|
|
173
189
|
__export
|
|
174
|
-
} from "./index-
|
|
190
|
+
} from "./index-k18nf2r7.js";
|
|
175
191
|
|
|
176
192
|
// src/index.ts
|
|
177
193
|
var exports_src2 = {};
|
|
@@ -181,14 +197,15 @@ __export(exports_src2, {
|
|
|
181
197
|
white: () => white,
|
|
182
198
|
vstyles: () => vstyles,
|
|
183
199
|
visualizeRenderableTree: () => visualizeRenderableTree,
|
|
184
|
-
updateAssets: () => main,
|
|
185
200
|
underline: () => underline,
|
|
186
201
|
treeSitterToTextChunks: () => treeSitterToTextChunks,
|
|
187
202
|
treeSitterToStyledText: () => treeSitterToStyledText,
|
|
203
|
+
terminalNamedSingleStrokeKeys: () => terminalNamedSingleStrokeKeys,
|
|
188
204
|
t: () => t,
|
|
189
205
|
stripAnsiSequences: () => stripAnsiSequences,
|
|
190
206
|
stringToStyledText: () => stringToStyledText,
|
|
191
207
|
strikethrough: () => strikethrough,
|
|
208
|
+
setupAudio: () => setupAudio,
|
|
192
209
|
setRenderLibPath: () => setRenderLibPath,
|
|
193
210
|
rgbToHex: () => rgbToHex,
|
|
194
211
|
reverse: () => reverse,
|
|
@@ -218,6 +235,9 @@ __export(exports_src2, {
|
|
|
218
235
|
parseBorderStyle: () => parseBorderStyle,
|
|
219
236
|
parseAlignItems: () => parseAlignItems,
|
|
220
237
|
parseAlign: () => parseAlign,
|
|
238
|
+
normalizeTerminalPalette: () => normalizeTerminalPalette,
|
|
239
|
+
normalizeIndexedColorIndex: () => normalizeIndexedColorIndex,
|
|
240
|
+
normalizeColorValue: () => normalizeColorValue,
|
|
221
241
|
nonAlphanumericKeys: () => nonAlphanumericKeys,
|
|
222
242
|
measureText: () => measureText,
|
|
223
243
|
maybeMakeRenderable: () => maybeMakeRenderable,
|
|
@@ -256,6 +276,7 @@ __export(exports_src2, {
|
|
|
256
276
|
dim: () => dim,
|
|
257
277
|
detectLinks: () => detectLinks,
|
|
258
278
|
delegate: () => delegate,
|
|
279
|
+
defaultTextareaKeyBindings: () => defaultTextareaKeyBindings,
|
|
259
280
|
decodePasteBytes: () => decodePasteBytes,
|
|
260
281
|
cyan: () => cyan,
|
|
261
282
|
createTimeline: () => createTimeline,
|
|
@@ -270,6 +291,7 @@ __export(exports_src2, {
|
|
|
270
291
|
convertGlobalToLocalSelection: () => convertGlobalToLocalSelection,
|
|
271
292
|
clearEnvCache: () => clearEnvCache,
|
|
272
293
|
capture: () => capture,
|
|
294
|
+
buildTerminalPaletteSignature: () => buildTerminalPaletteSignature,
|
|
273
295
|
buildKittyKeyboardFlags: () => buildKittyKeyboardFlags,
|
|
274
296
|
brightYellow: () => brightYellow,
|
|
275
297
|
brightWhite: () => brightWhite,
|
|
@@ -303,6 +325,7 @@ __export(exports_src2, {
|
|
|
303
325
|
applyChromaticAberration: () => applyChromaticAberration,
|
|
304
326
|
applyBrightness: () => applyBrightness,
|
|
305
327
|
applyAsciiArt: () => applyAsciiArt,
|
|
328
|
+
ansi256IndexToRgb: () => ansi256IndexToRgb,
|
|
306
329
|
addDefaultParsers: () => addDefaultParsers,
|
|
307
330
|
Yoga: () => exports_src,
|
|
308
331
|
VignetteEffect: () => VignetteEffect,
|
|
@@ -390,6 +413,8 @@ __export(exports_src2, {
|
|
|
390
413
|
DataPathsManager: () => DataPathsManager,
|
|
391
414
|
DEUTERANOPIA_SIM_MATRIX: () => DEUTERANOPIA_SIM_MATRIX,
|
|
392
415
|
DEUTERANOPIA_COMP_MATRIX: () => DEUTERANOPIA_COMP_MATRIX,
|
|
416
|
+
DEFAULT_FOREGROUND_RGB: () => DEFAULT_FOREGROUND_RGB,
|
|
417
|
+
DEFAULT_BACKGROUND_RGB: () => DEFAULT_BACKGROUND_RGB,
|
|
393
418
|
ConsolePosition: () => ConsolePosition,
|
|
394
419
|
CodeRenderable: () => CodeRenderable,
|
|
395
420
|
Code: () => Code,
|
|
@@ -403,6 +428,7 @@ __export(exports_src2, {
|
|
|
403
428
|
BorderCharArrays: () => BorderCharArrays,
|
|
404
429
|
BloomEffect: () => BloomEffect,
|
|
405
430
|
BaseRenderable: () => BaseRenderable,
|
|
431
|
+
Audio: () => Audio,
|
|
406
432
|
ArrowRenderable: () => ArrowRenderable,
|
|
407
433
|
ATTRIBUTE_BASE_MASK: () => ATTRIBUTE_BASE_MASK,
|
|
408
434
|
ATTRIBUTE_BASE_BITS: () => ATTRIBUTE_BASE_BITS,
|
|
@@ -412,327 +438,21 @@ __export(exports_src2, {
|
|
|
412
438
|
ACHROMATOPSIA_MATRIX: () => ACHROMATOPSIA_MATRIX
|
|
413
439
|
});
|
|
414
440
|
|
|
415
|
-
// src/
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
viewPtr;
|
|
419
|
-
textBuffer;
|
|
420
|
-
_destroyed = false;
|
|
421
|
-
constructor(lib, ptr, textBuffer) {
|
|
422
|
-
this.lib = lib;
|
|
423
|
-
this.viewPtr = ptr;
|
|
424
|
-
this.textBuffer = textBuffer;
|
|
425
|
-
}
|
|
426
|
-
static create(textBuffer) {
|
|
427
|
-
const lib = resolveRenderLib();
|
|
428
|
-
const viewPtr = lib.createTextBufferView(textBuffer.ptr);
|
|
429
|
-
return new TextBufferView(lib, viewPtr, textBuffer);
|
|
430
|
-
}
|
|
431
|
-
guard() {
|
|
432
|
-
if (this._destroyed)
|
|
433
|
-
throw new Error("TextBufferView is destroyed");
|
|
434
|
-
}
|
|
435
|
-
get ptr() {
|
|
436
|
-
this.guard();
|
|
437
|
-
return this.viewPtr;
|
|
438
|
-
}
|
|
439
|
-
setSelection(start, end, bgColor, fgColor) {
|
|
440
|
-
this.guard();
|
|
441
|
-
this.lib.textBufferViewSetSelection(this.viewPtr, start, end, bgColor || null, fgColor || null);
|
|
442
|
-
}
|
|
443
|
-
updateSelection(end, bgColor, fgColor) {
|
|
444
|
-
this.guard();
|
|
445
|
-
this.lib.textBufferViewUpdateSelection(this.viewPtr, end, bgColor || null, fgColor || null);
|
|
446
|
-
}
|
|
447
|
-
resetSelection() {
|
|
448
|
-
this.guard();
|
|
449
|
-
this.lib.textBufferViewResetSelection(this.viewPtr);
|
|
450
|
-
}
|
|
451
|
-
getSelection() {
|
|
452
|
-
this.guard();
|
|
453
|
-
return this.lib.textBufferViewGetSelection(this.viewPtr);
|
|
454
|
-
}
|
|
455
|
-
hasSelection() {
|
|
456
|
-
this.guard();
|
|
457
|
-
return this.getSelection() !== null;
|
|
458
|
-
}
|
|
459
|
-
setLocalSelection(anchorX, anchorY, focusX, focusY, bgColor, fgColor) {
|
|
460
|
-
this.guard();
|
|
461
|
-
return this.lib.textBufferViewSetLocalSelection(this.viewPtr, anchorX, anchorY, focusX, focusY, bgColor || null, fgColor || null);
|
|
462
|
-
}
|
|
463
|
-
updateLocalSelection(anchorX, anchorY, focusX, focusY, bgColor, fgColor) {
|
|
464
|
-
this.guard();
|
|
465
|
-
return this.lib.textBufferViewUpdateLocalSelection(this.viewPtr, anchorX, anchorY, focusX, focusY, bgColor || null, fgColor || null);
|
|
466
|
-
}
|
|
467
|
-
resetLocalSelection() {
|
|
468
|
-
this.guard();
|
|
469
|
-
this.lib.textBufferViewResetLocalSelection(this.viewPtr);
|
|
470
|
-
}
|
|
471
|
-
setWrapWidth(width) {
|
|
472
|
-
this.guard();
|
|
473
|
-
this.lib.textBufferViewSetWrapWidth(this.viewPtr, width ?? 0);
|
|
474
|
-
}
|
|
475
|
-
setWrapMode(mode) {
|
|
476
|
-
this.guard();
|
|
477
|
-
this.lib.textBufferViewSetWrapMode(this.viewPtr, mode);
|
|
478
|
-
}
|
|
479
|
-
setViewportSize(width, height) {
|
|
480
|
-
this.guard();
|
|
481
|
-
this.lib.textBufferViewSetViewportSize(this.viewPtr, width, height);
|
|
482
|
-
}
|
|
483
|
-
setViewport(x, y, width, height) {
|
|
484
|
-
this.guard();
|
|
485
|
-
this.lib.textBufferViewSetViewport(this.viewPtr, x, y, width, height);
|
|
486
|
-
}
|
|
487
|
-
get lineInfo() {
|
|
488
|
-
this.guard();
|
|
489
|
-
return this.lib.textBufferViewGetLineInfo(this.viewPtr);
|
|
490
|
-
}
|
|
491
|
-
get logicalLineInfo() {
|
|
492
|
-
this.guard();
|
|
493
|
-
return this.lib.textBufferViewGetLogicalLineInfo(this.viewPtr);
|
|
494
|
-
}
|
|
495
|
-
getSelectedText() {
|
|
496
|
-
this.guard();
|
|
497
|
-
const byteSize = this.textBuffer.byteSize;
|
|
498
|
-
if (byteSize === 0)
|
|
499
|
-
return "";
|
|
500
|
-
const selectedBytes = this.lib.textBufferViewGetSelectedTextBytes(this.viewPtr, byteSize);
|
|
501
|
-
if (!selectedBytes)
|
|
502
|
-
return "";
|
|
503
|
-
return this.lib.decoder.decode(selectedBytes);
|
|
504
|
-
}
|
|
505
|
-
getPlainText() {
|
|
506
|
-
this.guard();
|
|
507
|
-
const byteSize = this.textBuffer.byteSize;
|
|
508
|
-
if (byteSize === 0)
|
|
509
|
-
return "";
|
|
510
|
-
const plainBytes = this.lib.textBufferViewGetPlainTextBytes(this.viewPtr, byteSize);
|
|
511
|
-
if (!plainBytes)
|
|
512
|
-
return "";
|
|
513
|
-
return this.lib.decoder.decode(plainBytes);
|
|
514
|
-
}
|
|
515
|
-
setTabIndicator(indicator) {
|
|
516
|
-
this.guard();
|
|
517
|
-
const codePoint = typeof indicator === "string" ? indicator.codePointAt(0) ?? 0 : indicator;
|
|
518
|
-
this.lib.textBufferViewSetTabIndicator(this.viewPtr, codePoint);
|
|
519
|
-
}
|
|
520
|
-
setTabIndicatorColor(color) {
|
|
521
|
-
this.guard();
|
|
522
|
-
this.lib.textBufferViewSetTabIndicatorColor(this.viewPtr, color);
|
|
523
|
-
}
|
|
524
|
-
setTruncate(truncate) {
|
|
525
|
-
this.guard();
|
|
526
|
-
this.lib.textBufferViewSetTruncate(this.viewPtr, truncate);
|
|
527
|
-
}
|
|
528
|
-
measureForDimensions(width, height) {
|
|
529
|
-
this.guard();
|
|
530
|
-
return this.lib.textBufferViewMeasureForDimensions(this.viewPtr, width, height);
|
|
531
|
-
}
|
|
532
|
-
getVirtualLineCount() {
|
|
533
|
-
this.guard();
|
|
534
|
-
return this.lib.textBufferViewGetVirtualLineCount(this.viewPtr);
|
|
535
|
-
}
|
|
536
|
-
destroy() {
|
|
537
|
-
if (this._destroyed)
|
|
538
|
-
return;
|
|
539
|
-
this._destroyed = true;
|
|
540
|
-
this.lib.destroyTextBufferView(this.viewPtr);
|
|
541
|
-
}
|
|
441
|
+
// src/post/effects.ts
|
|
442
|
+
function toU8(value) {
|
|
443
|
+
return Math.round(Math.max(0, Math.min(1, Number.isFinite(value) ? value : 0)) * 255);
|
|
542
444
|
}
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
const flatStyles = {};
|
|
546
|
-
for (const tokenStyle of theme) {
|
|
547
|
-
const styleDefinition = {};
|
|
548
|
-
if (tokenStyle.style.foreground) {
|
|
549
|
-
styleDefinition.fg = parseColor(tokenStyle.style.foreground);
|
|
550
|
-
}
|
|
551
|
-
if (tokenStyle.style.background) {
|
|
552
|
-
styleDefinition.bg = parseColor(tokenStyle.style.background);
|
|
553
|
-
}
|
|
554
|
-
if (tokenStyle.style.bold !== undefined) {
|
|
555
|
-
styleDefinition.bold = tokenStyle.style.bold;
|
|
556
|
-
}
|
|
557
|
-
if (tokenStyle.style.italic !== undefined) {
|
|
558
|
-
styleDefinition.italic = tokenStyle.style.italic;
|
|
559
|
-
}
|
|
560
|
-
if (tokenStyle.style.underline !== undefined) {
|
|
561
|
-
styleDefinition.underline = tokenStyle.style.underline;
|
|
562
|
-
}
|
|
563
|
-
if (tokenStyle.style.dim !== undefined) {
|
|
564
|
-
styleDefinition.dim = tokenStyle.style.dim;
|
|
565
|
-
}
|
|
566
|
-
for (const scope of tokenStyle.scope) {
|
|
567
|
-
flatStyles[scope] = styleDefinition;
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
return flatStyles;
|
|
445
|
+
function channel(buffer, index) {
|
|
446
|
+
return (buffer[index] & 255) / 255;
|
|
571
447
|
}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
styleDefs = new Map;
|
|
579
|
-
mergedCache = new Map;
|
|
580
|
-
constructor(lib, ptr) {
|
|
581
|
-
this.lib = lib;
|
|
582
|
-
this.stylePtr = ptr;
|
|
583
|
-
}
|
|
584
|
-
static create() {
|
|
585
|
-
const lib = resolveRenderLib();
|
|
586
|
-
const ptr = lib.createSyntaxStyle();
|
|
587
|
-
return new SyntaxStyle(lib, ptr);
|
|
588
|
-
}
|
|
589
|
-
static fromTheme(theme) {
|
|
590
|
-
const style = SyntaxStyle.create();
|
|
591
|
-
const flatStyles = convertThemeToStyles(theme);
|
|
592
|
-
for (const [name, styleDef] of Object.entries(flatStyles)) {
|
|
593
|
-
style.registerStyle(name, styleDef);
|
|
594
|
-
}
|
|
595
|
-
return style;
|
|
596
|
-
}
|
|
597
|
-
static fromStyles(styles) {
|
|
598
|
-
const style = SyntaxStyle.create();
|
|
599
|
-
for (const [name, styleDef] of Object.entries(styles)) {
|
|
600
|
-
style.registerStyle(name, styleDef);
|
|
601
|
-
}
|
|
602
|
-
return style;
|
|
603
|
-
}
|
|
604
|
-
guard() {
|
|
605
|
-
if (this._destroyed)
|
|
606
|
-
throw new Error("NativeSyntaxStyle is destroyed");
|
|
607
|
-
}
|
|
608
|
-
registerStyle(name, style) {
|
|
609
|
-
this.guard();
|
|
610
|
-
const attributes = createTextAttributes({
|
|
611
|
-
bold: style.bold,
|
|
612
|
-
italic: style.italic,
|
|
613
|
-
underline: style.underline,
|
|
614
|
-
dim: style.dim
|
|
615
|
-
});
|
|
616
|
-
const id = this.lib.syntaxStyleRegister(this.stylePtr, name, style.fg || null, style.bg || null, attributes);
|
|
617
|
-
this.nameCache.set(name, id);
|
|
618
|
-
this.styleDefs.set(name, style);
|
|
619
|
-
return id;
|
|
620
|
-
}
|
|
621
|
-
resolveStyleId(name) {
|
|
622
|
-
this.guard();
|
|
623
|
-
const cached = this.nameCache.get(name);
|
|
624
|
-
if (cached !== undefined)
|
|
625
|
-
return cached;
|
|
626
|
-
const id = this.lib.syntaxStyleResolveByName(this.stylePtr, name);
|
|
627
|
-
if (id !== null) {
|
|
628
|
-
this.nameCache.set(name, id);
|
|
629
|
-
}
|
|
630
|
-
return id;
|
|
631
|
-
}
|
|
632
|
-
getStyleId(name) {
|
|
633
|
-
this.guard();
|
|
634
|
-
const id = this.resolveStyleId(name);
|
|
635
|
-
if (id !== null)
|
|
636
|
-
return id;
|
|
637
|
-
if (name.includes(".")) {
|
|
638
|
-
const baseName = name.split(".")[0];
|
|
639
|
-
return this.resolveStyleId(baseName);
|
|
640
|
-
}
|
|
641
|
-
return null;
|
|
642
|
-
}
|
|
643
|
-
get ptr() {
|
|
644
|
-
this.guard();
|
|
645
|
-
return this.stylePtr;
|
|
646
|
-
}
|
|
647
|
-
getStyleCount() {
|
|
648
|
-
this.guard();
|
|
649
|
-
return this.lib.syntaxStyleGetStyleCount(this.stylePtr);
|
|
650
|
-
}
|
|
651
|
-
clearNameCache() {
|
|
652
|
-
this.nameCache.clear();
|
|
653
|
-
}
|
|
654
|
-
getStyle(name) {
|
|
655
|
-
this.guard();
|
|
656
|
-
if (Object.prototype.hasOwnProperty.call(this.styleDefs, name)) {
|
|
657
|
-
return;
|
|
658
|
-
}
|
|
659
|
-
const style = this.styleDefs.get(name);
|
|
660
|
-
if (style)
|
|
661
|
-
return style;
|
|
662
|
-
if (name.includes(".")) {
|
|
663
|
-
const baseName = name.split(".")[0];
|
|
664
|
-
if (Object.prototype.hasOwnProperty.call(this.styleDefs, baseName)) {
|
|
665
|
-
return;
|
|
666
|
-
}
|
|
667
|
-
return this.styleDefs.get(baseName);
|
|
668
|
-
}
|
|
669
|
-
return;
|
|
670
|
-
}
|
|
671
|
-
mergeStyles(...styleNames) {
|
|
672
|
-
this.guard();
|
|
673
|
-
const cacheKey = styleNames.join(":");
|
|
674
|
-
const cached = this.mergedCache.get(cacheKey);
|
|
675
|
-
if (cached)
|
|
676
|
-
return cached;
|
|
677
|
-
const styleDefinition = {};
|
|
678
|
-
for (const name of styleNames) {
|
|
679
|
-
const style = this.getStyle(name);
|
|
680
|
-
if (!style)
|
|
681
|
-
continue;
|
|
682
|
-
if (style.fg)
|
|
683
|
-
styleDefinition.fg = style.fg;
|
|
684
|
-
if (style.bg)
|
|
685
|
-
styleDefinition.bg = style.bg;
|
|
686
|
-
if (style.bold !== undefined)
|
|
687
|
-
styleDefinition.bold = style.bold;
|
|
688
|
-
if (style.italic !== undefined)
|
|
689
|
-
styleDefinition.italic = style.italic;
|
|
690
|
-
if (style.underline !== undefined)
|
|
691
|
-
styleDefinition.underline = style.underline;
|
|
692
|
-
if (style.dim !== undefined)
|
|
693
|
-
styleDefinition.dim = style.dim;
|
|
694
|
-
}
|
|
695
|
-
const attributes = createTextAttributes({
|
|
696
|
-
bold: styleDefinition.bold,
|
|
697
|
-
italic: styleDefinition.italic,
|
|
698
|
-
underline: styleDefinition.underline,
|
|
699
|
-
dim: styleDefinition.dim
|
|
700
|
-
});
|
|
701
|
-
const merged = {
|
|
702
|
-
fg: styleDefinition.fg,
|
|
703
|
-
bg: styleDefinition.bg,
|
|
704
|
-
attributes
|
|
705
|
-
};
|
|
706
|
-
this.mergedCache.set(cacheKey, merged);
|
|
707
|
-
return merged;
|
|
708
|
-
}
|
|
709
|
-
clearCache() {
|
|
710
|
-
this.guard();
|
|
711
|
-
this.mergedCache.clear();
|
|
712
|
-
}
|
|
713
|
-
getCacheSize() {
|
|
714
|
-
this.guard();
|
|
715
|
-
return this.mergedCache.size;
|
|
716
|
-
}
|
|
717
|
-
getAllStyles() {
|
|
718
|
-
this.guard();
|
|
719
|
-
return new Map(this.styleDefs);
|
|
720
|
-
}
|
|
721
|
-
getRegisteredNames() {
|
|
722
|
-
this.guard();
|
|
723
|
-
return Array.from(this.styleDefs.keys());
|
|
724
|
-
}
|
|
725
|
-
destroy() {
|
|
726
|
-
if (this._destroyed)
|
|
727
|
-
return;
|
|
728
|
-
this._destroyed = true;
|
|
729
|
-
this.nameCache.clear();
|
|
730
|
-
this.styleDefs.clear();
|
|
731
|
-
this.mergedCache.clear();
|
|
732
|
-
this.lib.destroySyntaxStyle(this.stylePtr);
|
|
733
|
-
}
|
|
448
|
+
function setRgb(buffer, base, r, g, b) {
|
|
449
|
+
const a = buffer[base + 3] & 255;
|
|
450
|
+
buffer[base] = toU8(r);
|
|
451
|
+
buffer[base + 1] = toU8(g);
|
|
452
|
+
buffer[base + 2] = toU8(b);
|
|
453
|
+
buffer[base + 3] = a;
|
|
734
454
|
}
|
|
735
|
-
|
|
455
|
+
|
|
736
456
|
class DistortionEffect {
|
|
737
457
|
glitchChancePerSecond = 0.5;
|
|
738
458
|
maxGlitchLines = 3;
|
|
@@ -796,8 +516,8 @@ class DistortionEffect {
|
|
|
796
516
|
if (glitch.type === "shift" || glitch.type === "flip") {
|
|
797
517
|
if (!tempChar) {
|
|
798
518
|
tempChar = new Uint32Array(width);
|
|
799
|
-
tempFg = new
|
|
800
|
-
tempBg = new
|
|
519
|
+
tempFg = new Uint16Array(width * 4);
|
|
520
|
+
tempBg = new Uint16Array(width * 4);
|
|
801
521
|
tempAttr = new Uint8Array(width);
|
|
802
522
|
}
|
|
803
523
|
try {
|
|
@@ -904,12 +624,8 @@ class DistortionEffect {
|
|
|
904
624
|
gBg = 1 - gFg;
|
|
905
625
|
bBg = 1 - bFg;
|
|
906
626
|
}
|
|
907
|
-
buf.fg
|
|
908
|
-
buf.
|
|
909
|
-
buf.fg[destColorIndex + 2] = bFg;
|
|
910
|
-
buf.bg[destColorIndex] = rBg;
|
|
911
|
-
buf.bg[destColorIndex + 1] = gBg;
|
|
912
|
-
buf.bg[destColorIndex + 2] = bBg;
|
|
627
|
+
setRgb(buf.fg, destColorIndex, rFg, gFg, bFg);
|
|
628
|
+
setRgb(buf.bg, destColorIndex, rBg, gBg, bBg);
|
|
913
629
|
}
|
|
914
630
|
}
|
|
915
631
|
}
|
|
@@ -1174,9 +890,7 @@ class FlamesEffect {
|
|
|
1174
890
|
g = flameIntensity * 0.5;
|
|
1175
891
|
b = 0;
|
|
1176
892
|
}
|
|
1177
|
-
bg2
|
|
1178
|
-
bg2[colorIndex + 1] = Math.max(bg2[colorIndex + 1], g * flameIntensity);
|
|
1179
|
-
bg2[colorIndex + 2] = Math.max(bg2[colorIndex + 2], b * flameIntensity);
|
|
893
|
+
setRgb(bg2, colorIndex, Math.max(channel(bg2, colorIndex), r * flameIntensity), Math.max(channel(bg2, colorIndex + 1), g * flameIntensity), Math.max(channel(bg2, colorIndex + 2), b * flameIntensity));
|
|
1180
894
|
}
|
|
1181
895
|
}
|
|
1182
896
|
}
|
|
@@ -1242,12 +956,8 @@ class CRTRollingBarEffect {
|
|
|
1242
956
|
const rowMultiplier = 1 + this._intensity * barFactor;
|
|
1243
957
|
for (let x = 0;x < width; x++) {
|
|
1244
958
|
const colorIndex = (y * width + x) * 4;
|
|
1245
|
-
fg2
|
|
1246
|
-
|
|
1247
|
-
fg2[colorIndex + 2] = Math.min(1, fg2[colorIndex + 2] * rowMultiplier);
|
|
1248
|
-
bg2[colorIndex] = Math.min(1, bg2[colorIndex] * rowMultiplier);
|
|
1249
|
-
bg2[colorIndex + 1] = Math.min(1, bg2[colorIndex + 1] * rowMultiplier);
|
|
1250
|
-
bg2[colorIndex + 2] = Math.min(1, bg2[colorIndex + 2] * rowMultiplier);
|
|
959
|
+
setRgb(fg2, colorIndex, Math.min(1, channel(fg2, colorIndex) * rowMultiplier), Math.min(1, channel(fg2, colorIndex + 1) * rowMultiplier), Math.min(1, channel(fg2, colorIndex + 2) * rowMultiplier));
|
|
960
|
+
setRgb(bg2, colorIndex, Math.min(1, channel(bg2, colorIndex) * rowMultiplier), Math.min(1, channel(bg2, colorIndex + 1) * rowMultiplier), Math.min(1, channel(bg2, colorIndex + 2) * rowMultiplier));
|
|
1251
961
|
}
|
|
1252
962
|
}
|
|
1253
963
|
}
|
|
@@ -1346,23 +1056,34 @@ class RainbowTextEffect {
|
|
|
1346
1056
|
for (let y = 0;y < height; y++) {
|
|
1347
1057
|
for (let x = 0;x < width; x++) {
|
|
1348
1058
|
const colorIndex = (y * width + x) * 4;
|
|
1349
|
-
const r = fg2
|
|
1350
|
-
const g = fg2
|
|
1351
|
-
const b = fg2
|
|
1059
|
+
const r = channel(fg2, colorIndex);
|
|
1060
|
+
const g = channel(fg2, colorIndex + 1);
|
|
1061
|
+
const b = channel(fg2, colorIndex + 2);
|
|
1352
1062
|
if (r >= whiteThreshold && g >= whiteThreshold && b >= whiteThreshold) {
|
|
1353
1063
|
const projection = x * cosAngle + y * sinAngle;
|
|
1354
1064
|
const maxProjection = width * cosAngle + height * sinAngle;
|
|
1355
1065
|
const hue = (projection / maxProjection * repeats + this.time * 0.1) % 1;
|
|
1356
1066
|
const [newR, newG, newB] = this.hsvToRgb(hue, saturation, value);
|
|
1357
|
-
fg2
|
|
1358
|
-
fg2[colorIndex + 1] = newG;
|
|
1359
|
-
fg2[colorIndex + 2] = newB;
|
|
1067
|
+
setRgb(fg2, colorIndex, newR, newG, newB);
|
|
1360
1068
|
}
|
|
1361
1069
|
}
|
|
1362
1070
|
}
|
|
1363
1071
|
}
|
|
1364
1072
|
}
|
|
1365
1073
|
// src/post/filters.ts
|
|
1074
|
+
function toU82(value) {
|
|
1075
|
+
return Math.round(Math.max(0, Math.min(1, Number.isFinite(value) ? value : 0)) * 255);
|
|
1076
|
+
}
|
|
1077
|
+
function channel2(buffer, index) {
|
|
1078
|
+
return (buffer[index] & 255) / 255;
|
|
1079
|
+
}
|
|
1080
|
+
function setRgb2(buffer, base, r, g, b) {
|
|
1081
|
+
const a = buffer[base + 3] & 255;
|
|
1082
|
+
buffer[base] = toU82(r);
|
|
1083
|
+
buffer[base + 1] = toU82(g);
|
|
1084
|
+
buffer[base + 2] = toU82(b);
|
|
1085
|
+
buffer[base + 3] = a;
|
|
1086
|
+
}
|
|
1366
1087
|
function applyScanlines(buffer, strength = 0.8, step = 2) {
|
|
1367
1088
|
if (strength === 1 || step < 1)
|
|
1368
1089
|
return;
|
|
@@ -1462,7 +1183,7 @@ function applyNoise(buffer, strength = 0.1) {
|
|
|
1462
1183
|
function applyChromaticAberration(buffer, strength = 1) {
|
|
1463
1184
|
const width = buffer.width;
|
|
1464
1185
|
const height = buffer.height;
|
|
1465
|
-
const srcFg =
|
|
1186
|
+
const srcFg = Uint16Array.from(buffer.buffers.fg);
|
|
1466
1187
|
const destFg = buffer.buffers.fg;
|
|
1467
1188
|
const centerX = width / 2;
|
|
1468
1189
|
const centerY = height / 2;
|
|
@@ -1477,9 +1198,7 @@ function applyChromaticAberration(buffer, strength = 1) {
|
|
|
1477
1198
|
const gIndex = (y * width + x) * 4;
|
|
1478
1199
|
const bIndex = (y * width + bX) * 4;
|
|
1479
1200
|
const destIndex = (y * width + x) * 4;
|
|
1480
|
-
destFg
|
|
1481
|
-
destFg[destIndex + 1] = srcFg[gIndex + 1];
|
|
1482
|
-
destFg[destIndex + 2] = srcFg[bIndex + 2];
|
|
1201
|
+
setRgb2(destFg, destIndex, channel2(srcFg, rIndex), channel2(srcFg, gIndex + 1), channel2(srcFg, bIndex + 2));
|
|
1483
1202
|
}
|
|
1484
1203
|
}
|
|
1485
1204
|
}
|
|
@@ -1493,9 +1212,9 @@ function applyAsciiArt(buffer, ramp = ' .\'`^"",:;Il!i><~+_-?][}{1)(|\\/tfjrxnuv
|
|
|
1493
1212
|
for (let x = 0;x < width; x++) {
|
|
1494
1213
|
const index = y * width + x;
|
|
1495
1214
|
const colorIndex = index * 4;
|
|
1496
|
-
const bgR = bg2
|
|
1497
|
-
const bgG = bg2
|
|
1498
|
-
const bgB = bg2
|
|
1215
|
+
const bgR = channel2(bg2, colorIndex);
|
|
1216
|
+
const bgG = channel2(bg2, colorIndex + 1);
|
|
1217
|
+
const bgB = channel2(bg2, colorIndex + 2);
|
|
1499
1218
|
const lum = 0.299 * bgR + 0.587 * bgG + 0.114 * bgB;
|
|
1500
1219
|
const rampIndex = Math.min(rampLength - 1, Math.floor(lum * rampLength));
|
|
1501
1220
|
chars[index] = ramp[rampIndex].charCodeAt(0);
|
|
@@ -1676,16 +1395,16 @@ class BloomEffect {
|
|
|
1676
1395
|
return;
|
|
1677
1396
|
const width = buffer.width;
|
|
1678
1397
|
const height = buffer.height;
|
|
1679
|
-
const srcFg =
|
|
1680
|
-
const srcBg =
|
|
1398
|
+
const srcFg = Uint16Array.from(buffer.buffers.fg);
|
|
1399
|
+
const srcBg = Uint16Array.from(buffer.buffers.bg);
|
|
1681
1400
|
const destFg = buffer.buffers.fg;
|
|
1682
1401
|
const destBg = buffer.buffers.bg;
|
|
1683
1402
|
const brightPixels = [];
|
|
1684
1403
|
for (let y = 0;y < height; y++) {
|
|
1685
1404
|
for (let x = 0;x < width; x++) {
|
|
1686
1405
|
const index = (y * width + x) * 4;
|
|
1687
|
-
const fgLum = 0.299 * srcFg
|
|
1688
|
-
const bgLum = 0.299 * srcBg
|
|
1406
|
+
const fgLum = 0.299 * channel2(srcFg, index) + 0.587 * channel2(srcFg, index + 1) + 0.114 * channel2(srcFg, index + 2);
|
|
1407
|
+
const bgLum = 0.299 * channel2(srcBg, index) + 0.587 * channel2(srcBg, index + 1) + 0.114 * channel2(srcBg, index + 2);
|
|
1689
1408
|
const lum = Math.max(fgLum, bgLum);
|
|
1690
1409
|
if (lum > threshold) {
|
|
1691
1410
|
const intensity = (lum - threshold) / (1 - threshold + 0.000001);
|
|
@@ -1711,12 +1430,8 @@ class BloomEffect {
|
|
|
1711
1430
|
const falloff = 1 - distSq / radiusSq;
|
|
1712
1431
|
const bloomAmount = bright.intensity * strength * falloff;
|
|
1713
1432
|
const destIndex = (sampleY * width + sampleX) * 4;
|
|
1714
|
-
destFg
|
|
1715
|
-
|
|
1716
|
-
destFg[destIndex + 2] = Math.min(1, destFg[destIndex + 2] + bloomAmount);
|
|
1717
|
-
destBg[destIndex] = Math.min(1, destBg[destIndex] + bloomAmount);
|
|
1718
|
-
destBg[destIndex + 1] = Math.min(1, destBg[destIndex + 1] + bloomAmount);
|
|
1719
|
-
destBg[destIndex + 2] = Math.min(1, destBg[destIndex + 2] + bloomAmount);
|
|
1433
|
+
setRgb2(destFg, destIndex, Math.min(1, channel2(destFg, destIndex) + bloomAmount), Math.min(1, channel2(destFg, destIndex + 1) + bloomAmount), Math.min(1, channel2(destFg, destIndex + 2) + bloomAmount));
|
|
1434
|
+
setRgb2(destBg, destIndex, Math.min(1, channel2(destBg, destIndex) + bloomAmount), Math.min(1, channel2(destBg, destIndex + 1) + bloomAmount), Math.min(1, channel2(destBg, destIndex + 2) + bloomAmount));
|
|
1720
1435
|
}
|
|
1721
1436
|
}
|
|
1722
1437
|
}
|
|
@@ -3061,15 +2776,6 @@ class SlotRenderable extends Renderable {
|
|
|
3061
2776
|
}
|
|
3062
2777
|
}
|
|
3063
2778
|
// src/NativeSpanFeed.ts
|
|
3064
|
-
function toPointer(value) {
|
|
3065
|
-
if (typeof value === "bigint") {
|
|
3066
|
-
if (value > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
3067
|
-
throw new Error("Pointer exceeds safe integer range");
|
|
3068
|
-
}
|
|
3069
|
-
return Number(value);
|
|
3070
|
-
}
|
|
3071
|
-
return value;
|
|
3072
|
-
}
|
|
3073
2779
|
function toNumber(value) {
|
|
3074
2780
|
return typeof value === "bigint" ? Number(value) : value;
|
|
3075
2781
|
}
|
|
@@ -3090,12 +2796,11 @@ class NativeSpanFeed {
|
|
|
3090
2796
|
}
|
|
3091
2797
|
static attach(streamPtr, _options) {
|
|
3092
2798
|
const lib = resolveRenderLib();
|
|
3093
|
-
const
|
|
3094
|
-
|
|
3095
|
-
lib.
|
|
3096
|
-
const status = lib.attachNativeSpanFeed(ptr);
|
|
2799
|
+
const stream = new NativeSpanFeed(streamPtr);
|
|
2800
|
+
lib.registerNativeSpanFeedStream(streamPtr, stream.eventHandler);
|
|
2801
|
+
const status = lib.attachNativeSpanFeed(streamPtr);
|
|
3097
2802
|
if (status !== 0) {
|
|
3098
|
-
lib.unregisterNativeSpanFeedStream(
|
|
2803
|
+
lib.unregisterNativeSpanFeedStream(streamPtr);
|
|
3099
2804
|
throw new Error(`Failed to attach stream: ${status}`);
|
|
3100
2805
|
}
|
|
3101
2806
|
return stream;
|
|
@@ -3229,7 +2934,7 @@ class NativeSpanFeed {
|
|
|
3229
2934
|
break;
|
|
3230
2935
|
}
|
|
3231
2936
|
case 6 /* Error */: {
|
|
3232
|
-
const code = arg0;
|
|
2937
|
+
const code = toNumber(arg0);
|
|
3233
2938
|
for (const handler of this.errorHandlers)
|
|
3234
2939
|
handler(code);
|
|
3235
2940
|
break;
|
|
@@ -3319,6 +3024,362 @@ class NativeSpanFeed {
|
|
|
3319
3024
|
}
|
|
3320
3025
|
}
|
|
3321
3026
|
}
|
|
3027
|
+
// src/audio.ts
|
|
3028
|
+
import { EventEmitter } from "events";
|
|
3029
|
+
import { readFile } from "fs/promises";
|
|
3030
|
+
function statusToError(action, status) {
|
|
3031
|
+
return new Error(`Audio ${action} failed: ${status}`);
|
|
3032
|
+
}
|
|
3033
|
+
function toBytes(data) {
|
|
3034
|
+
return data instanceof Uint8Array ? data : new Uint8Array(data);
|
|
3035
|
+
}
|
|
3036
|
+
|
|
3037
|
+
class Audio extends EventEmitter {
|
|
3038
|
+
static create(options = {}) {
|
|
3039
|
+
return new Audio(resolveRenderLib(), options);
|
|
3040
|
+
}
|
|
3041
|
+
lib;
|
|
3042
|
+
defaultStartOptions;
|
|
3043
|
+
engine = null;
|
|
3044
|
+
groups = new Map;
|
|
3045
|
+
playbackStarted = false;
|
|
3046
|
+
mixerStarted = false;
|
|
3047
|
+
constructor(lib, options) {
|
|
3048
|
+
super();
|
|
3049
|
+
this.lib = lib;
|
|
3050
|
+
this.defaultStartOptions = options.startOptions;
|
|
3051
|
+
const createOptions = options.sampleRate == null && options.playbackChannels == null ? undefined : {
|
|
3052
|
+
sampleRate: options.sampleRate == null ? undefined : Math.max(0, Math.trunc(options.sampleRate)),
|
|
3053
|
+
playbackChannels: options.playbackChannels == null ? undefined : Math.max(0, Math.trunc(options.playbackChannels))
|
|
3054
|
+
};
|
|
3055
|
+
this.engine = this.lib.createAudioEngine(createOptions);
|
|
3056
|
+
if (!this.engine) {
|
|
3057
|
+
this.emitError("createAudioEngine", undefined, "Audio createAudioEngine returned null");
|
|
3058
|
+
return;
|
|
3059
|
+
}
|
|
3060
|
+
if (options.autoStart ?? false) {
|
|
3061
|
+
this.start(this.defaultStartOptions);
|
|
3062
|
+
}
|
|
3063
|
+
}
|
|
3064
|
+
emitError(action, status, message, cause) {
|
|
3065
|
+
const error = message ? new Error(message) : statusToError(action, status ?? -1);
|
|
3066
|
+
if (cause)
|
|
3067
|
+
error.cause = cause;
|
|
3068
|
+
this.emit("error", error, { action, status });
|
|
3069
|
+
}
|
|
3070
|
+
start(options) {
|
|
3071
|
+
if (this.playbackStarted)
|
|
3072
|
+
return true;
|
|
3073
|
+
const engine2 = this.engine;
|
|
3074
|
+
if (!engine2) {
|
|
3075
|
+
this.emitError("start", undefined, "Audio engine unavailable during start");
|
|
3076
|
+
return false;
|
|
3077
|
+
}
|
|
3078
|
+
const startOptions = options ?? this.defaultStartOptions;
|
|
3079
|
+
const status = this.lib.audioStart(engine2, startOptions);
|
|
3080
|
+
if (status !== 0) {
|
|
3081
|
+
this.emitError("start", status);
|
|
3082
|
+
return false;
|
|
3083
|
+
}
|
|
3084
|
+
this.playbackStarted = true;
|
|
3085
|
+
this.mixerStarted = true;
|
|
3086
|
+
this.emit("started");
|
|
3087
|
+
return true;
|
|
3088
|
+
}
|
|
3089
|
+
startMixer() {
|
|
3090
|
+
if (this.mixerStarted)
|
|
3091
|
+
return true;
|
|
3092
|
+
const engine2 = this.engine;
|
|
3093
|
+
if (!engine2) {
|
|
3094
|
+
this.emitError("startMixer", undefined, "Audio engine unavailable during startMixer");
|
|
3095
|
+
return false;
|
|
3096
|
+
}
|
|
3097
|
+
const status = this.lib.audioStartMixer(engine2);
|
|
3098
|
+
if (status !== 0) {
|
|
3099
|
+
this.emitError("startMixer", status);
|
|
3100
|
+
return false;
|
|
3101
|
+
}
|
|
3102
|
+
this.mixerStarted = true;
|
|
3103
|
+
this.emit("mixerStarted");
|
|
3104
|
+
return true;
|
|
3105
|
+
}
|
|
3106
|
+
stop() {
|
|
3107
|
+
if (!this.mixerStarted)
|
|
3108
|
+
return true;
|
|
3109
|
+
const engine2 = this.engine;
|
|
3110
|
+
if (!engine2) {
|
|
3111
|
+
this.emitError("stop", undefined, "Audio engine unavailable during stop");
|
|
3112
|
+
return false;
|
|
3113
|
+
}
|
|
3114
|
+
const status = this.lib.audioStop(engine2);
|
|
3115
|
+
if (status !== 0) {
|
|
3116
|
+
this.emitError("stop", status);
|
|
3117
|
+
return false;
|
|
3118
|
+
}
|
|
3119
|
+
this.playbackStarted = false;
|
|
3120
|
+
this.mixerStarted = false;
|
|
3121
|
+
this.emit("stopped");
|
|
3122
|
+
return true;
|
|
3123
|
+
}
|
|
3124
|
+
isStarted() {
|
|
3125
|
+
return this.playbackStarted;
|
|
3126
|
+
}
|
|
3127
|
+
isMixerStarted() {
|
|
3128
|
+
return this.mixerStarted;
|
|
3129
|
+
}
|
|
3130
|
+
loadSound(data) {
|
|
3131
|
+
const engine2 = this.engine;
|
|
3132
|
+
if (!engine2) {
|
|
3133
|
+
this.emitError("loadSound", undefined, "Audio engine unavailable during loadSound");
|
|
3134
|
+
return null;
|
|
3135
|
+
}
|
|
3136
|
+
const result = this.lib.audioLoad(engine2, toBytes(data));
|
|
3137
|
+
if (result.status !== 0 || result.soundId == null) {
|
|
3138
|
+
this.emitError("loadSound", result.status);
|
|
3139
|
+
return null;
|
|
3140
|
+
}
|
|
3141
|
+
return result.soundId;
|
|
3142
|
+
}
|
|
3143
|
+
async loadSoundFile(filePath) {
|
|
3144
|
+
const bytes = await readFile(filePath).catch((err) => {
|
|
3145
|
+
this.emitError("loadSoundFile", undefined, `Failed to read file '${filePath}': ${err.message}`, err);
|
|
3146
|
+
return null;
|
|
3147
|
+
});
|
|
3148
|
+
if (bytes == null)
|
|
3149
|
+
return null;
|
|
3150
|
+
return this.loadSound(bytes);
|
|
3151
|
+
}
|
|
3152
|
+
unloadSound(sound) {
|
|
3153
|
+
const engine2 = this.engine;
|
|
3154
|
+
if (!engine2) {
|
|
3155
|
+
this.emitError("unloadSound", undefined, "Audio engine unavailable during unloadSound");
|
|
3156
|
+
return false;
|
|
3157
|
+
}
|
|
3158
|
+
const status = this.lib.audioUnload(engine2, sound);
|
|
3159
|
+
if (status !== 0) {
|
|
3160
|
+
this.emitError("unloadSound", status);
|
|
3161
|
+
return false;
|
|
3162
|
+
}
|
|
3163
|
+
return true;
|
|
3164
|
+
}
|
|
3165
|
+
group(name) {
|
|
3166
|
+
const existing = this.groups.get(name);
|
|
3167
|
+
if (existing != null) {
|
|
3168
|
+
return existing;
|
|
3169
|
+
}
|
|
3170
|
+
const engine2 = this.engine;
|
|
3171
|
+
if (!engine2) {
|
|
3172
|
+
this.emitError("group", undefined, "Audio engine unavailable during group");
|
|
3173
|
+
return null;
|
|
3174
|
+
}
|
|
3175
|
+
const result = this.lib.audioCreateGroup(engine2, name);
|
|
3176
|
+
if (result.status !== 0 || result.groupId == null) {
|
|
3177
|
+
this.emitError("group", result.status);
|
|
3178
|
+
return null;
|
|
3179
|
+
}
|
|
3180
|
+
this.groups.set(name, result.groupId);
|
|
3181
|
+
return result.groupId;
|
|
3182
|
+
}
|
|
3183
|
+
play(sound, options) {
|
|
3184
|
+
const rawOptions = options ? {
|
|
3185
|
+
volume: options.volume,
|
|
3186
|
+
pan: options.pan,
|
|
3187
|
+
loop: options.loop,
|
|
3188
|
+
groupId: options.groupId ?? 0
|
|
3189
|
+
} : undefined;
|
|
3190
|
+
const engine2 = this.engine;
|
|
3191
|
+
if (!engine2) {
|
|
3192
|
+
this.emitError("play", undefined, "Audio engine unavailable during play");
|
|
3193
|
+
return null;
|
|
3194
|
+
}
|
|
3195
|
+
const result = this.lib.audioPlay(engine2, sound, rawOptions);
|
|
3196
|
+
if (result.status !== 0 || result.voiceId == null) {
|
|
3197
|
+
this.emitError("play", result.status);
|
|
3198
|
+
return null;
|
|
3199
|
+
}
|
|
3200
|
+
return result.voiceId;
|
|
3201
|
+
}
|
|
3202
|
+
stopVoice(voice) {
|
|
3203
|
+
const engine2 = this.engine;
|
|
3204
|
+
if (!engine2) {
|
|
3205
|
+
this.emitError("stopVoice", undefined, "Audio engine unavailable during stopVoice");
|
|
3206
|
+
return false;
|
|
3207
|
+
}
|
|
3208
|
+
const status = this.lib.audioStopVoice(engine2, voice);
|
|
3209
|
+
if (status !== 0) {
|
|
3210
|
+
this.emitError("stopVoice", status);
|
|
3211
|
+
return false;
|
|
3212
|
+
}
|
|
3213
|
+
return true;
|
|
3214
|
+
}
|
|
3215
|
+
setVoiceGroup(voice, group) {
|
|
3216
|
+
const engine2 = this.engine;
|
|
3217
|
+
if (!engine2) {
|
|
3218
|
+
this.emitError("setVoiceGroup", undefined, "Audio engine unavailable during setVoiceGroup");
|
|
3219
|
+
return false;
|
|
3220
|
+
}
|
|
3221
|
+
const status = this.lib.audioSetVoiceGroup(engine2, voice, group);
|
|
3222
|
+
if (status !== 0) {
|
|
3223
|
+
this.emitError("setVoiceGroup", status);
|
|
3224
|
+
return false;
|
|
3225
|
+
}
|
|
3226
|
+
return true;
|
|
3227
|
+
}
|
|
3228
|
+
setGroupVolume(group, volume) {
|
|
3229
|
+
const engine2 = this.engine;
|
|
3230
|
+
if (!engine2) {
|
|
3231
|
+
this.emitError("setGroupVolume", undefined, "Audio engine unavailable during setGroupVolume");
|
|
3232
|
+
return false;
|
|
3233
|
+
}
|
|
3234
|
+
const status = this.lib.audioSetGroupVolume(engine2, group, volume);
|
|
3235
|
+
if (status !== 0) {
|
|
3236
|
+
this.emitError("setGroupVolume", status);
|
|
3237
|
+
return false;
|
|
3238
|
+
}
|
|
3239
|
+
return true;
|
|
3240
|
+
}
|
|
3241
|
+
setMasterVolume(volume) {
|
|
3242
|
+
const engine2 = this.engine;
|
|
3243
|
+
if (!engine2) {
|
|
3244
|
+
this.emitError("setMasterVolume", undefined, "Audio engine unavailable during setMasterVolume");
|
|
3245
|
+
return false;
|
|
3246
|
+
}
|
|
3247
|
+
const status = this.lib.audioSetMasterVolume(engine2, volume);
|
|
3248
|
+
if (status !== 0) {
|
|
3249
|
+
this.emitError("setMasterVolume", status);
|
|
3250
|
+
return false;
|
|
3251
|
+
}
|
|
3252
|
+
return true;
|
|
3253
|
+
}
|
|
3254
|
+
mixFrames(frameCount, channels = 2) {
|
|
3255
|
+
const engine2 = this.engine;
|
|
3256
|
+
if (!engine2) {
|
|
3257
|
+
this.emitError("mixFrames", undefined, "Audio engine unavailable during mixFrames");
|
|
3258
|
+
return null;
|
|
3259
|
+
}
|
|
3260
|
+
const output = new Float32Array(frameCount * channels);
|
|
3261
|
+
const status = this.lib.audioMixToBuffer(engine2, output, frameCount, channels);
|
|
3262
|
+
if (status !== 0) {
|
|
3263
|
+
this.emitError("mixFrames", status);
|
|
3264
|
+
return null;
|
|
3265
|
+
}
|
|
3266
|
+
return output;
|
|
3267
|
+
}
|
|
3268
|
+
enableTap(capacityFrames = 8192) {
|
|
3269
|
+
const engine2 = this.engine;
|
|
3270
|
+
if (!engine2) {
|
|
3271
|
+
this.emitError("enableTap", undefined, "Audio engine unavailable during enableTap");
|
|
3272
|
+
return false;
|
|
3273
|
+
}
|
|
3274
|
+
const status = this.lib.audioEnableTap(engine2, true, capacityFrames);
|
|
3275
|
+
if (status !== 0) {
|
|
3276
|
+
this.emitError("enableTap", status);
|
|
3277
|
+
return false;
|
|
3278
|
+
}
|
|
3279
|
+
return true;
|
|
3280
|
+
}
|
|
3281
|
+
disableTap() {
|
|
3282
|
+
const engine2 = this.engine;
|
|
3283
|
+
if (!engine2) {
|
|
3284
|
+
this.emitError("enableTap", undefined, "Audio engine unavailable during disableTap");
|
|
3285
|
+
return false;
|
|
3286
|
+
}
|
|
3287
|
+
const status = this.lib.audioEnableTap(engine2, false, 0);
|
|
3288
|
+
if (status !== 0) {
|
|
3289
|
+
this.emitError("enableTap", status);
|
|
3290
|
+
return false;
|
|
3291
|
+
}
|
|
3292
|
+
return true;
|
|
3293
|
+
}
|
|
3294
|
+
readTapFrames(frameCount, channels = 2) {
|
|
3295
|
+
const engine2 = this.engine;
|
|
3296
|
+
if (!engine2) {
|
|
3297
|
+
this.emitError("readTapFrames", undefined, "Audio engine unavailable during readTapFrames");
|
|
3298
|
+
return null;
|
|
3299
|
+
}
|
|
3300
|
+
const output = new Float32Array(frameCount * channels);
|
|
3301
|
+
const result = this.lib.audioReadTap(engine2, output, frameCount, channels);
|
|
3302
|
+
if (result.status !== 0) {
|
|
3303
|
+
this.emitError("readTapFrames", result.status);
|
|
3304
|
+
return null;
|
|
3305
|
+
}
|
|
3306
|
+
return { frames: output, framesRead: result.framesRead };
|
|
3307
|
+
}
|
|
3308
|
+
listPlaybackDevices() {
|
|
3309
|
+
const engine2 = this.engine;
|
|
3310
|
+
if (!engine2) {
|
|
3311
|
+
this.emitError("listPlaybackDevices", undefined, "Audio engine unavailable during listPlaybackDevices");
|
|
3312
|
+
return null;
|
|
3313
|
+
}
|
|
3314
|
+
const refreshStatus = this.lib.audioRefreshPlaybackDevices(engine2);
|
|
3315
|
+
if (refreshStatus !== 0) {
|
|
3316
|
+
this.emitError("listPlaybackDevices", refreshStatus);
|
|
3317
|
+
return null;
|
|
3318
|
+
}
|
|
3319
|
+
const count = this.lib.audioGetPlaybackDeviceCount(engine2);
|
|
3320
|
+
const devices = [];
|
|
3321
|
+
for (let index = 0;index < count; index += 1) {
|
|
3322
|
+
devices.push({
|
|
3323
|
+
index,
|
|
3324
|
+
name: this.lib.audioGetPlaybackDeviceName(engine2, index),
|
|
3325
|
+
isDefault: this.lib.audioIsPlaybackDeviceDefault(engine2, index)
|
|
3326
|
+
});
|
|
3327
|
+
}
|
|
3328
|
+
return devices;
|
|
3329
|
+
}
|
|
3330
|
+
selectPlaybackDevice(index) {
|
|
3331
|
+
const engine2 = this.engine;
|
|
3332
|
+
if (!engine2) {
|
|
3333
|
+
this.emitError("selectPlaybackDevice", undefined, "Audio engine unavailable during selectPlaybackDevice");
|
|
3334
|
+
return false;
|
|
3335
|
+
}
|
|
3336
|
+
const refreshStatus = this.lib.audioRefreshPlaybackDevices(engine2);
|
|
3337
|
+
if (refreshStatus !== 0) {
|
|
3338
|
+
this.emitError("selectPlaybackDevice", refreshStatus);
|
|
3339
|
+
return false;
|
|
3340
|
+
}
|
|
3341
|
+
const status = this.lib.audioSelectPlaybackDevice(engine2, index);
|
|
3342
|
+
if (status !== 0) {
|
|
3343
|
+
this.emitError("selectPlaybackDevice", status);
|
|
3344
|
+
return false;
|
|
3345
|
+
}
|
|
3346
|
+
return true;
|
|
3347
|
+
}
|
|
3348
|
+
clearPlaybackDeviceSelection() {
|
|
3349
|
+
const engine2 = this.engine;
|
|
3350
|
+
if (!engine2) {
|
|
3351
|
+
this.emitError("clearPlaybackDeviceSelection", undefined, "Audio engine unavailable during clearPlaybackDeviceSelection");
|
|
3352
|
+
return;
|
|
3353
|
+
}
|
|
3354
|
+
this.lib.audioClearPlaybackDeviceSelection(engine2);
|
|
3355
|
+
}
|
|
3356
|
+
getStats() {
|
|
3357
|
+
const engine2 = this.engine;
|
|
3358
|
+
if (!engine2) {
|
|
3359
|
+
this.emitError("getStats", undefined, "Audio engine unavailable during getStats");
|
|
3360
|
+
return null;
|
|
3361
|
+
}
|
|
3362
|
+
const stats = this.lib.audioGetStats(engine2);
|
|
3363
|
+
if (stats == null) {
|
|
3364
|
+
this.emitError("getStats", undefined, "Failed to retrieve audio stats");
|
|
3365
|
+
}
|
|
3366
|
+
return stats;
|
|
3367
|
+
}
|
|
3368
|
+
dispose() {
|
|
3369
|
+
if (!this.engine)
|
|
3370
|
+
return;
|
|
3371
|
+
if (this.mixerStarted) {
|
|
3372
|
+
this.stop();
|
|
3373
|
+
}
|
|
3374
|
+
this.groups.clear();
|
|
3375
|
+
this.lib.destroyAudioEngine(this.engine);
|
|
3376
|
+
this.engine = null;
|
|
3377
|
+
this.emit("disposed");
|
|
3378
|
+
}
|
|
3379
|
+
}
|
|
3380
|
+
function setupAudio(options = {}) {
|
|
3381
|
+
return Audio.create(options);
|
|
3382
|
+
}
|
|
3322
3383
|
// src/renderables/FrameBuffer.ts
|
|
3323
3384
|
class FrameBufferRenderable extends Renderable {
|
|
3324
3385
|
frameBuffer;
|
|
@@ -3506,1139 +3567,9 @@ class ASCIIFontRenderable extends FrameBufferRenderable {
|
|
|
3506
3567
|
}
|
|
3507
3568
|
}
|
|
3508
3569
|
}
|
|
3509
|
-
// src/renderables/
|
|
3510
|
-
function
|
|
3511
|
-
|
|
3512
|
-
return true;
|
|
3513
|
-
}
|
|
3514
|
-
if (typeof value === "number" && !Number.isNaN(value)) {
|
|
3515
|
-
return true;
|
|
3516
|
-
}
|
|
3517
|
-
return isValidPercentage(value);
|
|
3518
|
-
}
|
|
3519
|
-
|
|
3520
|
-
class BoxRenderable extends Renderable {
|
|
3521
|
-
_backgroundColor;
|
|
3522
|
-
_border;
|
|
3523
|
-
_borderStyle;
|
|
3524
|
-
_borderColor;
|
|
3525
|
-
_focusedBorderColor;
|
|
3526
|
-
_customBorderCharsObj;
|
|
3527
|
-
_customBorderChars;
|
|
3528
|
-
borderSides;
|
|
3529
|
-
shouldFill;
|
|
3530
|
-
_title;
|
|
3531
|
-
_titleAlignment;
|
|
3532
|
-
_bottomTitle;
|
|
3533
|
-
_bottomTitleAlignment;
|
|
3534
|
-
_defaultOptions = {
|
|
3535
|
-
backgroundColor: "transparent",
|
|
3536
|
-
borderStyle: "single",
|
|
3537
|
-
border: false,
|
|
3538
|
-
borderColor: "#FFFFFF",
|
|
3539
|
-
shouldFill: true,
|
|
3540
|
-
titleAlignment: "left",
|
|
3541
|
-
bottomTitleAlignment: "left",
|
|
3542
|
-
focusedBorderColor: "#00AAFF"
|
|
3543
|
-
};
|
|
3544
|
-
constructor(ctx, options) {
|
|
3545
|
-
super(ctx, options);
|
|
3546
|
-
if (options.focusable === true) {
|
|
3547
|
-
this._focusable = true;
|
|
3548
|
-
}
|
|
3549
|
-
this._backgroundColor = parseColor(options.backgroundColor || this._defaultOptions.backgroundColor);
|
|
3550
|
-
this._border = options.border ?? this._defaultOptions.border;
|
|
3551
|
-
if (!options.border && (options.borderStyle || options.borderColor || options.focusedBorderColor || options.customBorderChars)) {
|
|
3552
|
-
this._border = true;
|
|
3553
|
-
}
|
|
3554
|
-
this._borderStyle = parseBorderStyle(options.borderStyle, this._defaultOptions.borderStyle);
|
|
3555
|
-
this._borderColor = parseColor(options.borderColor || this._defaultOptions.borderColor);
|
|
3556
|
-
this._focusedBorderColor = parseColor(options.focusedBorderColor || this._defaultOptions.focusedBorderColor);
|
|
3557
|
-
this._customBorderCharsObj = options.customBorderChars;
|
|
3558
|
-
this._customBorderChars = this._customBorderCharsObj ? borderCharsToArray(this._customBorderCharsObj) : undefined;
|
|
3559
|
-
this.borderSides = getBorderSides(this._border);
|
|
3560
|
-
this.shouldFill = options.shouldFill ?? this._defaultOptions.shouldFill;
|
|
3561
|
-
this._title = options.title;
|
|
3562
|
-
this._titleAlignment = options.titleAlignment || this._defaultOptions.titleAlignment;
|
|
3563
|
-
this._bottomTitle = options.bottomTitle;
|
|
3564
|
-
this._bottomTitleAlignment = options.bottomTitleAlignment || this._defaultOptions.bottomTitleAlignment;
|
|
3565
|
-
this.applyYogaBorders();
|
|
3566
|
-
const hasInitialGapProps = options.gap !== undefined || options.rowGap !== undefined || options.columnGap !== undefined;
|
|
3567
|
-
if (hasInitialGapProps) {
|
|
3568
|
-
this.applyYogaGap(options);
|
|
3569
|
-
}
|
|
3570
|
-
}
|
|
3571
|
-
initializeBorder() {
|
|
3572
|
-
if (this._border === false) {
|
|
3573
|
-
this._border = true;
|
|
3574
|
-
this.borderSides = getBorderSides(this._border);
|
|
3575
|
-
this.applyYogaBorders();
|
|
3576
|
-
}
|
|
3577
|
-
}
|
|
3578
|
-
get customBorderChars() {
|
|
3579
|
-
return this._customBorderCharsObj;
|
|
3580
|
-
}
|
|
3581
|
-
set customBorderChars(value) {
|
|
3582
|
-
this._customBorderCharsObj = value;
|
|
3583
|
-
this._customBorderChars = value ? borderCharsToArray(value) : undefined;
|
|
3584
|
-
this.requestRender();
|
|
3585
|
-
}
|
|
3586
|
-
get backgroundColor() {
|
|
3587
|
-
return this._backgroundColor;
|
|
3588
|
-
}
|
|
3589
|
-
set backgroundColor(value) {
|
|
3590
|
-
const newColor = parseColor(value ?? this._defaultOptions.backgroundColor);
|
|
3591
|
-
if (this._backgroundColor !== newColor) {
|
|
3592
|
-
this._backgroundColor = newColor;
|
|
3593
|
-
this.requestRender();
|
|
3594
|
-
}
|
|
3595
|
-
}
|
|
3596
|
-
get border() {
|
|
3597
|
-
return this._border;
|
|
3598
|
-
}
|
|
3599
|
-
set border(value) {
|
|
3600
|
-
if (this._border !== value) {
|
|
3601
|
-
this._border = value;
|
|
3602
|
-
this.borderSides = getBorderSides(value);
|
|
3603
|
-
this.applyYogaBorders();
|
|
3604
|
-
this.requestRender();
|
|
3605
|
-
}
|
|
3606
|
-
}
|
|
3607
|
-
get borderStyle() {
|
|
3608
|
-
return this._borderStyle;
|
|
3609
|
-
}
|
|
3610
|
-
set borderStyle(value) {
|
|
3611
|
-
const _value = parseBorderStyle(value, this._defaultOptions.borderStyle);
|
|
3612
|
-
if (this._borderStyle !== _value || !this._border) {
|
|
3613
|
-
this._borderStyle = _value;
|
|
3614
|
-
this._customBorderChars = undefined;
|
|
3615
|
-
this.initializeBorder();
|
|
3616
|
-
this.requestRender();
|
|
3617
|
-
}
|
|
3618
|
-
}
|
|
3619
|
-
get borderColor() {
|
|
3620
|
-
return this._borderColor;
|
|
3621
|
-
}
|
|
3622
|
-
set borderColor(value) {
|
|
3623
|
-
const newColor = parseColor(value ?? this._defaultOptions.borderColor);
|
|
3624
|
-
if (this._borderColor !== newColor) {
|
|
3625
|
-
this._borderColor = newColor;
|
|
3626
|
-
this.initializeBorder();
|
|
3627
|
-
this.requestRender();
|
|
3628
|
-
}
|
|
3629
|
-
}
|
|
3630
|
-
get focusedBorderColor() {
|
|
3631
|
-
return this._focusedBorderColor;
|
|
3632
|
-
}
|
|
3633
|
-
set focusedBorderColor(value) {
|
|
3634
|
-
const newColor = parseColor(value ?? this._defaultOptions.focusedBorderColor);
|
|
3635
|
-
if (this._focusedBorderColor !== newColor) {
|
|
3636
|
-
this._focusedBorderColor = newColor;
|
|
3637
|
-
this.initializeBorder();
|
|
3638
|
-
if (this._focused) {
|
|
3639
|
-
this.requestRender();
|
|
3640
|
-
}
|
|
3641
|
-
}
|
|
3642
|
-
}
|
|
3643
|
-
get title() {
|
|
3644
|
-
return this._title;
|
|
3645
|
-
}
|
|
3646
|
-
set title(value) {
|
|
3647
|
-
if (this._title !== value) {
|
|
3648
|
-
this._title = value;
|
|
3649
|
-
this.requestRender();
|
|
3650
|
-
}
|
|
3651
|
-
}
|
|
3652
|
-
get titleAlignment() {
|
|
3653
|
-
return this._titleAlignment;
|
|
3654
|
-
}
|
|
3655
|
-
set titleAlignment(value) {
|
|
3656
|
-
if (this._titleAlignment !== value) {
|
|
3657
|
-
this._titleAlignment = value;
|
|
3658
|
-
this.requestRender();
|
|
3659
|
-
}
|
|
3660
|
-
}
|
|
3661
|
-
get bottomTitle() {
|
|
3662
|
-
return this._bottomTitle;
|
|
3663
|
-
}
|
|
3664
|
-
set bottomTitle(value) {
|
|
3665
|
-
if (this._bottomTitle !== value) {
|
|
3666
|
-
this._bottomTitle = value;
|
|
3667
|
-
this.requestRender();
|
|
3668
|
-
}
|
|
3669
|
-
}
|
|
3670
|
-
get bottomTitleAlignment() {
|
|
3671
|
-
return this._bottomTitleAlignment;
|
|
3672
|
-
}
|
|
3673
|
-
set bottomTitleAlignment(value) {
|
|
3674
|
-
if (this._bottomTitleAlignment !== value) {
|
|
3675
|
-
this._bottomTitleAlignment = value;
|
|
3676
|
-
this.requestRender();
|
|
3677
|
-
}
|
|
3678
|
-
}
|
|
3679
|
-
renderSelf(buffer) {
|
|
3680
|
-
const currentBorderColor = this._focused ? this._focusedBorderColor : this._borderColor;
|
|
3681
|
-
buffer.drawBox({
|
|
3682
|
-
x: this.x,
|
|
3683
|
-
y: this.y,
|
|
3684
|
-
width: this.width,
|
|
3685
|
-
height: this.height,
|
|
3686
|
-
borderStyle: this._borderStyle,
|
|
3687
|
-
customBorderChars: this._customBorderChars,
|
|
3688
|
-
border: this._border,
|
|
3689
|
-
borderColor: currentBorderColor,
|
|
3690
|
-
backgroundColor: this._backgroundColor,
|
|
3691
|
-
shouldFill: this.shouldFill,
|
|
3692
|
-
title: this._title,
|
|
3693
|
-
titleAlignment: this._titleAlignment,
|
|
3694
|
-
bottomTitle: this._bottomTitle,
|
|
3695
|
-
bottomTitleAlignment: this._bottomTitleAlignment
|
|
3696
|
-
});
|
|
3697
|
-
}
|
|
3698
|
-
getScissorRect() {
|
|
3699
|
-
const baseRect = super.getScissorRect();
|
|
3700
|
-
if (!this.borderSides.top && !this.borderSides.right && !this.borderSides.bottom && !this.borderSides.left) {
|
|
3701
|
-
return baseRect;
|
|
3702
|
-
}
|
|
3703
|
-
const leftInset = this.borderSides.left ? 1 : 0;
|
|
3704
|
-
const rightInset = this.borderSides.right ? 1 : 0;
|
|
3705
|
-
const topInset = this.borderSides.top ? 1 : 0;
|
|
3706
|
-
const bottomInset = this.borderSides.bottom ? 1 : 0;
|
|
3707
|
-
return {
|
|
3708
|
-
x: baseRect.x + leftInset,
|
|
3709
|
-
y: baseRect.y + topInset,
|
|
3710
|
-
width: Math.max(0, baseRect.width - leftInset - rightInset),
|
|
3711
|
-
height: Math.max(0, baseRect.height - topInset - bottomInset)
|
|
3712
|
-
};
|
|
3713
|
-
}
|
|
3714
|
-
applyYogaBorders() {
|
|
3715
|
-
const node = this.yogaNode;
|
|
3716
|
-
node.setBorder(Edge.Left, this.borderSides.left ? 1 : 0);
|
|
3717
|
-
node.setBorder(Edge.Right, this.borderSides.right ? 1 : 0);
|
|
3718
|
-
node.setBorder(Edge.Top, this.borderSides.top ? 1 : 0);
|
|
3719
|
-
node.setBorder(Edge.Bottom, this.borderSides.bottom ? 1 : 0);
|
|
3720
|
-
this.requestRender();
|
|
3721
|
-
}
|
|
3722
|
-
applyYogaGap(options) {
|
|
3723
|
-
const node = this.yogaNode;
|
|
3724
|
-
if (isGapType(options.gap)) {
|
|
3725
|
-
node.setGap(Gutter.All, options.gap);
|
|
3726
|
-
}
|
|
3727
|
-
if (isGapType(options.rowGap)) {
|
|
3728
|
-
node.setGap(Gutter.Row, options.rowGap);
|
|
3729
|
-
}
|
|
3730
|
-
if (isGapType(options.columnGap)) {
|
|
3731
|
-
node.setGap(Gutter.Column, options.columnGap);
|
|
3732
|
-
}
|
|
3733
|
-
}
|
|
3734
|
-
set gap(gap) {
|
|
3735
|
-
if (isGapType(gap)) {
|
|
3736
|
-
this.yogaNode.setGap(Gutter.All, gap);
|
|
3737
|
-
this.requestRender();
|
|
3738
|
-
}
|
|
3739
|
-
}
|
|
3740
|
-
set rowGap(rowGap) {
|
|
3741
|
-
if (isGapType(rowGap)) {
|
|
3742
|
-
this.yogaNode.setGap(Gutter.Row, rowGap);
|
|
3743
|
-
this.requestRender();
|
|
3744
|
-
}
|
|
3745
|
-
}
|
|
3746
|
-
set columnGap(columnGap) {
|
|
3747
|
-
if (isGapType(columnGap)) {
|
|
3748
|
-
this.yogaNode.setGap(Gutter.Column, columnGap);
|
|
3749
|
-
this.requestRender();
|
|
3750
|
-
}
|
|
3751
|
-
}
|
|
3752
|
-
}
|
|
3753
|
-
// src/renderables/TextBufferRenderable.ts
|
|
3754
|
-
class TextBufferRenderable extends Renderable {
|
|
3755
|
-
selectable = true;
|
|
3756
|
-
_defaultFg;
|
|
3757
|
-
_defaultBg;
|
|
3758
|
-
_defaultAttributes;
|
|
3759
|
-
_selectionBg;
|
|
3760
|
-
_selectionFg;
|
|
3761
|
-
_wrapMode = "word";
|
|
3762
|
-
lastLocalSelection = null;
|
|
3763
|
-
_tabIndicator;
|
|
3764
|
-
_tabIndicatorColor;
|
|
3765
|
-
_scrollX = 0;
|
|
3766
|
-
_scrollY = 0;
|
|
3767
|
-
_truncate = false;
|
|
3768
|
-
textBuffer;
|
|
3769
|
-
textBufferView;
|
|
3770
|
-
_textBufferSyntaxStyle;
|
|
3771
|
-
_defaultOptions = {
|
|
3772
|
-
fg: RGBA.fromValues(1, 1, 1, 1),
|
|
3773
|
-
bg: RGBA.fromValues(0, 0, 0, 0),
|
|
3774
|
-
selectionBg: undefined,
|
|
3775
|
-
selectionFg: undefined,
|
|
3776
|
-
selectable: true,
|
|
3777
|
-
attributes: 0,
|
|
3778
|
-
wrapMode: "word",
|
|
3779
|
-
tabIndicator: undefined,
|
|
3780
|
-
tabIndicatorColor: undefined,
|
|
3781
|
-
truncate: false
|
|
3782
|
-
};
|
|
3783
|
-
constructor(ctx, options) {
|
|
3784
|
-
super(ctx, options);
|
|
3785
|
-
this._defaultFg = parseColor(options.fg ?? this._defaultOptions.fg);
|
|
3786
|
-
this._defaultBg = parseColor(options.bg ?? this._defaultOptions.bg);
|
|
3787
|
-
this._defaultAttributes = options.attributes ?? this._defaultOptions.attributes;
|
|
3788
|
-
this._selectionBg = options.selectionBg ? parseColor(options.selectionBg) : this._defaultOptions.selectionBg;
|
|
3789
|
-
this._selectionFg = options.selectionFg ? parseColor(options.selectionFg) : this._defaultOptions.selectionFg;
|
|
3790
|
-
this.selectable = options.selectable ?? this._defaultOptions.selectable;
|
|
3791
|
-
this._wrapMode = options.wrapMode ?? this._defaultOptions.wrapMode;
|
|
3792
|
-
this._tabIndicator = options.tabIndicator ?? this._defaultOptions.tabIndicator;
|
|
3793
|
-
this._tabIndicatorColor = options.tabIndicatorColor ? parseColor(options.tabIndicatorColor) : this._defaultOptions.tabIndicatorColor;
|
|
3794
|
-
this._truncate = options.truncate ?? this._defaultOptions.truncate;
|
|
3795
|
-
this.textBuffer = TextBuffer.create(this._ctx.widthMethod);
|
|
3796
|
-
this.textBufferView = TextBufferView.create(this.textBuffer);
|
|
3797
|
-
this._textBufferSyntaxStyle = SyntaxStyle.create();
|
|
3798
|
-
this.textBuffer.setSyntaxStyle(this._textBufferSyntaxStyle);
|
|
3799
|
-
this.textBufferView.setWrapMode(this._wrapMode);
|
|
3800
|
-
this.setupMeasureFunc();
|
|
3801
|
-
this.textBuffer.setDefaultFg(this._defaultFg);
|
|
3802
|
-
this.textBuffer.setDefaultBg(this._defaultBg);
|
|
3803
|
-
this.textBuffer.setDefaultAttributes(this._defaultAttributes);
|
|
3804
|
-
if (this._tabIndicator !== undefined) {
|
|
3805
|
-
this.textBufferView.setTabIndicator(this._tabIndicator);
|
|
3806
|
-
}
|
|
3807
|
-
if (this._tabIndicatorColor !== undefined) {
|
|
3808
|
-
this.textBufferView.setTabIndicatorColor(this._tabIndicatorColor);
|
|
3809
|
-
}
|
|
3810
|
-
if (this._wrapMode !== "none" && this.width > 0) {
|
|
3811
|
-
this.textBufferView.setWrapWidth(this.width);
|
|
3812
|
-
}
|
|
3813
|
-
if (this.width > 0 && this.height > 0) {
|
|
3814
|
-
this.textBufferView.setViewport(this._scrollX, this._scrollY, this.width, this.height);
|
|
3815
|
-
}
|
|
3816
|
-
this.textBufferView.setTruncate(this._truncate);
|
|
3817
|
-
this.updateTextInfo();
|
|
3818
|
-
}
|
|
3819
|
-
onMouseEvent(event) {
|
|
3820
|
-
if (event.type === "scroll") {
|
|
3821
|
-
this.handleScroll(event);
|
|
3822
|
-
}
|
|
3823
|
-
}
|
|
3824
|
-
handleScroll(event) {
|
|
3825
|
-
if (!event.scroll)
|
|
3826
|
-
return;
|
|
3827
|
-
const { direction, delta } = event.scroll;
|
|
3828
|
-
if (direction === "up") {
|
|
3829
|
-
this.scrollY -= delta;
|
|
3830
|
-
} else if (direction === "down") {
|
|
3831
|
-
this.scrollY += delta;
|
|
3832
|
-
}
|
|
3833
|
-
if (this._wrapMode === "none") {
|
|
3834
|
-
if (direction === "left") {
|
|
3835
|
-
this.scrollX -= delta;
|
|
3836
|
-
} else if (direction === "right") {
|
|
3837
|
-
this.scrollX += delta;
|
|
3838
|
-
}
|
|
3839
|
-
}
|
|
3840
|
-
}
|
|
3841
|
-
get lineInfo() {
|
|
3842
|
-
return this.textBufferView.logicalLineInfo;
|
|
3843
|
-
}
|
|
3844
|
-
get lineCount() {
|
|
3845
|
-
return this.textBuffer.getLineCount();
|
|
3846
|
-
}
|
|
3847
|
-
get virtualLineCount() {
|
|
3848
|
-
return this.textBufferView.getVirtualLineCount();
|
|
3849
|
-
}
|
|
3850
|
-
get scrollY() {
|
|
3851
|
-
return this._scrollY;
|
|
3852
|
-
}
|
|
3853
|
-
set scrollY(value) {
|
|
3854
|
-
const maxScrollY = Math.max(0, this.scrollHeight - this.height);
|
|
3855
|
-
const clamped = Math.max(0, Math.min(value, maxScrollY));
|
|
3856
|
-
if (this._scrollY !== clamped) {
|
|
3857
|
-
this._scrollY = clamped;
|
|
3858
|
-
this.updateViewportOffset();
|
|
3859
|
-
this.requestRender();
|
|
3860
|
-
}
|
|
3861
|
-
}
|
|
3862
|
-
get scrollX() {
|
|
3863
|
-
return this._scrollX;
|
|
3864
|
-
}
|
|
3865
|
-
set scrollX(value) {
|
|
3866
|
-
const maxScrollX = Math.max(0, this.scrollWidth - this.width);
|
|
3867
|
-
const clamped = Math.max(0, Math.min(value, maxScrollX));
|
|
3868
|
-
if (this._scrollX !== clamped) {
|
|
3869
|
-
this._scrollX = clamped;
|
|
3870
|
-
this.updateViewportOffset();
|
|
3871
|
-
this.requestRender();
|
|
3872
|
-
}
|
|
3873
|
-
}
|
|
3874
|
-
get scrollWidth() {
|
|
3875
|
-
return this.lineInfo.lineWidthColsMax;
|
|
3876
|
-
}
|
|
3877
|
-
get scrollHeight() {
|
|
3878
|
-
return this.lineInfo.lineStartCols.length;
|
|
3879
|
-
}
|
|
3880
|
-
get maxScrollY() {
|
|
3881
|
-
return Math.max(0, this.scrollHeight - this.height);
|
|
3882
|
-
}
|
|
3883
|
-
get maxScrollX() {
|
|
3884
|
-
return Math.max(0, this.scrollWidth - this.width);
|
|
3885
|
-
}
|
|
3886
|
-
updateViewportOffset() {
|
|
3887
|
-
if (this.width > 0 && this.height > 0) {
|
|
3888
|
-
this.textBufferView.setViewport(this._scrollX, this._scrollY, this.width, this.height);
|
|
3889
|
-
}
|
|
3890
|
-
}
|
|
3891
|
-
get plainText() {
|
|
3892
|
-
return this.textBuffer.getPlainText();
|
|
3893
|
-
}
|
|
3894
|
-
get textLength() {
|
|
3895
|
-
return this.textBuffer.length;
|
|
3896
|
-
}
|
|
3897
|
-
get fg() {
|
|
3898
|
-
return this._defaultFg;
|
|
3899
|
-
}
|
|
3900
|
-
set fg(value) {
|
|
3901
|
-
const newColor = parseColor(value ?? this._defaultOptions.fg);
|
|
3902
|
-
if (this._defaultFg !== newColor) {
|
|
3903
|
-
this._defaultFg = newColor;
|
|
3904
|
-
this.textBuffer.setDefaultFg(this._defaultFg);
|
|
3905
|
-
this.onFgChanged(newColor);
|
|
3906
|
-
this.requestRender();
|
|
3907
|
-
}
|
|
3908
|
-
}
|
|
3909
|
-
get selectionBg() {
|
|
3910
|
-
return this._selectionBg;
|
|
3911
|
-
}
|
|
3912
|
-
set selectionBg(value) {
|
|
3913
|
-
const newColor = value ? parseColor(value) : this._defaultOptions.selectionBg;
|
|
3914
|
-
if (this._selectionBg !== newColor) {
|
|
3915
|
-
this._selectionBg = newColor;
|
|
3916
|
-
if (this.lastLocalSelection) {
|
|
3917
|
-
this.updateLocalSelection(this.lastLocalSelection);
|
|
3918
|
-
}
|
|
3919
|
-
this.requestRender();
|
|
3920
|
-
}
|
|
3921
|
-
}
|
|
3922
|
-
get selectionFg() {
|
|
3923
|
-
return this._selectionFg;
|
|
3924
|
-
}
|
|
3925
|
-
set selectionFg(value) {
|
|
3926
|
-
const newColor = value ? parseColor(value) : this._defaultOptions.selectionFg;
|
|
3927
|
-
if (this._selectionFg !== newColor) {
|
|
3928
|
-
this._selectionFg = newColor;
|
|
3929
|
-
if (this.lastLocalSelection) {
|
|
3930
|
-
this.updateLocalSelection(this.lastLocalSelection);
|
|
3931
|
-
}
|
|
3932
|
-
this.requestRender();
|
|
3933
|
-
}
|
|
3934
|
-
}
|
|
3935
|
-
get bg() {
|
|
3936
|
-
return this._defaultBg;
|
|
3937
|
-
}
|
|
3938
|
-
set bg(value) {
|
|
3939
|
-
const newColor = parseColor(value ?? this._defaultOptions.bg);
|
|
3940
|
-
if (this._defaultBg !== newColor) {
|
|
3941
|
-
this._defaultBg = newColor;
|
|
3942
|
-
this.textBuffer.setDefaultBg(this._defaultBg);
|
|
3943
|
-
this.onBgChanged(newColor);
|
|
3944
|
-
this.requestRender();
|
|
3945
|
-
}
|
|
3946
|
-
}
|
|
3947
|
-
get attributes() {
|
|
3948
|
-
return this._defaultAttributes;
|
|
3949
|
-
}
|
|
3950
|
-
set attributes(value) {
|
|
3951
|
-
if (this._defaultAttributes !== value) {
|
|
3952
|
-
this._defaultAttributes = value;
|
|
3953
|
-
this.textBuffer.setDefaultAttributes(this._defaultAttributes);
|
|
3954
|
-
this.onAttributesChanged(value);
|
|
3955
|
-
this.requestRender();
|
|
3956
|
-
}
|
|
3957
|
-
}
|
|
3958
|
-
get wrapMode() {
|
|
3959
|
-
return this._wrapMode;
|
|
3960
|
-
}
|
|
3961
|
-
set wrapMode(value) {
|
|
3962
|
-
if (this._wrapMode !== value) {
|
|
3963
|
-
this._wrapMode = value;
|
|
3964
|
-
this.textBufferView.setWrapMode(this._wrapMode);
|
|
3965
|
-
if (value !== "none" && this.width > 0) {
|
|
3966
|
-
this.textBufferView.setWrapWidth(this.width);
|
|
3967
|
-
}
|
|
3968
|
-
this.yogaNode.markDirty();
|
|
3969
|
-
this.requestRender();
|
|
3970
|
-
}
|
|
3971
|
-
}
|
|
3972
|
-
get tabIndicator() {
|
|
3973
|
-
return this._tabIndicator;
|
|
3974
|
-
}
|
|
3975
|
-
set tabIndicator(value) {
|
|
3976
|
-
if (this._tabIndicator !== value) {
|
|
3977
|
-
this._tabIndicator = value;
|
|
3978
|
-
if (value !== undefined) {
|
|
3979
|
-
this.textBufferView.setTabIndicator(value);
|
|
3980
|
-
}
|
|
3981
|
-
this.requestRender();
|
|
3982
|
-
}
|
|
3983
|
-
}
|
|
3984
|
-
get tabIndicatorColor() {
|
|
3985
|
-
return this._tabIndicatorColor;
|
|
3986
|
-
}
|
|
3987
|
-
set tabIndicatorColor(value) {
|
|
3988
|
-
const newColor = value ? parseColor(value) : undefined;
|
|
3989
|
-
if (this._tabIndicatorColor !== newColor) {
|
|
3990
|
-
this._tabIndicatorColor = newColor;
|
|
3991
|
-
if (newColor !== undefined) {
|
|
3992
|
-
this.textBufferView.setTabIndicatorColor(newColor);
|
|
3993
|
-
}
|
|
3994
|
-
this.requestRender();
|
|
3995
|
-
}
|
|
3996
|
-
}
|
|
3997
|
-
get truncate() {
|
|
3998
|
-
return this._truncate;
|
|
3999
|
-
}
|
|
4000
|
-
set truncate(value) {
|
|
4001
|
-
if (this._truncate !== value) {
|
|
4002
|
-
this._truncate = value;
|
|
4003
|
-
this.textBufferView.setTruncate(value);
|
|
4004
|
-
this.requestRender();
|
|
4005
|
-
}
|
|
4006
|
-
}
|
|
4007
|
-
onResize(width, height) {
|
|
4008
|
-
this.textBufferView.setViewport(this._scrollX, this._scrollY, width, height);
|
|
4009
|
-
this.yogaNode.markDirty();
|
|
4010
|
-
this.requestRender();
|
|
4011
|
-
this.emit("line-info-change");
|
|
4012
|
-
}
|
|
4013
|
-
refreshLocalSelection() {
|
|
4014
|
-
if (this.lastLocalSelection) {
|
|
4015
|
-
return this.updateLocalSelection(this.lastLocalSelection);
|
|
4016
|
-
}
|
|
4017
|
-
return false;
|
|
4018
|
-
}
|
|
4019
|
-
updateLocalSelection(localSelection) {
|
|
4020
|
-
if (!localSelection?.isActive) {
|
|
4021
|
-
this.textBufferView.resetLocalSelection();
|
|
4022
|
-
return true;
|
|
4023
|
-
}
|
|
4024
|
-
return this.textBufferView.setLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg);
|
|
4025
|
-
}
|
|
4026
|
-
updateTextInfo() {
|
|
4027
|
-
if (this.lastLocalSelection) {
|
|
4028
|
-
this.updateLocalSelection(this.lastLocalSelection);
|
|
4029
|
-
}
|
|
4030
|
-
this.yogaNode.markDirty();
|
|
4031
|
-
this.requestRender();
|
|
4032
|
-
this.emit("line-info-change");
|
|
4033
|
-
}
|
|
4034
|
-
setupMeasureFunc() {
|
|
4035
|
-
const measureFunc = (width, widthMode, height, heightMode) => {
|
|
4036
|
-
let effectiveWidth;
|
|
4037
|
-
if (widthMode === MeasureMode.Undefined || isNaN(width)) {
|
|
4038
|
-
effectiveWidth = 0;
|
|
4039
|
-
} else {
|
|
4040
|
-
effectiveWidth = width;
|
|
4041
|
-
}
|
|
4042
|
-
const effectiveHeight = isNaN(height) ? 1 : height;
|
|
4043
|
-
const measureResult = this.textBufferView.measureForDimensions(Math.floor(effectiveWidth), Math.floor(effectiveHeight));
|
|
4044
|
-
const measuredWidth = measureResult ? Math.max(1, measureResult.widthColsMax) : 1;
|
|
4045
|
-
const measuredHeight = measureResult ? Math.max(1, measureResult.lineCount) : 1;
|
|
4046
|
-
if (widthMode === MeasureMode.AtMost && this._positionType !== "absolute") {
|
|
4047
|
-
return {
|
|
4048
|
-
width: Math.min(effectiveWidth, measuredWidth),
|
|
4049
|
-
height: Math.min(effectiveHeight, measuredHeight)
|
|
4050
|
-
};
|
|
4051
|
-
}
|
|
4052
|
-
return {
|
|
4053
|
-
width: measuredWidth,
|
|
4054
|
-
height: measuredHeight
|
|
4055
|
-
};
|
|
4056
|
-
};
|
|
4057
|
-
this.yogaNode.setMeasureFunc(measureFunc);
|
|
4058
|
-
}
|
|
4059
|
-
shouldStartSelection(x, y) {
|
|
4060
|
-
if (!this.selectable)
|
|
4061
|
-
return false;
|
|
4062
|
-
const localX = x - this.x;
|
|
4063
|
-
const localY = y - this.y;
|
|
4064
|
-
return localX >= 0 && localX < this.width && localY >= 0 && localY < this.height;
|
|
4065
|
-
}
|
|
4066
|
-
onSelectionChanged(selection) {
|
|
4067
|
-
const localSelection = convertGlobalToLocalSelection(selection, this.x, this.y);
|
|
4068
|
-
this.lastLocalSelection = localSelection;
|
|
4069
|
-
let changed;
|
|
4070
|
-
if (!localSelection?.isActive) {
|
|
4071
|
-
this.textBufferView.resetLocalSelection();
|
|
4072
|
-
changed = true;
|
|
4073
|
-
} else if (selection?.isStart) {
|
|
4074
|
-
changed = this.textBufferView.setLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg);
|
|
4075
|
-
} else {
|
|
4076
|
-
changed = this.textBufferView.updateLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg);
|
|
4077
|
-
}
|
|
4078
|
-
if (changed) {
|
|
4079
|
-
this.requestRender();
|
|
4080
|
-
}
|
|
4081
|
-
return this.hasSelection();
|
|
4082
|
-
}
|
|
4083
|
-
getSelectedText() {
|
|
4084
|
-
return this.textBufferView.getSelectedText();
|
|
4085
|
-
}
|
|
4086
|
-
hasSelection() {
|
|
4087
|
-
return this.textBufferView.hasSelection();
|
|
4088
|
-
}
|
|
4089
|
-
getSelection() {
|
|
4090
|
-
return this.textBufferView.getSelection();
|
|
4091
|
-
}
|
|
4092
|
-
render(buffer, deltaTime) {
|
|
4093
|
-
if (!this.visible)
|
|
4094
|
-
return;
|
|
4095
|
-
this.markClean();
|
|
4096
|
-
this._ctx.addToHitGrid(this.x, this.y, this.width, this.height, this.num);
|
|
4097
|
-
this.renderSelf(buffer);
|
|
4098
|
-
if (this.buffered && this.frameBuffer) {
|
|
4099
|
-
buffer.drawFrameBuffer(this.x, this.y, this.frameBuffer);
|
|
4100
|
-
}
|
|
4101
|
-
}
|
|
4102
|
-
renderSelf(buffer) {
|
|
4103
|
-
if (this.textBuffer.ptr) {
|
|
4104
|
-
buffer.drawTextBuffer(this.textBufferView, this.x, this.y);
|
|
4105
|
-
}
|
|
4106
|
-
}
|
|
4107
|
-
destroy() {
|
|
4108
|
-
if (this.isDestroyed)
|
|
4109
|
-
return;
|
|
4110
|
-
this.textBuffer.setSyntaxStyle(null);
|
|
4111
|
-
this._textBufferSyntaxStyle.destroy();
|
|
4112
|
-
this.textBufferView.destroy();
|
|
4113
|
-
this.textBuffer.destroy();
|
|
4114
|
-
super.destroy();
|
|
4115
|
-
}
|
|
4116
|
-
onFgChanged(newColor) {}
|
|
4117
|
-
onBgChanged(newColor) {}
|
|
4118
|
-
onAttributesChanged(newAttributes) {}
|
|
4119
|
-
}
|
|
4120
|
-
|
|
4121
|
-
// src/renderables/Code.ts
|
|
4122
|
-
class CodeRenderable extends TextBufferRenderable {
|
|
4123
|
-
_content;
|
|
4124
|
-
_filetype;
|
|
4125
|
-
_syntaxStyle;
|
|
4126
|
-
_isHighlighting = false;
|
|
4127
|
-
_treeSitterClient;
|
|
4128
|
-
_highlightsDirty = false;
|
|
4129
|
-
_highlightSnapshotId = 0;
|
|
4130
|
-
_conceal;
|
|
4131
|
-
_drawUnstyledText;
|
|
4132
|
-
_shouldRenderTextBuffer = true;
|
|
4133
|
-
_streaming;
|
|
4134
|
-
_hadInitialContent = false;
|
|
4135
|
-
_lastHighlights = [];
|
|
4136
|
-
_onHighlight;
|
|
4137
|
-
_onChunks;
|
|
4138
|
-
_highlightingPromise = Promise.resolve();
|
|
4139
|
-
_contentDefaultOptions = {
|
|
4140
|
-
content: "",
|
|
4141
|
-
conceal: true,
|
|
4142
|
-
drawUnstyledText: true,
|
|
4143
|
-
streaming: false
|
|
4144
|
-
};
|
|
4145
|
-
constructor(ctx, options) {
|
|
4146
|
-
super(ctx, options);
|
|
4147
|
-
this._content = options.content ?? this._contentDefaultOptions.content;
|
|
4148
|
-
this._filetype = options.filetype;
|
|
4149
|
-
this._syntaxStyle = options.syntaxStyle;
|
|
4150
|
-
this._treeSitterClient = options.treeSitterClient ?? getTreeSitterClient();
|
|
4151
|
-
this._conceal = options.conceal ?? this._contentDefaultOptions.conceal;
|
|
4152
|
-
this._drawUnstyledText = options.drawUnstyledText ?? this._contentDefaultOptions.drawUnstyledText;
|
|
4153
|
-
this._streaming = options.streaming ?? this._contentDefaultOptions.streaming;
|
|
4154
|
-
this._onHighlight = options.onHighlight;
|
|
4155
|
-
this._onChunks = options.onChunks;
|
|
4156
|
-
if (this._content.length > 0) {
|
|
4157
|
-
this.textBuffer.setText(this._content);
|
|
4158
|
-
this.updateTextInfo();
|
|
4159
|
-
this._shouldRenderTextBuffer = this._drawUnstyledText || !this._filetype;
|
|
4160
|
-
}
|
|
4161
|
-
this._highlightsDirty = this._content.length > 0;
|
|
4162
|
-
}
|
|
4163
|
-
get content() {
|
|
4164
|
-
return this._content;
|
|
4165
|
-
}
|
|
4166
|
-
set content(value) {
|
|
4167
|
-
if (this._content !== value) {
|
|
4168
|
-
this._content = value;
|
|
4169
|
-
this._highlightsDirty = true;
|
|
4170
|
-
this._highlightSnapshotId++;
|
|
4171
|
-
if (this._streaming && !this._drawUnstyledText && this._filetype) {
|
|
4172
|
-
return;
|
|
4173
|
-
}
|
|
4174
|
-
this.textBuffer.setText(value);
|
|
4175
|
-
this.updateTextInfo();
|
|
4176
|
-
}
|
|
4177
|
-
}
|
|
4178
|
-
get filetype() {
|
|
4179
|
-
return this._filetype;
|
|
4180
|
-
}
|
|
4181
|
-
set filetype(value) {
|
|
4182
|
-
if (this._filetype !== value) {
|
|
4183
|
-
this._filetype = value;
|
|
4184
|
-
this._highlightsDirty = true;
|
|
4185
|
-
}
|
|
4186
|
-
}
|
|
4187
|
-
get syntaxStyle() {
|
|
4188
|
-
return this._syntaxStyle;
|
|
4189
|
-
}
|
|
4190
|
-
set syntaxStyle(value) {
|
|
4191
|
-
if (this._syntaxStyle !== value) {
|
|
4192
|
-
this._syntaxStyle = value;
|
|
4193
|
-
this._highlightsDirty = true;
|
|
4194
|
-
}
|
|
4195
|
-
}
|
|
4196
|
-
get conceal() {
|
|
4197
|
-
return this._conceal;
|
|
4198
|
-
}
|
|
4199
|
-
set conceal(value) {
|
|
4200
|
-
if (this._conceal !== value) {
|
|
4201
|
-
this._conceal = value;
|
|
4202
|
-
this._highlightsDirty = true;
|
|
4203
|
-
}
|
|
4204
|
-
}
|
|
4205
|
-
get drawUnstyledText() {
|
|
4206
|
-
return this._drawUnstyledText;
|
|
4207
|
-
}
|
|
4208
|
-
set drawUnstyledText(value) {
|
|
4209
|
-
if (this._drawUnstyledText !== value) {
|
|
4210
|
-
this._drawUnstyledText = value;
|
|
4211
|
-
this._highlightsDirty = true;
|
|
4212
|
-
}
|
|
4213
|
-
}
|
|
4214
|
-
get streaming() {
|
|
4215
|
-
return this._streaming;
|
|
4216
|
-
}
|
|
4217
|
-
set streaming(value) {
|
|
4218
|
-
if (this._streaming !== value) {
|
|
4219
|
-
this._streaming = value;
|
|
4220
|
-
this._hadInitialContent = false;
|
|
4221
|
-
this._lastHighlights = [];
|
|
4222
|
-
this._highlightsDirty = true;
|
|
4223
|
-
}
|
|
4224
|
-
}
|
|
4225
|
-
get treeSitterClient() {
|
|
4226
|
-
return this._treeSitterClient;
|
|
4227
|
-
}
|
|
4228
|
-
set treeSitterClient(value) {
|
|
4229
|
-
if (this._treeSitterClient !== value) {
|
|
4230
|
-
this._treeSitterClient = value;
|
|
4231
|
-
this._highlightsDirty = true;
|
|
4232
|
-
}
|
|
4233
|
-
}
|
|
4234
|
-
get onHighlight() {
|
|
4235
|
-
return this._onHighlight;
|
|
4236
|
-
}
|
|
4237
|
-
set onHighlight(value) {
|
|
4238
|
-
if (this._onHighlight !== value) {
|
|
4239
|
-
this._onHighlight = value;
|
|
4240
|
-
this._highlightsDirty = true;
|
|
4241
|
-
}
|
|
4242
|
-
}
|
|
4243
|
-
get onChunks() {
|
|
4244
|
-
return this._onChunks;
|
|
4245
|
-
}
|
|
4246
|
-
set onChunks(value) {
|
|
4247
|
-
if (this._onChunks !== value) {
|
|
4248
|
-
this._onChunks = value;
|
|
4249
|
-
this._highlightsDirty = true;
|
|
4250
|
-
}
|
|
4251
|
-
}
|
|
4252
|
-
get isHighlighting() {
|
|
4253
|
-
return this._isHighlighting;
|
|
4254
|
-
}
|
|
4255
|
-
get highlightingDone() {
|
|
4256
|
-
return this._highlightingPromise;
|
|
4257
|
-
}
|
|
4258
|
-
async transformChunks(chunks, context) {
|
|
4259
|
-
if (!this._onChunks)
|
|
4260
|
-
return chunks;
|
|
4261
|
-
const modified = await this._onChunks(chunks, context);
|
|
4262
|
-
return modified ?? chunks;
|
|
4263
|
-
}
|
|
4264
|
-
ensureVisibleTextBeforeHighlight() {
|
|
4265
|
-
if (this.isDestroyed)
|
|
4266
|
-
return;
|
|
4267
|
-
const content = this._content;
|
|
4268
|
-
if (!this._filetype) {
|
|
4269
|
-
this._shouldRenderTextBuffer = true;
|
|
4270
|
-
return;
|
|
4271
|
-
}
|
|
4272
|
-
const isInitialContent = this._streaming && !this._hadInitialContent;
|
|
4273
|
-
const shouldDrawUnstyledNow = this._streaming ? isInitialContent && this._drawUnstyledText : this._drawUnstyledText;
|
|
4274
|
-
if (this._streaming && !isInitialContent) {
|
|
4275
|
-
this._shouldRenderTextBuffer = true;
|
|
4276
|
-
} else if (shouldDrawUnstyledNow) {
|
|
4277
|
-
this.textBuffer.setText(content);
|
|
4278
|
-
this._shouldRenderTextBuffer = true;
|
|
4279
|
-
} else {
|
|
4280
|
-
this._shouldRenderTextBuffer = false;
|
|
4281
|
-
}
|
|
4282
|
-
}
|
|
4283
|
-
async startHighlight() {
|
|
4284
|
-
const content = this._content;
|
|
4285
|
-
const filetype = this._filetype;
|
|
4286
|
-
const snapshotId = ++this._highlightSnapshotId;
|
|
4287
|
-
if (!filetype)
|
|
4288
|
-
return;
|
|
4289
|
-
const isInitialContent = this._streaming && !this._hadInitialContent;
|
|
4290
|
-
if (isInitialContent) {
|
|
4291
|
-
this._hadInitialContent = true;
|
|
4292
|
-
}
|
|
4293
|
-
this._isHighlighting = true;
|
|
4294
|
-
try {
|
|
4295
|
-
const result = await this._treeSitterClient.highlightOnce(content, filetype);
|
|
4296
|
-
if (snapshotId !== this._highlightSnapshotId) {
|
|
4297
|
-
return;
|
|
4298
|
-
}
|
|
4299
|
-
if (this.isDestroyed)
|
|
4300
|
-
return;
|
|
4301
|
-
let highlights = result.highlights ?? [];
|
|
4302
|
-
if (this._onHighlight && highlights.length >= 0) {
|
|
4303
|
-
const context = {
|
|
4304
|
-
content,
|
|
4305
|
-
filetype,
|
|
4306
|
-
syntaxStyle: this._syntaxStyle
|
|
4307
|
-
};
|
|
4308
|
-
const modified = await this._onHighlight(highlights, context);
|
|
4309
|
-
if (modified !== undefined) {
|
|
4310
|
-
highlights = modified;
|
|
4311
|
-
}
|
|
4312
|
-
}
|
|
4313
|
-
if (snapshotId !== this._highlightSnapshotId) {
|
|
4314
|
-
return;
|
|
4315
|
-
}
|
|
4316
|
-
if (this.isDestroyed)
|
|
4317
|
-
return;
|
|
4318
|
-
if (highlights.length > 0) {
|
|
4319
|
-
if (this._streaming) {
|
|
4320
|
-
this._lastHighlights = highlights;
|
|
4321
|
-
}
|
|
4322
|
-
}
|
|
4323
|
-
if (highlights.length > 0 || this._onChunks) {
|
|
4324
|
-
const context = {
|
|
4325
|
-
content,
|
|
4326
|
-
filetype,
|
|
4327
|
-
syntaxStyle: this._syntaxStyle,
|
|
4328
|
-
highlights
|
|
4329
|
-
};
|
|
4330
|
-
let chunks = treeSitterToTextChunks(content, highlights, this._syntaxStyle, {
|
|
4331
|
-
enabled: this._conceal
|
|
4332
|
-
});
|
|
4333
|
-
chunks = await this.transformChunks(chunks, context);
|
|
4334
|
-
if (snapshotId !== this._highlightSnapshotId) {
|
|
4335
|
-
return;
|
|
4336
|
-
}
|
|
4337
|
-
if (this.isDestroyed)
|
|
4338
|
-
return;
|
|
4339
|
-
const styledText = new StyledText(chunks);
|
|
4340
|
-
this.textBuffer.setStyledText(styledText);
|
|
4341
|
-
} else {
|
|
4342
|
-
this.textBuffer.setText(content);
|
|
4343
|
-
}
|
|
4344
|
-
this._shouldRenderTextBuffer = true;
|
|
4345
|
-
this._isHighlighting = false;
|
|
4346
|
-
this._highlightsDirty = false;
|
|
4347
|
-
this.updateTextInfo();
|
|
4348
|
-
this.requestRender();
|
|
4349
|
-
} catch (error) {
|
|
4350
|
-
if (snapshotId !== this._highlightSnapshotId) {
|
|
4351
|
-
return;
|
|
4352
|
-
}
|
|
4353
|
-
console.warn("Code highlighting failed, falling back to plain text:", error);
|
|
4354
|
-
if (this.isDestroyed)
|
|
4355
|
-
return;
|
|
4356
|
-
this.textBuffer.setText(content);
|
|
4357
|
-
this._shouldRenderTextBuffer = true;
|
|
4358
|
-
this._isHighlighting = false;
|
|
4359
|
-
this._highlightsDirty = false;
|
|
4360
|
-
this.updateTextInfo();
|
|
4361
|
-
this.requestRender();
|
|
4362
|
-
}
|
|
4363
|
-
}
|
|
4364
|
-
getLineHighlights(lineIdx) {
|
|
4365
|
-
return this.textBuffer.getLineHighlights(lineIdx);
|
|
4366
|
-
}
|
|
4367
|
-
renderSelf(buffer) {
|
|
4368
|
-
if (this._highlightsDirty) {
|
|
4369
|
-
if (this.isDestroyed)
|
|
4370
|
-
return;
|
|
4371
|
-
if (this._content.length === 0) {
|
|
4372
|
-
this._shouldRenderTextBuffer = false;
|
|
4373
|
-
this._highlightsDirty = false;
|
|
4374
|
-
} else if (!this._filetype) {
|
|
4375
|
-
this._shouldRenderTextBuffer = true;
|
|
4376
|
-
this._highlightsDirty = false;
|
|
4377
|
-
} else {
|
|
4378
|
-
this.ensureVisibleTextBeforeHighlight();
|
|
4379
|
-
this._highlightsDirty = false;
|
|
4380
|
-
this._highlightingPromise = this.startHighlight();
|
|
4381
|
-
}
|
|
4382
|
-
}
|
|
4383
|
-
if (!this._shouldRenderTextBuffer)
|
|
4384
|
-
return;
|
|
4385
|
-
super.renderSelf(buffer);
|
|
4386
|
-
}
|
|
4387
|
-
}
|
|
4388
|
-
// src/renderables/TextNode.ts
|
|
4389
|
-
var BrandedTextNodeRenderable = Symbol.for("@jitl/opentui-core/TextNodeRenderable");
|
|
4390
|
-
function isTextNodeRenderable(obj) {
|
|
4391
|
-
return !!obj?.[BrandedTextNodeRenderable];
|
|
4392
|
-
}
|
|
4393
|
-
function styledTextToTextNodes(styledText) {
|
|
4394
|
-
return styledText.chunks.map((chunk) => {
|
|
4395
|
-
const node = new TextNodeRenderable({
|
|
4396
|
-
fg: chunk.fg,
|
|
4397
|
-
bg: chunk.bg,
|
|
4398
|
-
attributes: chunk.attributes,
|
|
4399
|
-
link: chunk.link
|
|
4400
|
-
});
|
|
4401
|
-
node.add(chunk.text);
|
|
4402
|
-
return node;
|
|
4403
|
-
});
|
|
4404
|
-
}
|
|
4405
|
-
|
|
4406
|
-
class TextNodeRenderable extends BaseRenderable {
|
|
4407
|
-
[BrandedTextNodeRenderable] = true;
|
|
4408
|
-
_fg;
|
|
4409
|
-
_bg;
|
|
4410
|
-
_attributes;
|
|
4411
|
-
_link;
|
|
4412
|
-
_children = [];
|
|
4413
|
-
parent = null;
|
|
4414
|
-
constructor(options) {
|
|
4415
|
-
super(options);
|
|
4416
|
-
this._fg = options.fg ? parseColor(options.fg) : undefined;
|
|
4417
|
-
this._bg = options.bg ? parseColor(options.bg) : undefined;
|
|
4418
|
-
this._attributes = options.attributes ?? 0;
|
|
4419
|
-
this._link = options.link;
|
|
4420
|
-
}
|
|
4421
|
-
get children() {
|
|
4422
|
-
return this._children;
|
|
4423
|
-
}
|
|
4424
|
-
set children(children) {
|
|
4425
|
-
this._children = children;
|
|
4426
|
-
this.requestRender();
|
|
4427
|
-
}
|
|
4428
|
-
requestRender() {
|
|
4429
|
-
this.markDirty();
|
|
4430
|
-
this.parent?.requestRender();
|
|
4431
|
-
}
|
|
4432
|
-
add(obj, index) {
|
|
4433
|
-
if (typeof obj === "string") {
|
|
4434
|
-
if (index !== undefined) {
|
|
4435
|
-
this._children.splice(index, 0, obj);
|
|
4436
|
-
this.requestRender();
|
|
4437
|
-
return index;
|
|
4438
|
-
}
|
|
4439
|
-
const insertIndex = this._children.length;
|
|
4440
|
-
this._children.push(obj);
|
|
4441
|
-
this.requestRender();
|
|
4442
|
-
return insertIndex;
|
|
4443
|
-
}
|
|
4444
|
-
if (isTextNodeRenderable(obj)) {
|
|
4445
|
-
if (index !== undefined) {
|
|
4446
|
-
this._children.splice(index, 0, obj);
|
|
4447
|
-
obj.parent = this;
|
|
4448
|
-
this.requestRender();
|
|
4449
|
-
return index;
|
|
4450
|
-
}
|
|
4451
|
-
const insertIndex = this._children.length;
|
|
4452
|
-
this._children.push(obj);
|
|
4453
|
-
obj.parent = this;
|
|
4454
|
-
this.requestRender();
|
|
4455
|
-
return insertIndex;
|
|
4456
|
-
}
|
|
4457
|
-
if (isStyledText(obj)) {
|
|
4458
|
-
const textNodes = styledTextToTextNodes(obj);
|
|
4459
|
-
if (index !== undefined) {
|
|
4460
|
-
this._children.splice(index, 0, ...textNodes);
|
|
4461
|
-
textNodes.forEach((node) => node.parent = this);
|
|
4462
|
-
this.requestRender();
|
|
4463
|
-
return index;
|
|
4464
|
-
}
|
|
4465
|
-
const insertIndex = this._children.length;
|
|
4466
|
-
this._children.push(...textNodes);
|
|
4467
|
-
textNodes.forEach((node) => node.parent = this);
|
|
4468
|
-
this.requestRender();
|
|
4469
|
-
return insertIndex;
|
|
4470
|
-
}
|
|
4471
|
-
throw new Error("TextNodeRenderable only accepts strings, TextNodeRenderable instances, or StyledText instances");
|
|
4472
|
-
}
|
|
4473
|
-
replace(obj, index) {
|
|
4474
|
-
this._children[index] = obj;
|
|
4475
|
-
if (typeof obj !== "string") {
|
|
4476
|
-
obj.parent = this;
|
|
4477
|
-
}
|
|
4478
|
-
this.requestRender();
|
|
4479
|
-
}
|
|
4480
|
-
insertBefore(child, anchorNode) {
|
|
4481
|
-
if (!anchorNode || !isTextNodeRenderable(anchorNode)) {
|
|
4482
|
-
throw new Error("Anchor must be a TextNodeRenderable");
|
|
4483
|
-
}
|
|
4484
|
-
const anchorIndex = this._children.indexOf(anchorNode);
|
|
4485
|
-
if (anchorIndex === -1) {
|
|
4486
|
-
throw new Error("Anchor node not found in children");
|
|
4487
|
-
}
|
|
4488
|
-
if (typeof child === "string") {
|
|
4489
|
-
this._children.splice(anchorIndex, 0, child);
|
|
4490
|
-
} else if (isTextNodeRenderable(child)) {
|
|
4491
|
-
this._children.splice(anchorIndex, 0, child);
|
|
4492
|
-
child.parent = this;
|
|
4493
|
-
} else if (child instanceof StyledText) {
|
|
4494
|
-
const textNodes = styledTextToTextNodes(child);
|
|
4495
|
-
this._children.splice(anchorIndex, 0, ...textNodes);
|
|
4496
|
-
textNodes.forEach((node) => node.parent = this);
|
|
4497
|
-
} else {
|
|
4498
|
-
throw new Error("Child must be a string, TextNodeRenderable, or StyledText instance");
|
|
4499
|
-
}
|
|
4500
|
-
this.requestRender();
|
|
4501
|
-
return this;
|
|
4502
|
-
}
|
|
4503
|
-
remove(id) {
|
|
4504
|
-
const childIndex = this.getRenderableIndex(id);
|
|
4505
|
-
if (childIndex === -1) {
|
|
4506
|
-
throw new Error("Child not found in children");
|
|
4507
|
-
}
|
|
4508
|
-
const child = this._children[childIndex];
|
|
4509
|
-
this._children.splice(childIndex, 1);
|
|
4510
|
-
child.parent = null;
|
|
4511
|
-
this.requestRender();
|
|
4512
|
-
return this;
|
|
4513
|
-
}
|
|
4514
|
-
clear() {
|
|
4515
|
-
this._children = [];
|
|
4516
|
-
this.requestRender();
|
|
4517
|
-
}
|
|
4518
|
-
mergeStyles(parentStyle) {
|
|
4519
|
-
return {
|
|
4520
|
-
fg: this._fg ?? parentStyle.fg,
|
|
4521
|
-
bg: this._bg ?? parentStyle.bg,
|
|
4522
|
-
attributes: this._attributes | parentStyle.attributes,
|
|
4523
|
-
link: this._link ?? parentStyle.link
|
|
4524
|
-
};
|
|
4525
|
-
}
|
|
4526
|
-
gatherWithInheritedStyle(parentStyle = {
|
|
4527
|
-
fg: undefined,
|
|
4528
|
-
bg: undefined,
|
|
4529
|
-
attributes: 0
|
|
4530
|
-
}) {
|
|
4531
|
-
const currentStyle = this.mergeStyles(parentStyle);
|
|
4532
|
-
const chunks = [];
|
|
4533
|
-
for (const child of this._children) {
|
|
4534
|
-
if (typeof child === "string") {
|
|
4535
|
-
chunks.push({
|
|
4536
|
-
__isChunk: true,
|
|
4537
|
-
text: child,
|
|
4538
|
-
fg: currentStyle.fg,
|
|
4539
|
-
bg: currentStyle.bg,
|
|
4540
|
-
attributes: currentStyle.attributes,
|
|
4541
|
-
link: currentStyle.link
|
|
4542
|
-
});
|
|
4543
|
-
} else {
|
|
4544
|
-
const childChunks = child.gatherWithInheritedStyle(currentStyle);
|
|
4545
|
-
chunks.push(...childChunks);
|
|
4546
|
-
}
|
|
4547
|
-
}
|
|
4548
|
-
this.markClean();
|
|
4549
|
-
return chunks;
|
|
4550
|
-
}
|
|
4551
|
-
static fromString(text, options = {}) {
|
|
4552
|
-
const node = new TextNodeRenderable(options);
|
|
4553
|
-
node.add(text);
|
|
4554
|
-
return node;
|
|
4555
|
-
}
|
|
4556
|
-
static fromNodes(nodes, options = {}) {
|
|
4557
|
-
const node = new TextNodeRenderable(options);
|
|
4558
|
-
for (const childNode of nodes) {
|
|
4559
|
-
node.add(childNode);
|
|
4560
|
-
}
|
|
4561
|
-
return node;
|
|
4562
|
-
}
|
|
4563
|
-
toChunks(parentStyle = {
|
|
4564
|
-
fg: undefined,
|
|
4565
|
-
bg: undefined,
|
|
4566
|
-
attributes: 0
|
|
4567
|
-
}) {
|
|
4568
|
-
return this.gatherWithInheritedStyle(parentStyle);
|
|
4569
|
-
}
|
|
4570
|
-
getChildren() {
|
|
4571
|
-
return this._children.filter((child) => typeof child !== "string");
|
|
4572
|
-
}
|
|
4573
|
-
getChildrenCount() {
|
|
4574
|
-
return this._children.length;
|
|
4575
|
-
}
|
|
4576
|
-
getRenderable(id) {
|
|
4577
|
-
return this._children.find((child) => typeof child !== "string" && child.id === id);
|
|
4578
|
-
}
|
|
4579
|
-
getRenderableIndex(id) {
|
|
4580
|
-
return this._children.findIndex((child) => isTextNodeRenderable(child) && child.id === id);
|
|
4581
|
-
}
|
|
4582
|
-
get fg() {
|
|
4583
|
-
return this._fg;
|
|
4584
|
-
}
|
|
4585
|
-
set fg(fg2) {
|
|
4586
|
-
if (!fg2) {
|
|
4587
|
-
this._fg = undefined;
|
|
4588
|
-
this.requestRender();
|
|
4589
|
-
return;
|
|
4590
|
-
}
|
|
4591
|
-
this._fg = parseColor(fg2);
|
|
4592
|
-
this.requestRender();
|
|
4593
|
-
}
|
|
4594
|
-
set bg(bg2) {
|
|
4595
|
-
if (!bg2) {
|
|
4596
|
-
this._bg = undefined;
|
|
4597
|
-
this.requestRender();
|
|
4598
|
-
return;
|
|
4599
|
-
}
|
|
4600
|
-
this._bg = parseColor(bg2);
|
|
4601
|
-
this.requestRender();
|
|
4602
|
-
}
|
|
4603
|
-
get bg() {
|
|
4604
|
-
return this._bg;
|
|
4605
|
-
}
|
|
4606
|
-
set attributes(attributes) {
|
|
4607
|
-
this._attributes = attributes;
|
|
4608
|
-
this.requestRender();
|
|
4609
|
-
}
|
|
4610
|
-
get attributes() {
|
|
4611
|
-
return this._attributes;
|
|
4612
|
-
}
|
|
4613
|
-
set link(link2) {
|
|
4614
|
-
this._link = link2;
|
|
4615
|
-
this.requestRender();
|
|
4616
|
-
}
|
|
4617
|
-
get link() {
|
|
4618
|
-
return this._link;
|
|
4619
|
-
}
|
|
4620
|
-
findDescendantById(id) {
|
|
4621
|
-
return;
|
|
4622
|
-
}
|
|
4623
|
-
}
|
|
4624
|
-
|
|
4625
|
-
class RootTextNodeRenderable extends TextNodeRenderable {
|
|
4626
|
-
ctx;
|
|
4627
|
-
textParent;
|
|
4628
|
-
constructor(ctx, options, textParent) {
|
|
4629
|
-
super(options);
|
|
4630
|
-
this.ctx = ctx;
|
|
4631
|
-
this.textParent = textParent;
|
|
4632
|
-
}
|
|
4633
|
-
requestRender() {
|
|
4634
|
-
this.markDirty();
|
|
4635
|
-
this.ctx.requestRender();
|
|
4636
|
-
}
|
|
4637
|
-
}
|
|
4638
|
-
|
|
4639
|
-
// src/renderables/composition/constructs.ts
|
|
4640
|
-
function Generic(props, ...children) {
|
|
4641
|
-
return h(VRenderable, props || {}, ...children);
|
|
3570
|
+
// src/renderables/composition/constructs.ts
|
|
3571
|
+
function Generic(props, ...children) {
|
|
3572
|
+
return h(VRenderable, props || {}, ...children);
|
|
4642
3573
|
}
|
|
4643
3574
|
function Box(props, ...children) {
|
|
4644
3575
|
return h(BoxRenderable, props || {}, ...children);
|
|
@@ -5235,49 +4166,271 @@ class LineNumberRenderable extends Renderable {
|
|
|
5235
4166
|
}
|
|
5236
4167
|
}
|
|
5237
4168
|
}
|
|
5238
|
-
// ../../node_modules/.bun/diff@
|
|
4169
|
+
// ../../node_modules/.bun/diff@9.0.0/node_modules/diff/libesm/patch/parse.js
|
|
5239
4170
|
function parsePatch(uniDiff) {
|
|
5240
4171
|
const diffstr = uniDiff.split(/\n/), list = [];
|
|
5241
4172
|
let i = 0;
|
|
4173
|
+
function isGitDiffHeader(line) {
|
|
4174
|
+
return /^diff --git /.test(line);
|
|
4175
|
+
}
|
|
4176
|
+
function isDiffHeader(line) {
|
|
4177
|
+
return isGitDiffHeader(line) || /^Index:\s/.test(line) || /^diff(?: -r \w+)+\s/.test(line);
|
|
4178
|
+
}
|
|
4179
|
+
function isFileHeader(line) {
|
|
4180
|
+
return /^(---|\+\+\+)\s/.test(line);
|
|
4181
|
+
}
|
|
4182
|
+
function isHunkHeader(line) {
|
|
4183
|
+
return /^@@\s/.test(line);
|
|
4184
|
+
}
|
|
5242
4185
|
function parseIndex() {
|
|
4186
|
+
var _a;
|
|
5243
4187
|
const index = {};
|
|
4188
|
+
index.hunks = [];
|
|
5244
4189
|
list.push(index);
|
|
4190
|
+
let seenDiffHeader = false;
|
|
5245
4191
|
while (i < diffstr.length) {
|
|
5246
4192
|
const line = diffstr[i];
|
|
5247
|
-
if (
|
|
4193
|
+
if (isFileHeader(line) || isHunkHeader(line)) {
|
|
5248
4194
|
break;
|
|
5249
4195
|
}
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
4196
|
+
if (isGitDiffHeader(line)) {
|
|
4197
|
+
if (seenDiffHeader) {
|
|
4198
|
+
return;
|
|
4199
|
+
}
|
|
4200
|
+
seenDiffHeader = true;
|
|
4201
|
+
index.isGit = true;
|
|
4202
|
+
const paths = parseGitDiffHeader(line);
|
|
4203
|
+
if (paths) {
|
|
4204
|
+
index.oldFileName = paths.oldFileName;
|
|
4205
|
+
index.newFileName = paths.newFileName;
|
|
4206
|
+
}
|
|
4207
|
+
i++;
|
|
4208
|
+
while (i < diffstr.length) {
|
|
4209
|
+
const extLine = diffstr[i];
|
|
4210
|
+
if (isFileHeader(extLine) || isHunkHeader(extLine) || isDiffHeader(extLine)) {
|
|
4211
|
+
break;
|
|
4212
|
+
}
|
|
4213
|
+
const renameFromMatch = /^rename from (.*)/.exec(extLine);
|
|
4214
|
+
if (renameFromMatch) {
|
|
4215
|
+
index.oldFileName = "a/" + unquoteIfQuoted(renameFromMatch[1]);
|
|
4216
|
+
index.isRename = true;
|
|
4217
|
+
}
|
|
4218
|
+
const renameToMatch = /^rename to (.*)/.exec(extLine);
|
|
4219
|
+
if (renameToMatch) {
|
|
4220
|
+
index.newFileName = "b/" + unquoteIfQuoted(renameToMatch[1]);
|
|
4221
|
+
index.isRename = true;
|
|
4222
|
+
}
|
|
4223
|
+
const copyFromMatch = /^copy from (.*)/.exec(extLine);
|
|
4224
|
+
if (copyFromMatch) {
|
|
4225
|
+
index.oldFileName = "a/" + unquoteIfQuoted(copyFromMatch[1]);
|
|
4226
|
+
index.isCopy = true;
|
|
4227
|
+
}
|
|
4228
|
+
const copyToMatch = /^copy to (.*)/.exec(extLine);
|
|
4229
|
+
if (copyToMatch) {
|
|
4230
|
+
index.newFileName = "b/" + unquoteIfQuoted(copyToMatch[1]);
|
|
4231
|
+
index.isCopy = true;
|
|
4232
|
+
}
|
|
4233
|
+
const newFileModeMatch = /^new file mode (\d+)/.exec(extLine);
|
|
4234
|
+
if (newFileModeMatch) {
|
|
4235
|
+
index.isCreate = true;
|
|
4236
|
+
index.newMode = newFileModeMatch[1];
|
|
4237
|
+
}
|
|
4238
|
+
const deletedFileModeMatch = /^deleted file mode (\d+)/.exec(extLine);
|
|
4239
|
+
if (deletedFileModeMatch) {
|
|
4240
|
+
index.isDelete = true;
|
|
4241
|
+
index.oldMode = deletedFileModeMatch[1];
|
|
4242
|
+
}
|
|
4243
|
+
const oldModeMatch = /^old mode (\d+)/.exec(extLine);
|
|
4244
|
+
if (oldModeMatch) {
|
|
4245
|
+
index.oldMode = oldModeMatch[1];
|
|
4246
|
+
}
|
|
4247
|
+
const newModeMatch = /^new mode (\d+)/.exec(extLine);
|
|
4248
|
+
if (newModeMatch) {
|
|
4249
|
+
index.newMode = newModeMatch[1];
|
|
4250
|
+
}
|
|
4251
|
+
if (/^Binary files /.test(extLine)) {
|
|
4252
|
+
index.isBinary = true;
|
|
4253
|
+
}
|
|
4254
|
+
i++;
|
|
4255
|
+
}
|
|
4256
|
+
continue;
|
|
4257
|
+
} else if (isDiffHeader(line)) {
|
|
4258
|
+
if (seenDiffHeader) {
|
|
4259
|
+
return;
|
|
4260
|
+
}
|
|
4261
|
+
seenDiffHeader = true;
|
|
4262
|
+
const headerMatch = /^(?:Index:|diff(?: -r \w+)+)\s+/.exec(line);
|
|
4263
|
+
if (headerMatch) {
|
|
4264
|
+
index.index = line.substring(headerMatch[0].length).trim();
|
|
4265
|
+
}
|
|
5253
4266
|
}
|
|
5254
4267
|
i++;
|
|
5255
4268
|
}
|
|
5256
4269
|
parseFileHeader(index);
|
|
5257
4270
|
parseFileHeader(index);
|
|
5258
|
-
index.
|
|
4271
|
+
if (index.oldFileName === undefined !== (index.newFileName === undefined)) {
|
|
4272
|
+
throw new Error("Missing " + (index.oldFileName !== undefined ? '"+++ ..."' : '"--- ..."') + " file header for " + ((_a = index.oldFileName) !== null && _a !== undefined ? _a : index.newFileName));
|
|
4273
|
+
}
|
|
5259
4274
|
while (i < diffstr.length) {
|
|
5260
4275
|
const line = diffstr[i];
|
|
5261
|
-
if (
|
|
4276
|
+
if (isDiffHeader(line) || isFileHeader(line) || /^===================================================================/.test(line)) {
|
|
5262
4277
|
break;
|
|
5263
|
-
} else if (
|
|
4278
|
+
} else if (isHunkHeader(line)) {
|
|
5264
4279
|
index.hunks.push(parseHunk());
|
|
5265
|
-
} else if (line) {
|
|
5266
|
-
throw new Error("Unknown line " + (i + 1) + " " + JSON.stringify(line));
|
|
5267
4280
|
} else {
|
|
5268
4281
|
i++;
|
|
5269
4282
|
}
|
|
5270
4283
|
}
|
|
5271
4284
|
}
|
|
4285
|
+
function parseGitDiffHeader(line) {
|
|
4286
|
+
const rest = line.substring("diff --git ".length);
|
|
4287
|
+
if (rest.startsWith('"')) {
|
|
4288
|
+
const oldPath = parseQuotedFileName(rest);
|
|
4289
|
+
if (oldPath === null) {
|
|
4290
|
+
return null;
|
|
4291
|
+
}
|
|
4292
|
+
const afterOld = rest.substring(oldPath.rawLength + 1);
|
|
4293
|
+
let newFileName;
|
|
4294
|
+
if (afterOld.startsWith('"')) {
|
|
4295
|
+
const newPath = parseQuotedFileName(afterOld);
|
|
4296
|
+
if (newPath === null) {
|
|
4297
|
+
return null;
|
|
4298
|
+
}
|
|
4299
|
+
newFileName = newPath.fileName;
|
|
4300
|
+
} else {
|
|
4301
|
+
newFileName = afterOld;
|
|
4302
|
+
}
|
|
4303
|
+
return {
|
|
4304
|
+
oldFileName: oldPath.fileName,
|
|
4305
|
+
newFileName
|
|
4306
|
+
};
|
|
4307
|
+
}
|
|
4308
|
+
const quoteIdx = rest.indexOf('"');
|
|
4309
|
+
if (quoteIdx > 0) {
|
|
4310
|
+
const oldFileName = rest.substring(0, quoteIdx - 1);
|
|
4311
|
+
const newPath = parseQuotedFileName(rest.substring(quoteIdx));
|
|
4312
|
+
if (newPath === null) {
|
|
4313
|
+
return null;
|
|
4314
|
+
}
|
|
4315
|
+
return {
|
|
4316
|
+
oldFileName,
|
|
4317
|
+
newFileName: newPath.fileName
|
|
4318
|
+
};
|
|
4319
|
+
}
|
|
4320
|
+
if (rest.startsWith("a/")) {
|
|
4321
|
+
const splits = [];
|
|
4322
|
+
let idx = 0;
|
|
4323
|
+
while (true) {
|
|
4324
|
+
idx = rest.indexOf(" b/", idx + 1);
|
|
4325
|
+
if (idx === -1) {
|
|
4326
|
+
break;
|
|
4327
|
+
}
|
|
4328
|
+
splits.push(idx);
|
|
4329
|
+
}
|
|
4330
|
+
if (splits.length > 0) {
|
|
4331
|
+
const mid = splits[Math.floor(splits.length / 2)];
|
|
4332
|
+
return {
|
|
4333
|
+
oldFileName: rest.substring(0, mid),
|
|
4334
|
+
newFileName: rest.substring(mid + 1)
|
|
4335
|
+
};
|
|
4336
|
+
}
|
|
4337
|
+
}
|
|
4338
|
+
return null;
|
|
4339
|
+
}
|
|
4340
|
+
function unquoteIfQuoted(s) {
|
|
4341
|
+
if (s.startsWith('"')) {
|
|
4342
|
+
const parsed = parseQuotedFileName(s);
|
|
4343
|
+
if (parsed) {
|
|
4344
|
+
return parsed.fileName;
|
|
4345
|
+
}
|
|
4346
|
+
}
|
|
4347
|
+
return s;
|
|
4348
|
+
}
|
|
4349
|
+
function parseQuotedFileName(s) {
|
|
4350
|
+
if (!s.startsWith('"')) {
|
|
4351
|
+
return null;
|
|
4352
|
+
}
|
|
4353
|
+
let result = "";
|
|
4354
|
+
let j = 1;
|
|
4355
|
+
while (j < s.length) {
|
|
4356
|
+
if (s[j] === '"') {
|
|
4357
|
+
return { fileName: result, rawLength: j + 1 };
|
|
4358
|
+
}
|
|
4359
|
+
if (s[j] === "\\" && j + 1 < s.length) {
|
|
4360
|
+
j++;
|
|
4361
|
+
switch (s[j]) {
|
|
4362
|
+
case "a":
|
|
4363
|
+
result += "\x07";
|
|
4364
|
+
break;
|
|
4365
|
+
case "b":
|
|
4366
|
+
result += "\b";
|
|
4367
|
+
break;
|
|
4368
|
+
case "f":
|
|
4369
|
+
result += "\f";
|
|
4370
|
+
break;
|
|
4371
|
+
case "n":
|
|
4372
|
+
result += `
|
|
4373
|
+
`;
|
|
4374
|
+
break;
|
|
4375
|
+
case "r":
|
|
4376
|
+
result += "\r";
|
|
4377
|
+
break;
|
|
4378
|
+
case "t":
|
|
4379
|
+
result += "\t";
|
|
4380
|
+
break;
|
|
4381
|
+
case "v":
|
|
4382
|
+
result += "\v";
|
|
4383
|
+
break;
|
|
4384
|
+
case "\\":
|
|
4385
|
+
result += "\\";
|
|
4386
|
+
break;
|
|
4387
|
+
case '"':
|
|
4388
|
+
result += '"';
|
|
4389
|
+
break;
|
|
4390
|
+
case "0":
|
|
4391
|
+
case "1":
|
|
4392
|
+
case "2":
|
|
4393
|
+
case "3":
|
|
4394
|
+
case "4":
|
|
4395
|
+
case "5":
|
|
4396
|
+
case "6":
|
|
4397
|
+
case "7": {
|
|
4398
|
+
if (j + 2 >= s.length || s[j + 1] < "0" || s[j + 1] > "7" || s[j + 2] < "0" || s[j + 2] > "7") {
|
|
4399
|
+
return null;
|
|
4400
|
+
}
|
|
4401
|
+
const bytes = [parseInt(s.substring(j, j + 3), 8)];
|
|
4402
|
+
j += 3;
|
|
4403
|
+
while (s[j] === "\\" && s[j + 1] >= "0" && s[j + 1] <= "7") {
|
|
4404
|
+
if (j + 3 >= s.length || s[j + 2] < "0" || s[j + 2] > "7" || s[j + 3] < "0" || s[j + 3] > "7") {
|
|
4405
|
+
return null;
|
|
4406
|
+
}
|
|
4407
|
+
bytes.push(parseInt(s.substring(j + 1, j + 4), 8));
|
|
4408
|
+
j += 4;
|
|
4409
|
+
}
|
|
4410
|
+
result += new TextDecoder("utf-8").decode(new Uint8Array(bytes));
|
|
4411
|
+
continue;
|
|
4412
|
+
}
|
|
4413
|
+
default:
|
|
4414
|
+
return null;
|
|
4415
|
+
}
|
|
4416
|
+
} else {
|
|
4417
|
+
result += s[j];
|
|
4418
|
+
}
|
|
4419
|
+
j++;
|
|
4420
|
+
}
|
|
4421
|
+
return null;
|
|
4422
|
+
}
|
|
5272
4423
|
function parseFileHeader(index) {
|
|
5273
|
-
const
|
|
5274
|
-
if (
|
|
5275
|
-
const data =
|
|
5276
|
-
let fileName = data[0]
|
|
5277
|
-
if (
|
|
5278
|
-
fileName =
|
|
5279
|
-
}
|
|
5280
|
-
|
|
4424
|
+
const fileHeaderMatch = /^(---|\+\+\+)\s+/.exec(diffstr[i]);
|
|
4425
|
+
if (fileHeaderMatch) {
|
|
4426
|
+
const prefix = fileHeaderMatch[1], data = diffstr[i].substring(3).trim().split("\t", 2), header = (data[1] || "").trim();
|
|
4427
|
+
let fileName = data[0];
|
|
4428
|
+
if (fileName.startsWith('"')) {
|
|
4429
|
+
fileName = unquoteIfQuoted(fileName);
|
|
4430
|
+
} else {
|
|
4431
|
+
fileName = fileName.replace(/\\\\/g, "\\");
|
|
4432
|
+
}
|
|
4433
|
+
if (prefix === "---") {
|
|
5281
4434
|
index.oldFileName = fileName;
|
|
5282
4435
|
index.oldHeader = header;
|
|
5283
4436
|
} else {
|
|
@@ -5332,110 +4485,16 @@ function parsePatch(uniDiff) {
|
|
|
5332
4485
|
if (removeCount !== hunk.oldLines) {
|
|
5333
4486
|
throw new Error("Removed line count did not match for hunk at line " + (chunkHeaderIndex + 1));
|
|
5334
4487
|
}
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
while (i < diffstr.length) {
|
|
5338
|
-
parseIndex();
|
|
5339
|
-
}
|
|
5340
|
-
return list;
|
|
5341
|
-
}
|
|
5342
|
-
// src/renderables/Text.ts
|
|
5343
|
-
class TextRenderable extends TextBufferRenderable {
|
|
5344
|
-
_text;
|
|
5345
|
-
_hasManualStyledText = false;
|
|
5346
|
-
rootTextNode;
|
|
5347
|
-
_contentDefaultOptions = {
|
|
5348
|
-
content: ""
|
|
5349
|
-
};
|
|
5350
|
-
constructor(ctx, options) {
|
|
5351
|
-
super(ctx, options);
|
|
5352
|
-
const content = options.content ?? this._contentDefaultOptions.content;
|
|
5353
|
-
const styledText = typeof content === "string" ? stringToStyledText(content) : content;
|
|
5354
|
-
this._text = styledText;
|
|
5355
|
-
this._hasManualStyledText = options.content !== undefined && content !== "";
|
|
5356
|
-
this.rootTextNode = new RootTextNodeRenderable(ctx, {
|
|
5357
|
-
id: `${this.id}-root`,
|
|
5358
|
-
fg: this._defaultFg,
|
|
5359
|
-
bg: this._defaultBg,
|
|
5360
|
-
attributes: this._defaultAttributes
|
|
5361
|
-
}, this);
|
|
5362
|
-
this.updateTextBuffer(styledText);
|
|
5363
|
-
}
|
|
5364
|
-
updateTextBuffer(styledText) {
|
|
5365
|
-
this.textBuffer.setStyledText(styledText);
|
|
5366
|
-
this.clearChunks(styledText);
|
|
5367
|
-
}
|
|
5368
|
-
clearChunks(styledText) {}
|
|
5369
|
-
get content() {
|
|
5370
|
-
return this._text;
|
|
5371
|
-
}
|
|
5372
|
-
get chunks() {
|
|
5373
|
-
return this._text.chunks;
|
|
5374
|
-
}
|
|
5375
|
-
get textNode() {
|
|
5376
|
-
return this.rootTextNode;
|
|
5377
|
-
}
|
|
5378
|
-
set content(value) {
|
|
5379
|
-
this._hasManualStyledText = true;
|
|
5380
|
-
const styledText = typeof value === "string" ? stringToStyledText(value) : value;
|
|
5381
|
-
if (this._text !== styledText) {
|
|
5382
|
-
this._text = styledText;
|
|
5383
|
-
this.updateTextBuffer(styledText);
|
|
5384
|
-
this.updateTextInfo();
|
|
5385
|
-
}
|
|
5386
|
-
}
|
|
5387
|
-
updateTextFromNodes() {
|
|
5388
|
-
if (this.rootTextNode.isDirty && !this._hasManualStyledText) {
|
|
5389
|
-
const chunks = this.rootTextNode.gatherWithInheritedStyle({
|
|
5390
|
-
fg: this._defaultFg,
|
|
5391
|
-
bg: this._defaultBg,
|
|
5392
|
-
attributes: this._defaultAttributes,
|
|
5393
|
-
link: undefined
|
|
5394
|
-
});
|
|
5395
|
-
this.textBuffer.setStyledText(new StyledText(chunks));
|
|
5396
|
-
this.refreshLocalSelection();
|
|
5397
|
-
this.yogaNode.markDirty();
|
|
4488
|
+
if (i < diffstr.length && diffstr[i] && /^[+ -]/.test(diffstr[i]) && !isFileHeader(diffstr[i])) {
|
|
4489
|
+
throw new Error("Hunk at line " + (chunkHeaderIndex + 1) + " has more lines than expected (expected " + hunk.oldLines + " old lines and " + hunk.newLines + " new lines)");
|
|
5398
4490
|
}
|
|
4491
|
+
return hunk;
|
|
5399
4492
|
}
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
}
|
|
5403
|
-
remove(id) {
|
|
5404
|
-
this.rootTextNode.remove(id);
|
|
5405
|
-
}
|
|
5406
|
-
insertBefore(obj, anchor) {
|
|
5407
|
-
this.rootTextNode.insertBefore(obj, anchor);
|
|
5408
|
-
return this.rootTextNode.children.indexOf(obj);
|
|
5409
|
-
}
|
|
5410
|
-
getTextChildren() {
|
|
5411
|
-
return this.rootTextNode.getChildren();
|
|
5412
|
-
}
|
|
5413
|
-
clear() {
|
|
5414
|
-
this.rootTextNode.clear();
|
|
5415
|
-
const emptyStyledText = stringToStyledText("");
|
|
5416
|
-
this._text = emptyStyledText;
|
|
5417
|
-
this.updateTextBuffer(emptyStyledText);
|
|
5418
|
-
this.updateTextInfo();
|
|
5419
|
-
this.requestRender();
|
|
5420
|
-
}
|
|
5421
|
-
onLifecyclePass = () => {
|
|
5422
|
-
this.updateTextFromNodes();
|
|
5423
|
-
};
|
|
5424
|
-
onFgChanged(newColor) {
|
|
5425
|
-
this.rootTextNode.fg = newColor;
|
|
5426
|
-
}
|
|
5427
|
-
onBgChanged(newColor) {
|
|
5428
|
-
this.rootTextNode.bg = newColor;
|
|
5429
|
-
}
|
|
5430
|
-
onAttributesChanged(newAttributes) {
|
|
5431
|
-
this.rootTextNode.attributes = newAttributes;
|
|
5432
|
-
}
|
|
5433
|
-
destroy() {
|
|
5434
|
-
this.rootTextNode.children.length = 0;
|
|
5435
|
-
super.destroy();
|
|
4493
|
+
while (i < diffstr.length) {
|
|
4494
|
+
parseIndex();
|
|
5436
4495
|
}
|
|
4496
|
+
return list;
|
|
5437
4497
|
}
|
|
5438
|
-
|
|
5439
4498
|
// src/renderables/Diff.ts
|
|
5440
4499
|
class DiffRenderable extends Renderable {
|
|
5441
4500
|
_diff;
|
|
@@ -6412,7 +5471,7 @@ class DiffRenderable extends Renderable {
|
|
|
6412
5471
|
}
|
|
6413
5472
|
}
|
|
6414
5473
|
// src/renderables/Textarea.ts
|
|
6415
|
-
var
|
|
5474
|
+
var defaultTextareaKeyBindings = [
|
|
6416
5475
|
{ name: "left", action: "move-left" },
|
|
6417
5476
|
{ name: "right", action: "move-right" },
|
|
6418
5477
|
{ name: "up", action: "move-up" },
|
|
@@ -6449,8 +5508,10 @@ var defaultTextareaKeybindings = [
|
|
|
6449
5508
|
{ name: "delete", action: "delete" },
|
|
6450
5509
|
{ name: "delete", shift: true, action: "delete" },
|
|
6451
5510
|
{ name: "return", action: "newline" },
|
|
5511
|
+
{ name: "kpenter", action: "newline" },
|
|
6452
5512
|
{ name: "linefeed", action: "newline" },
|
|
6453
5513
|
{ name: "return", meta: true, action: "submit" },
|
|
5514
|
+
{ name: "kpenter", meta: true, action: "submit" },
|
|
6454
5515
|
{ name: "-", ctrl: true, action: "undo" },
|
|
6455
5516
|
{ name: ".", ctrl: true, action: "redo" },
|
|
6456
5517
|
{ name: "z", super: true, action: "undo" },
|
|
@@ -6514,7 +5575,7 @@ class TextareaRenderable extends EditBufferRenderable {
|
|
|
6514
5575
|
this._placeholderColor = parseColor(options.placeholderColor ?? defaults.placeholderColor);
|
|
6515
5576
|
this._keyAliasMap = mergeKeyAliases(defaultKeyAliases, options.keyAliasMap || {});
|
|
6516
5577
|
this._keyBindings = options.keyBindings || [];
|
|
6517
|
-
const mergedBindings = mergeKeyBindings(
|
|
5578
|
+
const mergedBindings = mergeKeyBindings(defaultTextareaKeyBindings, this._keyBindings);
|
|
6518
5579
|
this._keyBindingsMap = buildKeyBindingsMap(mergedBindings, this._keyAliasMap);
|
|
6519
5580
|
this._actionHandlers = this.buildActionHandlers();
|
|
6520
5581
|
this._submitListener = options.onSubmit;
|
|
@@ -6582,19 +5643,13 @@ class TextareaRenderable extends EditBufferRenderable {
|
|
|
6582
5643
|
this.insertText(stripAnsiSequences(decodePasteBytes(event.bytes)));
|
|
6583
5644
|
}
|
|
6584
5645
|
handleKeyPress(key) {
|
|
6585
|
-
|
|
6586
|
-
|
|
6587
|
-
|
|
6588
|
-
|
|
6589
|
-
|
|
6590
|
-
|
|
6591
|
-
|
|
6592
|
-
});
|
|
6593
|
-
const action = this._keyBindingsMap.get(bindingKey);
|
|
6594
|
-
if (action) {
|
|
6595
|
-
const handler = this._actionHandlers.get(action);
|
|
6596
|
-
if (handler) {
|
|
6597
|
-
return handler();
|
|
5646
|
+
if (this.traits.suspend !== true) {
|
|
5647
|
+
const action = getKeyBindingAction(this._keyBindingsMap, key);
|
|
5648
|
+
if (action) {
|
|
5649
|
+
const handler = this._actionHandlers.get(action);
|
|
5650
|
+
if (handler) {
|
|
5651
|
+
return handler();
|
|
5652
|
+
}
|
|
6598
5653
|
}
|
|
6599
5654
|
}
|
|
6600
5655
|
if (!key.ctrl && !key.meta && !key.super && !key.hyper) {
|
|
@@ -6708,12 +5763,12 @@ class TextareaRenderable extends EditBufferRenderable {
|
|
|
6708
5763
|
}
|
|
6709
5764
|
set keyBindings(bindings) {
|
|
6710
5765
|
this._keyBindings = bindings;
|
|
6711
|
-
const mergedBindings = mergeKeyBindings(
|
|
5766
|
+
const mergedBindings = mergeKeyBindings(defaultTextareaKeyBindings, bindings);
|
|
6712
5767
|
this._keyBindingsMap = buildKeyBindingsMap(mergedBindings, this._keyAliasMap);
|
|
6713
5768
|
}
|
|
6714
5769
|
set keyAliasMap(aliases) {
|
|
6715
5770
|
this._keyAliasMap = mergeKeyAliases(defaultKeyAliases, aliases);
|
|
6716
|
-
const mergedBindings = mergeKeyBindings(
|
|
5771
|
+
const mergedBindings = mergeKeyBindings(defaultTextareaKeyBindings, this._keyBindings);
|
|
6717
5772
|
this._keyBindingsMap = buildKeyBindingsMap(mergedBindings, this._keyAliasMap);
|
|
6718
5773
|
}
|
|
6719
5774
|
get extmarks() {
|
|
@@ -6750,6 +5805,7 @@ class InputRenderable extends TextareaRenderable {
|
|
|
6750
5805
|
wrapMode: "none",
|
|
6751
5806
|
keyBindings: [
|
|
6752
5807
|
{ name: "return", action: "submit" },
|
|
5808
|
+
{ name: "kpenter", action: "submit" },
|
|
6753
5809
|
{ name: "linefeed", action: "submit" },
|
|
6754
5810
|
...options.keyBindings || []
|
|
6755
5811
|
]
|
|
@@ -6895,7 +5951,9 @@ class TextTableRenderable extends Renderable {
|
|
|
6895
5951
|
_wrapMode;
|
|
6896
5952
|
_columnWidthMode;
|
|
6897
5953
|
_columnFitter;
|
|
6898
|
-
|
|
5954
|
+
_cellPaddingX;
|
|
5955
|
+
_cellPaddingY;
|
|
5956
|
+
_columnGap;
|
|
6899
5957
|
_showBorders;
|
|
6900
5958
|
_border;
|
|
6901
5959
|
_outerBorder;
|
|
@@ -6926,6 +5984,9 @@ class TextTableRenderable extends Renderable {
|
|
|
6926
5984
|
columnWidthMode: "full",
|
|
6927
5985
|
columnFitter: "proportional",
|
|
6928
5986
|
cellPadding: 0,
|
|
5987
|
+
cellPaddingX: undefined,
|
|
5988
|
+
cellPaddingY: undefined,
|
|
5989
|
+
columnGap: 0,
|
|
6929
5990
|
showBorders: true,
|
|
6930
5991
|
border: true,
|
|
6931
5992
|
outerBorder: true,
|
|
@@ -6946,7 +6007,9 @@ class TextTableRenderable extends Renderable {
|
|
|
6946
6007
|
this._wrapMode = options.wrapMode ?? this._defaultOptions.wrapMode;
|
|
6947
6008
|
this._columnWidthMode = options.columnWidthMode ?? this._defaultOptions.columnWidthMode;
|
|
6948
6009
|
this._columnFitter = this.resolveColumnFitter(options.columnFitter);
|
|
6949
|
-
this.
|
|
6010
|
+
this._cellPaddingX = this.resolveCellPadding(options.cellPaddingX ?? options.cellPadding);
|
|
6011
|
+
this._cellPaddingY = this.resolveCellPadding(options.cellPaddingY ?? options.cellPadding);
|
|
6012
|
+
this._columnGap = this.resolveColumnGap(options.columnGap);
|
|
6950
6013
|
this._showBorders = options.showBorders ?? this._defaultOptions.showBorders;
|
|
6951
6014
|
this._border = options.border ?? this._defaultOptions.border;
|
|
6952
6015
|
this._hasExplicitOuterBorder = options.outerBorder !== undefined;
|
|
@@ -7005,13 +6068,44 @@ class TextTableRenderable extends Renderable {
|
|
|
7005
6068
|
this.invalidateLayoutAndRaster();
|
|
7006
6069
|
}
|
|
7007
6070
|
get cellPadding() {
|
|
7008
|
-
return this.
|
|
6071
|
+
return this._cellPaddingX === this._cellPaddingY ? this._cellPaddingX : 0;
|
|
7009
6072
|
}
|
|
7010
6073
|
set cellPadding(value) {
|
|
7011
6074
|
const next = this.resolveCellPadding(value);
|
|
7012
|
-
if (this.
|
|
6075
|
+
if (this._cellPaddingX === next && this._cellPaddingY === next)
|
|
6076
|
+
return;
|
|
6077
|
+
this._cellPaddingX = next;
|
|
6078
|
+
this._cellPaddingY = next;
|
|
6079
|
+
this.invalidateLayoutAndRaster();
|
|
6080
|
+
}
|
|
6081
|
+
get cellPaddingX() {
|
|
6082
|
+
return this._cellPaddingX;
|
|
6083
|
+
}
|
|
6084
|
+
set cellPaddingX(value) {
|
|
6085
|
+
const next = this.resolveCellPadding(value);
|
|
6086
|
+
if (this._cellPaddingX === next)
|
|
6087
|
+
return;
|
|
6088
|
+
this._cellPaddingX = next;
|
|
6089
|
+
this.invalidateLayoutAndRaster();
|
|
6090
|
+
}
|
|
6091
|
+
get cellPaddingY() {
|
|
6092
|
+
return this._cellPaddingY;
|
|
6093
|
+
}
|
|
6094
|
+
set cellPaddingY(value) {
|
|
6095
|
+
const next = this.resolveCellPadding(value);
|
|
6096
|
+
if (this._cellPaddingY === next)
|
|
7013
6097
|
return;
|
|
7014
|
-
this.
|
|
6098
|
+
this._cellPaddingY = next;
|
|
6099
|
+
this.invalidateLayoutAndRaster();
|
|
6100
|
+
}
|
|
6101
|
+
get columnGap() {
|
|
6102
|
+
return this._columnGap;
|
|
6103
|
+
}
|
|
6104
|
+
set columnGap(value) {
|
|
6105
|
+
const next = this.resolveColumnGap(value);
|
|
6106
|
+
if (this._columnGap === next)
|
|
6107
|
+
return;
|
|
6108
|
+
this._columnGap = next;
|
|
7015
6109
|
this.invalidateLayoutAndRaster();
|
|
7016
6110
|
}
|
|
7017
6111
|
get showBorders() {
|
|
@@ -7327,7 +6421,7 @@ class TextTableRenderable extends Renderable {
|
|
|
7327
6421
|
const borderLayout = this.resolveBorderLayout();
|
|
7328
6422
|
const columnWidths = this.computeColumnWidths(maxTableWidth, borderLayout);
|
|
7329
6423
|
const rowHeights = this.computeRowHeights(columnWidths);
|
|
7330
|
-
const columnOffsets = this.computeOffsets(columnWidths, borderLayout.left, borderLayout.right, borderLayout.innerVertical);
|
|
6424
|
+
const columnOffsets = this.computeOffsets(columnWidths, borderLayout.left, borderLayout.right, borderLayout.innerVertical, this.getInterColumnGap(borderLayout));
|
|
7331
6425
|
const rowOffsets = this.computeOffsets(rowHeights, borderLayout.top, borderLayout.bottom, borderLayout.innerHorizontal);
|
|
7332
6426
|
return {
|
|
7333
6427
|
columnWidths,
|
|
@@ -7359,7 +6453,7 @@ class TextTableRenderable extends Renderable {
|
|
|
7359
6453
|
if (maxTableWidth === undefined || !Number.isFinite(maxTableWidth) || maxTableWidth <= 0) {
|
|
7360
6454
|
return intrinsicWidths;
|
|
7361
6455
|
}
|
|
7362
|
-
const maxContentWidth = Math.max(1, Math.floor(maxTableWidth) - this.getVerticalBorderCount(borderLayout));
|
|
6456
|
+
const maxContentWidth = Math.max(1, Math.floor(maxTableWidth) - this.getVerticalBorderCount(borderLayout) - this.getTotalInterColumnGap(borderLayout));
|
|
7363
6457
|
const currentWidth = intrinsicWidths.reduce((sum, width) => sum + width, 0);
|
|
7364
6458
|
if (currentWidth === maxContentWidth) {
|
|
7365
6459
|
return intrinsicWidths;
|
|
@@ -7542,17 +6636,26 @@ class TextTableRenderable extends Renderable {
|
|
|
7542
6636
|
}
|
|
7543
6637
|
return rowHeights;
|
|
7544
6638
|
}
|
|
7545
|
-
computeOffsets(parts, startBoundary, endBoundary, includeInnerBoundaries) {
|
|
6639
|
+
computeOffsets(parts, startBoundary, endBoundary, includeInnerBoundaries, innerGap = 0) {
|
|
7546
6640
|
const offsets = [startBoundary ? 0 : -1];
|
|
7547
6641
|
let cursor = offsets[0] ?? 0;
|
|
7548
6642
|
for (let idx = 0;idx < parts.length; idx++) {
|
|
7549
6643
|
const size = parts[idx] ?? 1;
|
|
7550
|
-
const
|
|
7551
|
-
cursor += size +
|
|
6644
|
+
const separatorAfter = idx < parts.length - 1 ? includeInnerBoundaries ? 1 : innerGap : endBoundary ? 1 : 0;
|
|
6645
|
+
cursor += size + separatorAfter;
|
|
7552
6646
|
offsets.push(cursor);
|
|
7553
6647
|
}
|
|
7554
6648
|
return offsets;
|
|
7555
6649
|
}
|
|
6650
|
+
getInterColumnGap(borderLayout) {
|
|
6651
|
+
if (borderLayout.innerVertical) {
|
|
6652
|
+
return 0;
|
|
6653
|
+
}
|
|
6654
|
+
return this._columnGap;
|
|
6655
|
+
}
|
|
6656
|
+
getTotalInterColumnGap(borderLayout) {
|
|
6657
|
+
return Math.max(0, this._columnCount - 1) * this.getInterColumnGap(borderLayout);
|
|
6658
|
+
}
|
|
7556
6659
|
applyLayoutToViews(layout) {
|
|
7557
6660
|
const horizontalPadding = this.getHorizontalCellPadding();
|
|
7558
6661
|
const verticalPadding = this.getVerticalCellPadding();
|
|
@@ -7614,14 +6717,15 @@ class TextTableRenderable extends Renderable {
|
|
|
7614
6717
|
drawCellRange(buffer, firstRow, lastRow) {
|
|
7615
6718
|
const colOffsets = this._layout.columnOffsets;
|
|
7616
6719
|
const rowOffsets = this._layout.rowOffsets;
|
|
7617
|
-
const
|
|
6720
|
+
const cellPaddingX = this._cellPaddingX;
|
|
6721
|
+
const cellPaddingY = this._cellPaddingY;
|
|
7618
6722
|
for (let rowIdx = firstRow;rowIdx <= lastRow; rowIdx++) {
|
|
7619
|
-
const cellY = (rowOffsets[rowIdx] ?? 0) + 1 +
|
|
6723
|
+
const cellY = (rowOffsets[rowIdx] ?? 0) + 1 + cellPaddingY;
|
|
7620
6724
|
for (let colIdx = 0;colIdx < this._columnCount; colIdx++) {
|
|
7621
6725
|
const cell = this._cells[rowIdx]?.[colIdx];
|
|
7622
6726
|
if (!cell)
|
|
7623
6727
|
continue;
|
|
7624
|
-
buffer.drawTextBuffer(cell.textBufferView, (colOffsets[colIdx] ?? 0) + 1 +
|
|
6728
|
+
buffer.drawTextBuffer(cell.textBufferView, (colOffsets[colIdx] ?? 0) + 1 + cellPaddingX, cellY);
|
|
7625
6729
|
}
|
|
7626
6730
|
}
|
|
7627
6731
|
}
|
|
@@ -7650,7 +6754,15 @@ class TextTableRenderable extends Renderable {
|
|
|
7650
6754
|
for (let colIdx = 0;colIdx < this._columnCount; colIdx++) {
|
|
7651
6755
|
const cellX = (colOffsets[colIdx] ?? 0) + 1;
|
|
7652
6756
|
const colWidth = colWidths[colIdx] ?? 1;
|
|
7653
|
-
|
|
6757
|
+
if (this._backgroundColor.a < 1) {
|
|
6758
|
+
for (let y = cellY;y < cellY + rowHeight; y++) {
|
|
6759
|
+
for (let x = cellX;x < cellX + colWidth; x++) {
|
|
6760
|
+
buffer.setCell(x, y, " ", this._defaultFg, this._backgroundColor, this._defaultAttributes);
|
|
6761
|
+
}
|
|
6762
|
+
}
|
|
6763
|
+
} else {
|
|
6764
|
+
buffer.fillRect(cellX, cellY, colWidth, rowHeight, this._backgroundColor);
|
|
6765
|
+
}
|
|
7654
6766
|
}
|
|
7655
6767
|
}
|
|
7656
6768
|
}
|
|
@@ -7690,6 +6802,11 @@ class TextTableRenderable extends Renderable {
|
|
|
7690
6802
|
return { rowIdx, colIdx };
|
|
7691
6803
|
}
|
|
7692
6804
|
applySelectionToCells(localSelection, isStart) {
|
|
6805
|
+
if (localSelection.anchorX === localSelection.focusX && localSelection.anchorY === localSelection.focusY) {
|
|
6806
|
+
this.resetCellSelections();
|
|
6807
|
+
this._lastSelectionMode = null;
|
|
6808
|
+
return;
|
|
6809
|
+
}
|
|
7693
6810
|
const minSelY = Math.min(localSelection.anchorY, localSelection.focusY);
|
|
7694
6811
|
const maxSelY = Math.max(localSelection.anchorY, localSelection.focusY);
|
|
7695
6812
|
const firstRow = this.findRowForLocalY(minSelY);
|
|
@@ -7703,7 +6820,7 @@ class TextTableRenderable extends Renderable {
|
|
|
7703
6820
|
this.resetRowSelection(rowIdx);
|
|
7704
6821
|
continue;
|
|
7705
6822
|
}
|
|
7706
|
-
const cellTop = (this._layout.rowOffsets[rowIdx] ?? 0) + 1 + this.
|
|
6823
|
+
const cellTop = (this._layout.rowOffsets[rowIdx] ?? 0) + 1 + this._cellPaddingY;
|
|
7707
6824
|
for (let colIdx = 0;colIdx < this._columnCount; colIdx++) {
|
|
7708
6825
|
const cell = this._cells[rowIdx]?.[colIdx];
|
|
7709
6826
|
if (!cell)
|
|
@@ -7712,7 +6829,7 @@ class TextTableRenderable extends Renderable {
|
|
|
7712
6829
|
cell.textBufferView.resetLocalSelection();
|
|
7713
6830
|
continue;
|
|
7714
6831
|
}
|
|
7715
|
-
const cellLeft = (this._layout.columnOffsets[colIdx] ?? 0) + 1 + this.
|
|
6832
|
+
const cellLeft = (this._layout.columnOffsets[colIdx] ?? 0) + 1 + this._cellPaddingX;
|
|
7716
6833
|
let coords = {
|
|
7717
6834
|
anchorX: localSelection.anchorX - cellLeft,
|
|
7718
6835
|
anchorY: localSelection.anchorY - cellTop,
|
|
@@ -7720,6 +6837,10 @@ class TextTableRenderable extends Renderable {
|
|
|
7720
6837
|
focusY: localSelection.focusY - cellTop
|
|
7721
6838
|
};
|
|
7722
6839
|
const isAnchorCell = selection.anchorCell !== null && selection.anchorCell.rowIdx === rowIdx && selection.anchorCell.colIdx === colIdx;
|
|
6840
|
+
if (selection.mode === "single-cell" && !isAnchorCell) {
|
|
6841
|
+
cell.textBufferView.resetLocalSelection();
|
|
6842
|
+
continue;
|
|
6843
|
+
}
|
|
7723
6844
|
const forceSet = isAnchorCell && selection.mode !== "single-cell";
|
|
7724
6845
|
if (forceSet) {
|
|
7725
6846
|
coords = this.getFullCellSelectionCoords(rowIdx, colIdx);
|
|
@@ -7854,10 +6975,10 @@ class TextTableRenderable extends Renderable {
|
|
|
7854
6975
|
return;
|
|
7855
6976
|
}
|
|
7856
6977
|
getHorizontalCellPadding() {
|
|
7857
|
-
return this.
|
|
6978
|
+
return this._cellPaddingX * 2;
|
|
7858
6979
|
}
|
|
7859
6980
|
getVerticalCellPadding() {
|
|
7860
|
-
return this.
|
|
6981
|
+
return this._cellPaddingY * 2;
|
|
7861
6982
|
}
|
|
7862
6983
|
resolveColumnFitter(value) {
|
|
7863
6984
|
if (value === undefined) {
|
|
@@ -7871,6 +6992,12 @@ class TextTableRenderable extends Renderable {
|
|
|
7871
6992
|
}
|
|
7872
6993
|
return Math.max(0, Math.floor(value));
|
|
7873
6994
|
}
|
|
6995
|
+
resolveColumnGap(value) {
|
|
6996
|
+
if (value === undefined || !Number.isFinite(value)) {
|
|
6997
|
+
return this._defaultOptions.columnGap;
|
|
6998
|
+
}
|
|
6999
|
+
return Math.max(0, Math.floor(value));
|
|
7000
|
+
}
|
|
7874
7001
|
invalidateLayoutAndRaster(markYogaDirty = true) {
|
|
7875
7002
|
this._layoutDirty = true;
|
|
7876
7003
|
this._rasterDirty = true;
|
|
@@ -9157,9 +8284,13 @@ function parseMarkdownIncremental(newContent, prevState, trailingUnstable = 2) {
|
|
|
9157
8284
|
if (!prevState || prevState.tokens.length === 0) {
|
|
9158
8285
|
try {
|
|
9159
8286
|
const tokens = x.lex(newContent, { gfm: true });
|
|
9160
|
-
return {
|
|
8287
|
+
return {
|
|
8288
|
+
content: newContent,
|
|
8289
|
+
tokens,
|
|
8290
|
+
stableTokenCount: Math.max(0, tokens.length - trailingUnstable)
|
|
8291
|
+
};
|
|
9161
8292
|
} catch {
|
|
9162
|
-
return { content: newContent, tokens: [] };
|
|
8293
|
+
return { content: newContent, tokens: [], stableTokenCount: 0 };
|
|
9163
8294
|
}
|
|
9164
8295
|
}
|
|
9165
8296
|
let offset = 0;
|
|
@@ -9181,23 +8312,32 @@ function parseMarkdownIncremental(newContent, prevState, trailingUnstable = 2) {
|
|
|
9181
8312
|
const stableTokens = prevState.tokens.slice(0, reuseCount);
|
|
9182
8313
|
const remainingContent = newContent.slice(offset);
|
|
9183
8314
|
if (!remainingContent) {
|
|
9184
|
-
return {
|
|
8315
|
+
return {
|
|
8316
|
+
content: newContent,
|
|
8317
|
+
tokens: stableTokens,
|
|
8318
|
+
stableTokenCount: stableTokens.length
|
|
8319
|
+
};
|
|
9185
8320
|
}
|
|
9186
8321
|
try {
|
|
9187
8322
|
const newTokens = x.lex(remainingContent, { gfm: true });
|
|
9188
|
-
return {
|
|
8323
|
+
return {
|
|
8324
|
+
content: newContent,
|
|
8325
|
+
tokens: [...stableTokens, ...newTokens],
|
|
8326
|
+
stableTokenCount: trailingUnstable === 0 ? stableTokens.length + newTokens.length : stableTokens.length
|
|
8327
|
+
};
|
|
9189
8328
|
} catch {
|
|
9190
8329
|
try {
|
|
9191
8330
|
const fullTokens = x.lex(newContent, { gfm: true });
|
|
9192
|
-
return { content: newContent, tokens: fullTokens };
|
|
8331
|
+
return { content: newContent, tokens: fullTokens, stableTokenCount: 0 };
|
|
9193
8332
|
} catch {
|
|
9194
|
-
return { content: newContent, tokens: [] };
|
|
8333
|
+
return { content: newContent, tokens: [], stableTokenCount: 0 };
|
|
9195
8334
|
}
|
|
9196
8335
|
}
|
|
9197
8336
|
}
|
|
9198
8337
|
|
|
9199
8338
|
// src/renderables/Markdown.ts
|
|
9200
8339
|
var TRAILING_MARKDOWN_BLOCK_BREAKS_RE = /(?:\r?\n){2,}$/;
|
|
8340
|
+
var TRAILING_MARKDOWN_BLOCK_NEWLINES_RE = /(?:\r?\n)+$/;
|
|
9201
8341
|
function colorsEqual(left, right) {
|
|
9202
8342
|
if (!left || !right)
|
|
9203
8343
|
return left === right;
|
|
@@ -9214,9 +8354,11 @@ class MarkdownRenderable extends Renderable {
|
|
|
9214
8354
|
_treeSitterClient;
|
|
9215
8355
|
_tableOptions;
|
|
9216
8356
|
_renderNode;
|
|
8357
|
+
_internalBlockMode;
|
|
9217
8358
|
_parseState = null;
|
|
9218
8359
|
_streaming = false;
|
|
9219
8360
|
_blockStates = [];
|
|
8361
|
+
_stableBlockCount = 0;
|
|
9220
8362
|
_styleDirty = false;
|
|
9221
8363
|
_linkifyMarkdownChunks = (chunks, context) => detectLinks(chunks, {
|
|
9222
8364
|
content: context.content,
|
|
@@ -9226,7 +8368,8 @@ class MarkdownRenderable extends Renderable {
|
|
|
9226
8368
|
content: "",
|
|
9227
8369
|
conceal: true,
|
|
9228
8370
|
concealCode: false,
|
|
9229
|
-
streaming: false
|
|
8371
|
+
streaming: false,
|
|
8372
|
+
internalBlockMode: "coalesced"
|
|
9230
8373
|
};
|
|
9231
8374
|
constructor(ctx, options) {
|
|
9232
8375
|
super(ctx, {
|
|
@@ -9244,6 +8387,7 @@ class MarkdownRenderable extends Renderable {
|
|
|
9244
8387
|
this._tableOptions = options.tableOptions;
|
|
9245
8388
|
this._renderNode = options.renderNode;
|
|
9246
8389
|
this._streaming = options.streaming ?? this._contentDefaultOptions.streaming;
|
|
8390
|
+
this._internalBlockMode = options.internalBlockMode ?? this._contentDefaultOptions.internalBlockMode;
|
|
9247
8391
|
this.updateBlocks();
|
|
9248
8392
|
}
|
|
9249
8393
|
get content() {
|
|
@@ -9323,6 +8467,28 @@ class MarkdownRenderable extends Renderable {
|
|
|
9323
8467
|
this._tableOptions = value;
|
|
9324
8468
|
this.applyTableOptionsToBlocks();
|
|
9325
8469
|
}
|
|
8470
|
+
get renderNode() {
|
|
8471
|
+
return this._renderNode;
|
|
8472
|
+
}
|
|
8473
|
+
set renderNode(value) {
|
|
8474
|
+
if (this._renderNode === value)
|
|
8475
|
+
return;
|
|
8476
|
+
this._renderNode = value;
|
|
8477
|
+
this.clearBlockStates();
|
|
8478
|
+
this._parseState = null;
|
|
8479
|
+
this.updateBlocks(true);
|
|
8480
|
+
this.requestRender();
|
|
8481
|
+
}
|
|
8482
|
+
get internalBlockMode() {
|
|
8483
|
+
return this._internalBlockMode;
|
|
8484
|
+
}
|
|
8485
|
+
set internalBlockMode(value) {
|
|
8486
|
+
if (this._internalBlockMode === value)
|
|
8487
|
+
return;
|
|
8488
|
+
this._internalBlockMode = value;
|
|
8489
|
+
this.updateBlocks(true);
|
|
8490
|
+
this.requestRender();
|
|
8491
|
+
}
|
|
9326
8492
|
getStyle(group) {
|
|
9327
8493
|
if (!this._syntaxStyle)
|
|
9328
8494
|
return;
|
|
@@ -9475,7 +8641,11 @@ class MarkdownRenderable extends Renderable {
|
|
|
9475
8641
|
break;
|
|
9476
8642
|
}
|
|
9477
8643
|
}
|
|
9478
|
-
|
|
8644
|
+
applyMargins(renderable, marginTop, marginBottom) {
|
|
8645
|
+
renderable.marginTop = marginTop;
|
|
8646
|
+
renderable.marginBottom = marginBottom;
|
|
8647
|
+
}
|
|
8648
|
+
createMarkdownCodeRenderable(content, id, marginBottom = 0, onChunks = this._linkifyMarkdownChunks, baseHighlight) {
|
|
9479
8649
|
return new CodeRenderable(this.ctx, {
|
|
9480
8650
|
id,
|
|
9481
8651
|
content,
|
|
@@ -9486,12 +8656,239 @@ class MarkdownRenderable extends Renderable {
|
|
|
9486
8656
|
conceal: this._conceal,
|
|
9487
8657
|
drawUnstyledText: false,
|
|
9488
8658
|
streaming: true,
|
|
9489
|
-
|
|
8659
|
+
baseHighlight,
|
|
8660
|
+
onChunks,
|
|
9490
8661
|
treeSitterClient: this._treeSitterClient,
|
|
9491
8662
|
width: "100%",
|
|
9492
8663
|
marginBottom
|
|
9493
8664
|
});
|
|
9494
8665
|
}
|
|
8666
|
+
getBlockquoteContent(token) {
|
|
8667
|
+
return "text" in token && typeof token.text === "string" && token.text ? token.text : " ";
|
|
8668
|
+
}
|
|
8669
|
+
getBlockquoteBorderColor() {
|
|
8670
|
+
return this.getStyle("conceal")?.fg ?? this.getStyle("default")?.fg ?? this._fg ?? "#FFFFFF";
|
|
8671
|
+
}
|
|
8672
|
+
createBlockquoteRenderable(token, id, marginBottom = 0) {
|
|
8673
|
+
const renderable = new BoxRenderable(this.ctx, {
|
|
8674
|
+
id,
|
|
8675
|
+
width: "100%",
|
|
8676
|
+
border: ["left"],
|
|
8677
|
+
borderColor: this.getBlockquoteBorderColor(),
|
|
8678
|
+
paddingLeft: 1,
|
|
8679
|
+
flexShrink: 0,
|
|
8680
|
+
marginBottom
|
|
8681
|
+
});
|
|
8682
|
+
renderable.add(this.createMarkdownCodeRenderable(this.getBlockquoteContent(token), `${id}-content`, 0, this._linkifyMarkdownChunks, "markup.quote"));
|
|
8683
|
+
return renderable;
|
|
8684
|
+
}
|
|
8685
|
+
createListRenderable(token, id, marginBottom = 0) {
|
|
8686
|
+
const list = new BoxRenderable(this.ctx, {
|
|
8687
|
+
id,
|
|
8688
|
+
width: "100%",
|
|
8689
|
+
flexDirection: "column",
|
|
8690
|
+
flexShrink: 0,
|
|
8691
|
+
marginBottom
|
|
8692
|
+
});
|
|
8693
|
+
for (const item of this.getListItemInputs(token, id)) {
|
|
8694
|
+
list.add(this.createListItemRenderable(item));
|
|
8695
|
+
}
|
|
8696
|
+
return list;
|
|
8697
|
+
}
|
|
8698
|
+
getListItemInputs(token, id) {
|
|
8699
|
+
const items = token.items ?? [];
|
|
8700
|
+
const start = token.start === "" || token.start === undefined || token.start === null ? 1 : Number(token.start);
|
|
8701
|
+
const markerWidth = Math.max(1, ...items.map((_2, index) => (token.ordered ? `${start + index}.` : "-").length));
|
|
8702
|
+
return items.map((item, index) => ({
|
|
8703
|
+
item,
|
|
8704
|
+
marker: token.ordered ? `${start + index}.` : "-",
|
|
8705
|
+
markerWidth,
|
|
8706
|
+
id: `${id}-item-${index}`
|
|
8707
|
+
}));
|
|
8708
|
+
}
|
|
8709
|
+
applyListRenderable(renderable, token, previousToken, id, marginBottom = 0) {
|
|
8710
|
+
if (!(renderable instanceof BoxRenderable))
|
|
8711
|
+
return false;
|
|
8712
|
+
renderable.marginBottom = marginBottom;
|
|
8713
|
+
const inputs = this.getListItemInputs(token, id);
|
|
8714
|
+
const previousItems = previousToken?.items ?? [];
|
|
8715
|
+
const rows = renderable.getChildren();
|
|
8716
|
+
for (let index = 0;index < inputs.length; index += 1) {
|
|
8717
|
+
const input = inputs[index];
|
|
8718
|
+
const existing = rows[index];
|
|
8719
|
+
if (existing instanceof BoxRenderable && this.applyListItemRenderable(existing, input, previousItems[index])) {
|
|
8720
|
+
continue;
|
|
8721
|
+
}
|
|
8722
|
+
existing?.destroyRecursively();
|
|
8723
|
+
renderable.add(this.createListItemRenderable(input), index);
|
|
8724
|
+
}
|
|
8725
|
+
for (let index = rows.length - 1;index >= inputs.length; index -= 1) {
|
|
8726
|
+
rows[index]?.destroyRecursively();
|
|
8727
|
+
}
|
|
8728
|
+
return true;
|
|
8729
|
+
}
|
|
8730
|
+
createListItemRenderable(input) {
|
|
8731
|
+
const row = new BoxRenderable(this.ctx, {
|
|
8732
|
+
id: input.id,
|
|
8733
|
+
width: "100%",
|
|
8734
|
+
flexDirection: "row",
|
|
8735
|
+
flexShrink: 0,
|
|
8736
|
+
marginBottom: /\n[ \t]*\n$/.test(input.item.raw) ? 1 : 0
|
|
8737
|
+
});
|
|
8738
|
+
row.add(new TextRenderable(this.ctx, {
|
|
8739
|
+
id: `${input.id}-marker`,
|
|
8740
|
+
content: new StyledText([this.createChunk(input.marker.padStart(input.markerWidth) + " ", "markup.list")]),
|
|
8741
|
+
width: input.markerWidth + 1,
|
|
8742
|
+
flexShrink: 0
|
|
8743
|
+
}));
|
|
8744
|
+
const content = new BoxRenderable(this.ctx, {
|
|
8745
|
+
id: `${input.id}-content`,
|
|
8746
|
+
flexDirection: "column",
|
|
8747
|
+
flexGrow: 1,
|
|
8748
|
+
flexShrink: 1
|
|
8749
|
+
});
|
|
8750
|
+
row.add(content);
|
|
8751
|
+
let pendingMarginTop = 0;
|
|
8752
|
+
for (let index = 0;index < input.item.tokens.length; index += 1) {
|
|
8753
|
+
const child = input.item.tokens[index];
|
|
8754
|
+
if (!child)
|
|
8755
|
+
continue;
|
|
8756
|
+
if (child.type === "checkbox")
|
|
8757
|
+
continue;
|
|
8758
|
+
if (child.type === "space") {
|
|
8759
|
+
pendingMarginTop = Math.max(pendingMarginTop, 1);
|
|
8760
|
+
continue;
|
|
8761
|
+
}
|
|
8762
|
+
const renderable = this.createListChildRenderable(child, `${input.id}-child-${index}`);
|
|
8763
|
+
if (!renderable)
|
|
8764
|
+
continue;
|
|
8765
|
+
renderable.marginTop = child.type === "list" ? 0 : pendingMarginTop;
|
|
8766
|
+
pendingMarginTop = 0;
|
|
8767
|
+
content.add(renderable);
|
|
8768
|
+
}
|
|
8769
|
+
return row;
|
|
8770
|
+
}
|
|
8771
|
+
applyListItemRenderable(row, input, previousItem) {
|
|
8772
|
+
this.applyListItemMarker(row, input);
|
|
8773
|
+
const content = row.getChildren()[1];
|
|
8774
|
+
if (!(content instanceof BoxRenderable))
|
|
8775
|
+
return false;
|
|
8776
|
+
if (previousItem && previousItem.raw === input.item.raw) {
|
|
8777
|
+
return true;
|
|
8778
|
+
}
|
|
8779
|
+
return this.applyListItemChildren(content, input.item, previousItem, input.id);
|
|
8780
|
+
}
|
|
8781
|
+
applyListItemChildren(content, item, previousItem, id) {
|
|
8782
|
+
const previousTokens = previousItem ? this.getRenderableListItemTokens(previousItem) : [];
|
|
8783
|
+
const children = content.getChildren();
|
|
8784
|
+
let childIndex = 0;
|
|
8785
|
+
let pendingMarginTop = 0;
|
|
8786
|
+
for (let tokenIndex = 0;tokenIndex < item.tokens.length; tokenIndex += 1) {
|
|
8787
|
+
const token = item.tokens[tokenIndex];
|
|
8788
|
+
if (!token)
|
|
8789
|
+
continue;
|
|
8790
|
+
if (token.type === "checkbox")
|
|
8791
|
+
continue;
|
|
8792
|
+
if (token.type === "space") {
|
|
8793
|
+
pendingMarginTop = Math.max(pendingMarginTop, 1);
|
|
8794
|
+
continue;
|
|
8795
|
+
}
|
|
8796
|
+
const existing = children[childIndex];
|
|
8797
|
+
const childId = `${id}-child-${tokenIndex}`;
|
|
8798
|
+
const marginTop = token.type === "list" ? 0 : pendingMarginTop;
|
|
8799
|
+
pendingMarginTop = 0;
|
|
8800
|
+
if (!existing) {
|
|
8801
|
+
const renderable = this.createListChildRenderable(token, childId);
|
|
8802
|
+
if (!renderable)
|
|
8803
|
+
return false;
|
|
8804
|
+
renderable.marginTop = marginTop;
|
|
8805
|
+
content.add(renderable, childIndex);
|
|
8806
|
+
childIndex += 1;
|
|
8807
|
+
continue;
|
|
8808
|
+
}
|
|
8809
|
+
if (!this.applyListChildRenderable(existing, token, previousTokens[childIndex], childId)) {
|
|
8810
|
+
return false;
|
|
8811
|
+
}
|
|
8812
|
+
existing.marginTop = marginTop;
|
|
8813
|
+
childIndex += 1;
|
|
8814
|
+
}
|
|
8815
|
+
this.destroyListItemChildrenAfter(content, childIndex);
|
|
8816
|
+
return true;
|
|
8817
|
+
}
|
|
8818
|
+
getRenderableListItemTokens(item) {
|
|
8819
|
+
const tokens = [];
|
|
8820
|
+
for (const token of item.tokens) {
|
|
8821
|
+
if (token.type === "checkbox" || token.type === "space")
|
|
8822
|
+
continue;
|
|
8823
|
+
tokens.push(token);
|
|
8824
|
+
}
|
|
8825
|
+
return tokens;
|
|
8826
|
+
}
|
|
8827
|
+
applyListChildRenderable(renderable, token, previousToken, id) {
|
|
8828
|
+
if ((token.type === "text" || token.type === "paragraph") && renderable instanceof CodeRenderable) {
|
|
8829
|
+
this.applyMarkdownCodeRenderable(renderable, this.getListChildMarkdownRaw(token), 0);
|
|
8830
|
+
return true;
|
|
8831
|
+
}
|
|
8832
|
+
if (token.type === "list" && renderable instanceof BoxRenderable) {
|
|
8833
|
+
return this.applyListRenderable(renderable, token, previousToken, id);
|
|
8834
|
+
}
|
|
8835
|
+
if (token.type === "code" && renderable instanceof CodeRenderable) {
|
|
8836
|
+
this.applyCodeBlockRenderable(renderable, token, 0);
|
|
8837
|
+
return true;
|
|
8838
|
+
}
|
|
8839
|
+
return previousToken?.raw === token.raw;
|
|
8840
|
+
}
|
|
8841
|
+
destroyListItemChildrenAfter(content, index) {
|
|
8842
|
+
const children = content.getChildren();
|
|
8843
|
+
for (let i = children.length - 1;i >= index; i -= 1) {
|
|
8844
|
+
children[i]?.destroyRecursively();
|
|
8845
|
+
}
|
|
8846
|
+
}
|
|
8847
|
+
getListChildMarkdownRaw(token) {
|
|
8848
|
+
return token.type === "paragraph" ? this.normalizeScrollbackMarkdownBlockRaw(token.raw) : token.raw;
|
|
8849
|
+
}
|
|
8850
|
+
applyListItemMarker(row, input) {
|
|
8851
|
+
const marker = row.getChildren()[0];
|
|
8852
|
+
if (!(marker instanceof TextRenderable))
|
|
8853
|
+
return;
|
|
8854
|
+
const marginBottom = /\n[ \t]*\n$/.test(input.item.raw) ? 1 : 0;
|
|
8855
|
+
const markerWidth = input.markerWidth + 1;
|
|
8856
|
+
const markerText = input.marker.padStart(input.markerWidth) + " ";
|
|
8857
|
+
if (row.marginBottom !== marginBottom)
|
|
8858
|
+
row.marginBottom = marginBottom;
|
|
8859
|
+
if (marker.width !== markerWidth)
|
|
8860
|
+
marker.width = markerWidth;
|
|
8861
|
+
if (marker.chunks[0]?.text !== markerText) {
|
|
8862
|
+
marker.content = new StyledText([this.createChunk(markerText, "markup.list")]);
|
|
8863
|
+
}
|
|
8864
|
+
}
|
|
8865
|
+
createListChildRenderable(token, id) {
|
|
8866
|
+
if (token.type === "text" || token.type === "paragraph") {
|
|
8867
|
+
return this.createMarkdownCodeRenderable(this.getListChildMarkdownRaw(token), id);
|
|
8868
|
+
}
|
|
8869
|
+
if (token.type === "list")
|
|
8870
|
+
return this.createListRenderable(token, id);
|
|
8871
|
+
if (token.type === "code")
|
|
8872
|
+
return this.createCodeRenderable(token, id);
|
|
8873
|
+
if (token.type === "blockquote")
|
|
8874
|
+
return this.createBlockquoteRenderable(token, id);
|
|
8875
|
+
if (token.type === "hr")
|
|
8876
|
+
return this.createHorizontalRuleRenderable(id);
|
|
8877
|
+
if (token.type === "table")
|
|
8878
|
+
return this.createTableBlock(token, id).renderable;
|
|
8879
|
+
return token.raw ? this.createMarkdownCodeRenderable(token.raw, id) : null;
|
|
8880
|
+
}
|
|
8881
|
+
createHorizontalRuleRenderable(id, marginBottom = 0) {
|
|
8882
|
+
return new BoxRenderable(this.ctx, {
|
|
8883
|
+
id,
|
|
8884
|
+
width: "100%",
|
|
8885
|
+
height: 1,
|
|
8886
|
+
border: ["top"],
|
|
8887
|
+
borderColor: this.getStyle("conceal")?.fg ?? this._fg ?? "#888888",
|
|
8888
|
+
flexShrink: 0,
|
|
8889
|
+
marginBottom
|
|
8890
|
+
});
|
|
8891
|
+
}
|
|
9495
8892
|
createCodeRenderable(token, id, marginBottom = 0) {
|
|
9496
8893
|
return new CodeRenderable(this.ctx, {
|
|
9497
8894
|
id,
|
|
@@ -9501,14 +8898,14 @@ class MarkdownRenderable extends Renderable {
|
|
|
9501
8898
|
fg: this._fg,
|
|
9502
8899
|
bg: this._bg,
|
|
9503
8900
|
conceal: this._concealCode,
|
|
9504
|
-
drawUnstyledText: !
|
|
8901
|
+
drawUnstyledText: !this._streaming,
|
|
9505
8902
|
streaming: this._streaming,
|
|
9506
8903
|
treeSitterClient: this._treeSitterClient,
|
|
9507
8904
|
width: "100%",
|
|
9508
8905
|
marginBottom
|
|
9509
8906
|
});
|
|
9510
8907
|
}
|
|
9511
|
-
applyMarkdownCodeRenderable(renderable, content, marginBottom) {
|
|
8908
|
+
applyMarkdownCodeRenderable(renderable, content, marginBottom, baseHighlight) {
|
|
9512
8909
|
renderable.content = content;
|
|
9513
8910
|
renderable.filetype = "markdown";
|
|
9514
8911
|
renderable.syntaxStyle = this._syntaxStyle;
|
|
@@ -9517,21 +8914,39 @@ class MarkdownRenderable extends Renderable {
|
|
|
9517
8914
|
renderable.conceal = this._conceal;
|
|
9518
8915
|
renderable.drawUnstyledText = false;
|
|
9519
8916
|
renderable.streaming = true;
|
|
8917
|
+
renderable.baseHighlight = baseHighlight;
|
|
8918
|
+
renderable.marginBottom = marginBottom;
|
|
8919
|
+
}
|
|
8920
|
+
applyBlockquoteRenderable(renderable, token, marginBottom) {
|
|
8921
|
+
if (!(renderable instanceof BoxRenderable))
|
|
8922
|
+
return;
|
|
8923
|
+
renderable.borderColor = this.getBlockquoteBorderColor();
|
|
9520
8924
|
renderable.marginBottom = marginBottom;
|
|
8925
|
+
const child = renderable.getChildren()[0];
|
|
8926
|
+
if (child instanceof CodeRenderable) {
|
|
8927
|
+
this.applyMarkdownCodeRenderable(child, this.getBlockquoteContent(token), 0, "markup.quote");
|
|
8928
|
+
return;
|
|
8929
|
+
}
|
|
8930
|
+
for (const existing of renderable.getChildren()) {
|
|
8931
|
+
existing.destroyRecursively();
|
|
8932
|
+
}
|
|
8933
|
+
renderable.add(this.createMarkdownCodeRenderable(this.getBlockquoteContent(token), `${renderable.id}-content`, 0, this._linkifyMarkdownChunks, "markup.quote"));
|
|
9521
8934
|
}
|
|
9522
8935
|
applyCodeBlockRenderable(renderable, token, marginBottom) {
|
|
9523
|
-
renderable
|
|
8936
|
+
if (!(renderable instanceof CodeRenderable))
|
|
8937
|
+
return;
|
|
9524
8938
|
renderable.filetype = infoStringToFiletype(token.lang ?? "");
|
|
9525
8939
|
renderable.syntaxStyle = this._syntaxStyle;
|
|
9526
8940
|
renderable.fg = this._fg;
|
|
9527
8941
|
renderable.bg = this._bg;
|
|
9528
8942
|
renderable.conceal = this._concealCode;
|
|
9529
|
-
renderable.drawUnstyledText = !
|
|
8943
|
+
renderable.drawUnstyledText = !this._streaming;
|
|
9530
8944
|
renderable.streaming = this._streaming;
|
|
8945
|
+
renderable.content = token.text;
|
|
9531
8946
|
renderable.marginBottom = marginBottom;
|
|
9532
8947
|
}
|
|
9533
8948
|
shouldRenderSeparately(token) {
|
|
9534
|
-
return token.type === "code" || token.type === "table" || token.type === "blockquote";
|
|
8949
|
+
return token.type === "code" || token.type === "table" || token.type === "blockquote" || token.type === "hr";
|
|
9535
8950
|
}
|
|
9536
8951
|
getInterBlockMargin(token, hasNextToken) {
|
|
9537
8952
|
if (!hasNextToken)
|
|
@@ -9550,6 +8965,9 @@ class MarkdownRenderable extends Renderable {
|
|
|
9550
8965
|
return raw.replace(TRAILING_MARKDOWN_BLOCK_BREAKS_RE, `
|
|
9551
8966
|
`);
|
|
9552
8967
|
}
|
|
8968
|
+
normalizeScrollbackMarkdownBlockRaw(raw) {
|
|
8969
|
+
return raw.replace(TRAILING_MARKDOWN_BLOCK_NEWLINES_RE, "");
|
|
8970
|
+
}
|
|
9553
8971
|
buildRenderableTokens(tokens) {
|
|
9554
8972
|
if (this._renderNode) {
|
|
9555
8973
|
return tokens.filter((token) => token.type !== "space");
|
|
@@ -9591,6 +9009,36 @@ class MarkdownRenderable extends Renderable {
|
|
|
9591
9009
|
flushMarkdownRaw();
|
|
9592
9010
|
return renderTokens;
|
|
9593
9011
|
}
|
|
9012
|
+
buildTopLevelRenderBlocks(tokens) {
|
|
9013
|
+
const blocks = [];
|
|
9014
|
+
let gapBefore = "";
|
|
9015
|
+
for (let i = 0;i < tokens.length; i += 1) {
|
|
9016
|
+
const token = tokens[i];
|
|
9017
|
+
if (token.type === "space") {
|
|
9018
|
+
gapBefore += token.raw;
|
|
9019
|
+
continue;
|
|
9020
|
+
}
|
|
9021
|
+
const prev = blocks[blocks.length - 1];
|
|
9022
|
+
const marginTop = prev && this.shouldAddTopLevelMargin(prev.token, token, gapBefore) ? 1 : 0;
|
|
9023
|
+
blocks.push({
|
|
9024
|
+
token,
|
|
9025
|
+
sourceTokenEnd: i + 1,
|
|
9026
|
+
marginTop
|
|
9027
|
+
});
|
|
9028
|
+
gapBefore = "";
|
|
9029
|
+
}
|
|
9030
|
+
return blocks;
|
|
9031
|
+
}
|
|
9032
|
+
shouldAddTopLevelMargin(prev, current, gapBefore) {
|
|
9033
|
+
if (this.isSeparatedTopLevelBlock(prev) || this.isSeparatedTopLevelBlock(current))
|
|
9034
|
+
return true;
|
|
9035
|
+
if (prev.type !== "paragraph" || current.type !== "paragraph")
|
|
9036
|
+
return false;
|
|
9037
|
+
return TRAILING_MARKDOWN_BLOCK_BREAKS_RE.test(prev.raw + gapBefore);
|
|
9038
|
+
}
|
|
9039
|
+
isSeparatedTopLevelBlock(token) {
|
|
9040
|
+
return token.type === "heading" || token.type === "list" || this.shouldRenderSeparately(token);
|
|
9041
|
+
}
|
|
9594
9042
|
getTableRowsToRender(table) {
|
|
9595
9043
|
return table.rows;
|
|
9596
9044
|
}
|
|
@@ -9712,13 +9160,31 @@ class MarkdownRenderable extends Renderable {
|
|
|
9712
9160
|
changed
|
|
9713
9161
|
};
|
|
9714
9162
|
}
|
|
9163
|
+
resolveTableStyle(options = this._tableOptions) {
|
|
9164
|
+
if (options?.style === "columns") {
|
|
9165
|
+
return "columns";
|
|
9166
|
+
}
|
|
9167
|
+
if (options?.style === "grid") {
|
|
9168
|
+
return "grid";
|
|
9169
|
+
}
|
|
9170
|
+
return this._internalBlockMode === "top-level" ? "columns" : "grid";
|
|
9171
|
+
}
|
|
9172
|
+
usesBorderlessColumnSpacing(options = this._tableOptions) {
|
|
9173
|
+
const style = this.resolveTableStyle(options);
|
|
9174
|
+
const borders = options?.borders ?? style === "grid";
|
|
9175
|
+
return style === "columns" && !borders;
|
|
9176
|
+
}
|
|
9715
9177
|
resolveTableRenderableOptions() {
|
|
9716
|
-
const
|
|
9178
|
+
const style = this.resolveTableStyle();
|
|
9179
|
+
const borders = this._tableOptions?.borders ?? style === "grid";
|
|
9717
9180
|
return {
|
|
9718
|
-
columnWidthMode: this._tableOptions?.widthMode ?? "full",
|
|
9181
|
+
columnWidthMode: this._tableOptions?.widthMode ?? (style === "columns" ? "content" : "full"),
|
|
9719
9182
|
columnFitter: this._tableOptions?.columnFitter ?? "proportional",
|
|
9720
9183
|
wrapMode: this._tableOptions?.wrapMode ?? "word",
|
|
9721
9184
|
cellPadding: this._tableOptions?.cellPadding ?? 0,
|
|
9185
|
+
cellPaddingX: this._tableOptions?.cellPaddingX ?? this._tableOptions?.cellPadding ?? 0,
|
|
9186
|
+
cellPaddingY: this._tableOptions?.cellPaddingY ?? this._tableOptions?.cellPadding ?? 0,
|
|
9187
|
+
columnGap: this.usesBorderlessColumnSpacing() ? 2 : 0,
|
|
9722
9188
|
border: borders,
|
|
9723
9189
|
outerBorder: this._tableOptions?.outerBorder ?? borders,
|
|
9724
9190
|
showBorders: borders,
|
|
@@ -9731,7 +9197,9 @@ class MarkdownRenderable extends Renderable {
|
|
|
9731
9197
|
tableRenderable.columnWidthMode = options.columnWidthMode;
|
|
9732
9198
|
tableRenderable.columnFitter = options.columnFitter;
|
|
9733
9199
|
tableRenderable.wrapMode = options.wrapMode;
|
|
9734
|
-
tableRenderable.
|
|
9200
|
+
tableRenderable.cellPaddingX = options.cellPaddingX;
|
|
9201
|
+
tableRenderable.cellPaddingY = options.cellPaddingY;
|
|
9202
|
+
tableRenderable.columnGap = options.columnGap;
|
|
9735
9203
|
tableRenderable.border = options.border;
|
|
9736
9204
|
tableRenderable.outerBorder = options.outerBorder;
|
|
9737
9205
|
tableRenderable.showBorders = options.showBorders;
|
|
@@ -9763,6 +9231,9 @@ class MarkdownRenderable extends Renderable {
|
|
|
9763
9231
|
columnFitter: options.columnFitter,
|
|
9764
9232
|
wrapMode: options.wrapMode,
|
|
9765
9233
|
cellPadding: options.cellPadding,
|
|
9234
|
+
cellPaddingX: options.cellPaddingX,
|
|
9235
|
+
cellPaddingY: options.cellPaddingY,
|
|
9236
|
+
columnGap: options.columnGap,
|
|
9766
9237
|
border: options.border,
|
|
9767
9238
|
outerBorder: options.outerBorder,
|
|
9768
9239
|
showBorders: options.showBorders,
|
|
@@ -9783,12 +9254,106 @@ class MarkdownRenderable extends Renderable {
|
|
|
9783
9254
|
tableContentCache: cache
|
|
9784
9255
|
};
|
|
9785
9256
|
}
|
|
9257
|
+
getStableBlockCount(blocks, stableTokenCount) {
|
|
9258
|
+
if (this._internalBlockMode !== "top-level") {
|
|
9259
|
+
return 0;
|
|
9260
|
+
}
|
|
9261
|
+
let stableBlockCount = 0;
|
|
9262
|
+
for (const block of blocks) {
|
|
9263
|
+
if (block.sourceTokenEnd <= stableTokenCount) {
|
|
9264
|
+
stableBlockCount += 1;
|
|
9265
|
+
continue;
|
|
9266
|
+
}
|
|
9267
|
+
break;
|
|
9268
|
+
}
|
|
9269
|
+
return stableBlockCount;
|
|
9270
|
+
}
|
|
9271
|
+
syncTopLevelBlockState(state, block, tableContentCache = state.tableContentCache) {
|
|
9272
|
+
state.token = block.token;
|
|
9273
|
+
state.tokenRaw = block.token.raw;
|
|
9274
|
+
state.marginTop = block.marginTop;
|
|
9275
|
+
state.tableContentCache = tableContentCache;
|
|
9276
|
+
}
|
|
9277
|
+
getTopLevelBlockRaw(token) {
|
|
9278
|
+
if (!token.raw) {
|
|
9279
|
+
return;
|
|
9280
|
+
}
|
|
9281
|
+
return this.shouldRenderSeparately(token) ? token.raw : this.normalizeScrollbackMarkdownBlockRaw(token.raw);
|
|
9282
|
+
}
|
|
9283
|
+
createTopLevelDefaultRenderable(block, index) {
|
|
9284
|
+
const { token, marginTop } = block;
|
|
9285
|
+
const id = `${this.id}-block-${index}`;
|
|
9286
|
+
if (token.type === "code") {
|
|
9287
|
+
const renderable2 = this.createCodeRenderable(token, id);
|
|
9288
|
+
renderable2.marginTop = marginTop;
|
|
9289
|
+
return { renderable: renderable2 };
|
|
9290
|
+
}
|
|
9291
|
+
if (token.type === "table") {
|
|
9292
|
+
const next = this.createTableBlock(token, id);
|
|
9293
|
+
next.renderable.marginTop = marginTop;
|
|
9294
|
+
return next;
|
|
9295
|
+
}
|
|
9296
|
+
if (token.type === "blockquote") {
|
|
9297
|
+
const renderable2 = this.createBlockquoteRenderable(token, id);
|
|
9298
|
+
renderable2.marginTop = marginTop;
|
|
9299
|
+
return { renderable: renderable2 };
|
|
9300
|
+
}
|
|
9301
|
+
if (token.type === "list") {
|
|
9302
|
+
const renderable2 = this.createListRenderable(token, id);
|
|
9303
|
+
renderable2.marginTop = marginTop;
|
|
9304
|
+
return { renderable: renderable2 };
|
|
9305
|
+
}
|
|
9306
|
+
if (token.type === "hr") {
|
|
9307
|
+
const renderable2 = this.createHorizontalRuleRenderable(id);
|
|
9308
|
+
renderable2.marginTop = marginTop;
|
|
9309
|
+
return { renderable: renderable2 };
|
|
9310
|
+
}
|
|
9311
|
+
const markdownRaw = this.getTopLevelBlockRaw(token);
|
|
9312
|
+
if (!markdownRaw) {
|
|
9313
|
+
return { renderable: undefined };
|
|
9314
|
+
}
|
|
9315
|
+
const renderable = this.createMarkdownCodeRenderable(markdownRaw, id);
|
|
9316
|
+
renderable.marginTop = marginTop;
|
|
9317
|
+
return { renderable };
|
|
9318
|
+
}
|
|
9319
|
+
createTopLevelRenderable(block, index) {
|
|
9320
|
+
if (!this._renderNode) {
|
|
9321
|
+
return this.createTopLevelDefaultRenderable(block, index);
|
|
9322
|
+
}
|
|
9323
|
+
let next;
|
|
9324
|
+
const context = {
|
|
9325
|
+
syntaxStyle: this._syntaxStyle,
|
|
9326
|
+
conceal: this._conceal,
|
|
9327
|
+
concealCode: this._concealCode,
|
|
9328
|
+
treeSitterClient: this._treeSitterClient,
|
|
9329
|
+
defaultRender: () => {
|
|
9330
|
+
next = this.createTopLevelDefaultRenderable(block, index);
|
|
9331
|
+
return next.renderable ?? null;
|
|
9332
|
+
}
|
|
9333
|
+
};
|
|
9334
|
+
const custom = this._renderNode(block.token, context);
|
|
9335
|
+
if (custom) {
|
|
9336
|
+
const marginTop = typeof custom.marginTop === "number" ? Math.max(custom.marginTop, block.marginTop) : block.marginTop;
|
|
9337
|
+
this.applyMargins(custom, marginTop, 0);
|
|
9338
|
+
return { renderable: custom };
|
|
9339
|
+
}
|
|
9340
|
+
return next ?? this.createTopLevelDefaultRenderable(block, index);
|
|
9341
|
+
}
|
|
9786
9342
|
createDefaultRenderable(token, index, hasNextToken = false) {
|
|
9787
9343
|
const id = `${this.id}-block-${index}`;
|
|
9788
9344
|
const marginBottom = this.getInterBlockMargin(token, hasNextToken);
|
|
9789
9345
|
if (token.type === "code") {
|
|
9790
9346
|
return this.createCodeRenderable(token, id, marginBottom);
|
|
9791
9347
|
}
|
|
9348
|
+
if (token.type === "blockquote") {
|
|
9349
|
+
return this.createBlockquoteRenderable(token, id, marginBottom);
|
|
9350
|
+
}
|
|
9351
|
+
if (token.type === "list") {
|
|
9352
|
+
return this.createListRenderable(token, id, marginBottom);
|
|
9353
|
+
}
|
|
9354
|
+
if (token.type === "hr") {
|
|
9355
|
+
return this.createHorizontalRuleRenderable(id, marginBottom);
|
|
9356
|
+
}
|
|
9792
9357
|
if (token.type === "table") {
|
|
9793
9358
|
return this.createTableBlock(token, id, marginBottom).renderable;
|
|
9794
9359
|
}
|
|
@@ -9800,12 +9365,28 @@ class MarkdownRenderable extends Renderable {
|
|
|
9800
9365
|
}
|
|
9801
9366
|
return this.createMarkdownCodeRenderable(token.raw, id, marginBottom);
|
|
9802
9367
|
}
|
|
9803
|
-
updateBlockRenderable(state, token, index, hasNextToken) {
|
|
9368
|
+
updateBlockRenderable(state, token, index, hasNextToken, forceListRefresh = false) {
|
|
9804
9369
|
const marginBottom = this.getInterBlockMargin(token, hasNextToken);
|
|
9805
9370
|
if (token.type === "code") {
|
|
9806
9371
|
this.applyCodeBlockRenderable(state.renderable, token, marginBottom);
|
|
9807
9372
|
return;
|
|
9808
9373
|
}
|
|
9374
|
+
if (token.type === "blockquote") {
|
|
9375
|
+
this.applyBlockquoteRenderable(state.renderable, token, marginBottom);
|
|
9376
|
+
return;
|
|
9377
|
+
}
|
|
9378
|
+
if (token.type === "list") {
|
|
9379
|
+
if (!this.applyListRenderable(state.renderable, token, forceListRefresh ? undefined : state.token, `${this.id}-block-${index}`, marginBottom)) {
|
|
9380
|
+
state.renderable.destroyRecursively();
|
|
9381
|
+
state.renderable = this.createListRenderable(token, `${this.id}-block-${index}`, marginBottom);
|
|
9382
|
+
this.add(state.renderable, index);
|
|
9383
|
+
}
|
|
9384
|
+
return;
|
|
9385
|
+
}
|
|
9386
|
+
if (token.type === "hr") {
|
|
9387
|
+
state.renderable.marginBottom = marginBottom;
|
|
9388
|
+
return;
|
|
9389
|
+
}
|
|
9809
9390
|
if (token.type === "table") {
|
|
9810
9391
|
const tableToken = token;
|
|
9811
9392
|
const { cache, changed } = this.buildTableContentCache(tableToken, state.tableContentCache);
|
|
@@ -9817,7 +9398,7 @@ class MarkdownRenderable extends Renderable {
|
|
|
9817
9398
|
}
|
|
9818
9399
|
state.renderable.destroyRecursively();
|
|
9819
9400
|
const fallbackRenderable = this.createMarkdownCodeRenderable(tableToken.raw, `${this.id}-block-${index}`, marginBottom);
|
|
9820
|
-
this.add(fallbackRenderable);
|
|
9401
|
+
this.add(fallbackRenderable, index);
|
|
9821
9402
|
state.renderable = fallbackRenderable;
|
|
9822
9403
|
state.tableContentCache = undefined;
|
|
9823
9404
|
return;
|
|
@@ -9833,26 +9414,94 @@ class MarkdownRenderable extends Renderable {
|
|
|
9833
9414
|
}
|
|
9834
9415
|
state.renderable.destroyRecursively();
|
|
9835
9416
|
const tableRenderable = this.createTextTableRenderable(cache.content, `${this.id}-block-${index}`, marginBottom);
|
|
9836
|
-
this.add(tableRenderable);
|
|
9417
|
+
this.add(tableRenderable, index);
|
|
9837
9418
|
state.renderable = tableRenderable;
|
|
9838
9419
|
state.tableContentCache = cache;
|
|
9839
9420
|
return;
|
|
9840
9421
|
}
|
|
9841
9422
|
if (state.renderable instanceof CodeRenderable) {
|
|
9842
|
-
this.applyMarkdownCodeRenderable(state.renderable, token.raw, marginBottom);
|
|
9423
|
+
this.applyMarkdownCodeRenderable(state.renderable, this.getTopLevelBlockRaw(token) ?? token.raw, marginBottom);
|
|
9843
9424
|
return;
|
|
9844
9425
|
}
|
|
9845
9426
|
state.renderable.destroyRecursively();
|
|
9846
|
-
const markdownRenderable = this.createMarkdownCodeRenderable(token.raw, `${this.id}-block-${index}`, marginBottom);
|
|
9847
|
-
this.add(markdownRenderable);
|
|
9427
|
+
const markdownRenderable = this.createMarkdownCodeRenderable(this.getTopLevelBlockRaw(token) ?? token.raw, `${this.id}-block-${index}`, marginBottom);
|
|
9428
|
+
this.add(markdownRenderable, index);
|
|
9848
9429
|
state.renderable = markdownRenderable;
|
|
9849
9430
|
}
|
|
9431
|
+
updateTopLevelBlocks(tokens, forceTableRefresh) {
|
|
9432
|
+
const blocks = this.buildTopLevelRenderBlocks(tokens);
|
|
9433
|
+
this._stableBlockCount = this.getStableBlockCount(blocks, this._parseState?.stableTokenCount ?? 0);
|
|
9434
|
+
let blockIndex = 0;
|
|
9435
|
+
for (let i = 0;i < blocks.length; i += 1) {
|
|
9436
|
+
const block = blocks[i];
|
|
9437
|
+
const existing = this._blockStates[blockIndex];
|
|
9438
|
+
if (existing && existing.token === block.token && !forceTableRefresh) {
|
|
9439
|
+
if (existing.marginTop !== block.marginTop) {
|
|
9440
|
+
this.applyMargins(existing.renderable, block.marginTop, 0);
|
|
9441
|
+
}
|
|
9442
|
+
this.syncTopLevelBlockState(existing, block);
|
|
9443
|
+
blockIndex++;
|
|
9444
|
+
continue;
|
|
9445
|
+
}
|
|
9446
|
+
if (existing && existing.tokenRaw === block.token.raw && existing.token.type === block.token.type && !forceTableRefresh) {
|
|
9447
|
+
if (existing.marginTop !== block.marginTop) {
|
|
9448
|
+
this.applyMargins(existing.renderable, block.marginTop, 0);
|
|
9449
|
+
}
|
|
9450
|
+
this.syncTopLevelBlockState(existing, block);
|
|
9451
|
+
blockIndex++;
|
|
9452
|
+
continue;
|
|
9453
|
+
}
|
|
9454
|
+
if (existing && !forceTableRefresh && !this._renderNode && existing.token.type === block.token.type && this.canUpdateBlockRenderable(existing.renderable, block.token)) {
|
|
9455
|
+
this.updateBlockRenderable(existing, block.token, blockIndex, blockIndex < blocks.length - 1);
|
|
9456
|
+
existing.renderable.marginBottom = 0;
|
|
9457
|
+
if (existing.marginTop !== block.marginTop) {
|
|
9458
|
+
this.applyMargins(existing.renderable, block.marginTop, 0);
|
|
9459
|
+
}
|
|
9460
|
+
this.syncTopLevelBlockState(existing, block);
|
|
9461
|
+
blockIndex++;
|
|
9462
|
+
continue;
|
|
9463
|
+
}
|
|
9464
|
+
if (existing) {
|
|
9465
|
+
existing.renderable.destroyRecursively();
|
|
9466
|
+
}
|
|
9467
|
+
const next = this.createTopLevelRenderable(block, blockIndex);
|
|
9468
|
+
if (next.renderable) {
|
|
9469
|
+
this.add(next.renderable, blockIndex);
|
|
9470
|
+
this._blockStates[blockIndex] = {
|
|
9471
|
+
token: block.token,
|
|
9472
|
+
tokenRaw: block.token.raw,
|
|
9473
|
+
marginTop: block.marginTop,
|
|
9474
|
+
renderable: next.renderable,
|
|
9475
|
+
tableContentCache: next.tableContentCache
|
|
9476
|
+
};
|
|
9477
|
+
}
|
|
9478
|
+
blockIndex++;
|
|
9479
|
+
}
|
|
9480
|
+
while (this._blockStates.length > blockIndex) {
|
|
9481
|
+
const removed = this._blockStates.pop();
|
|
9482
|
+
removed.renderable.destroyRecursively();
|
|
9483
|
+
}
|
|
9484
|
+
}
|
|
9485
|
+
canUpdateBlockRenderable(renderable, token) {
|
|
9486
|
+
if (token.type === "code")
|
|
9487
|
+
return renderable instanceof CodeRenderable;
|
|
9488
|
+
if (token.type === "table")
|
|
9489
|
+
return renderable instanceof TextTableRenderable;
|
|
9490
|
+
if (token.type === "blockquote")
|
|
9491
|
+
return renderable instanceof BoxRenderable;
|
|
9492
|
+
if (token.type === "list")
|
|
9493
|
+
return renderable instanceof BoxRenderable;
|
|
9494
|
+
if (token.type === "hr")
|
|
9495
|
+
return renderable instanceof BoxRenderable;
|
|
9496
|
+
return renderable instanceof CodeRenderable;
|
|
9497
|
+
}
|
|
9850
9498
|
updateBlocks(forceTableRefresh = false) {
|
|
9851
9499
|
if (this.isDestroyed)
|
|
9852
9500
|
return;
|
|
9853
9501
|
if (!this._content) {
|
|
9854
9502
|
this.clearBlockStates();
|
|
9855
9503
|
this._parseState = null;
|
|
9504
|
+
this._stableBlockCount = 0;
|
|
9856
9505
|
return;
|
|
9857
9506
|
}
|
|
9858
9507
|
const trailingUnstable = this._streaming ? 2 : 0;
|
|
@@ -9860,17 +9509,24 @@ class MarkdownRenderable extends Renderable {
|
|
|
9860
9509
|
const tokens = this._parseState.tokens;
|
|
9861
9510
|
if (tokens.length === 0 && this._content.length > 0) {
|
|
9862
9511
|
this.clearBlockStates();
|
|
9512
|
+
this._stableBlockCount = 0;
|
|
9863
9513
|
const fallback = this.createMarkdownCodeRenderable(this._content, `${this.id}-fallback`);
|
|
9864
9514
|
this.add(fallback);
|
|
9865
9515
|
this._blockStates = [
|
|
9866
9516
|
{
|
|
9867
9517
|
token: { type: "text", raw: this._content, text: this._content },
|
|
9868
9518
|
tokenRaw: this._content,
|
|
9519
|
+
marginTop: 0,
|
|
9869
9520
|
renderable: fallback
|
|
9870
9521
|
}
|
|
9871
9522
|
];
|
|
9872
9523
|
return;
|
|
9873
9524
|
}
|
|
9525
|
+
if (this._internalBlockMode === "top-level") {
|
|
9526
|
+
this.updateTopLevelBlocks(tokens, forceTableRefresh);
|
|
9527
|
+
return;
|
|
9528
|
+
}
|
|
9529
|
+
this._stableBlockCount = 0;
|
|
9874
9530
|
const blockTokens = this.buildRenderableTokens(tokens);
|
|
9875
9531
|
const lastBlockIndex = blockTokens.length - 1;
|
|
9876
9532
|
let blockIndex = 0;
|
|
@@ -9935,7 +9591,7 @@ class MarkdownRenderable extends Renderable {
|
|
|
9935
9591
|
tableContentCache = cache ?? undefined;
|
|
9936
9592
|
}
|
|
9937
9593
|
if (renderable) {
|
|
9938
|
-
this.add(renderable);
|
|
9594
|
+
this.add(renderable, blockIndex);
|
|
9939
9595
|
this._blockStates[blockIndex] = {
|
|
9940
9596
|
token,
|
|
9941
9597
|
tokenRaw: token.raw,
|
|
@@ -9955,8 +9611,13 @@ class MarkdownRenderable extends Renderable {
|
|
|
9955
9611
|
state.renderable.destroyRecursively();
|
|
9956
9612
|
}
|
|
9957
9613
|
this._blockStates = [];
|
|
9614
|
+
this._stableBlockCount = 0;
|
|
9958
9615
|
}
|
|
9959
9616
|
rerenderBlocks() {
|
|
9617
|
+
if (this._internalBlockMode === "top-level") {
|
|
9618
|
+
this.updateBlocks(true);
|
|
9619
|
+
return;
|
|
9620
|
+
}
|
|
9960
9621
|
for (let i = 0;i < this._blockStates.length; i++) {
|
|
9961
9622
|
const state = this._blockStates[i];
|
|
9962
9623
|
const hasNextToken = i < this._blockStates.length - 1;
|
|
@@ -9965,6 +9626,18 @@ class MarkdownRenderable extends Renderable {
|
|
|
9965
9626
|
this.applyCodeBlockRenderable(state.renderable, state.token, marginBottom);
|
|
9966
9627
|
continue;
|
|
9967
9628
|
}
|
|
9629
|
+
if (state.token.type === "blockquote") {
|
|
9630
|
+
this.applyBlockquoteRenderable(state.renderable, state.token, marginBottom);
|
|
9631
|
+
continue;
|
|
9632
|
+
}
|
|
9633
|
+
if (state.token.type === "list") {
|
|
9634
|
+
this.updateBlockRenderable(state, state.token, i, hasNextToken, true);
|
|
9635
|
+
continue;
|
|
9636
|
+
}
|
|
9637
|
+
if (state.token.type === "hr") {
|
|
9638
|
+
state.renderable.marginBottom = marginBottom;
|
|
9639
|
+
continue;
|
|
9640
|
+
}
|
|
9968
9641
|
if (state.token.type === "table") {
|
|
9969
9642
|
const tableToken = state.token;
|
|
9970
9643
|
const { cache } = this.buildTableContentCache(tableToken, state.tableContentCache, true);
|
|
@@ -9974,7 +9647,7 @@ class MarkdownRenderable extends Renderable {
|
|
|
9974
9647
|
} else {
|
|
9975
9648
|
state.renderable.destroyRecursively();
|
|
9976
9649
|
const fallbackRenderable = this.createMarkdownCodeRenderable(tableToken.raw, `${this.id}-block-${i}`, marginBottom);
|
|
9977
|
-
this.add(fallbackRenderable);
|
|
9650
|
+
this.add(fallbackRenderable, i);
|
|
9978
9651
|
state.renderable = fallbackRenderable;
|
|
9979
9652
|
}
|
|
9980
9653
|
state.tableContentCache = undefined;
|
|
@@ -9989,18 +9662,18 @@ class MarkdownRenderable extends Renderable {
|
|
|
9989
9662
|
}
|
|
9990
9663
|
state.renderable.destroyRecursively();
|
|
9991
9664
|
const tableRenderable = this.createTextTableRenderable(cache.content, `${this.id}-block-${i}`, marginBottom);
|
|
9992
|
-
this.add(tableRenderable);
|
|
9665
|
+
this.add(tableRenderable, i);
|
|
9993
9666
|
state.renderable = tableRenderable;
|
|
9994
9667
|
state.tableContentCache = cache;
|
|
9995
9668
|
continue;
|
|
9996
9669
|
}
|
|
9997
9670
|
if (state.renderable instanceof CodeRenderable) {
|
|
9998
|
-
this.applyMarkdownCodeRenderable(state.renderable, state.token.raw, marginBottom);
|
|
9671
|
+
this.applyMarkdownCodeRenderable(state.renderable, this.getTopLevelBlockRaw(state.token) ?? state.token.raw, marginBottom);
|
|
9999
9672
|
continue;
|
|
10000
9673
|
}
|
|
10001
9674
|
state.renderable.destroyRecursively();
|
|
10002
|
-
const markdownRenderable = this.createMarkdownCodeRenderable(state.token.raw, `${this.id}-block-${i}`, marginBottom);
|
|
10003
|
-
this.add(markdownRenderable);
|
|
9675
|
+
const markdownRenderable = this.createMarkdownCodeRenderable(this.getTopLevelBlockRaw(state.token) ?? state.token.raw, `${this.id}-block-${i}`, marginBottom);
|
|
9676
|
+
this.add(markdownRenderable, i);
|
|
10004
9677
|
state.renderable = markdownRenderable;
|
|
10005
9678
|
}
|
|
10006
9679
|
}
|
|
@@ -10619,11 +10292,19 @@ class ContentRenderable extends BoxRenderable {
|
|
|
10619
10292
|
set viewportCulling(value) {
|
|
10620
10293
|
this._viewportCulling = value;
|
|
10621
10294
|
}
|
|
10295
|
+
_hasVisibleChildFilter() {
|
|
10296
|
+
return this._viewportCulling;
|
|
10297
|
+
}
|
|
10622
10298
|
_getVisibleChildren() {
|
|
10623
10299
|
if (this._viewportCulling) {
|
|
10624
|
-
return getObjectsInViewport(
|
|
10300
|
+
return getObjectsInViewport({
|
|
10301
|
+
x: this.viewport.screenX,
|
|
10302
|
+
y: this.viewport.screenY,
|
|
10303
|
+
width: this.viewport.width,
|
|
10304
|
+
height: this.viewport.height
|
|
10305
|
+
}, this.getChildrenSortedByPrimaryAxis(), this.primaryAxis, 0).map((child) => child.num);
|
|
10625
10306
|
}
|
|
10626
|
-
return
|
|
10307
|
+
return super._getVisibleChildren();
|
|
10627
10308
|
}
|
|
10628
10309
|
}
|
|
10629
10310
|
var SCROLLBOX_PADDING_KEYS = [
|
|
@@ -11210,7 +10891,9 @@ class ScrollBoxRenderable extends BoxRenderable {
|
|
|
11210
10891
|
} finally {
|
|
11211
10892
|
this._isApplyingStickyScroll = wasApplyingStickyScroll;
|
|
11212
10893
|
}
|
|
11213
|
-
|
|
10894
|
+
process.nextTick(() => {
|
|
10895
|
+
this.requestRender();
|
|
10896
|
+
});
|
|
11214
10897
|
}
|
|
11215
10898
|
set padding(value) {
|
|
11216
10899
|
this.content.padding = value;
|
|
@@ -11516,15 +11199,7 @@ class SelectRenderable extends Renderable {
|
|
|
11516
11199
|
this.requestRender();
|
|
11517
11200
|
}
|
|
11518
11201
|
handleKeyPress(key) {
|
|
11519
|
-
const
|
|
11520
|
-
name: key.name,
|
|
11521
|
-
ctrl: key.ctrl,
|
|
11522
|
-
shift: key.shift,
|
|
11523
|
-
meta: key.meta,
|
|
11524
|
-
super: key.super,
|
|
11525
|
-
action: "move-up"
|
|
11526
|
-
});
|
|
11527
|
-
const action = this._keyBindingsMap.get(bindingKey);
|
|
11202
|
+
const action = getKeyBindingAction(this._keyBindingsMap, key);
|
|
11528
11203
|
if (action) {
|
|
11529
11204
|
switch (action) {
|
|
11530
11205
|
case "move-up":
|
|
@@ -11884,15 +11559,7 @@ class TabSelectRenderable extends Renderable {
|
|
|
11884
11559
|
return this._tabWidth;
|
|
11885
11560
|
}
|
|
11886
11561
|
handleKeyPress(key) {
|
|
11887
|
-
const
|
|
11888
|
-
name: key.name,
|
|
11889
|
-
ctrl: key.ctrl,
|
|
11890
|
-
shift: key.shift,
|
|
11891
|
-
meta: key.meta,
|
|
11892
|
-
super: key.super,
|
|
11893
|
-
action: "move-left"
|
|
11894
|
-
});
|
|
11895
|
-
const action = this._keyBindingsMap.get(bindingKey);
|
|
11562
|
+
const action = getKeyBindingAction(this._keyBindingsMap, key);
|
|
11896
11563
|
if (action) {
|
|
11897
11564
|
switch (action) {
|
|
11898
11565
|
case "move-left":
|
|
@@ -12068,7 +11735,7 @@ class TimeToFirstDrawRenderable extends Renderable {
|
|
|
12068
11735
|
return Math.max(0, Math.floor(value));
|
|
12069
11736
|
}
|
|
12070
11737
|
}
|
|
12071
|
-
export {
|
|
11738
|
+
export { DistortionEffect, VignetteEffect, CloudsEffect, FlamesEffect, CRTRollingBarEffect, RainbowTextEffect, applyScanlines, applyInvert, applyNoise, applyChromaticAberration, applyAsciiArt, applyBrightness, applyGain, applySaturation, BloomEffect, SEPIA_MATRIX, PROTANOPIA_SIM_MATRIX, DEUTERANOPIA_SIM_MATRIX, TRITANOPIA_SIM_MATRIX, ACHROMATOPSIA_MATRIX, PROTANOPIA_COMP_MATRIX, DEUTERANOPIA_COMP_MATRIX, TRITANOPIA_COMP_MATRIX, TECHNICOLOR_MATRIX, SOLARIZATION_MATRIX, SYNTHWAVE_MATRIX, GREENSCALE_MATRIX, GRAYSCALE_MATRIX, INVERT_MATRIX, Timeline, engine, createTimeline, SlotRegistry, createSlotRegistry, createCoreSlotRegistry, registerCorePlugin, resolveCoreSlot, SlotRenderable, NativeSpanFeed, Audio, setupAudio, FrameBufferRenderable, ASCIIFontRenderable, Generic, Box, Text, ASCIIFont, Input, Select, TabSelect, FrameBuffer, Code, ScrollBox, vstyles, VRenderable, LineNumberRenderable, DiffRenderable, defaultTextareaKeyBindings, TextareaRenderable, InputRenderableEvents, InputRenderable, TextTableRenderable, MarkdownRenderable, SliderRenderable, ScrollBarRenderable, ArrowRenderable, ScrollBoxRenderable, SelectRenderableEvents, SelectRenderable, TabSelectRenderableEvents, TabSelectRenderable, TimeToFirstDrawRenderable, exports_src2 as exports_src };
|
|
12072
11739
|
|
|
12073
|
-
//# debugId=
|
|
12074
|
-
//# sourceMappingURL=index-
|
|
11740
|
+
//# debugId=F2F05271FFA5C07164756E2164756E21
|
|
11741
|
+
//# sourceMappingURL=index-46f5e8m6.js.map
|