@opentui/core 0.1.81 → 0.1.83
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/3d.js +1 -1
- package/buffer.d.ts +9 -0
- package/{index-ve2seej0.js → index-a215gqtt.js} +130 -32
- package/{index-ve2seej0.js.map → index-a215gqtt.js.map} +7 -7
- package/index.js +1179 -179
- package/index.js.map +7 -6
- package/package.json +7 -7
- package/renderables/Markdown.d.ts +64 -6
- package/renderables/TextBufferRenderable.d.ts +2 -0
- package/renderables/TextTable.d.ts +130 -0
- package/renderables/index.d.ts +1 -0
- package/renderer.d.ts +2 -0
- package/testing.js +1 -1
- package/zig-structs.d.ts +36 -2
- package/zig.d.ts +9 -2
package/index.js
CHANGED
|
@@ -153,7 +153,7 @@ import {
|
|
|
153
153
|
white,
|
|
154
154
|
wrapWithDelegates,
|
|
155
155
|
yellow
|
|
156
|
-
} from "./index-
|
|
156
|
+
} from "./index-a215gqtt.js";
|
|
157
157
|
// src/text-buffer-view.ts
|
|
158
158
|
class TextBufferView {
|
|
159
159
|
lib;
|
|
@@ -2748,6 +2748,7 @@ class TextBufferRenderable extends Renderable {
|
|
|
2748
2748
|
_truncate = false;
|
|
2749
2749
|
textBuffer;
|
|
2750
2750
|
textBufferView;
|
|
2751
|
+
_textBufferSyntaxStyle;
|
|
2751
2752
|
_defaultOptions = {
|
|
2752
2753
|
fg: RGBA.fromValues(1, 1, 1, 1),
|
|
2753
2754
|
bg: RGBA.fromValues(0, 0, 0, 0),
|
|
@@ -2774,8 +2775,8 @@ class TextBufferRenderable extends Renderable {
|
|
|
2774
2775
|
this._truncate = options.truncate ?? this._defaultOptions.truncate;
|
|
2775
2776
|
this.textBuffer = TextBuffer.create(this._ctx.widthMethod);
|
|
2776
2777
|
this.textBufferView = TextBufferView.create(this.textBuffer);
|
|
2777
|
-
|
|
2778
|
-
this.textBuffer.setSyntaxStyle(
|
|
2778
|
+
this._textBufferSyntaxStyle = SyntaxStyle.create();
|
|
2779
|
+
this.textBuffer.setSyntaxStyle(this._textBufferSyntaxStyle);
|
|
2779
2780
|
this.textBufferView.setWrapMode(this._wrapMode);
|
|
2780
2781
|
this.setupMeasureFunc();
|
|
2781
2782
|
this.textBuffer.setDefaultFg(this._defaultFg);
|
|
@@ -3085,6 +3086,10 @@ class TextBufferRenderable extends Renderable {
|
|
|
3085
3086
|
}
|
|
3086
3087
|
}
|
|
3087
3088
|
destroy() {
|
|
3089
|
+
if (this.isDestroyed)
|
|
3090
|
+
return;
|
|
3091
|
+
this.textBuffer.setSyntaxStyle(null);
|
|
3092
|
+
this._textBufferSyntaxStyle.destroy();
|
|
3088
3093
|
this.textBufferView.destroy();
|
|
3089
3094
|
this.textBuffer.destroy();
|
|
3090
3095
|
super.destroy();
|
|
@@ -7159,6 +7164,907 @@ class InputRenderable extends TextareaRenderable {
|
|
|
7159
7164
|
}
|
|
7160
7165
|
set initialValue(value) {}
|
|
7161
7166
|
}
|
|
7167
|
+
// src/renderables/TextTable.ts
|
|
7168
|
+
var MEASURE_HEIGHT = 1e4;
|
|
7169
|
+
|
|
7170
|
+
class TextTableRenderable extends Renderable {
|
|
7171
|
+
_content;
|
|
7172
|
+
_wrapMode;
|
|
7173
|
+
_columnWidthMode;
|
|
7174
|
+
_cellPadding;
|
|
7175
|
+
_showBorders;
|
|
7176
|
+
_border;
|
|
7177
|
+
_outerBorder;
|
|
7178
|
+
_hasExplicitOuterBorder;
|
|
7179
|
+
_borderStyle;
|
|
7180
|
+
_borderColor;
|
|
7181
|
+
_borderBackgroundColor;
|
|
7182
|
+
_backgroundColor;
|
|
7183
|
+
_defaultFg;
|
|
7184
|
+
_defaultBg;
|
|
7185
|
+
_defaultAttributes;
|
|
7186
|
+
_selectionBg;
|
|
7187
|
+
_selectionFg;
|
|
7188
|
+
_lastLocalSelection = null;
|
|
7189
|
+
_lastSelectionMode = null;
|
|
7190
|
+
_cells = [];
|
|
7191
|
+
_prevCellContent = [];
|
|
7192
|
+
_rowCount = 0;
|
|
7193
|
+
_columnCount = 0;
|
|
7194
|
+
_layout = this.createEmptyLayout();
|
|
7195
|
+
_layoutDirty = true;
|
|
7196
|
+
_rasterDirty = true;
|
|
7197
|
+
_cachedMeasureLayout = null;
|
|
7198
|
+
_cachedMeasureWidth = undefined;
|
|
7199
|
+
_defaultOptions = {
|
|
7200
|
+
content: [],
|
|
7201
|
+
wrapMode: "none",
|
|
7202
|
+
columnWidthMode: "content",
|
|
7203
|
+
cellPadding: 0,
|
|
7204
|
+
showBorders: true,
|
|
7205
|
+
border: true,
|
|
7206
|
+
outerBorder: true,
|
|
7207
|
+
selectable: true,
|
|
7208
|
+
selectionBg: undefined,
|
|
7209
|
+
selectionFg: undefined,
|
|
7210
|
+
borderStyle: "single",
|
|
7211
|
+
borderColor: "#FFFFFF",
|
|
7212
|
+
borderBackgroundColor: "transparent",
|
|
7213
|
+
backgroundColor: "transparent",
|
|
7214
|
+
fg: "#FFFFFF",
|
|
7215
|
+
bg: "transparent",
|
|
7216
|
+
attributes: 0
|
|
7217
|
+
};
|
|
7218
|
+
constructor(ctx, options = {}) {
|
|
7219
|
+
super(ctx, { ...options, buffered: true });
|
|
7220
|
+
this._content = options.content ?? this._defaultOptions.content;
|
|
7221
|
+
this._wrapMode = options.wrapMode ?? this._defaultOptions.wrapMode;
|
|
7222
|
+
this._columnWidthMode = options.columnWidthMode ?? this._defaultOptions.columnWidthMode;
|
|
7223
|
+
this._cellPadding = this.resolveCellPadding(options.cellPadding);
|
|
7224
|
+
this._showBorders = options.showBorders ?? this._defaultOptions.showBorders;
|
|
7225
|
+
this._border = options.border ?? this._defaultOptions.border;
|
|
7226
|
+
this._hasExplicitOuterBorder = options.outerBorder !== undefined;
|
|
7227
|
+
this._outerBorder = options.outerBorder ?? this._border;
|
|
7228
|
+
this.selectable = options.selectable ?? this._defaultOptions.selectable;
|
|
7229
|
+
this._selectionBg = options.selectionBg ? parseColor(options.selectionBg) : undefined;
|
|
7230
|
+
this._selectionFg = options.selectionFg ? parseColor(options.selectionFg) : undefined;
|
|
7231
|
+
this._borderStyle = parseBorderStyle(options.borderStyle, this._defaultOptions.borderStyle);
|
|
7232
|
+
this._borderColor = parseColor(options.borderColor ?? this._defaultOptions.borderColor);
|
|
7233
|
+
this._borderBackgroundColor = parseColor(options.borderBackgroundColor ?? this._defaultOptions.borderBackgroundColor);
|
|
7234
|
+
this._backgroundColor = parseColor(options.backgroundColor ?? this._defaultOptions.backgroundColor);
|
|
7235
|
+
this._defaultFg = parseColor(options.fg ?? this._defaultOptions.fg);
|
|
7236
|
+
this._defaultBg = parseColor(options.bg ?? this._defaultOptions.bg);
|
|
7237
|
+
this._defaultAttributes = options.attributes ?? this._defaultOptions.attributes;
|
|
7238
|
+
this.setupMeasureFunc();
|
|
7239
|
+
this.rebuildCells();
|
|
7240
|
+
}
|
|
7241
|
+
get content() {
|
|
7242
|
+
return this._content;
|
|
7243
|
+
}
|
|
7244
|
+
set content(value) {
|
|
7245
|
+
this._content = value ?? [];
|
|
7246
|
+
this.rebuildCells();
|
|
7247
|
+
}
|
|
7248
|
+
get wrapMode() {
|
|
7249
|
+
return this._wrapMode;
|
|
7250
|
+
}
|
|
7251
|
+
set wrapMode(value) {
|
|
7252
|
+
if (this._wrapMode === value)
|
|
7253
|
+
return;
|
|
7254
|
+
this._wrapMode = value;
|
|
7255
|
+
for (const row of this._cells) {
|
|
7256
|
+
for (const cell of row) {
|
|
7257
|
+
cell.textBufferView.setWrapMode(value);
|
|
7258
|
+
}
|
|
7259
|
+
}
|
|
7260
|
+
this.invalidateLayoutAndRaster();
|
|
7261
|
+
}
|
|
7262
|
+
get columnWidthMode() {
|
|
7263
|
+
return this._columnWidthMode;
|
|
7264
|
+
}
|
|
7265
|
+
set columnWidthMode(value) {
|
|
7266
|
+
if (this._columnWidthMode === value)
|
|
7267
|
+
return;
|
|
7268
|
+
this._columnWidthMode = value;
|
|
7269
|
+
this.invalidateLayoutAndRaster();
|
|
7270
|
+
}
|
|
7271
|
+
get cellPadding() {
|
|
7272
|
+
return this._cellPadding;
|
|
7273
|
+
}
|
|
7274
|
+
set cellPadding(value) {
|
|
7275
|
+
const next = this.resolveCellPadding(value);
|
|
7276
|
+
if (this._cellPadding === next)
|
|
7277
|
+
return;
|
|
7278
|
+
this._cellPadding = next;
|
|
7279
|
+
this.invalidateLayoutAndRaster();
|
|
7280
|
+
}
|
|
7281
|
+
get showBorders() {
|
|
7282
|
+
return this._showBorders;
|
|
7283
|
+
}
|
|
7284
|
+
set showBorders(value) {
|
|
7285
|
+
if (this._showBorders === value)
|
|
7286
|
+
return;
|
|
7287
|
+
this._showBorders = value;
|
|
7288
|
+
this.invalidateRasterOnly();
|
|
7289
|
+
}
|
|
7290
|
+
get outerBorder() {
|
|
7291
|
+
return this._outerBorder;
|
|
7292
|
+
}
|
|
7293
|
+
set outerBorder(value) {
|
|
7294
|
+
if (this._outerBorder === value)
|
|
7295
|
+
return;
|
|
7296
|
+
this._hasExplicitOuterBorder = true;
|
|
7297
|
+
this._outerBorder = value;
|
|
7298
|
+
this.invalidateLayoutAndRaster();
|
|
7299
|
+
}
|
|
7300
|
+
get border() {
|
|
7301
|
+
return this._border;
|
|
7302
|
+
}
|
|
7303
|
+
set border(value) {
|
|
7304
|
+
if (this._border === value)
|
|
7305
|
+
return;
|
|
7306
|
+
this._border = value;
|
|
7307
|
+
if (!this._hasExplicitOuterBorder) {
|
|
7308
|
+
this._outerBorder = value;
|
|
7309
|
+
}
|
|
7310
|
+
this.invalidateLayoutAndRaster();
|
|
7311
|
+
}
|
|
7312
|
+
get borderStyle() {
|
|
7313
|
+
return this._borderStyle;
|
|
7314
|
+
}
|
|
7315
|
+
set borderStyle(value) {
|
|
7316
|
+
const next = parseBorderStyle(value, this._defaultOptions.borderStyle);
|
|
7317
|
+
if (this._borderStyle === next)
|
|
7318
|
+
return;
|
|
7319
|
+
this._borderStyle = next;
|
|
7320
|
+
this.invalidateRasterOnly();
|
|
7321
|
+
}
|
|
7322
|
+
get borderColor() {
|
|
7323
|
+
return this._borderColor;
|
|
7324
|
+
}
|
|
7325
|
+
set borderColor(value) {
|
|
7326
|
+
const next = parseColor(value);
|
|
7327
|
+
if (this._borderColor === next)
|
|
7328
|
+
return;
|
|
7329
|
+
this._borderColor = next;
|
|
7330
|
+
this.invalidateRasterOnly();
|
|
7331
|
+
}
|
|
7332
|
+
shouldStartSelection(x, y) {
|
|
7333
|
+
if (!this.selectable)
|
|
7334
|
+
return false;
|
|
7335
|
+
this.ensureLayoutReady();
|
|
7336
|
+
const localX = x - this.x;
|
|
7337
|
+
const localY = y - this.y;
|
|
7338
|
+
return this.getCellAtLocalPosition(localX, localY) !== null;
|
|
7339
|
+
}
|
|
7340
|
+
onSelectionChanged(selection) {
|
|
7341
|
+
this.ensureLayoutReady();
|
|
7342
|
+
const previousLocalSelection = this._lastLocalSelection;
|
|
7343
|
+
const localSelection = convertGlobalToLocalSelection(selection, this.x, this.y);
|
|
7344
|
+
this._lastLocalSelection = localSelection;
|
|
7345
|
+
const dirtyRows = this.getDirtySelectionRowRange(previousLocalSelection, localSelection);
|
|
7346
|
+
if (!localSelection?.isActive) {
|
|
7347
|
+
this.resetCellSelections();
|
|
7348
|
+
this._lastSelectionMode = null;
|
|
7349
|
+
} else {
|
|
7350
|
+
this.applySelectionToCells(localSelection, selection?.isStart ?? false);
|
|
7351
|
+
}
|
|
7352
|
+
if (dirtyRows !== null) {
|
|
7353
|
+
this.redrawSelectionRows(dirtyRows.firstRow, dirtyRows.lastRow);
|
|
7354
|
+
}
|
|
7355
|
+
return this.hasSelection();
|
|
7356
|
+
}
|
|
7357
|
+
hasSelection() {
|
|
7358
|
+
for (const row of this._cells) {
|
|
7359
|
+
for (const cell of row) {
|
|
7360
|
+
if (cell.textBufferView.hasSelection()) {
|
|
7361
|
+
return true;
|
|
7362
|
+
}
|
|
7363
|
+
}
|
|
7364
|
+
}
|
|
7365
|
+
return false;
|
|
7366
|
+
}
|
|
7367
|
+
getSelection() {
|
|
7368
|
+
for (const row of this._cells) {
|
|
7369
|
+
for (const cell of row) {
|
|
7370
|
+
const selection = cell.textBufferView.getSelection();
|
|
7371
|
+
if (selection) {
|
|
7372
|
+
return selection;
|
|
7373
|
+
}
|
|
7374
|
+
}
|
|
7375
|
+
}
|
|
7376
|
+
return null;
|
|
7377
|
+
}
|
|
7378
|
+
getSelectedText() {
|
|
7379
|
+
const selectedRows = [];
|
|
7380
|
+
for (let rowIdx = 0;rowIdx < this._rowCount; rowIdx++) {
|
|
7381
|
+
const rowSelections = [];
|
|
7382
|
+
for (let colIdx = 0;colIdx < this._columnCount; colIdx++) {
|
|
7383
|
+
const cell = this._cells[rowIdx]?.[colIdx];
|
|
7384
|
+
if (!cell || !cell.textBufferView.hasSelection())
|
|
7385
|
+
continue;
|
|
7386
|
+
const selectedText = cell.textBufferView.getSelectedText();
|
|
7387
|
+
if (selectedText.length > 0) {
|
|
7388
|
+
rowSelections.push(selectedText);
|
|
7389
|
+
}
|
|
7390
|
+
}
|
|
7391
|
+
if (rowSelections.length > 0) {
|
|
7392
|
+
selectedRows.push(rowSelections.join("\t"));
|
|
7393
|
+
}
|
|
7394
|
+
}
|
|
7395
|
+
return selectedRows.join(`
|
|
7396
|
+
`);
|
|
7397
|
+
}
|
|
7398
|
+
onResize(width, height) {
|
|
7399
|
+
this.invalidateLayoutAndRaster(false);
|
|
7400
|
+
super.onResize(width, height);
|
|
7401
|
+
}
|
|
7402
|
+
renderSelf(buffer) {
|
|
7403
|
+
if (!this.visible || this.isDestroyed)
|
|
7404
|
+
return;
|
|
7405
|
+
if (this._layoutDirty) {
|
|
7406
|
+
this.rebuildLayoutForCurrentWidth();
|
|
7407
|
+
}
|
|
7408
|
+
if (!this._rasterDirty)
|
|
7409
|
+
return;
|
|
7410
|
+
buffer.clear(this._backgroundColor);
|
|
7411
|
+
if (this._rowCount === 0 || this._columnCount === 0) {
|
|
7412
|
+
this._rasterDirty = false;
|
|
7413
|
+
return;
|
|
7414
|
+
}
|
|
7415
|
+
this.drawBorders(buffer);
|
|
7416
|
+
this.drawCells(buffer);
|
|
7417
|
+
this._rasterDirty = false;
|
|
7418
|
+
}
|
|
7419
|
+
destroySelf() {
|
|
7420
|
+
this.destroyCells();
|
|
7421
|
+
super.destroySelf();
|
|
7422
|
+
}
|
|
7423
|
+
setupMeasureFunc() {
|
|
7424
|
+
const measureFunc = (width, widthMode, height, heightMode) => {
|
|
7425
|
+
const hasWidthConstraint = widthMode !== MeasureMode.Undefined && Number.isFinite(width);
|
|
7426
|
+
const rawWidthConstraint = hasWidthConstraint ? Math.max(1, Math.floor(width)) : undefined;
|
|
7427
|
+
const widthConstraint = this.resolveLayoutWidthConstraint(rawWidthConstraint);
|
|
7428
|
+
const measuredLayout = this.computeLayout(widthConstraint);
|
|
7429
|
+
this._cachedMeasureLayout = measuredLayout;
|
|
7430
|
+
this._cachedMeasureWidth = widthConstraint;
|
|
7431
|
+
let measuredWidth = measuredLayout.tableWidth > 0 ? measuredLayout.tableWidth : 1;
|
|
7432
|
+
let measuredHeight = measuredLayout.tableHeight > 0 ? measuredLayout.tableHeight : 1;
|
|
7433
|
+
if (widthMode === MeasureMode.AtMost && rawWidthConstraint !== undefined && this._positionType !== "absolute") {
|
|
7434
|
+
measuredWidth = Math.min(rawWidthConstraint, measuredWidth);
|
|
7435
|
+
}
|
|
7436
|
+
if (heightMode === MeasureMode.AtMost && Number.isFinite(height) && this._positionType !== "absolute") {
|
|
7437
|
+
measuredHeight = Math.min(Math.max(1, Math.floor(height)), measuredHeight);
|
|
7438
|
+
}
|
|
7439
|
+
return {
|
|
7440
|
+
width: measuredWidth,
|
|
7441
|
+
height: measuredHeight
|
|
7442
|
+
};
|
|
7443
|
+
};
|
|
7444
|
+
this.yogaNode.setMeasureFunc(measureFunc);
|
|
7445
|
+
}
|
|
7446
|
+
rebuildCells() {
|
|
7447
|
+
const newRowCount = this._content.length;
|
|
7448
|
+
const newColumnCount = this._content.reduce((max, row) => Math.max(max, row.length), 0);
|
|
7449
|
+
if (this._cells.length === 0) {
|
|
7450
|
+
this._rowCount = newRowCount;
|
|
7451
|
+
this._columnCount = newColumnCount;
|
|
7452
|
+
this._cells = [];
|
|
7453
|
+
this._prevCellContent = [];
|
|
7454
|
+
for (let rowIdx = 0;rowIdx < newRowCount; rowIdx++) {
|
|
7455
|
+
const row = this._content[rowIdx] ?? [];
|
|
7456
|
+
const rowCells = [];
|
|
7457
|
+
const rowRefs = [];
|
|
7458
|
+
for (let colIdx = 0;colIdx < newColumnCount; colIdx++) {
|
|
7459
|
+
const cellContent = row[colIdx];
|
|
7460
|
+
rowCells.push(this.createCell(cellContent));
|
|
7461
|
+
rowRefs.push(cellContent);
|
|
7462
|
+
}
|
|
7463
|
+
this._cells.push(rowCells);
|
|
7464
|
+
this._prevCellContent.push(rowRefs);
|
|
7465
|
+
}
|
|
7466
|
+
this.invalidateLayoutAndRaster();
|
|
7467
|
+
return;
|
|
7468
|
+
}
|
|
7469
|
+
this.updateCellsDiff(newRowCount, newColumnCount);
|
|
7470
|
+
this.invalidateLayoutAndRaster();
|
|
7471
|
+
}
|
|
7472
|
+
updateCellsDiff(newRowCount, newColumnCount) {
|
|
7473
|
+
const oldRowCount = this._rowCount;
|
|
7474
|
+
const oldColumnCount = this._columnCount;
|
|
7475
|
+
const keepRows = Math.min(oldRowCount, newRowCount);
|
|
7476
|
+
const keepCols = Math.min(oldColumnCount, newColumnCount);
|
|
7477
|
+
for (let rowIdx = 0;rowIdx < keepRows; rowIdx++) {
|
|
7478
|
+
const newRow = this._content[rowIdx] ?? [];
|
|
7479
|
+
const cellRow = this._cells[rowIdx];
|
|
7480
|
+
const refRow = this._prevCellContent[rowIdx];
|
|
7481
|
+
for (let colIdx = 0;colIdx < keepCols; colIdx++) {
|
|
7482
|
+
const cellContent = newRow[colIdx];
|
|
7483
|
+
if (cellContent === refRow[colIdx])
|
|
7484
|
+
continue;
|
|
7485
|
+
const oldCell = cellRow[colIdx];
|
|
7486
|
+
oldCell.textBufferView.destroy();
|
|
7487
|
+
oldCell.textBuffer.destroy();
|
|
7488
|
+
oldCell.syntaxStyle.destroy();
|
|
7489
|
+
cellRow[colIdx] = this.createCell(cellContent);
|
|
7490
|
+
refRow[colIdx] = cellContent;
|
|
7491
|
+
}
|
|
7492
|
+
if (newColumnCount > oldColumnCount) {
|
|
7493
|
+
for (let colIdx = oldColumnCount;colIdx < newColumnCount; colIdx++) {
|
|
7494
|
+
const cellContent = newRow[colIdx];
|
|
7495
|
+
cellRow.push(this.createCell(cellContent));
|
|
7496
|
+
refRow.push(cellContent);
|
|
7497
|
+
}
|
|
7498
|
+
} else if (newColumnCount < oldColumnCount) {
|
|
7499
|
+
for (let colIdx = newColumnCount;colIdx < oldColumnCount; colIdx++) {
|
|
7500
|
+
const cell = cellRow[colIdx];
|
|
7501
|
+
cell.textBufferView.destroy();
|
|
7502
|
+
cell.textBuffer.destroy();
|
|
7503
|
+
cell.syntaxStyle.destroy();
|
|
7504
|
+
}
|
|
7505
|
+
cellRow.length = newColumnCount;
|
|
7506
|
+
refRow.length = newColumnCount;
|
|
7507
|
+
}
|
|
7508
|
+
}
|
|
7509
|
+
if (newRowCount > oldRowCount) {
|
|
7510
|
+
for (let rowIdx = oldRowCount;rowIdx < newRowCount; rowIdx++) {
|
|
7511
|
+
const newRow = this._content[rowIdx] ?? [];
|
|
7512
|
+
const rowCells = [];
|
|
7513
|
+
const rowRefs = [];
|
|
7514
|
+
for (let colIdx = 0;colIdx < newColumnCount; colIdx++) {
|
|
7515
|
+
const cellContent = newRow[colIdx];
|
|
7516
|
+
rowCells.push(this.createCell(cellContent));
|
|
7517
|
+
rowRefs.push(cellContent);
|
|
7518
|
+
}
|
|
7519
|
+
this._cells.push(rowCells);
|
|
7520
|
+
this._prevCellContent.push(rowRefs);
|
|
7521
|
+
}
|
|
7522
|
+
} else if (newRowCount < oldRowCount) {
|
|
7523
|
+
for (let rowIdx = newRowCount;rowIdx < oldRowCount; rowIdx++) {
|
|
7524
|
+
const row = this._cells[rowIdx];
|
|
7525
|
+
for (const cell of row) {
|
|
7526
|
+
cell.textBufferView.destroy();
|
|
7527
|
+
cell.textBuffer.destroy();
|
|
7528
|
+
cell.syntaxStyle.destroy();
|
|
7529
|
+
}
|
|
7530
|
+
}
|
|
7531
|
+
this._cells.length = newRowCount;
|
|
7532
|
+
this._prevCellContent.length = newRowCount;
|
|
7533
|
+
}
|
|
7534
|
+
this._rowCount = newRowCount;
|
|
7535
|
+
this._columnCount = newColumnCount;
|
|
7536
|
+
}
|
|
7537
|
+
createCell(content) {
|
|
7538
|
+
const styledText = this.toStyledText(content);
|
|
7539
|
+
const textBuffer = TextBuffer.create(this._ctx.widthMethod);
|
|
7540
|
+
const syntaxStyle = SyntaxStyle.create();
|
|
7541
|
+
textBuffer.setDefaultFg(this._defaultFg);
|
|
7542
|
+
textBuffer.setDefaultBg(this._defaultBg);
|
|
7543
|
+
textBuffer.setDefaultAttributes(this._defaultAttributes);
|
|
7544
|
+
textBuffer.setSyntaxStyle(syntaxStyle);
|
|
7545
|
+
textBuffer.setStyledText(styledText);
|
|
7546
|
+
const textBufferView = TextBufferView.create(textBuffer);
|
|
7547
|
+
textBufferView.setWrapMode(this._wrapMode);
|
|
7548
|
+
return { textBuffer, textBufferView, syntaxStyle };
|
|
7549
|
+
}
|
|
7550
|
+
toStyledText(content) {
|
|
7551
|
+
if (Array.isArray(content)) {
|
|
7552
|
+
return new StyledText(content);
|
|
7553
|
+
}
|
|
7554
|
+
if (content === null || content === undefined) {
|
|
7555
|
+
return stringToStyledText("");
|
|
7556
|
+
}
|
|
7557
|
+
return stringToStyledText(String(content));
|
|
7558
|
+
}
|
|
7559
|
+
destroyCells() {
|
|
7560
|
+
for (const row of this._cells) {
|
|
7561
|
+
for (const cell of row) {
|
|
7562
|
+
cell.textBufferView.destroy();
|
|
7563
|
+
cell.textBuffer.destroy();
|
|
7564
|
+
cell.syntaxStyle.destroy();
|
|
7565
|
+
}
|
|
7566
|
+
}
|
|
7567
|
+
this._cells = [];
|
|
7568
|
+
this._prevCellContent = [];
|
|
7569
|
+
this._rowCount = 0;
|
|
7570
|
+
this._columnCount = 0;
|
|
7571
|
+
this._layout = this.createEmptyLayout();
|
|
7572
|
+
}
|
|
7573
|
+
rebuildLayoutForCurrentWidth() {
|
|
7574
|
+
const maxTableWidth = this.resolveLayoutWidthConstraint(this.width);
|
|
7575
|
+
let layout;
|
|
7576
|
+
if (this._cachedMeasureLayout !== null && this._cachedMeasureWidth === maxTableWidth) {
|
|
7577
|
+
layout = this._cachedMeasureLayout;
|
|
7578
|
+
} else {
|
|
7579
|
+
layout = this.computeLayout(maxTableWidth);
|
|
7580
|
+
}
|
|
7581
|
+
this._cachedMeasureLayout = null;
|
|
7582
|
+
this._cachedMeasureWidth = undefined;
|
|
7583
|
+
this._layout = layout;
|
|
7584
|
+
this.applyLayoutToViews(layout);
|
|
7585
|
+
this._layoutDirty = false;
|
|
7586
|
+
if (this._lastLocalSelection?.isActive) {
|
|
7587
|
+
this.applySelectionToCells(this._lastLocalSelection, true);
|
|
7588
|
+
}
|
|
7589
|
+
}
|
|
7590
|
+
computeLayout(maxTableWidth) {
|
|
7591
|
+
if (this._rowCount === 0 || this._columnCount === 0) {
|
|
7592
|
+
return this.createEmptyLayout();
|
|
7593
|
+
}
|
|
7594
|
+
const borderLayout = this.resolveBorderLayout();
|
|
7595
|
+
const columnWidths = this.computeColumnWidths(maxTableWidth, borderLayout);
|
|
7596
|
+
const rowHeights = this.computeRowHeights(columnWidths);
|
|
7597
|
+
const columnOffsets = this.computeOffsets(columnWidths, borderLayout.left, borderLayout.right, borderLayout.innerVertical);
|
|
7598
|
+
const rowOffsets = this.computeOffsets(rowHeights, borderLayout.top, borderLayout.bottom, borderLayout.innerHorizontal);
|
|
7599
|
+
return {
|
|
7600
|
+
columnWidths,
|
|
7601
|
+
rowHeights,
|
|
7602
|
+
columnOffsets,
|
|
7603
|
+
rowOffsets,
|
|
7604
|
+
columnOffsetsI32: new Int32Array(columnOffsets),
|
|
7605
|
+
rowOffsetsI32: new Int32Array(rowOffsets),
|
|
7606
|
+
tableWidth: (columnOffsets[columnOffsets.length - 1] ?? 0) + 1,
|
|
7607
|
+
tableHeight: (rowOffsets[rowOffsets.length - 1] ?? 0) + 1
|
|
7608
|
+
};
|
|
7609
|
+
}
|
|
7610
|
+
computeColumnWidths(maxTableWidth, borderLayout) {
|
|
7611
|
+
const horizontalPadding = this.getHorizontalCellPadding();
|
|
7612
|
+
const intrinsicWidths = new Array(this._columnCount).fill(1 + horizontalPadding);
|
|
7613
|
+
for (let rowIdx = 0;rowIdx < this._rowCount; rowIdx++) {
|
|
7614
|
+
for (let colIdx = 0;colIdx < this._columnCount; colIdx++) {
|
|
7615
|
+
const cell = this._cells[rowIdx]?.[colIdx];
|
|
7616
|
+
if (!cell)
|
|
7617
|
+
continue;
|
|
7618
|
+
const measure = cell.textBufferView.measureForDimensions(0, MEASURE_HEIGHT);
|
|
7619
|
+
const measuredWidth = Math.max(1, measure?.maxWidth ?? 0) + horizontalPadding;
|
|
7620
|
+
intrinsicWidths[colIdx] = Math.max(intrinsicWidths[colIdx], measuredWidth);
|
|
7621
|
+
}
|
|
7622
|
+
}
|
|
7623
|
+
if (maxTableWidth === undefined || !Number.isFinite(maxTableWidth) || maxTableWidth <= 0) {
|
|
7624
|
+
return intrinsicWidths;
|
|
7625
|
+
}
|
|
7626
|
+
const maxContentWidth = Math.max(1, Math.floor(maxTableWidth) - this.getVerticalBorderCount(borderLayout));
|
|
7627
|
+
const currentWidth = intrinsicWidths.reduce((sum, width) => sum + width, 0);
|
|
7628
|
+
if (currentWidth === maxContentWidth) {
|
|
7629
|
+
return intrinsicWidths;
|
|
7630
|
+
}
|
|
7631
|
+
if (currentWidth < maxContentWidth) {
|
|
7632
|
+
if (this._columnWidthMode === "fill") {
|
|
7633
|
+
return this.expandColumnWidths(intrinsicWidths, maxContentWidth);
|
|
7634
|
+
}
|
|
7635
|
+
return intrinsicWidths;
|
|
7636
|
+
}
|
|
7637
|
+
if (this._wrapMode === "none") {
|
|
7638
|
+
return intrinsicWidths;
|
|
7639
|
+
}
|
|
7640
|
+
return this.fitColumnWidths(intrinsicWidths, maxContentWidth);
|
|
7641
|
+
}
|
|
7642
|
+
expandColumnWidths(widths, targetContentWidth) {
|
|
7643
|
+
const baseWidths = widths.map((width) => Math.max(1, Math.floor(width)));
|
|
7644
|
+
const totalBaseWidth = baseWidths.reduce((sum, width) => sum + width, 0);
|
|
7645
|
+
if (totalBaseWidth >= targetContentWidth) {
|
|
7646
|
+
return baseWidths;
|
|
7647
|
+
}
|
|
7648
|
+
const expanded = [...baseWidths];
|
|
7649
|
+
const columns = expanded.length;
|
|
7650
|
+
const extraWidth = targetContentWidth - totalBaseWidth;
|
|
7651
|
+
const sharedWidth = Math.floor(extraWidth / columns);
|
|
7652
|
+
const remainder = extraWidth % columns;
|
|
7653
|
+
for (let idx = 0;idx < columns; idx++) {
|
|
7654
|
+
expanded[idx] += sharedWidth;
|
|
7655
|
+
if (idx < remainder) {
|
|
7656
|
+
expanded[idx] += 1;
|
|
7657
|
+
}
|
|
7658
|
+
}
|
|
7659
|
+
return expanded;
|
|
7660
|
+
}
|
|
7661
|
+
fitColumnWidths(widths, targetContentWidth) {
|
|
7662
|
+
const minWidth = 1 + this.getHorizontalCellPadding();
|
|
7663
|
+
const hardMinWidths = new Array(widths.length).fill(minWidth);
|
|
7664
|
+
const baseWidths = widths.map((width) => Math.max(1, Math.floor(width)));
|
|
7665
|
+
const preferredMinWidths = baseWidths.map((width) => Math.min(width, minWidth + 1));
|
|
7666
|
+
const preferredMinTotal = preferredMinWidths.reduce((sum, width) => sum + width, 0);
|
|
7667
|
+
const floorWidths = preferredMinTotal <= targetContentWidth ? preferredMinWidths : hardMinWidths;
|
|
7668
|
+
const floorTotal = floorWidths.reduce((sum, width) => sum + width, 0);
|
|
7669
|
+
const clampedTarget = Math.max(floorTotal, targetContentWidth);
|
|
7670
|
+
const totalBaseWidth = baseWidths.reduce((sum, width) => sum + width, 0);
|
|
7671
|
+
if (totalBaseWidth <= clampedTarget) {
|
|
7672
|
+
return baseWidths;
|
|
7673
|
+
}
|
|
7674
|
+
const shrinkable = baseWidths.map((width, idx) => width - floorWidths[idx]);
|
|
7675
|
+
const totalShrinkable = shrinkable.reduce((sum, value) => sum + value, 0);
|
|
7676
|
+
if (totalShrinkable <= 0) {
|
|
7677
|
+
return [...floorWidths];
|
|
7678
|
+
}
|
|
7679
|
+
const targetShrink = totalBaseWidth - clampedTarget;
|
|
7680
|
+
const integerShrink = new Array(baseWidths.length).fill(0);
|
|
7681
|
+
const fractions = new Array(baseWidths.length).fill(0);
|
|
7682
|
+
let usedShrink = 0;
|
|
7683
|
+
for (let idx = 0;idx < baseWidths.length; idx++) {
|
|
7684
|
+
if (shrinkable[idx] <= 0)
|
|
7685
|
+
continue;
|
|
7686
|
+
const exact = shrinkable[idx] / totalShrinkable * targetShrink;
|
|
7687
|
+
const whole = Math.min(shrinkable[idx], Math.floor(exact));
|
|
7688
|
+
integerShrink[idx] = whole;
|
|
7689
|
+
fractions[idx] = exact - whole;
|
|
7690
|
+
usedShrink += whole;
|
|
7691
|
+
}
|
|
7692
|
+
let remainingShrink = targetShrink - usedShrink;
|
|
7693
|
+
while (remainingShrink > 0) {
|
|
7694
|
+
let bestIdx = -1;
|
|
7695
|
+
let bestFraction = -1;
|
|
7696
|
+
for (let idx = 0;idx < baseWidths.length; idx++) {
|
|
7697
|
+
if (shrinkable[idx] - integerShrink[idx] <= 0)
|
|
7698
|
+
continue;
|
|
7699
|
+
if (fractions[idx] > bestFraction) {
|
|
7700
|
+
bestFraction = fractions[idx];
|
|
7701
|
+
bestIdx = idx;
|
|
7702
|
+
}
|
|
7703
|
+
}
|
|
7704
|
+
if (bestIdx === -1)
|
|
7705
|
+
break;
|
|
7706
|
+
integerShrink[bestIdx] += 1;
|
|
7707
|
+
fractions[bestIdx] = 0;
|
|
7708
|
+
remainingShrink -= 1;
|
|
7709
|
+
}
|
|
7710
|
+
return baseWidths.map((width, idx) => Math.max(floorWidths[idx], width - integerShrink[idx]));
|
|
7711
|
+
}
|
|
7712
|
+
computeRowHeights(columnWidths) {
|
|
7713
|
+
const horizontalPadding = this.getHorizontalCellPadding();
|
|
7714
|
+
const verticalPadding = this.getVerticalCellPadding();
|
|
7715
|
+
const rowHeights = new Array(this._rowCount).fill(1 + verticalPadding);
|
|
7716
|
+
for (let rowIdx = 0;rowIdx < this._rowCount; rowIdx++) {
|
|
7717
|
+
for (let colIdx = 0;colIdx < this._columnCount; colIdx++) {
|
|
7718
|
+
const cell = this._cells[rowIdx]?.[colIdx];
|
|
7719
|
+
if (!cell)
|
|
7720
|
+
continue;
|
|
7721
|
+
const width = Math.max(1, (columnWidths[colIdx] ?? 1) - horizontalPadding);
|
|
7722
|
+
const measure = cell.textBufferView.measureForDimensions(width, MEASURE_HEIGHT);
|
|
7723
|
+
const lineCount = Math.max(1, measure?.lineCount ?? 1);
|
|
7724
|
+
rowHeights[rowIdx] = Math.max(rowHeights[rowIdx], lineCount + verticalPadding);
|
|
7725
|
+
}
|
|
7726
|
+
}
|
|
7727
|
+
return rowHeights;
|
|
7728
|
+
}
|
|
7729
|
+
computeOffsets(parts, startBoundary, endBoundary, includeInnerBoundaries) {
|
|
7730
|
+
const offsets = [startBoundary ? 0 : -1];
|
|
7731
|
+
let cursor = offsets[0] ?? 0;
|
|
7732
|
+
for (let idx = 0;idx < parts.length; idx++) {
|
|
7733
|
+
const size = parts[idx] ?? 1;
|
|
7734
|
+
const hasBoundaryAfter = idx < parts.length - 1 ? includeInnerBoundaries : endBoundary;
|
|
7735
|
+
cursor += size + (hasBoundaryAfter ? 1 : 0);
|
|
7736
|
+
offsets.push(cursor);
|
|
7737
|
+
}
|
|
7738
|
+
return offsets;
|
|
7739
|
+
}
|
|
7740
|
+
applyLayoutToViews(layout) {
|
|
7741
|
+
const horizontalPadding = this.getHorizontalCellPadding();
|
|
7742
|
+
const verticalPadding = this.getVerticalCellPadding();
|
|
7743
|
+
for (let rowIdx = 0;rowIdx < this._rowCount; rowIdx++) {
|
|
7744
|
+
for (let colIdx = 0;colIdx < this._columnCount; colIdx++) {
|
|
7745
|
+
const cell = this._cells[rowIdx]?.[colIdx];
|
|
7746
|
+
if (!cell)
|
|
7747
|
+
continue;
|
|
7748
|
+
const colWidth = layout.columnWidths[colIdx] ?? 1;
|
|
7749
|
+
const rowHeight = layout.rowHeights[rowIdx] ?? 1;
|
|
7750
|
+
const contentWidth = Math.max(1, colWidth - horizontalPadding);
|
|
7751
|
+
const contentHeight = Math.max(1, rowHeight - verticalPadding);
|
|
7752
|
+
if (this._wrapMode === "none") {
|
|
7753
|
+
cell.textBufferView.setWrapWidth(null);
|
|
7754
|
+
} else {
|
|
7755
|
+
cell.textBufferView.setWrapWidth(contentWidth);
|
|
7756
|
+
}
|
|
7757
|
+
cell.textBufferView.setViewport(0, 0, contentWidth, contentHeight);
|
|
7758
|
+
}
|
|
7759
|
+
}
|
|
7760
|
+
}
|
|
7761
|
+
resolveBorderLayout() {
|
|
7762
|
+
return {
|
|
7763
|
+
left: this._outerBorder,
|
|
7764
|
+
right: this._outerBorder,
|
|
7765
|
+
top: this._outerBorder,
|
|
7766
|
+
bottom: this._outerBorder,
|
|
7767
|
+
innerVertical: this._border && this._columnCount > 1,
|
|
7768
|
+
innerHorizontal: this._border && this._rowCount > 1
|
|
7769
|
+
};
|
|
7770
|
+
}
|
|
7771
|
+
getVerticalBorderCount(borderLayout) {
|
|
7772
|
+
return (borderLayout.left ? 1 : 0) + (borderLayout.right ? 1 : 0) + (borderLayout.innerVertical ? Math.max(0, this._columnCount - 1) : 0);
|
|
7773
|
+
}
|
|
7774
|
+
getHorizontalBorderCount(borderLayout) {
|
|
7775
|
+
return (borderLayout.top ? 1 : 0) + (borderLayout.bottom ? 1 : 0) + (borderLayout.innerHorizontal ? Math.max(0, this._rowCount - 1) : 0);
|
|
7776
|
+
}
|
|
7777
|
+
drawBorders(buffer) {
|
|
7778
|
+
if (!this._showBorders) {
|
|
7779
|
+
return;
|
|
7780
|
+
}
|
|
7781
|
+
const borderLayout = this.resolveBorderLayout();
|
|
7782
|
+
if (this.getVerticalBorderCount(borderLayout) === 0 && this.getHorizontalBorderCount(borderLayout) === 0) {
|
|
7783
|
+
return;
|
|
7784
|
+
}
|
|
7785
|
+
buffer.drawGrid({
|
|
7786
|
+
borderChars: BorderCharArrays[this._borderStyle],
|
|
7787
|
+
borderFg: this._borderColor,
|
|
7788
|
+
borderBg: this._borderBackgroundColor,
|
|
7789
|
+
columnOffsets: this._layout.columnOffsetsI32,
|
|
7790
|
+
rowOffsets: this._layout.rowOffsetsI32,
|
|
7791
|
+
drawInner: this._border,
|
|
7792
|
+
drawOuter: this._outerBorder
|
|
7793
|
+
});
|
|
7794
|
+
}
|
|
7795
|
+
drawCells(buffer) {
|
|
7796
|
+
this.drawCellRange(buffer, 0, this._rowCount - 1);
|
|
7797
|
+
}
|
|
7798
|
+
drawCellRange(buffer, firstRow, lastRow) {
|
|
7799
|
+
const colOffsets = this._layout.columnOffsets;
|
|
7800
|
+
const rowOffsets = this._layout.rowOffsets;
|
|
7801
|
+
const cellPadding = this._cellPadding;
|
|
7802
|
+
for (let rowIdx = firstRow;rowIdx <= lastRow; rowIdx++) {
|
|
7803
|
+
const cellY = (rowOffsets[rowIdx] ?? 0) + 1 + cellPadding;
|
|
7804
|
+
for (let colIdx = 0;colIdx < this._columnCount; colIdx++) {
|
|
7805
|
+
const cell = this._cells[rowIdx]?.[colIdx];
|
|
7806
|
+
if (!cell)
|
|
7807
|
+
continue;
|
|
7808
|
+
buffer.drawTextBuffer(cell.textBufferView, (colOffsets[colIdx] ?? 0) + 1 + cellPadding, cellY);
|
|
7809
|
+
}
|
|
7810
|
+
}
|
|
7811
|
+
}
|
|
7812
|
+
redrawSelectionRows(firstRow, lastRow) {
|
|
7813
|
+
if (firstRow > lastRow)
|
|
7814
|
+
return;
|
|
7815
|
+
if (this._backgroundColor.a < 1) {
|
|
7816
|
+
this.invalidateRasterOnly();
|
|
7817
|
+
return;
|
|
7818
|
+
}
|
|
7819
|
+
const buffer = this.frameBuffer;
|
|
7820
|
+
if (!buffer)
|
|
7821
|
+
return;
|
|
7822
|
+
this.clearCellRange(buffer, firstRow, lastRow);
|
|
7823
|
+
this.drawCellRange(buffer, firstRow, lastRow);
|
|
7824
|
+
this.requestRender();
|
|
7825
|
+
}
|
|
7826
|
+
clearCellRange(buffer, firstRow, lastRow) {
|
|
7827
|
+
const colWidths = this._layout.columnWidths;
|
|
7828
|
+
const rowHeights = this._layout.rowHeights;
|
|
7829
|
+
const colOffsets = this._layout.columnOffsets;
|
|
7830
|
+
const rowOffsets = this._layout.rowOffsets;
|
|
7831
|
+
for (let rowIdx = firstRow;rowIdx <= lastRow; rowIdx++) {
|
|
7832
|
+
const cellY = (rowOffsets[rowIdx] ?? 0) + 1;
|
|
7833
|
+
const rowHeight = rowHeights[rowIdx] ?? 1;
|
|
7834
|
+
for (let colIdx = 0;colIdx < this._columnCount; colIdx++) {
|
|
7835
|
+
const cellX = (colOffsets[colIdx] ?? 0) + 1;
|
|
7836
|
+
const colWidth = colWidths[colIdx] ?? 1;
|
|
7837
|
+
buffer.fillRect(cellX, cellY, colWidth, rowHeight, this._backgroundColor);
|
|
7838
|
+
}
|
|
7839
|
+
}
|
|
7840
|
+
}
|
|
7841
|
+
ensureLayoutReady() {
|
|
7842
|
+
if (!this._layoutDirty)
|
|
7843
|
+
return;
|
|
7844
|
+
this.rebuildLayoutForCurrentWidth();
|
|
7845
|
+
}
|
|
7846
|
+
getCellAtLocalPosition(localX, localY) {
|
|
7847
|
+
if (this._rowCount === 0 || this._columnCount === 0)
|
|
7848
|
+
return null;
|
|
7849
|
+
if (localX < 0 || localY < 0 || localX >= this._layout.tableWidth || localY >= this._layout.tableHeight) {
|
|
7850
|
+
return null;
|
|
7851
|
+
}
|
|
7852
|
+
let rowIdx = -1;
|
|
7853
|
+
for (let idx = 0;idx < this._rowCount; idx++) {
|
|
7854
|
+
const top = (this._layout.rowOffsets[idx] ?? 0) + 1;
|
|
7855
|
+
const bottom = top + (this._layout.rowHeights[idx] ?? 1) - 1;
|
|
7856
|
+
if (localY >= top && localY <= bottom) {
|
|
7857
|
+
rowIdx = idx;
|
|
7858
|
+
break;
|
|
7859
|
+
}
|
|
7860
|
+
}
|
|
7861
|
+
if (rowIdx < 0)
|
|
7862
|
+
return null;
|
|
7863
|
+
let colIdx = -1;
|
|
7864
|
+
for (let idx = 0;idx < this._columnCount; idx++) {
|
|
7865
|
+
const left = (this._layout.columnOffsets[idx] ?? 0) + 1;
|
|
7866
|
+
const right = left + (this._layout.columnWidths[idx] ?? 1) - 1;
|
|
7867
|
+
if (localX >= left && localX <= right) {
|
|
7868
|
+
colIdx = idx;
|
|
7869
|
+
break;
|
|
7870
|
+
}
|
|
7871
|
+
}
|
|
7872
|
+
if (colIdx < 0)
|
|
7873
|
+
return null;
|
|
7874
|
+
return { rowIdx, colIdx };
|
|
7875
|
+
}
|
|
7876
|
+
applySelectionToCells(localSelection, isStart) {
|
|
7877
|
+
const minSelY = Math.min(localSelection.anchorY, localSelection.focusY);
|
|
7878
|
+
const maxSelY = Math.max(localSelection.anchorY, localSelection.focusY);
|
|
7879
|
+
const firstRow = this.findRowForLocalY(minSelY);
|
|
7880
|
+
const lastRow = this.findRowForLocalY(maxSelY);
|
|
7881
|
+
const selection = this.resolveSelectionResolution(localSelection);
|
|
7882
|
+
const modeChanged = this._lastSelectionMode !== selection.mode;
|
|
7883
|
+
this._lastSelectionMode = selection.mode;
|
|
7884
|
+
const lockToAnchorColumn = selection.mode === "column-locked" && selection.anchorColumn !== null;
|
|
7885
|
+
for (let rowIdx = 0;rowIdx < this._rowCount; rowIdx++) {
|
|
7886
|
+
if (rowIdx < firstRow || rowIdx > lastRow) {
|
|
7887
|
+
this.resetRowSelection(rowIdx);
|
|
7888
|
+
continue;
|
|
7889
|
+
}
|
|
7890
|
+
const cellTop = (this._layout.rowOffsets[rowIdx] ?? 0) + 1 + this._cellPadding;
|
|
7891
|
+
for (let colIdx = 0;colIdx < this._columnCount; colIdx++) {
|
|
7892
|
+
const cell = this._cells[rowIdx]?.[colIdx];
|
|
7893
|
+
if (!cell)
|
|
7894
|
+
continue;
|
|
7895
|
+
if (lockToAnchorColumn && colIdx !== selection.anchorColumn) {
|
|
7896
|
+
cell.textBufferView.resetLocalSelection();
|
|
7897
|
+
continue;
|
|
7898
|
+
}
|
|
7899
|
+
const cellLeft = (this._layout.columnOffsets[colIdx] ?? 0) + 1 + this._cellPadding;
|
|
7900
|
+
let coords = {
|
|
7901
|
+
anchorX: localSelection.anchorX - cellLeft,
|
|
7902
|
+
anchorY: localSelection.anchorY - cellTop,
|
|
7903
|
+
focusX: localSelection.focusX - cellLeft,
|
|
7904
|
+
focusY: localSelection.focusY - cellTop
|
|
7905
|
+
};
|
|
7906
|
+
const isAnchorCell = selection.anchorCell !== null && selection.anchorCell.rowIdx === rowIdx && selection.anchorCell.colIdx === colIdx;
|
|
7907
|
+
const forceSet = isAnchorCell && selection.mode !== "single-cell";
|
|
7908
|
+
if (forceSet) {
|
|
7909
|
+
coords = this.getFullCellSelectionCoords(rowIdx, colIdx);
|
|
7910
|
+
}
|
|
7911
|
+
const shouldUseSet = isStart || modeChanged || forceSet;
|
|
7912
|
+
if (shouldUseSet) {
|
|
7913
|
+
cell.textBufferView.setLocalSelection(coords.anchorX, coords.anchorY, coords.focusX, coords.focusY, this._selectionBg, this._selectionFg);
|
|
7914
|
+
} else {
|
|
7915
|
+
cell.textBufferView.updateLocalSelection(coords.anchorX, coords.anchorY, coords.focusX, coords.focusY, this._selectionBg, this._selectionFg);
|
|
7916
|
+
}
|
|
7917
|
+
}
|
|
7918
|
+
}
|
|
7919
|
+
}
|
|
7920
|
+
resolveSelectionResolution(localSelection) {
|
|
7921
|
+
const anchorCell = this.getCellAtLocalPosition(localSelection.anchorX, localSelection.anchorY);
|
|
7922
|
+
const focusCell = this.getCellAtLocalPosition(localSelection.focusX, localSelection.focusY);
|
|
7923
|
+
const anchorColumn = anchorCell?.colIdx ?? this.getColumnAtLocalX(localSelection.anchorX);
|
|
7924
|
+
if (anchorCell !== null && focusCell !== null && anchorCell.rowIdx === focusCell.rowIdx && anchorCell.colIdx === focusCell.colIdx) {
|
|
7925
|
+
return {
|
|
7926
|
+
mode: "single-cell",
|
|
7927
|
+
anchorCell,
|
|
7928
|
+
anchorColumn
|
|
7929
|
+
};
|
|
7930
|
+
}
|
|
7931
|
+
const focusColumn = this.getColumnAtLocalX(localSelection.focusX);
|
|
7932
|
+
if (anchorColumn !== null && focusColumn === anchorColumn) {
|
|
7933
|
+
return {
|
|
7934
|
+
mode: "column-locked",
|
|
7935
|
+
anchorCell,
|
|
7936
|
+
anchorColumn
|
|
7937
|
+
};
|
|
7938
|
+
}
|
|
7939
|
+
return {
|
|
7940
|
+
mode: "grid",
|
|
7941
|
+
anchorCell,
|
|
7942
|
+
anchorColumn
|
|
7943
|
+
};
|
|
7944
|
+
}
|
|
7945
|
+
getColumnAtLocalX(localX) {
|
|
7946
|
+
if (this._columnCount === 0)
|
|
7947
|
+
return null;
|
|
7948
|
+
if (localX < 0 || localX >= this._layout.tableWidth)
|
|
7949
|
+
return null;
|
|
7950
|
+
for (let colIdx = 0;colIdx < this._columnCount; colIdx++) {
|
|
7951
|
+
const colStart = (this._layout.columnOffsets[colIdx] ?? 0) + 1;
|
|
7952
|
+
const colEnd = colStart + (this._layout.columnWidths[colIdx] ?? 1) - 1;
|
|
7953
|
+
if (localX >= colStart && localX <= colEnd) {
|
|
7954
|
+
return colIdx;
|
|
7955
|
+
}
|
|
7956
|
+
}
|
|
7957
|
+
return null;
|
|
7958
|
+
}
|
|
7959
|
+
getFullCellSelectionCoords(rowIdx, colIdx) {
|
|
7960
|
+
const colWidth = this._layout.columnWidths[colIdx] ?? 1;
|
|
7961
|
+
const rowHeight = this._layout.rowHeights[rowIdx] ?? 1;
|
|
7962
|
+
const contentWidth = Math.max(1, colWidth - this.getHorizontalCellPadding());
|
|
7963
|
+
const contentHeight = Math.max(1, rowHeight - this.getVerticalCellPadding());
|
|
7964
|
+
return {
|
|
7965
|
+
anchorX: -1,
|
|
7966
|
+
anchorY: 0,
|
|
7967
|
+
focusX: contentWidth,
|
|
7968
|
+
focusY: contentHeight
|
|
7969
|
+
};
|
|
7970
|
+
}
|
|
7971
|
+
findRowForLocalY(localY) {
|
|
7972
|
+
if (this._rowCount === 0)
|
|
7973
|
+
return 0;
|
|
7974
|
+
if (localY < 0)
|
|
7975
|
+
return 0;
|
|
7976
|
+
for (let rowIdx = 0;rowIdx < this._rowCount; rowIdx++) {
|
|
7977
|
+
const rowStart = (this._layout.rowOffsets[rowIdx] ?? 0) + 1;
|
|
7978
|
+
const rowEnd = rowStart + (this._layout.rowHeights[rowIdx] ?? 1) - 1;
|
|
7979
|
+
if (localY <= rowEnd)
|
|
7980
|
+
return rowIdx;
|
|
7981
|
+
}
|
|
7982
|
+
return this._rowCount - 1;
|
|
7983
|
+
}
|
|
7984
|
+
getSelectionRowRange(selection) {
|
|
7985
|
+
if (!selection?.isActive || this._rowCount === 0)
|
|
7986
|
+
return null;
|
|
7987
|
+
const minSelY = Math.min(selection.anchorY, selection.focusY);
|
|
7988
|
+
const maxSelY = Math.max(selection.anchorY, selection.focusY);
|
|
7989
|
+
return {
|
|
7990
|
+
firstRow: this.findRowForLocalY(minSelY),
|
|
7991
|
+
lastRow: this.findRowForLocalY(maxSelY)
|
|
7992
|
+
};
|
|
7993
|
+
}
|
|
7994
|
+
getDirtySelectionRowRange(previousSelection, currentSelection) {
|
|
7995
|
+
const previousRange = this.getSelectionRowRange(previousSelection);
|
|
7996
|
+
const currentRange = this.getSelectionRowRange(currentSelection);
|
|
7997
|
+
if (previousRange === null)
|
|
7998
|
+
return currentRange;
|
|
7999
|
+
if (currentRange === null)
|
|
8000
|
+
return previousRange;
|
|
8001
|
+
return {
|
|
8002
|
+
firstRow: Math.min(previousRange.firstRow, currentRange.firstRow),
|
|
8003
|
+
lastRow: Math.max(previousRange.lastRow, currentRange.lastRow)
|
|
8004
|
+
};
|
|
8005
|
+
}
|
|
8006
|
+
resetRowSelection(rowIdx) {
|
|
8007
|
+
const row = this._cells[rowIdx];
|
|
8008
|
+
if (!row)
|
|
8009
|
+
return;
|
|
8010
|
+
for (const cell of row) {
|
|
8011
|
+
cell.textBufferView.resetLocalSelection();
|
|
8012
|
+
}
|
|
8013
|
+
}
|
|
8014
|
+
resetCellSelections() {
|
|
8015
|
+
for (let rowIdx = 0;rowIdx < this._rowCount; rowIdx++) {
|
|
8016
|
+
this.resetRowSelection(rowIdx);
|
|
8017
|
+
}
|
|
8018
|
+
}
|
|
8019
|
+
createEmptyLayout() {
|
|
8020
|
+
return {
|
|
8021
|
+
columnWidths: [],
|
|
8022
|
+
rowHeights: [],
|
|
8023
|
+
columnOffsets: [0],
|
|
8024
|
+
rowOffsets: [0],
|
|
8025
|
+
columnOffsetsI32: new Int32Array([0]),
|
|
8026
|
+
rowOffsetsI32: new Int32Array([0]),
|
|
8027
|
+
tableWidth: 0,
|
|
8028
|
+
tableHeight: 0
|
|
8029
|
+
};
|
|
8030
|
+
}
|
|
8031
|
+
resolveLayoutWidthConstraint(width) {
|
|
8032
|
+
if (width === undefined || !Number.isFinite(width) || width <= 0) {
|
|
8033
|
+
return;
|
|
8034
|
+
}
|
|
8035
|
+
if (this._wrapMode !== "none" || this._columnWidthMode === "fill") {
|
|
8036
|
+
return Math.max(1, Math.floor(width));
|
|
8037
|
+
}
|
|
8038
|
+
return;
|
|
8039
|
+
}
|
|
8040
|
+
getHorizontalCellPadding() {
|
|
8041
|
+
return this._cellPadding * 2;
|
|
8042
|
+
}
|
|
8043
|
+
getVerticalCellPadding() {
|
|
8044
|
+
return this._cellPadding * 2;
|
|
8045
|
+
}
|
|
8046
|
+
resolveCellPadding(value) {
|
|
8047
|
+
if (value === undefined || !Number.isFinite(value)) {
|
|
8048
|
+
return this._defaultOptions.cellPadding;
|
|
8049
|
+
}
|
|
8050
|
+
return Math.max(0, Math.floor(value));
|
|
8051
|
+
}
|
|
8052
|
+
invalidateLayoutAndRaster(markYogaDirty = true) {
|
|
8053
|
+
this._layoutDirty = true;
|
|
8054
|
+
this._rasterDirty = true;
|
|
8055
|
+
this._cachedMeasureLayout = null;
|
|
8056
|
+
this._cachedMeasureWidth = undefined;
|
|
8057
|
+
if (markYogaDirty) {
|
|
8058
|
+
this.yogaNode.markDirty();
|
|
8059
|
+
}
|
|
8060
|
+
this.requestRender();
|
|
8061
|
+
}
|
|
8062
|
+
invalidateRasterOnly() {
|
|
8063
|
+
this._rasterDirty = true;
|
|
8064
|
+
this.requestRender();
|
|
8065
|
+
}
|
|
8066
|
+
}
|
|
8067
|
+
|
|
7162
8068
|
// ../../node_modules/.bun/marked@17.0.1/node_modules/marked/lib/marked.esm.js
|
|
7163
8069
|
function L() {
|
|
7164
8070
|
return { async: false, breaks: false, extensions: null, gfm: true, hooks: null, pedantic: false, renderer: null, silent: false, tokenizer: null, walkTokens: null };
|
|
@@ -8437,10 +9343,10 @@ function parseMarkdownIncremental(newContent, prevState, trailingUnstable = 2) {
|
|
|
8437
9343
|
let offset = 0;
|
|
8438
9344
|
let reuseCount = 0;
|
|
8439
9345
|
for (const token of prevState.tokens) {
|
|
8440
|
-
const
|
|
8441
|
-
if (
|
|
9346
|
+
const tokenLength = token.raw.length;
|
|
9347
|
+
if (offset + tokenLength <= newContent.length && newContent.startsWith(token.raw, offset)) {
|
|
8442
9348
|
reuseCount++;
|
|
8443
|
-
offset
|
|
9349
|
+
offset += tokenLength;
|
|
8444
9350
|
} else {
|
|
8445
9351
|
break;
|
|
8446
9352
|
}
|
|
@@ -8469,6 +9375,7 @@ class MarkdownRenderable extends Renderable {
|
|
|
8469
9375
|
_syntaxStyle;
|
|
8470
9376
|
_conceal;
|
|
8471
9377
|
_treeSitterClient;
|
|
9378
|
+
_tableOptions;
|
|
8472
9379
|
_renderNode;
|
|
8473
9380
|
_parseState = null;
|
|
8474
9381
|
_streaming = false;
|
|
@@ -8489,6 +9396,7 @@ class MarkdownRenderable extends Renderable {
|
|
|
8489
9396
|
this._conceal = options.conceal ?? this._contentDefaultOptions.conceal;
|
|
8490
9397
|
this._content = options.content ?? this._contentDefaultOptions.content;
|
|
8491
9398
|
this._treeSitterClient = options.treeSitterClient;
|
|
9399
|
+
this._tableOptions = options.tableOptions;
|
|
8492
9400
|
this._renderNode = options.renderNode;
|
|
8493
9401
|
this._streaming = options.streaming ?? this._contentDefaultOptions.streaming;
|
|
8494
9402
|
this.updateBlocks();
|
|
@@ -8530,6 +9438,13 @@ class MarkdownRenderable extends Renderable {
|
|
|
8530
9438
|
this.clearCache();
|
|
8531
9439
|
}
|
|
8532
9440
|
}
|
|
9441
|
+
get tableOptions() {
|
|
9442
|
+
return this._tableOptions;
|
|
9443
|
+
}
|
|
9444
|
+
set tableOptions(value) {
|
|
9445
|
+
this._tableOptions = value;
|
|
9446
|
+
this.applyTableOptionsToBlocks();
|
|
9447
|
+
}
|
|
8533
9448
|
getStyle(group) {
|
|
8534
9449
|
if (!this._syntaxStyle)
|
|
8535
9450
|
return;
|
|
@@ -8784,159 +9699,194 @@ class MarkdownRenderable extends Renderable {
|
|
|
8784
9699
|
marginBottom
|
|
8785
9700
|
});
|
|
8786
9701
|
}
|
|
8787
|
-
|
|
8788
|
-
|
|
8789
|
-
|
|
9702
|
+
getTableRowsToRender(table) {
|
|
9703
|
+
return this._streaming && table.rows.length > 0 ? table.rows.slice(0, -1) : table.rows;
|
|
9704
|
+
}
|
|
9705
|
+
hashString(value, seed) {
|
|
9706
|
+
let hash = seed >>> 0;
|
|
9707
|
+
for (let i = 0;i < value.length; i += 1) {
|
|
9708
|
+
hash ^= value.charCodeAt(i);
|
|
9709
|
+
hash = Math.imul(hash, 16777619);
|
|
9710
|
+
}
|
|
9711
|
+
return hash >>> 0;
|
|
9712
|
+
}
|
|
9713
|
+
hashTableToken(token, seed, depth = 0) {
|
|
9714
|
+
let hash = this.hashString(token.type, seed);
|
|
9715
|
+
if ("raw" in token && typeof token.raw === "string") {
|
|
9716
|
+
return this.hashString(token.raw, hash);
|
|
9717
|
+
}
|
|
9718
|
+
if ("text" in token && typeof token.text === "string") {
|
|
9719
|
+
hash = this.hashString(token.text, hash);
|
|
9720
|
+
}
|
|
9721
|
+
if (depth < 2 && "tokens" in token && Array.isArray(token.tokens)) {
|
|
9722
|
+
for (const child of token.tokens) {
|
|
9723
|
+
hash = this.hashTableToken(child, hash, depth + 1);
|
|
9724
|
+
}
|
|
9725
|
+
}
|
|
9726
|
+
return hash >>> 0;
|
|
9727
|
+
}
|
|
9728
|
+
getTableCellKey(cell, isHeader) {
|
|
9729
|
+
const seed = isHeader ? 2902232141 : 1371922141;
|
|
9730
|
+
if (!cell) {
|
|
9731
|
+
return seed;
|
|
9732
|
+
}
|
|
9733
|
+
if (typeof cell.text === "string") {
|
|
9734
|
+
return this.hashString(cell.text, seed);
|
|
9735
|
+
}
|
|
9736
|
+
if (Array.isArray(cell.tokens) && cell.tokens.length > 0) {
|
|
9737
|
+
let hash = seed ^ cell.tokens.length;
|
|
9738
|
+
for (const token of cell.tokens) {
|
|
9739
|
+
hash = this.hashTableToken(token, hash);
|
|
9740
|
+
}
|
|
9741
|
+
return hash >>> 0;
|
|
9742
|
+
}
|
|
9743
|
+
return (seed ^ 2654435769) >>> 0;
|
|
9744
|
+
}
|
|
9745
|
+
createTableDataCellChunks(cell) {
|
|
9746
|
+
const chunks = [];
|
|
9747
|
+
if (cell) {
|
|
9748
|
+
this.renderInlineContent(cell.tokens, chunks);
|
|
9749
|
+
}
|
|
9750
|
+
return chunks.length > 0 ? chunks : [this.createDefaultChunk(" ")];
|
|
9751
|
+
}
|
|
9752
|
+
createTableHeaderCellChunks(cell) {
|
|
9753
|
+
const chunks = [];
|
|
9754
|
+
this.renderInlineContent(cell.tokens, chunks);
|
|
9755
|
+
const baseChunks = chunks.length > 0 ? chunks : [this.createDefaultChunk(" ")];
|
|
8790
9756
|
const headingStyle = this.getStyle("markup.heading") || this.getStyle("default");
|
|
8791
|
-
|
|
9757
|
+
if (!headingStyle) {
|
|
9758
|
+
return baseChunks;
|
|
9759
|
+
}
|
|
9760
|
+
const headingAttributes = createTextAttributes({
|
|
9761
|
+
bold: headingStyle.bold,
|
|
9762
|
+
italic: headingStyle.italic,
|
|
9763
|
+
underline: headingStyle.underline,
|
|
9764
|
+
dim: headingStyle.dim
|
|
9765
|
+
});
|
|
9766
|
+
return baseChunks.map((chunk) => ({
|
|
9767
|
+
...chunk,
|
|
9768
|
+
fg: headingStyle.fg ?? chunk.fg,
|
|
9769
|
+
bg: headingStyle.bg ?? chunk.bg,
|
|
9770
|
+
attributes: headingAttributes
|
|
9771
|
+
}));
|
|
9772
|
+
}
|
|
9773
|
+
buildTableContentCache(table, previous, forceRegenerate = false) {
|
|
8792
9774
|
const colCount = table.header.length;
|
|
8793
|
-
const
|
|
8794
|
-
|
|
8795
|
-
|
|
8796
|
-
|
|
8797
|
-
|
|
8798
|
-
|
|
8799
|
-
|
|
8800
|
-
|
|
8801
|
-
|
|
8802
|
-
const
|
|
8803
|
-
|
|
8804
|
-
|
|
8805
|
-
const
|
|
8806
|
-
const
|
|
8807
|
-
|
|
8808
|
-
|
|
8809
|
-
|
|
8810
|
-
|
|
8811
|
-
|
|
8812
|
-
|
|
8813
|
-
|
|
8814
|
-
|
|
8815
|
-
|
|
8816
|
-
|
|
8817
|
-
|
|
8818
|
-
|
|
8819
|
-
|
|
8820
|
-
|
|
8821
|
-
|
|
8822
|
-
|
|
8823
|
-
|
|
8824
|
-
}
|
|
8825
|
-
|
|
8826
|
-
|
|
8827
|
-
|
|
8828
|
-
|
|
8829
|
-
if (cellContainer instanceof BoxRenderable) {
|
|
8830
|
-
cellContainer.borderColor = borderColor;
|
|
8831
|
-
const cellChildren = cellContainer._childrenInLayoutOrder;
|
|
8832
|
-
cellText = cellChildren[0];
|
|
8833
|
-
} else if (cellContainer instanceof TextRenderable) {
|
|
8834
|
-
cellText = cellContainer;
|
|
8835
|
-
}
|
|
8836
|
-
if (cellText) {
|
|
8837
|
-
const cell = rowsToRender[row][col];
|
|
8838
|
-
const cellChunks = [];
|
|
8839
|
-
if (cell) {
|
|
8840
|
-
this.renderInlineContent(cell.tokens, cellChunks);
|
|
9775
|
+
const rowsToRender = this.getTableRowsToRender(table);
|
|
9776
|
+
if (colCount === 0 || rowsToRender.length === 0) {
|
|
9777
|
+
return { cache: null, changed: previous !== undefined };
|
|
9778
|
+
}
|
|
9779
|
+
const content = [];
|
|
9780
|
+
const cellKeys = [];
|
|
9781
|
+
const totalRows = rowsToRender.length + 1;
|
|
9782
|
+
let changed = forceRegenerate || !previous;
|
|
9783
|
+
for (let rowIndex = 0;rowIndex < totalRows; rowIndex += 1) {
|
|
9784
|
+
const rowContent = [];
|
|
9785
|
+
const rowKeys = new Uint32Array(colCount);
|
|
9786
|
+
for (let colIndex = 0;colIndex < colCount; colIndex += 1) {
|
|
9787
|
+
const isHeader = rowIndex === 0;
|
|
9788
|
+
const cell = isHeader ? table.header[colIndex] : rowsToRender[rowIndex - 1]?.[colIndex];
|
|
9789
|
+
const cellKey = this.getTableCellKey(cell, isHeader);
|
|
9790
|
+
rowKeys[colIndex] = cellKey;
|
|
9791
|
+
const previousCellKey = previous?.cellKeys[rowIndex]?.[colIndex];
|
|
9792
|
+
const previousCellContent = previous?.content[rowIndex]?.[colIndex];
|
|
9793
|
+
if (!forceRegenerate && previousCellKey === cellKey && Array.isArray(previousCellContent)) {
|
|
9794
|
+
rowContent.push(previousCellContent);
|
|
9795
|
+
continue;
|
|
9796
|
+
}
|
|
9797
|
+
changed = true;
|
|
9798
|
+
rowContent.push(isHeader ? this.createTableHeaderCellChunks(table.header[colIndex]) : this.createTableDataCellChunks(cell));
|
|
9799
|
+
}
|
|
9800
|
+
content.push(rowContent);
|
|
9801
|
+
cellKeys.push(rowKeys);
|
|
9802
|
+
}
|
|
9803
|
+
if (previous && !changed) {
|
|
9804
|
+
if (previous.content.length !== content.length) {
|
|
9805
|
+
changed = true;
|
|
9806
|
+
} else {
|
|
9807
|
+
for (let rowIndex = 0;rowIndex < content.length; rowIndex += 1) {
|
|
9808
|
+
if ((previous.content[rowIndex]?.length ?? 0) !== content[rowIndex].length) {
|
|
9809
|
+
changed = true;
|
|
9810
|
+
break;
|
|
8841
9811
|
}
|
|
8842
|
-
cellText.content = new StyledText(cellChunks.length > 0 ? cellChunks : [this.createDefaultChunk(" ")]);
|
|
8843
9812
|
}
|
|
8844
9813
|
}
|
|
8845
9814
|
}
|
|
9815
|
+
return {
|
|
9816
|
+
cache: {
|
|
9817
|
+
content,
|
|
9818
|
+
cellKeys
|
|
9819
|
+
},
|
|
9820
|
+
changed
|
|
9821
|
+
};
|
|
8846
9822
|
}
|
|
8847
|
-
|
|
8848
|
-
const
|
|
8849
|
-
|
|
8850
|
-
|
|
8851
|
-
|
|
9823
|
+
resolveTableRenderableOptions() {
|
|
9824
|
+
const borders = this._tableOptions?.borders ?? true;
|
|
9825
|
+
return {
|
|
9826
|
+
columnWidthMode: this._tableOptions?.widthMode ?? "content",
|
|
9827
|
+
wrapMode: this._tableOptions?.wrapMode ?? "none",
|
|
9828
|
+
cellPadding: this._tableOptions?.cellPadding ?? 0,
|
|
9829
|
+
border: borders,
|
|
9830
|
+
outerBorder: this._tableOptions?.outerBorder ?? borders,
|
|
9831
|
+
showBorders: borders,
|
|
9832
|
+
borderStyle: this._tableOptions?.borderStyle ?? "single",
|
|
9833
|
+
borderColor: this._tableOptions?.borderColor ?? this.getStyle("conceal")?.fg ?? "#888888",
|
|
9834
|
+
selectable: this._tableOptions?.selectable ?? true
|
|
9835
|
+
};
|
|
9836
|
+
}
|
|
9837
|
+
applyTableRenderableOptions(tableRenderable, options) {
|
|
9838
|
+
tableRenderable.columnWidthMode = options.columnWidthMode;
|
|
9839
|
+
tableRenderable.wrapMode = options.wrapMode;
|
|
9840
|
+
tableRenderable.cellPadding = options.cellPadding;
|
|
9841
|
+
tableRenderable.border = options.border;
|
|
9842
|
+
tableRenderable.outerBorder = options.outerBorder;
|
|
9843
|
+
tableRenderable.showBorders = options.showBorders;
|
|
9844
|
+
tableRenderable.borderStyle = options.borderStyle;
|
|
9845
|
+
tableRenderable.borderColor = options.borderColor;
|
|
9846
|
+
tableRenderable.selectable = options.selectable;
|
|
9847
|
+
}
|
|
9848
|
+
applyTableOptionsToBlocks() {
|
|
9849
|
+
const options = this.resolveTableRenderableOptions();
|
|
9850
|
+
let updated = false;
|
|
9851
|
+
for (const state of this._blockStates) {
|
|
9852
|
+
if (state.renderable instanceof TextTableRenderable) {
|
|
9853
|
+
this.applyTableRenderableOptions(state.renderable, options);
|
|
9854
|
+
updated = true;
|
|
9855
|
+
}
|
|
8852
9856
|
}
|
|
8853
|
-
|
|
9857
|
+
if (updated) {
|
|
9858
|
+
this.requestRender();
|
|
9859
|
+
}
|
|
9860
|
+
}
|
|
9861
|
+
createTextTableRenderable(content, id, marginBottom = 0) {
|
|
9862
|
+
const options = this.resolveTableRenderableOptions();
|
|
9863
|
+
return new TextTableRenderable(this.ctx, {
|
|
8854
9864
|
id,
|
|
8855
|
-
|
|
8856
|
-
|
|
9865
|
+
content,
|
|
9866
|
+
width: "100%",
|
|
9867
|
+
marginBottom,
|
|
9868
|
+
columnWidthMode: options.columnWidthMode,
|
|
9869
|
+
wrapMode: options.wrapMode,
|
|
9870
|
+
cellPadding: options.cellPadding,
|
|
9871
|
+
border: options.border,
|
|
9872
|
+
outerBorder: options.outerBorder,
|
|
9873
|
+
showBorders: options.showBorders,
|
|
9874
|
+
borderStyle: options.borderStyle,
|
|
9875
|
+
borderColor: options.borderColor,
|
|
9876
|
+
selectable: options.selectable
|
|
8857
9877
|
});
|
|
8858
|
-
|
|
8859
|
-
|
|
8860
|
-
|
|
8861
|
-
|
|
8862
|
-
|
|
8863
|
-
|
|
8864
|
-
|
|
8865
|
-
border: isLastCol ? true : ["top", "bottom", "left"],
|
|
8866
|
-
borderColor,
|
|
8867
|
-
customBorderChars: isFirstCol ? undefined : {
|
|
8868
|
-
topLeft: "\u252C",
|
|
8869
|
-
topRight: "\u2510",
|
|
8870
|
-
bottomLeft: "\u2534",
|
|
8871
|
-
bottomRight: "\u2518",
|
|
8872
|
-
horizontal: "\u2500",
|
|
8873
|
-
vertical: "\u2502",
|
|
8874
|
-
topT: "\u252C",
|
|
8875
|
-
bottomT: "\u2534",
|
|
8876
|
-
leftT: "\u251C",
|
|
8877
|
-
rightT: "\u2524",
|
|
8878
|
-
cross: "\u253C"
|
|
8879
|
-
}
|
|
8880
|
-
});
|
|
8881
|
-
const headerCell = table.header[col];
|
|
8882
|
-
const headerChunks = [];
|
|
8883
|
-
this.renderInlineContent(headerCell.tokens, headerChunks);
|
|
8884
|
-
const headingStyle = this.getStyle("markup.heading") || this.getStyle("default");
|
|
8885
|
-
const styledHeaderChunks = headerChunks.map((chunk) => ({
|
|
8886
|
-
...chunk,
|
|
8887
|
-
fg: headingStyle?.fg ?? chunk.fg,
|
|
8888
|
-
bg: headingStyle?.bg ?? chunk.bg,
|
|
8889
|
-
attributes: headingStyle ? createTextAttributes({
|
|
8890
|
-
bold: headingStyle.bold,
|
|
8891
|
-
italic: headingStyle.italic,
|
|
8892
|
-
underline: headingStyle.underline,
|
|
8893
|
-
dim: headingStyle.dim
|
|
8894
|
-
}) : chunk.attributes
|
|
8895
|
-
}));
|
|
8896
|
-
const headerBox = new BoxRenderable(this.ctx, {
|
|
8897
|
-
id: `${id}-col-${col}-header-box`,
|
|
8898
|
-
border: ["bottom"],
|
|
8899
|
-
borderColor
|
|
8900
|
-
});
|
|
8901
|
-
headerBox.add(new TextRenderable(this.ctx, {
|
|
8902
|
-
id: `${id}-col-${col}-header`,
|
|
8903
|
-
content: new StyledText(styledHeaderChunks),
|
|
8904
|
-
height: 1,
|
|
8905
|
-
overflow: "hidden",
|
|
8906
|
-
paddingLeft: 1,
|
|
8907
|
-
paddingRight: 1
|
|
8908
|
-
}));
|
|
8909
|
-
columnBox.add(headerBox);
|
|
8910
|
-
for (let row = 0;row < rowsToRender.length; row++) {
|
|
8911
|
-
const cell = rowsToRender[row][col];
|
|
8912
|
-
const cellChunks = [];
|
|
8913
|
-
if (cell) {
|
|
8914
|
-
this.renderInlineContent(cell.tokens, cellChunks);
|
|
8915
|
-
}
|
|
8916
|
-
const isLastRow = row === rowsToRender.length - 1;
|
|
8917
|
-
const cellText = new TextRenderable(this.ctx, {
|
|
8918
|
-
id: `${id}-col-${col}-row-${row}`,
|
|
8919
|
-
content: new StyledText(cellChunks.length > 0 ? cellChunks : [this.createDefaultChunk(" ")]),
|
|
8920
|
-
height: 1,
|
|
8921
|
-
overflow: "hidden",
|
|
8922
|
-
paddingLeft: 1,
|
|
8923
|
-
paddingRight: 1
|
|
8924
|
-
});
|
|
8925
|
-
if (isLastRow) {
|
|
8926
|
-
columnBox.add(cellText);
|
|
8927
|
-
} else {
|
|
8928
|
-
const cellBox = new BoxRenderable(this.ctx, {
|
|
8929
|
-
id: `${id}-col-${col}-row-${row}-box`,
|
|
8930
|
-
border: ["bottom"],
|
|
8931
|
-
borderColor
|
|
8932
|
-
});
|
|
8933
|
-
cellBox.add(cellText);
|
|
8934
|
-
columnBox.add(cellBox);
|
|
8935
|
-
}
|
|
8936
|
-
}
|
|
8937
|
-
tableBox.add(columnBox);
|
|
9878
|
+
}
|
|
9879
|
+
createTableBlock(table, id, marginBottom = 0, previousCache, forceRegenerate = false) {
|
|
9880
|
+
const { cache } = this.buildTableContentCache(table, previousCache, forceRegenerate);
|
|
9881
|
+
if (!cache) {
|
|
9882
|
+
return {
|
|
9883
|
+
renderable: this.createTextRenderable([this.createDefaultChunk(table.raw)], id, marginBottom)
|
|
9884
|
+
};
|
|
8938
9885
|
}
|
|
8939
|
-
return
|
|
9886
|
+
return {
|
|
9887
|
+
renderable: this.createTextTableRenderable(cache.content, id, marginBottom),
|
|
9888
|
+
tableContentCache: cache
|
|
9889
|
+
};
|
|
8940
9890
|
}
|
|
8941
9891
|
createDefaultRenderable(token, index, hasNextToken = false) {
|
|
8942
9892
|
const id = `${this.id}-block-${index}`;
|
|
@@ -8945,7 +9895,7 @@ class MarkdownRenderable extends Renderable {
|
|
|
8945
9895
|
return this.createCodeRenderable(token, id, marginBottom);
|
|
8946
9896
|
}
|
|
8947
9897
|
if (token.type === "table") {
|
|
8948
|
-
return this.
|
|
9898
|
+
return this.createTableBlock(token, id, marginBottom).renderable;
|
|
8949
9899
|
}
|
|
8950
9900
|
if (token.type === "space") {
|
|
8951
9901
|
return null;
|
|
@@ -8969,26 +9919,39 @@ class MarkdownRenderable extends Renderable {
|
|
|
8969
9919
|
return;
|
|
8970
9920
|
}
|
|
8971
9921
|
if (token.type === "table") {
|
|
8972
|
-
const
|
|
8973
|
-
const
|
|
8974
|
-
if (
|
|
8975
|
-
const
|
|
8976
|
-
|
|
8977
|
-
|
|
8978
|
-
|
|
8979
|
-
if (prevCompleteRows === newCompleteRows && prevTable.header.length === newTable.header.length) {
|
|
8980
|
-
if (prevIsRawFallback && newIsRawFallback && prevTable.raw !== newTable.raw) {
|
|
8981
|
-
const textRenderable2 = state.renderable;
|
|
8982
|
-
textRenderable2.content = new StyledText([this.createDefaultChunk(newTable.raw)]);
|
|
8983
|
-
textRenderable2.marginBottom = marginBottom;
|
|
9922
|
+
const tableToken = token;
|
|
9923
|
+
const { cache, changed } = this.buildTableContentCache(tableToken, state.tableContentCache);
|
|
9924
|
+
if (!cache) {
|
|
9925
|
+
const fallbackChunks = [this.createDefaultChunk(tableToken.raw)];
|
|
9926
|
+
if (state.renderable instanceof TextRenderable) {
|
|
9927
|
+
if (state.tokenRaw !== tableToken.raw) {
|
|
9928
|
+
state.renderable.content = new StyledText(fallbackChunks);
|
|
8984
9929
|
}
|
|
9930
|
+
state.renderable.marginBottom = marginBottom;
|
|
9931
|
+
state.tableContentCache = undefined;
|
|
8985
9932
|
return;
|
|
8986
9933
|
}
|
|
9934
|
+
state.renderable.destroyRecursively();
|
|
9935
|
+
const fallbackRenderable = this.createTextRenderable(fallbackChunks, `${this.id}-block-${index}`, marginBottom);
|
|
9936
|
+
this.add(fallbackRenderable);
|
|
9937
|
+
state.renderable = fallbackRenderable;
|
|
9938
|
+
state.tableContentCache = undefined;
|
|
9939
|
+
return;
|
|
8987
9940
|
}
|
|
8988
|
-
|
|
8989
|
-
|
|
8990
|
-
|
|
8991
|
-
|
|
9941
|
+
if (state.renderable instanceof TextTableRenderable) {
|
|
9942
|
+
if (changed) {
|
|
9943
|
+
state.renderable.content = cache.content;
|
|
9944
|
+
}
|
|
9945
|
+
this.applyTableRenderableOptions(state.renderable, this.resolveTableRenderableOptions());
|
|
9946
|
+
state.renderable.marginBottom = marginBottom;
|
|
9947
|
+
state.tableContentCache = cache;
|
|
9948
|
+
return;
|
|
9949
|
+
}
|
|
9950
|
+
state.renderable.destroyRecursively();
|
|
9951
|
+
const tableRenderable = this.createTextTableRenderable(cache.content, `${this.id}-block-${index}`, marginBottom);
|
|
9952
|
+
this.add(tableRenderable);
|
|
9953
|
+
state.renderable = tableRenderable;
|
|
9954
|
+
state.tableContentCache = cache;
|
|
8992
9955
|
return;
|
|
8993
9956
|
}
|
|
8994
9957
|
const textRenderable = state.renderable;
|
|
@@ -8998,10 +9961,7 @@ class MarkdownRenderable extends Renderable {
|
|
|
8998
9961
|
}
|
|
8999
9962
|
updateBlocks() {
|
|
9000
9963
|
if (!this._content) {
|
|
9001
|
-
|
|
9002
|
-
this.remove(state.renderable.id);
|
|
9003
|
-
}
|
|
9004
|
-
this._blockStates = [];
|
|
9964
|
+
this.clearBlockStates();
|
|
9005
9965
|
this._parseState = null;
|
|
9006
9966
|
return;
|
|
9007
9967
|
}
|
|
@@ -9009,9 +9969,7 @@ class MarkdownRenderable extends Renderable {
|
|
|
9009
9969
|
this._parseState = parseMarkdownIncremental(this._content, this._parseState, trailingUnstable);
|
|
9010
9970
|
const tokens = this._parseState.tokens;
|
|
9011
9971
|
if (tokens.length === 0 && this._content.length > 0) {
|
|
9012
|
-
|
|
9013
|
-
this.remove(state.renderable.id);
|
|
9014
|
-
}
|
|
9972
|
+
this.clearBlockStates();
|
|
9015
9973
|
const text = this.createTextRenderable([this.createDefaultChunk(this._content)], `${this.id}-fallback`);
|
|
9016
9974
|
this.add(text);
|
|
9017
9975
|
this._blockStates = [
|
|
@@ -9052,9 +10010,10 @@ class MarkdownRenderable extends Renderable {
|
|
|
9052
10010
|
continue;
|
|
9053
10011
|
}
|
|
9054
10012
|
if (existing) {
|
|
9055
|
-
|
|
10013
|
+
existing.renderable.destroyRecursively();
|
|
9056
10014
|
}
|
|
9057
10015
|
let renderable;
|
|
10016
|
+
let tableContentCache;
|
|
9058
10017
|
if (this._renderNode) {
|
|
9059
10018
|
const context = {
|
|
9060
10019
|
syntaxStyle: this._syntaxStyle,
|
|
@@ -9068,26 +10027,37 @@ class MarkdownRenderable extends Renderable {
|
|
|
9068
10027
|
}
|
|
9069
10028
|
}
|
|
9070
10029
|
if (!renderable) {
|
|
9071
|
-
|
|
10030
|
+
if (token.type === "table") {
|
|
10031
|
+
const tableBlock = this.createTableBlock(token, `${this.id}-block-${blockIndex}`, hasNextToken ? 1 : 0);
|
|
10032
|
+
renderable = tableBlock.renderable;
|
|
10033
|
+
tableContentCache = tableBlock.tableContentCache;
|
|
10034
|
+
} else {
|
|
10035
|
+
renderable = this.createDefaultRenderable(token, blockIndex, hasNextToken) ?? undefined;
|
|
10036
|
+
}
|
|
10037
|
+
}
|
|
10038
|
+
if (token.type === "table" && !tableContentCache && renderable instanceof TextTableRenderable) {
|
|
10039
|
+
const { cache } = this.buildTableContentCache(token);
|
|
10040
|
+
tableContentCache = cache ?? undefined;
|
|
9072
10041
|
}
|
|
9073
10042
|
if (renderable) {
|
|
9074
10043
|
this.add(renderable);
|
|
9075
10044
|
this._blockStates[blockIndex] = {
|
|
9076
10045
|
token,
|
|
9077
10046
|
tokenRaw: token.raw,
|
|
9078
|
-
renderable
|
|
10047
|
+
renderable,
|
|
10048
|
+
tableContentCache
|
|
9079
10049
|
};
|
|
9080
10050
|
}
|
|
9081
10051
|
blockIndex++;
|
|
9082
10052
|
}
|
|
9083
10053
|
while (this._blockStates.length > blockIndex) {
|
|
9084
10054
|
const removed = this._blockStates.pop();
|
|
9085
|
-
|
|
10055
|
+
removed.renderable.destroyRecursively();
|
|
9086
10056
|
}
|
|
9087
10057
|
}
|
|
9088
10058
|
clearBlockStates() {
|
|
9089
10059
|
for (const state of this._blockStates) {
|
|
9090
|
-
|
|
10060
|
+
state.renderable.destroyRecursively();
|
|
9091
10061
|
}
|
|
9092
10062
|
this._blockStates = [];
|
|
9093
10063
|
}
|
|
@@ -9100,8 +10070,32 @@ class MarkdownRenderable extends Renderable {
|
|
|
9100
10070
|
codeRenderable.syntaxStyle = this._syntaxStyle;
|
|
9101
10071
|
codeRenderable.conceal = this._conceal;
|
|
9102
10072
|
} else if (state.token.type === "table") {
|
|
10073
|
+
const tableToken = state.token;
|
|
9103
10074
|
const marginBottom = hasNextToken ? 1 : 0;
|
|
9104
|
-
this.
|
|
10075
|
+
const { cache } = this.buildTableContentCache(tableToken, state.tableContentCache, true);
|
|
10076
|
+
if (!cache) {
|
|
10077
|
+
if (state.renderable instanceof TextRenderable) {
|
|
10078
|
+
state.renderable.content = new StyledText([this.createDefaultChunk(tableToken.raw)]);
|
|
10079
|
+
state.renderable.marginBottom = marginBottom;
|
|
10080
|
+
} else {
|
|
10081
|
+
state.renderable.destroyRecursively();
|
|
10082
|
+
const fallbackRenderable = this.createTextRenderable([this.createDefaultChunk(tableToken.raw)], `${this.id}-block-${i}`, marginBottom);
|
|
10083
|
+
this.add(fallbackRenderable);
|
|
10084
|
+
state.renderable = fallbackRenderable;
|
|
10085
|
+
}
|
|
10086
|
+
state.tableContentCache = undefined;
|
|
10087
|
+
} else if (state.renderable instanceof TextTableRenderable) {
|
|
10088
|
+
state.renderable.content = cache.content;
|
|
10089
|
+
this.applyTableRenderableOptions(state.renderable, this.resolveTableRenderableOptions());
|
|
10090
|
+
state.renderable.marginBottom = marginBottom;
|
|
10091
|
+
state.tableContentCache = cache;
|
|
10092
|
+
} else {
|
|
10093
|
+
state.renderable.destroyRecursively();
|
|
10094
|
+
const tableRenderable = this.createTextTableRenderable(cache.content, `${this.id}-block-${i}`, marginBottom);
|
|
10095
|
+
this.add(tableRenderable);
|
|
10096
|
+
state.renderable = tableRenderable;
|
|
10097
|
+
state.tableContentCache = cache;
|
|
10098
|
+
}
|
|
9105
10099
|
} else {
|
|
9106
10100
|
const textRenderable = state.renderable;
|
|
9107
10101
|
const chunks = this.renderTokenToChunks(state.token);
|
|
@@ -9117,6 +10111,11 @@ class MarkdownRenderable extends Renderable {
|
|
|
9117
10111
|
this.updateBlocks();
|
|
9118
10112
|
this.requestRender();
|
|
9119
10113
|
}
|
|
10114
|
+
refreshStyles() {
|
|
10115
|
+
this._styleDirty = false;
|
|
10116
|
+
this.rerenderBlocks();
|
|
10117
|
+
this.requestRender();
|
|
10118
|
+
}
|
|
9120
10119
|
renderSelf(buffer, deltaTime) {
|
|
9121
10120
|
if (this._styleDirty) {
|
|
9122
10121
|
this._styleDirty = false;
|
|
@@ -11128,6 +12127,7 @@ export {
|
|
|
11128
12127
|
TreeSitterClient,
|
|
11129
12128
|
Timeline,
|
|
11130
12129
|
TextareaRenderable,
|
|
12130
|
+
TextTableRenderable,
|
|
11131
12131
|
TextRenderable,
|
|
11132
12132
|
TextNodeRenderable,
|
|
11133
12133
|
TextBufferView,
|
|
@@ -11206,5 +12206,5 @@ export {
|
|
|
11206
12206
|
ASCIIFont
|
|
11207
12207
|
};
|
|
11208
12208
|
|
|
11209
|
-
//# debugId=
|
|
12209
|
+
//# debugId=0C8001DA726AC37664756E2164756E21
|
|
11210
12210
|
//# sourceMappingURL=index.js.map
|