@fairyhunter13/opentui-core 0.1.130 → 0.1.132
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/{index-3dryhc1d.js → index-gwfqqvw5.js} +335 -1663
- package/index-gwfqqvw5.js.map +35 -0
- package/{index-pr4swpf9.js → index-t3rrpex7.js} +2894 -298
- package/{index-pr4swpf9.js.map → index-t3rrpex7.js.map} +15 -7
- package/{index-983h7jnd.js → index-t54p24hr.js} +3 -3
- package/index.js +13 -13
- package/index.js.map +1 -1
- package/lib/render-geometry.d.ts +8 -0
- package/lib/stdin-parser.d.ts +2 -1
- package/package.json +7 -7
- package/renderables/Markdown.d.ts +30 -0
- package/renderables/TextBufferRenderable.d.ts +1 -0
- package/renderables/TextTable.d.ts +7 -0
- package/renderables/markdown-parser.d.ts +1 -0
- package/renderer.d.ts +72 -1
- package/runtime-plugin-support.js +3 -3
- package/runtime-plugin.js +3 -3
- package/testing.js +7 -4
- package/testing.js.map +3 -3
- package/text-buffer-view.d.ts +1 -0
- package/types.d.ts +1 -0
- package/zig.d.ts +8 -0
- package/index-3dryhc1d.js.map +0 -42
- /package/{index-983h7jnd.js.map → index-t54p24hr.js.map} +0 -0
|
@@ -6867,7 +6867,8 @@ var DEFAULT_PROTOCOL_CONTEXT = {
|
|
|
6867
6867
|
kittyKeyboardEnabled: false,
|
|
6868
6868
|
privateCapabilityRepliesActive: false,
|
|
6869
6869
|
pixelResolutionQueryActive: false,
|
|
6870
|
-
explicitWidthCprActive: false
|
|
6870
|
+
explicitWidthCprActive: false,
|
|
6871
|
+
startupCursorCprActive: false
|
|
6871
6872
|
};
|
|
6872
6873
|
var RXVT_DOLLAR_CSI_RE = /^\x1b\[\d+\$$/;
|
|
6873
6874
|
var SYSTEM_CLOCK = new SystemClock;
|
|
@@ -7056,11 +7057,14 @@ function canStillBeKittySpecial(state) {
|
|
|
7056
7057
|
function canStillBeExplicitWidthCpr(state) {
|
|
7057
7058
|
return state.firstParamValue === 1 && state.semicolons === 1;
|
|
7058
7059
|
}
|
|
7060
|
+
function canStillBeStartupCursorCpr(state) {
|
|
7061
|
+
return state.semicolons === 1;
|
|
7062
|
+
}
|
|
7059
7063
|
function canStillBePixelResolution(state) {
|
|
7060
7064
|
return state.firstParamValue === 4 && state.semicolons === 2;
|
|
7061
7065
|
}
|
|
7062
7066
|
function canDeferParametricCsi(state, context) {
|
|
7063
|
-
return context.kittyKeyboardEnabled && (canStillBeKittyU(state) || canStillBeKittySpecial(state)) || context.explicitWidthCprActive && canStillBeExplicitWidthCpr(state) || context.pixelResolutionQueryActive && canStillBePixelResolution(state);
|
|
7067
|
+
return context.kittyKeyboardEnabled && (canStillBeKittyU(state) || canStillBeKittySpecial(state)) || context.explicitWidthCprActive && canStillBeExplicitWidthCpr(state) || context.startupCursorCprActive && canStillBeStartupCursorCpr(state) || context.pixelResolutionQueryActive && canStillBePixelResolution(state);
|
|
7064
7068
|
}
|
|
7065
7069
|
function canCompleteDeferredParametricCsi(state, byte, context) {
|
|
7066
7070
|
if (context.kittyKeyboardEnabled) {
|
|
@@ -7073,11 +7077,20 @@ function canCompleteDeferredParametricCsi(state, byte, context) {
|
|
|
7073
7077
|
if (context.explicitWidthCprActive && state.hasDigit && state.firstParamValue === 1 && state.semicolons === 1 && byte === 82) {
|
|
7074
7078
|
return true;
|
|
7075
7079
|
}
|
|
7080
|
+
if (context.startupCursorCprActive && state.hasDigit && state.semicolons === 1 && byte === 82) {
|
|
7081
|
+
return true;
|
|
7082
|
+
}
|
|
7076
7083
|
if (context.pixelResolutionQueryActive && state.hasDigit && state.firstParamValue === 4 && state.semicolons === 2 && byte === 116) {
|
|
7077
7084
|
return true;
|
|
7078
7085
|
}
|
|
7079
7086
|
return false;
|
|
7080
7087
|
}
|
|
7088
|
+
function classifyParametricCsiProtocol(state, finalByte) {
|
|
7089
|
+
if (finalByte === 82 && state.semicolons === 1 && state.segments === 1 && state.hasDigit) {
|
|
7090
|
+
return "cpr";
|
|
7091
|
+
}
|
|
7092
|
+
return "csi";
|
|
7093
|
+
}
|
|
7081
7094
|
function canDeferPrivateReplyCsi(context) {
|
|
7082
7095
|
return context.privateCapabilityRepliesActive;
|
|
7083
7096
|
}
|
|
@@ -7184,7 +7197,8 @@ class StdinParser {
|
|
|
7184
7197
|
kittyKeyboardEnabled: options.protocolContext?.kittyKeyboardEnabled ?? false,
|
|
7185
7198
|
privateCapabilityRepliesActive: options.protocolContext?.privateCapabilityRepliesActive ?? false,
|
|
7186
7199
|
pixelResolutionQueryActive: options.protocolContext?.pixelResolutionQueryActive ?? false,
|
|
7187
|
-
explicitWidthCprActive: options.protocolContext?.explicitWidthCprActive ?? false
|
|
7200
|
+
explicitWidthCprActive: options.protocolContext?.explicitWidthCprActive ?? false,
|
|
7201
|
+
startupCursorCprActive: options.protocolContext?.startupCursorCprActive ?? false
|
|
7188
7202
|
};
|
|
7189
7203
|
}
|
|
7190
7204
|
get bufferCapacity() {
|
|
@@ -7686,7 +7700,8 @@ class StdinParser {
|
|
|
7686
7700
|
}
|
|
7687
7701
|
if (byte >= 64 && byte <= 126) {
|
|
7688
7702
|
const end = this.cursor + 1;
|
|
7689
|
-
|
|
7703
|
+
const protocol = classifyParametricCsiProtocol(this.state, byte);
|
|
7704
|
+
this.emitKeyOrResponse(protocol, decodeUtf8(bytes.subarray(this.unitStart, end)));
|
|
7690
7705
|
this.state = { tag: "ground" };
|
|
7691
7706
|
this.consumePrefix(end);
|
|
7692
7707
|
continue;
|
|
@@ -11895,6 +11910,10 @@ function getOpenTUILib(libPath) {
|
|
|
11895
11910
|
args: ["ptr", "bool"],
|
|
11896
11911
|
returns: "void"
|
|
11897
11912
|
},
|
|
11913
|
+
setClearOnShutdown: {
|
|
11914
|
+
args: ["ptr", "bool"],
|
|
11915
|
+
returns: "void"
|
|
11916
|
+
},
|
|
11898
11917
|
setBackgroundColor: {
|
|
11899
11918
|
args: ["ptr", "ptr"],
|
|
11900
11919
|
returns: "void"
|
|
@@ -11903,6 +11922,22 @@ function getOpenTUILib(libPath) {
|
|
|
11903
11922
|
args: ["ptr", "u32"],
|
|
11904
11923
|
returns: "void"
|
|
11905
11924
|
},
|
|
11925
|
+
resetSplitScrollback: {
|
|
11926
|
+
args: ["ptr", "u32", "u32"],
|
|
11927
|
+
returns: "u32"
|
|
11928
|
+
},
|
|
11929
|
+
syncSplitScrollback: {
|
|
11930
|
+
args: ["ptr", "u32"],
|
|
11931
|
+
returns: "u32"
|
|
11932
|
+
},
|
|
11933
|
+
setPendingSplitFooterTransition: {
|
|
11934
|
+
args: ["ptr", "u8", "u32", "u32", "u32", "u32"],
|
|
11935
|
+
returns: "void"
|
|
11936
|
+
},
|
|
11937
|
+
clearPendingSplitFooterTransition: {
|
|
11938
|
+
args: ["ptr"],
|
|
11939
|
+
returns: "void"
|
|
11940
|
+
},
|
|
11906
11941
|
updateStats: {
|
|
11907
11942
|
args: ["ptr", "f64", "u32", "f64"],
|
|
11908
11943
|
returns: "void"
|
|
@@ -11915,6 +11950,14 @@ function getOpenTUILib(libPath) {
|
|
|
11915
11950
|
args: ["ptr", "bool"],
|
|
11916
11951
|
returns: "void"
|
|
11917
11952
|
},
|
|
11953
|
+
repaintSplitFooter: {
|
|
11954
|
+
args: ["ptr", "u32", "bool"],
|
|
11955
|
+
returns: "u32"
|
|
11956
|
+
},
|
|
11957
|
+
commitSplitFooterSnapshot: {
|
|
11958
|
+
args: ["ptr", "ptr", "u32", "bool", "bool", "u32", "bool", "bool", "bool"],
|
|
11959
|
+
returns: "u32"
|
|
11960
|
+
},
|
|
11918
11961
|
getNextBuffer: {
|
|
11919
11962
|
args: ["ptr"],
|
|
11920
11963
|
returns: "ptr"
|
|
@@ -12387,6 +12430,10 @@ function getOpenTUILib(libPath) {
|
|
|
12387
12430
|
args: ["ptr", "u8"],
|
|
12388
12431
|
returns: "void"
|
|
12389
12432
|
},
|
|
12433
|
+
textBufferViewSetFirstLineOffset: {
|
|
12434
|
+
args: ["ptr", "u32"],
|
|
12435
|
+
returns: "void"
|
|
12436
|
+
},
|
|
12390
12437
|
textBufferViewSetViewportSize: {
|
|
12391
12438
|
args: ["ptr", "u32", "u32"],
|
|
12392
12439
|
returns: "void"
|
|
@@ -13124,12 +13171,27 @@ class FFIRenderLib {
|
|
|
13124
13171
|
setUseThread(renderer, useThread) {
|
|
13125
13172
|
this.opentui.symbols.setUseThread(renderer, useThread);
|
|
13126
13173
|
}
|
|
13174
|
+
setClearOnShutdown(renderer, clear) {
|
|
13175
|
+
this.opentui.symbols.setClearOnShutdown(renderer, clear);
|
|
13176
|
+
}
|
|
13127
13177
|
setBackgroundColor(renderer, color) {
|
|
13128
13178
|
this.opentui.symbols.setBackgroundColor(renderer, color.buffer);
|
|
13129
13179
|
}
|
|
13130
13180
|
setRenderOffset(renderer, offset) {
|
|
13131
13181
|
this.opentui.symbols.setRenderOffset(renderer, offset);
|
|
13132
13182
|
}
|
|
13183
|
+
resetSplitScrollback(renderer, seedRows, pinnedRenderOffset) {
|
|
13184
|
+
return this.opentui.symbols.resetSplitScrollback(renderer, seedRows, pinnedRenderOffset);
|
|
13185
|
+
}
|
|
13186
|
+
syncSplitScrollback(renderer, pinnedRenderOffset) {
|
|
13187
|
+
return this.opentui.symbols.syncSplitScrollback(renderer, pinnedRenderOffset);
|
|
13188
|
+
}
|
|
13189
|
+
setPendingSplitFooterTransition(renderer, mode, sourceTopLine, sourceHeight, targetTopLine, targetHeight) {
|
|
13190
|
+
this.opentui.symbols.setPendingSplitFooterTransition(renderer, mode, sourceTopLine, sourceHeight, targetTopLine, targetHeight);
|
|
13191
|
+
}
|
|
13192
|
+
clearPendingSplitFooterTransition(renderer) {
|
|
13193
|
+
this.opentui.symbols.clearPendingSplitFooterTransition(renderer);
|
|
13194
|
+
}
|
|
13133
13195
|
updateStats(renderer, time, fps, frameCallbackTime) {
|
|
13134
13196
|
this.opentui.symbols.updateStats(renderer, time, fps, frameCallbackTime);
|
|
13135
13197
|
}
|
|
@@ -13319,6 +13381,12 @@ class FFIRenderLib {
|
|
|
13319
13381
|
render(renderer, force) {
|
|
13320
13382
|
this.opentui.symbols.render(renderer, force);
|
|
13321
13383
|
}
|
|
13384
|
+
repaintSplitFooter(renderer, pinnedRenderOffset, force) {
|
|
13385
|
+
return this.opentui.symbols.repaintSplitFooter(renderer, pinnedRenderOffset, force);
|
|
13386
|
+
}
|
|
13387
|
+
commitSplitFooterSnapshot(renderer, snapshot, rowColumns, startOnNewLine, trailingNewline, pinnedRenderOffset, force, beginFrame = true, finalizeFrame = true) {
|
|
13388
|
+
return this.opentui.symbols.commitSplitFooterSnapshot(renderer, snapshot.ptr, rowColumns, startOnNewLine, trailingNewline, pinnedRenderOffset, force, beginFrame, finalizeFrame);
|
|
13389
|
+
}
|
|
13322
13390
|
createOptimizedBuffer(width, height, widthMethod, respectAlpha = false, id) {
|
|
13323
13391
|
if (Number.isNaN(width) || Number.isNaN(height)) {
|
|
13324
13392
|
console.error(new Error(`Invalid dimensions for OptimizedBuffer: ${width}x${height}`).stack);
|
|
@@ -13598,6 +13666,9 @@ class FFIRenderLib {
|
|
|
13598
13666
|
const modeValue = mode === "none" ? 0 : mode === "char" ? 1 : 2;
|
|
13599
13667
|
this.opentui.symbols.textBufferViewSetWrapMode(view, modeValue);
|
|
13600
13668
|
}
|
|
13669
|
+
textBufferViewSetFirstLineOffset(view, offset) {
|
|
13670
|
+
this.opentui.symbols.textBufferViewSetFirstLineOffset(view, offset);
|
|
13671
|
+
}
|
|
13601
13672
|
textBufferViewSetViewportSize(view, width, height) {
|
|
13602
13673
|
this.opentui.symbols.textBufferViewSetViewportSize(view, width, height);
|
|
13603
13674
|
}
|
|
@@ -16062,6 +16133,139 @@ function delegate(mapping, vnode) {
|
|
|
16062
16133
|
return vnode;
|
|
16063
16134
|
}
|
|
16064
16135
|
|
|
16136
|
+
// src/text-buffer-view.ts
|
|
16137
|
+
class TextBufferView {
|
|
16138
|
+
lib;
|
|
16139
|
+
viewPtr;
|
|
16140
|
+
textBuffer;
|
|
16141
|
+
_destroyed = false;
|
|
16142
|
+
constructor(lib, ptr5, textBuffer) {
|
|
16143
|
+
this.lib = lib;
|
|
16144
|
+
this.viewPtr = ptr5;
|
|
16145
|
+
this.textBuffer = textBuffer;
|
|
16146
|
+
}
|
|
16147
|
+
static create(textBuffer) {
|
|
16148
|
+
const lib = resolveRenderLib();
|
|
16149
|
+
const viewPtr = lib.createTextBufferView(textBuffer.ptr);
|
|
16150
|
+
return new TextBufferView(lib, viewPtr, textBuffer);
|
|
16151
|
+
}
|
|
16152
|
+
guard() {
|
|
16153
|
+
if (this._destroyed)
|
|
16154
|
+
throw new Error("TextBufferView is destroyed");
|
|
16155
|
+
}
|
|
16156
|
+
get ptr() {
|
|
16157
|
+
this.guard();
|
|
16158
|
+
return this.viewPtr;
|
|
16159
|
+
}
|
|
16160
|
+
setSelection(start, end, bgColor, fgColor) {
|
|
16161
|
+
this.guard();
|
|
16162
|
+
this.lib.textBufferViewSetSelection(this.viewPtr, start, end, bgColor || null, fgColor || null);
|
|
16163
|
+
}
|
|
16164
|
+
updateSelection(end, bgColor, fgColor) {
|
|
16165
|
+
this.guard();
|
|
16166
|
+
this.lib.textBufferViewUpdateSelection(this.viewPtr, end, bgColor || null, fgColor || null);
|
|
16167
|
+
}
|
|
16168
|
+
resetSelection() {
|
|
16169
|
+
this.guard();
|
|
16170
|
+
this.lib.textBufferViewResetSelection(this.viewPtr);
|
|
16171
|
+
}
|
|
16172
|
+
getSelection() {
|
|
16173
|
+
this.guard();
|
|
16174
|
+
return this.lib.textBufferViewGetSelection(this.viewPtr);
|
|
16175
|
+
}
|
|
16176
|
+
hasSelection() {
|
|
16177
|
+
this.guard();
|
|
16178
|
+
return this.getSelection() !== null;
|
|
16179
|
+
}
|
|
16180
|
+
setLocalSelection(anchorX, anchorY, focusX, focusY, bgColor, fgColor) {
|
|
16181
|
+
this.guard();
|
|
16182
|
+
return this.lib.textBufferViewSetLocalSelection(this.viewPtr, anchorX, anchorY, focusX, focusY, bgColor || null, fgColor || null);
|
|
16183
|
+
}
|
|
16184
|
+
updateLocalSelection(anchorX, anchorY, focusX, focusY, bgColor, fgColor) {
|
|
16185
|
+
this.guard();
|
|
16186
|
+
return this.lib.textBufferViewUpdateLocalSelection(this.viewPtr, anchorX, anchorY, focusX, focusY, bgColor || null, fgColor || null);
|
|
16187
|
+
}
|
|
16188
|
+
resetLocalSelection() {
|
|
16189
|
+
this.guard();
|
|
16190
|
+
this.lib.textBufferViewResetLocalSelection(this.viewPtr);
|
|
16191
|
+
}
|
|
16192
|
+
setWrapWidth(width) {
|
|
16193
|
+
this.guard();
|
|
16194
|
+
this.lib.textBufferViewSetWrapWidth(this.viewPtr, width ?? 0);
|
|
16195
|
+
}
|
|
16196
|
+
setWrapMode(mode) {
|
|
16197
|
+
this.guard();
|
|
16198
|
+
this.lib.textBufferViewSetWrapMode(this.viewPtr, mode);
|
|
16199
|
+
}
|
|
16200
|
+
setFirstLineOffset(offset) {
|
|
16201
|
+
this.guard();
|
|
16202
|
+
this.lib.textBufferViewSetFirstLineOffset(this.viewPtr, offset);
|
|
16203
|
+
}
|
|
16204
|
+
setViewportSize(width, height) {
|
|
16205
|
+
this.guard();
|
|
16206
|
+
this.lib.textBufferViewSetViewportSize(this.viewPtr, width, height);
|
|
16207
|
+
}
|
|
16208
|
+
setViewport(x, y, width, height) {
|
|
16209
|
+
this.guard();
|
|
16210
|
+
this.lib.textBufferViewSetViewport(this.viewPtr, x, y, width, height);
|
|
16211
|
+
}
|
|
16212
|
+
get lineInfo() {
|
|
16213
|
+
this.guard();
|
|
16214
|
+
return this.lib.textBufferViewGetLineInfo(this.viewPtr);
|
|
16215
|
+
}
|
|
16216
|
+
get logicalLineInfo() {
|
|
16217
|
+
this.guard();
|
|
16218
|
+
return this.lib.textBufferViewGetLogicalLineInfo(this.viewPtr);
|
|
16219
|
+
}
|
|
16220
|
+
getSelectedText() {
|
|
16221
|
+
this.guard();
|
|
16222
|
+
const byteSize = this.textBuffer.byteSize;
|
|
16223
|
+
if (byteSize === 0)
|
|
16224
|
+
return "";
|
|
16225
|
+
const selectedBytes = this.lib.textBufferViewGetSelectedTextBytes(this.viewPtr, byteSize);
|
|
16226
|
+
if (!selectedBytes)
|
|
16227
|
+
return "";
|
|
16228
|
+
return this.lib.decoder.decode(selectedBytes);
|
|
16229
|
+
}
|
|
16230
|
+
getPlainText() {
|
|
16231
|
+
this.guard();
|
|
16232
|
+
const byteSize = this.textBuffer.byteSize;
|
|
16233
|
+
if (byteSize === 0)
|
|
16234
|
+
return "";
|
|
16235
|
+
const plainBytes = this.lib.textBufferViewGetPlainTextBytes(this.viewPtr, byteSize);
|
|
16236
|
+
if (!plainBytes)
|
|
16237
|
+
return "";
|
|
16238
|
+
return this.lib.decoder.decode(plainBytes);
|
|
16239
|
+
}
|
|
16240
|
+
setTabIndicator(indicator) {
|
|
16241
|
+
this.guard();
|
|
16242
|
+
const codePoint = typeof indicator === "string" ? indicator.codePointAt(0) ?? 0 : indicator;
|
|
16243
|
+
this.lib.textBufferViewSetTabIndicator(this.viewPtr, codePoint);
|
|
16244
|
+
}
|
|
16245
|
+
setTabIndicatorColor(color) {
|
|
16246
|
+
this.guard();
|
|
16247
|
+
this.lib.textBufferViewSetTabIndicatorColor(this.viewPtr, color);
|
|
16248
|
+
}
|
|
16249
|
+
setTruncate(truncate) {
|
|
16250
|
+
this.guard();
|
|
16251
|
+
this.lib.textBufferViewSetTruncate(this.viewPtr, truncate);
|
|
16252
|
+
}
|
|
16253
|
+
measureForDimensions(width, height) {
|
|
16254
|
+
this.guard();
|
|
16255
|
+
return this.lib.textBufferViewMeasureForDimensions(this.viewPtr, width, height);
|
|
16256
|
+
}
|
|
16257
|
+
getVirtualLineCount() {
|
|
16258
|
+
this.guard();
|
|
16259
|
+
return this.lib.textBufferViewGetVirtualLineCount(this.viewPtr);
|
|
16260
|
+
}
|
|
16261
|
+
destroy() {
|
|
16262
|
+
if (this._destroyed)
|
|
16263
|
+
return;
|
|
16264
|
+
this._destroyed = true;
|
|
16265
|
+
this.lib.destroyTextBufferView(this.viewPtr);
|
|
16266
|
+
}
|
|
16267
|
+
}
|
|
16268
|
+
|
|
16065
16269
|
// src/edit-buffer.ts
|
|
16066
16270
|
import { EventEmitter as EventEmitter6 } from "events";
|
|
16067
16271
|
|
|
@@ -16566,113 +16770,1542 @@ class EditorView {
|
|
|
16566
16770
|
}
|
|
16567
16771
|
}
|
|
16568
16772
|
|
|
16569
|
-
// src/
|
|
16570
|
-
|
|
16571
|
-
|
|
16572
|
-
|
|
16573
|
-
|
|
16574
|
-
|
|
16575
|
-
|
|
16576
|
-
|
|
16577
|
-
|
|
16578
|
-
|
|
16773
|
+
// src/syntax-style.ts
|
|
16774
|
+
function convertThemeToStyles(theme) {
|
|
16775
|
+
const flatStyles = {};
|
|
16776
|
+
for (const tokenStyle of theme) {
|
|
16777
|
+
const styleDefinition = {};
|
|
16778
|
+
if (tokenStyle.style.foreground) {
|
|
16779
|
+
styleDefinition.fg = parseColor(tokenStyle.style.foreground);
|
|
16780
|
+
}
|
|
16781
|
+
if (tokenStyle.style.background) {
|
|
16782
|
+
styleDefinition.bg = parseColor(tokenStyle.style.background);
|
|
16783
|
+
}
|
|
16784
|
+
if (tokenStyle.style.bold !== undefined) {
|
|
16785
|
+
styleDefinition.bold = tokenStyle.style.bold;
|
|
16786
|
+
}
|
|
16787
|
+
if (tokenStyle.style.italic !== undefined) {
|
|
16788
|
+
styleDefinition.italic = tokenStyle.style.italic;
|
|
16789
|
+
}
|
|
16790
|
+
if (tokenStyle.style.underline !== undefined) {
|
|
16791
|
+
styleDefinition.underline = tokenStyle.style.underline;
|
|
16792
|
+
}
|
|
16793
|
+
if (tokenStyle.style.dim !== undefined) {
|
|
16794
|
+
styleDefinition.dim = tokenStyle.style.dim;
|
|
16795
|
+
}
|
|
16796
|
+
for (const scope of tokenStyle.scope) {
|
|
16797
|
+
flatStyles[scope] = styleDefinition;
|
|
16798
|
+
}
|
|
16799
|
+
}
|
|
16800
|
+
return flatStyles;
|
|
16801
|
+
}
|
|
16579
16802
|
|
|
16580
|
-
class
|
|
16581
|
-
|
|
16582
|
-
|
|
16583
|
-
|
|
16803
|
+
class SyntaxStyle {
|
|
16804
|
+
lib;
|
|
16805
|
+
stylePtr;
|
|
16806
|
+
_destroyed = false;
|
|
16807
|
+
nameCache = new Map;
|
|
16808
|
+
styleDefs = new Map;
|
|
16809
|
+
mergedCache = new Map;
|
|
16810
|
+
constructor(lib, ptr5) {
|
|
16811
|
+
this.lib = lib;
|
|
16812
|
+
this.stylePtr = ptr5;
|
|
16584
16813
|
}
|
|
16585
|
-
|
|
16586
|
-
|
|
16814
|
+
static create() {
|
|
16815
|
+
const lib = resolveRenderLib();
|
|
16816
|
+
const ptr5 = lib.createSyntaxStyle();
|
|
16817
|
+
return new SyntaxStyle(lib, ptr5);
|
|
16587
16818
|
}
|
|
16588
|
-
|
|
16589
|
-
|
|
16590
|
-
|
|
16819
|
+
static fromTheme(theme) {
|
|
16820
|
+
const style = SyntaxStyle.create();
|
|
16821
|
+
const flatStyles = convertThemeToStyles(theme);
|
|
16822
|
+
for (const [name, styleDef] of Object.entries(flatStyles)) {
|
|
16823
|
+
style.registerStyle(name, styleDef);
|
|
16824
|
+
}
|
|
16825
|
+
return style;
|
|
16591
16826
|
}
|
|
16592
|
-
|
|
16593
|
-
const
|
|
16594
|
-
|
|
16595
|
-
|
|
16827
|
+
static fromStyles(styles) {
|
|
16828
|
+
const style = SyntaxStyle.create();
|
|
16829
|
+
for (const [name, styleDef] of Object.entries(styles)) {
|
|
16830
|
+
style.registerStyle(name, styleDef);
|
|
16831
|
+
}
|
|
16832
|
+
return style;
|
|
16596
16833
|
}
|
|
16597
|
-
|
|
16598
|
-
this.
|
|
16834
|
+
guard() {
|
|
16835
|
+
if (this._destroyed)
|
|
16836
|
+
throw new Error("NativeSyntaxStyle is destroyed");
|
|
16599
16837
|
}
|
|
16600
|
-
|
|
16601
|
-
|
|
16602
|
-
|
|
16603
|
-
|
|
16604
|
-
|
|
16605
|
-
|
|
16606
|
-
|
|
16607
|
-
|
|
16608
|
-
|
|
16609
|
-
|
|
16610
|
-
this.
|
|
16611
|
-
|
|
16838
|
+
registerStyle(name, style) {
|
|
16839
|
+
this.guard();
|
|
16840
|
+
const attributes = createTextAttributes({
|
|
16841
|
+
bold: style.bold,
|
|
16842
|
+
italic: style.italic,
|
|
16843
|
+
underline: style.underline,
|
|
16844
|
+
dim: style.dim
|
|
16845
|
+
});
|
|
16846
|
+
const id = this.lib.syntaxStyleRegister(this.stylePtr, name, style.fg || null, style.bg || null, attributes);
|
|
16847
|
+
this.nameCache.set(name, id);
|
|
16848
|
+
this.styleDefs.set(name, style);
|
|
16849
|
+
return id;
|
|
16612
16850
|
}
|
|
16613
|
-
|
|
16614
|
-
|
|
16615
|
-
this.
|
|
16616
|
-
|
|
16851
|
+
resolveStyleId(name) {
|
|
16852
|
+
this.guard();
|
|
16853
|
+
const cached = this.nameCache.get(name);
|
|
16854
|
+
if (cached !== undefined)
|
|
16855
|
+
return cached;
|
|
16856
|
+
const id = this.lib.syntaxStyleResolveByName(this.stylePtr, name);
|
|
16857
|
+
if (id !== null) {
|
|
16858
|
+
this.nameCache.set(name, id);
|
|
16859
|
+
}
|
|
16860
|
+
return id;
|
|
16617
16861
|
}
|
|
16618
|
-
|
|
16619
|
-
|
|
16862
|
+
getStyleId(name) {
|
|
16863
|
+
this.guard();
|
|
16864
|
+
const id = this.resolveStyleId(name);
|
|
16865
|
+
if (id !== null)
|
|
16866
|
+
return id;
|
|
16867
|
+
if (name.includes(".")) {
|
|
16868
|
+
const baseName = name.split(".")[0];
|
|
16869
|
+
return this.resolveStyleId(baseName);
|
|
16870
|
+
}
|
|
16871
|
+
return null;
|
|
16620
16872
|
}
|
|
16621
|
-
|
|
16622
|
-
|
|
16623
|
-
|
|
16624
|
-
var defaultKeyAliases = {
|
|
16625
|
-
enter: "return",
|
|
16626
|
-
esc: "escape",
|
|
16627
|
-
kp0: "0",
|
|
16628
|
-
kp1: "1",
|
|
16629
|
-
kp2: "2",
|
|
16630
|
-
kp3: "3",
|
|
16631
|
-
kp4: "4",
|
|
16632
|
-
kp5: "5",
|
|
16633
|
-
kp6: "6",
|
|
16634
|
-
kp7: "7",
|
|
16635
|
-
kp8: "8",
|
|
16636
|
-
kp9: "9",
|
|
16637
|
-
kpdecimal: ".",
|
|
16638
|
-
kpdivide: "/",
|
|
16639
|
-
kpmultiply: "*",
|
|
16640
|
-
kpminus: "-",
|
|
16641
|
-
kpplus: "+",
|
|
16642
|
-
kpenter: "enter",
|
|
16643
|
-
kpequal: "=",
|
|
16644
|
-
kpseparator: ",",
|
|
16645
|
-
kpleft: "left",
|
|
16646
|
-
kpright: "right",
|
|
16647
|
-
kpup: "up",
|
|
16648
|
-
kpdown: "down",
|
|
16649
|
-
kppageup: "pageup",
|
|
16650
|
-
kppagedown: "pagedown",
|
|
16651
|
-
kphome: "home",
|
|
16652
|
-
kpend: "end",
|
|
16653
|
-
kpinsert: "insert",
|
|
16654
|
-
kpdelete: "delete"
|
|
16655
|
-
};
|
|
16656
|
-
function mergeKeyAliases(defaults, custom) {
|
|
16657
|
-
return { ...defaults, ...custom };
|
|
16658
|
-
}
|
|
16659
|
-
function mergeKeyBindings(defaults, custom) {
|
|
16660
|
-
const map = new Map;
|
|
16661
|
-
for (const binding of defaults) {
|
|
16662
|
-
const key = getKeyBindingKey(binding);
|
|
16663
|
-
map.set(key, binding);
|
|
16873
|
+
get ptr() {
|
|
16874
|
+
this.guard();
|
|
16875
|
+
return this.stylePtr;
|
|
16664
16876
|
}
|
|
16665
|
-
|
|
16666
|
-
|
|
16667
|
-
|
|
16877
|
+
getStyleCount() {
|
|
16878
|
+
this.guard();
|
|
16879
|
+
return this.lib.syntaxStyleGetStyleCount(this.stylePtr);
|
|
16668
16880
|
}
|
|
16669
|
-
|
|
16670
|
-
|
|
16671
|
-
|
|
16672
|
-
|
|
16673
|
-
|
|
16674
|
-
|
|
16675
|
-
|
|
16881
|
+
clearNameCache() {
|
|
16882
|
+
this.nameCache.clear();
|
|
16883
|
+
}
|
|
16884
|
+
getStyle(name) {
|
|
16885
|
+
this.guard();
|
|
16886
|
+
const style = this.styleDefs.get(name);
|
|
16887
|
+
if (style)
|
|
16888
|
+
return style;
|
|
16889
|
+
if (name.includes(".")) {
|
|
16890
|
+
const baseName = name.split(".")[0];
|
|
16891
|
+
return this.styleDefs.get(baseName);
|
|
16892
|
+
}
|
|
16893
|
+
return;
|
|
16894
|
+
}
|
|
16895
|
+
mergeStyles(...styleNames) {
|
|
16896
|
+
this.guard();
|
|
16897
|
+
const cacheKey = styleNames.join(":");
|
|
16898
|
+
const cached = this.mergedCache.get(cacheKey);
|
|
16899
|
+
if (cached)
|
|
16900
|
+
return cached;
|
|
16901
|
+
const styleDefinition = {};
|
|
16902
|
+
for (const name of styleNames) {
|
|
16903
|
+
const style = this.getStyle(name);
|
|
16904
|
+
if (!style)
|
|
16905
|
+
continue;
|
|
16906
|
+
if (style.fg)
|
|
16907
|
+
styleDefinition.fg = style.fg;
|
|
16908
|
+
if (style.bg)
|
|
16909
|
+
styleDefinition.bg = style.bg;
|
|
16910
|
+
if (style.bold !== undefined)
|
|
16911
|
+
styleDefinition.bold = style.bold;
|
|
16912
|
+
if (style.italic !== undefined)
|
|
16913
|
+
styleDefinition.italic = style.italic;
|
|
16914
|
+
if (style.underline !== undefined)
|
|
16915
|
+
styleDefinition.underline = style.underline;
|
|
16916
|
+
if (style.dim !== undefined)
|
|
16917
|
+
styleDefinition.dim = style.dim;
|
|
16918
|
+
}
|
|
16919
|
+
const attributes = createTextAttributes({
|
|
16920
|
+
bold: styleDefinition.bold,
|
|
16921
|
+
italic: styleDefinition.italic,
|
|
16922
|
+
underline: styleDefinition.underline,
|
|
16923
|
+
dim: styleDefinition.dim
|
|
16924
|
+
});
|
|
16925
|
+
const merged = {
|
|
16926
|
+
fg: styleDefinition.fg,
|
|
16927
|
+
bg: styleDefinition.bg,
|
|
16928
|
+
attributes
|
|
16929
|
+
};
|
|
16930
|
+
this.mergedCache.set(cacheKey, merged);
|
|
16931
|
+
return merged;
|
|
16932
|
+
}
|
|
16933
|
+
clearCache() {
|
|
16934
|
+
this.guard();
|
|
16935
|
+
this.mergedCache.clear();
|
|
16936
|
+
}
|
|
16937
|
+
getCacheSize() {
|
|
16938
|
+
this.guard();
|
|
16939
|
+
return this.mergedCache.size;
|
|
16940
|
+
}
|
|
16941
|
+
getAllStyles() {
|
|
16942
|
+
this.guard();
|
|
16943
|
+
return new Map(this.styleDefs);
|
|
16944
|
+
}
|
|
16945
|
+
getRegisteredNames() {
|
|
16946
|
+
this.guard();
|
|
16947
|
+
return Array.from(this.styleDefs.keys());
|
|
16948
|
+
}
|
|
16949
|
+
destroy() {
|
|
16950
|
+
if (this._destroyed)
|
|
16951
|
+
return;
|
|
16952
|
+
this._destroyed = true;
|
|
16953
|
+
this.nameCache.clear();
|
|
16954
|
+
this.styleDefs.clear();
|
|
16955
|
+
this.mergedCache.clear();
|
|
16956
|
+
this.lib.destroySyntaxStyle(this.stylePtr);
|
|
16957
|
+
}
|
|
16958
|
+
}
|
|
16959
|
+
|
|
16960
|
+
// src/renderables/Box.ts
|
|
16961
|
+
function isGapType(value) {
|
|
16962
|
+
if (value === undefined) {
|
|
16963
|
+
return true;
|
|
16964
|
+
}
|
|
16965
|
+
if (typeof value === "number" && !Number.isNaN(value)) {
|
|
16966
|
+
return true;
|
|
16967
|
+
}
|
|
16968
|
+
return isValidPercentage(value);
|
|
16969
|
+
}
|
|
16970
|
+
|
|
16971
|
+
class BoxRenderable extends Renderable {
|
|
16972
|
+
_backgroundColor;
|
|
16973
|
+
_border;
|
|
16974
|
+
_borderStyle;
|
|
16975
|
+
_borderColor;
|
|
16976
|
+
_focusedBorderColor;
|
|
16977
|
+
_customBorderCharsObj;
|
|
16978
|
+
_customBorderChars;
|
|
16979
|
+
borderSides;
|
|
16980
|
+
shouldFill;
|
|
16981
|
+
_title;
|
|
16982
|
+
_titleAlignment;
|
|
16983
|
+
_bottomTitle;
|
|
16984
|
+
_bottomTitleAlignment;
|
|
16985
|
+
_defaultOptions = {
|
|
16986
|
+
backgroundColor: "transparent",
|
|
16987
|
+
borderStyle: "single",
|
|
16988
|
+
border: false,
|
|
16989
|
+
borderColor: "#FFFFFF",
|
|
16990
|
+
shouldFill: true,
|
|
16991
|
+
titleAlignment: "left",
|
|
16992
|
+
bottomTitleAlignment: "left",
|
|
16993
|
+
focusedBorderColor: "#00AAFF"
|
|
16994
|
+
};
|
|
16995
|
+
constructor(ctx, options) {
|
|
16996
|
+
super(ctx, options);
|
|
16997
|
+
if (options.focusable === true) {
|
|
16998
|
+
this._focusable = true;
|
|
16999
|
+
}
|
|
17000
|
+
this._backgroundColor = parseColor(options.backgroundColor || this._defaultOptions.backgroundColor);
|
|
17001
|
+
this._border = options.border ?? this._defaultOptions.border;
|
|
17002
|
+
if (!options.border && (options.borderStyle || options.borderColor || options.focusedBorderColor || options.customBorderChars)) {
|
|
17003
|
+
this._border = true;
|
|
17004
|
+
}
|
|
17005
|
+
this._borderStyle = parseBorderStyle(options.borderStyle, this._defaultOptions.borderStyle);
|
|
17006
|
+
this._borderColor = parseColor(options.borderColor || this._defaultOptions.borderColor);
|
|
17007
|
+
this._focusedBorderColor = parseColor(options.focusedBorderColor || this._defaultOptions.focusedBorderColor);
|
|
17008
|
+
this._customBorderCharsObj = options.customBorderChars;
|
|
17009
|
+
this._customBorderChars = this._customBorderCharsObj ? borderCharsToArray(this._customBorderCharsObj) : undefined;
|
|
17010
|
+
this.borderSides = getBorderSides(this._border);
|
|
17011
|
+
this.shouldFill = options.shouldFill ?? this._defaultOptions.shouldFill;
|
|
17012
|
+
this._title = options.title;
|
|
17013
|
+
this._titleAlignment = options.titleAlignment || this._defaultOptions.titleAlignment;
|
|
17014
|
+
this._bottomTitle = options.bottomTitle;
|
|
17015
|
+
this._bottomTitleAlignment = options.bottomTitleAlignment || this._defaultOptions.bottomTitleAlignment;
|
|
17016
|
+
this.applyYogaBorders();
|
|
17017
|
+
const hasInitialGapProps = options.gap !== undefined || options.rowGap !== undefined || options.columnGap !== undefined;
|
|
17018
|
+
if (hasInitialGapProps) {
|
|
17019
|
+
this.applyYogaGap(options);
|
|
17020
|
+
}
|
|
17021
|
+
}
|
|
17022
|
+
initializeBorder() {
|
|
17023
|
+
if (this._border === false) {
|
|
17024
|
+
this._border = true;
|
|
17025
|
+
this.borderSides = getBorderSides(this._border);
|
|
17026
|
+
this.applyYogaBorders();
|
|
17027
|
+
}
|
|
17028
|
+
}
|
|
17029
|
+
get customBorderChars() {
|
|
17030
|
+
return this._customBorderCharsObj;
|
|
17031
|
+
}
|
|
17032
|
+
set customBorderChars(value) {
|
|
17033
|
+
this._customBorderCharsObj = value;
|
|
17034
|
+
this._customBorderChars = value ? borderCharsToArray(value) : undefined;
|
|
17035
|
+
this.requestRender();
|
|
17036
|
+
}
|
|
17037
|
+
get backgroundColor() {
|
|
17038
|
+
return this._backgroundColor;
|
|
17039
|
+
}
|
|
17040
|
+
set backgroundColor(value) {
|
|
17041
|
+
const newColor = parseColor(value ?? this._defaultOptions.backgroundColor);
|
|
17042
|
+
if (this._backgroundColor !== newColor) {
|
|
17043
|
+
this._backgroundColor = newColor;
|
|
17044
|
+
this.requestRender();
|
|
17045
|
+
}
|
|
17046
|
+
}
|
|
17047
|
+
get border() {
|
|
17048
|
+
return this._border;
|
|
17049
|
+
}
|
|
17050
|
+
set border(value) {
|
|
17051
|
+
if (this._border !== value) {
|
|
17052
|
+
this._border = value;
|
|
17053
|
+
this.borderSides = getBorderSides(value);
|
|
17054
|
+
this.applyYogaBorders();
|
|
17055
|
+
this.requestRender();
|
|
17056
|
+
}
|
|
17057
|
+
}
|
|
17058
|
+
get borderStyle() {
|
|
17059
|
+
return this._borderStyle;
|
|
17060
|
+
}
|
|
17061
|
+
set borderStyle(value) {
|
|
17062
|
+
const _value = parseBorderStyle(value, this._defaultOptions.borderStyle);
|
|
17063
|
+
if (this._borderStyle !== _value || !this._border) {
|
|
17064
|
+
this._borderStyle = _value;
|
|
17065
|
+
this._customBorderChars = undefined;
|
|
17066
|
+
this.initializeBorder();
|
|
17067
|
+
this.requestRender();
|
|
17068
|
+
}
|
|
17069
|
+
}
|
|
17070
|
+
get borderColor() {
|
|
17071
|
+
return this._borderColor;
|
|
17072
|
+
}
|
|
17073
|
+
set borderColor(value) {
|
|
17074
|
+
const newColor = parseColor(value ?? this._defaultOptions.borderColor);
|
|
17075
|
+
if (this._borderColor !== newColor) {
|
|
17076
|
+
this._borderColor = newColor;
|
|
17077
|
+
this.initializeBorder();
|
|
17078
|
+
this.requestRender();
|
|
17079
|
+
}
|
|
17080
|
+
}
|
|
17081
|
+
get focusedBorderColor() {
|
|
17082
|
+
return this._focusedBorderColor;
|
|
17083
|
+
}
|
|
17084
|
+
set focusedBorderColor(value) {
|
|
17085
|
+
const newColor = parseColor(value ?? this._defaultOptions.focusedBorderColor);
|
|
17086
|
+
if (this._focusedBorderColor !== newColor) {
|
|
17087
|
+
this._focusedBorderColor = newColor;
|
|
17088
|
+
this.initializeBorder();
|
|
17089
|
+
if (this._focused) {
|
|
17090
|
+
this.requestRender();
|
|
17091
|
+
}
|
|
17092
|
+
}
|
|
17093
|
+
}
|
|
17094
|
+
get title() {
|
|
17095
|
+
return this._title;
|
|
17096
|
+
}
|
|
17097
|
+
set title(value) {
|
|
17098
|
+
if (this._title !== value) {
|
|
17099
|
+
this._title = value;
|
|
17100
|
+
this.requestRender();
|
|
17101
|
+
}
|
|
17102
|
+
}
|
|
17103
|
+
get titleAlignment() {
|
|
17104
|
+
return this._titleAlignment;
|
|
17105
|
+
}
|
|
17106
|
+
set titleAlignment(value) {
|
|
17107
|
+
if (this._titleAlignment !== value) {
|
|
17108
|
+
this._titleAlignment = value;
|
|
17109
|
+
this.requestRender();
|
|
17110
|
+
}
|
|
17111
|
+
}
|
|
17112
|
+
get bottomTitle() {
|
|
17113
|
+
return this._bottomTitle;
|
|
17114
|
+
}
|
|
17115
|
+
set bottomTitle(value) {
|
|
17116
|
+
if (this._bottomTitle !== value) {
|
|
17117
|
+
this._bottomTitle = value;
|
|
17118
|
+
this.requestRender();
|
|
17119
|
+
}
|
|
17120
|
+
}
|
|
17121
|
+
get bottomTitleAlignment() {
|
|
17122
|
+
return this._bottomTitleAlignment;
|
|
17123
|
+
}
|
|
17124
|
+
set bottomTitleAlignment(value) {
|
|
17125
|
+
if (this._bottomTitleAlignment !== value) {
|
|
17126
|
+
this._bottomTitleAlignment = value;
|
|
17127
|
+
this.requestRender();
|
|
17128
|
+
}
|
|
17129
|
+
}
|
|
17130
|
+
renderSelf(buffer) {
|
|
17131
|
+
const hasBorder = this.borderSides.top || this.borderSides.right || this.borderSides.bottom || this.borderSides.left;
|
|
17132
|
+
const hasVisibleFill = this.shouldFill && this._backgroundColor.a > 0;
|
|
17133
|
+
if (!hasBorder && !hasVisibleFill) {
|
|
17134
|
+
return;
|
|
17135
|
+
}
|
|
17136
|
+
const hasFocusWithin = this._focusable && (this._focused || this._hasFocusedDescendant);
|
|
17137
|
+
const currentBorderColor = hasFocusWithin ? this._focusedBorderColor : this._borderColor;
|
|
17138
|
+
const screenX = this._screenX;
|
|
17139
|
+
const screenY = this._screenY;
|
|
17140
|
+
buffer.drawBox({
|
|
17141
|
+
x: screenX,
|
|
17142
|
+
y: screenY,
|
|
17143
|
+
width: this.width,
|
|
17144
|
+
height: this.height,
|
|
17145
|
+
borderStyle: this._borderStyle,
|
|
17146
|
+
customBorderChars: this._customBorderChars,
|
|
17147
|
+
border: this._border,
|
|
17148
|
+
borderColor: currentBorderColor,
|
|
17149
|
+
backgroundColor: this._backgroundColor,
|
|
17150
|
+
shouldFill: this.shouldFill,
|
|
17151
|
+
title: this._title,
|
|
17152
|
+
titleAlignment: this._titleAlignment,
|
|
17153
|
+
bottomTitle: this._bottomTitle,
|
|
17154
|
+
bottomTitleAlignment: this._bottomTitleAlignment
|
|
17155
|
+
});
|
|
17156
|
+
}
|
|
17157
|
+
getScissorRect() {
|
|
17158
|
+
const baseRect = super.getScissorRect();
|
|
17159
|
+
if (!this.borderSides.top && !this.borderSides.right && !this.borderSides.bottom && !this.borderSides.left) {
|
|
17160
|
+
return baseRect;
|
|
17161
|
+
}
|
|
17162
|
+
const leftInset = this.borderSides.left ? 1 : 0;
|
|
17163
|
+
const rightInset = this.borderSides.right ? 1 : 0;
|
|
17164
|
+
const topInset = this.borderSides.top ? 1 : 0;
|
|
17165
|
+
const bottomInset = this.borderSides.bottom ? 1 : 0;
|
|
17166
|
+
return {
|
|
17167
|
+
x: baseRect.x + leftInset,
|
|
17168
|
+
y: baseRect.y + topInset,
|
|
17169
|
+
width: Math.max(0, baseRect.width - leftInset - rightInset),
|
|
17170
|
+
height: Math.max(0, baseRect.height - topInset - bottomInset)
|
|
17171
|
+
};
|
|
17172
|
+
}
|
|
17173
|
+
applyYogaBorders() {
|
|
17174
|
+
const node = this.yogaNode;
|
|
17175
|
+
node.setBorder(Edge.Left, this.borderSides.left ? 1 : 0);
|
|
17176
|
+
node.setBorder(Edge.Right, this.borderSides.right ? 1 : 0);
|
|
17177
|
+
node.setBorder(Edge.Top, this.borderSides.top ? 1 : 0);
|
|
17178
|
+
node.setBorder(Edge.Bottom, this.borderSides.bottom ? 1 : 0);
|
|
17179
|
+
this.requestRender();
|
|
17180
|
+
}
|
|
17181
|
+
applyYogaGap(options) {
|
|
17182
|
+
const node = this.yogaNode;
|
|
17183
|
+
if (isGapType(options.gap)) {
|
|
17184
|
+
node.setGap(Gutter.All, options.gap);
|
|
17185
|
+
}
|
|
17186
|
+
if (isGapType(options.rowGap)) {
|
|
17187
|
+
node.setGap(Gutter.Row, options.rowGap);
|
|
17188
|
+
}
|
|
17189
|
+
if (isGapType(options.columnGap)) {
|
|
17190
|
+
node.setGap(Gutter.Column, options.columnGap);
|
|
17191
|
+
}
|
|
17192
|
+
}
|
|
17193
|
+
set gap(gap) {
|
|
17194
|
+
if (isGapType(gap)) {
|
|
17195
|
+
this.yogaNode.setGap(Gutter.All, gap);
|
|
17196
|
+
this.requestRender();
|
|
17197
|
+
}
|
|
17198
|
+
}
|
|
17199
|
+
set rowGap(rowGap) {
|
|
17200
|
+
if (isGapType(rowGap)) {
|
|
17201
|
+
this.yogaNode.setGap(Gutter.Row, rowGap);
|
|
17202
|
+
this.requestRender();
|
|
17203
|
+
}
|
|
17204
|
+
}
|
|
17205
|
+
set columnGap(columnGap) {
|
|
17206
|
+
if (isGapType(columnGap)) {
|
|
17207
|
+
this.yogaNode.setGap(Gutter.Column, columnGap);
|
|
17208
|
+
this.requestRender();
|
|
17209
|
+
}
|
|
17210
|
+
}
|
|
17211
|
+
}
|
|
17212
|
+
|
|
17213
|
+
// src/renderables/TextBufferRenderable.ts
|
|
17214
|
+
class TextBufferRenderable extends Renderable {
|
|
17215
|
+
selectable = true;
|
|
17216
|
+
_defaultFg;
|
|
17217
|
+
_defaultBg;
|
|
17218
|
+
_defaultAttributes;
|
|
17219
|
+
_selectionBg;
|
|
17220
|
+
_selectionFg;
|
|
17221
|
+
_wrapMode = "word";
|
|
17222
|
+
lastLocalSelection = null;
|
|
17223
|
+
_tabIndicator;
|
|
17224
|
+
_tabIndicatorColor;
|
|
17225
|
+
_scrollX = 0;
|
|
17226
|
+
_scrollY = 0;
|
|
17227
|
+
_truncate = false;
|
|
17228
|
+
_firstLineOffset = 0;
|
|
17229
|
+
textBuffer;
|
|
17230
|
+
textBufferView;
|
|
17231
|
+
_textBufferSyntaxStyle;
|
|
17232
|
+
_defaultOptions = {
|
|
17233
|
+
fg: RGBA.fromValues(1, 1, 1, 1),
|
|
17234
|
+
bg: RGBA.fromValues(0, 0, 0, 0),
|
|
17235
|
+
selectionBg: undefined,
|
|
17236
|
+
selectionFg: undefined,
|
|
17237
|
+
selectable: true,
|
|
17238
|
+
attributes: 0,
|
|
17239
|
+
wrapMode: "word",
|
|
17240
|
+
tabIndicator: undefined,
|
|
17241
|
+
tabIndicatorColor: undefined,
|
|
17242
|
+
truncate: false
|
|
17243
|
+
};
|
|
17244
|
+
constructor(ctx, options) {
|
|
17245
|
+
super(ctx, options);
|
|
17246
|
+
this._defaultFg = parseColor(options.fg ?? this._defaultOptions.fg);
|
|
17247
|
+
this._defaultBg = parseColor(options.bg ?? this._defaultOptions.bg);
|
|
17248
|
+
this._defaultAttributes = options.attributes ?? this._defaultOptions.attributes;
|
|
17249
|
+
this._selectionBg = options.selectionBg ? parseColor(options.selectionBg) : this._defaultOptions.selectionBg;
|
|
17250
|
+
this._selectionFg = options.selectionFg ? parseColor(options.selectionFg) : this._defaultOptions.selectionFg;
|
|
17251
|
+
this.selectable = options.selectable ?? this._defaultOptions.selectable;
|
|
17252
|
+
this._wrapMode = options.wrapMode ?? this._defaultOptions.wrapMode;
|
|
17253
|
+
this._tabIndicator = options.tabIndicator ?? this._defaultOptions.tabIndicator;
|
|
17254
|
+
this._tabIndicatorColor = options.tabIndicatorColor ? parseColor(options.tabIndicatorColor) : this._defaultOptions.tabIndicatorColor;
|
|
17255
|
+
this._truncate = options.truncate ?? this._defaultOptions.truncate;
|
|
17256
|
+
this.textBuffer = TextBuffer.create(this._ctx.widthMethod);
|
|
17257
|
+
this.textBufferView = TextBufferView.create(this.textBuffer);
|
|
17258
|
+
this._firstLineOffset = ctx.claimFirstLineOffset?.(this) ?? 0;
|
|
17259
|
+
this._textBufferSyntaxStyle = SyntaxStyle.create();
|
|
17260
|
+
this.textBuffer.setSyntaxStyle(this._textBufferSyntaxStyle);
|
|
17261
|
+
this.textBufferView.setWrapMode(this._wrapMode);
|
|
17262
|
+
this.textBufferView.setFirstLineOffset(this._firstLineOffset);
|
|
17263
|
+
this.setupMeasureFunc();
|
|
17264
|
+
this.textBuffer.setDefaultFg(this._defaultFg);
|
|
17265
|
+
this.textBuffer.setDefaultBg(this._defaultBg);
|
|
17266
|
+
this.textBuffer.setDefaultAttributes(this._defaultAttributes);
|
|
17267
|
+
if (this._tabIndicator !== undefined) {
|
|
17268
|
+
this.textBufferView.setTabIndicator(this._tabIndicator);
|
|
17269
|
+
}
|
|
17270
|
+
if (this._tabIndicatorColor !== undefined) {
|
|
17271
|
+
this.textBufferView.setTabIndicatorColor(this._tabIndicatorColor);
|
|
17272
|
+
}
|
|
17273
|
+
if (this._wrapMode !== "none" && this.width > 0) {
|
|
17274
|
+
this.textBufferView.setWrapWidth(this.width);
|
|
17275
|
+
}
|
|
17276
|
+
if (this.width > 0 && this.height > 0) {
|
|
17277
|
+
this.textBufferView.setViewport(this._scrollX, this._scrollY, this.width, this.height);
|
|
17278
|
+
}
|
|
17279
|
+
this.textBufferView.setTruncate(this._truncate);
|
|
17280
|
+
this.updateTextInfo();
|
|
17281
|
+
}
|
|
17282
|
+
onMouseEvent(event) {
|
|
17283
|
+
if (event.type === "scroll") {
|
|
17284
|
+
this.handleScroll(event);
|
|
17285
|
+
}
|
|
17286
|
+
}
|
|
17287
|
+
handleScroll(event) {
|
|
17288
|
+
if (!event.scroll)
|
|
17289
|
+
return;
|
|
17290
|
+
const { direction, delta } = event.scroll;
|
|
17291
|
+
if (direction === "up") {
|
|
17292
|
+
this.scrollY -= delta;
|
|
17293
|
+
} else if (direction === "down") {
|
|
17294
|
+
this.scrollY += delta;
|
|
17295
|
+
}
|
|
17296
|
+
if (this._wrapMode === "none") {
|
|
17297
|
+
if (direction === "left") {
|
|
17298
|
+
this.scrollX -= delta;
|
|
17299
|
+
} else if (direction === "right") {
|
|
17300
|
+
this.scrollX += delta;
|
|
17301
|
+
}
|
|
17302
|
+
}
|
|
17303
|
+
}
|
|
17304
|
+
get lineInfo() {
|
|
17305
|
+
return this.textBufferView.logicalLineInfo;
|
|
17306
|
+
}
|
|
17307
|
+
get lineCount() {
|
|
17308
|
+
return this.textBuffer.getLineCount();
|
|
17309
|
+
}
|
|
17310
|
+
get virtualLineCount() {
|
|
17311
|
+
return this.textBufferView.getVirtualLineCount();
|
|
17312
|
+
}
|
|
17313
|
+
get scrollY() {
|
|
17314
|
+
return this._scrollY;
|
|
17315
|
+
}
|
|
17316
|
+
set scrollY(value) {
|
|
17317
|
+
const maxScrollY = Math.max(0, this.scrollHeight - this.height);
|
|
17318
|
+
const clamped = Math.max(0, Math.min(value, maxScrollY));
|
|
17319
|
+
if (this._scrollY !== clamped) {
|
|
17320
|
+
this._scrollY = clamped;
|
|
17321
|
+
this.updateViewportOffset();
|
|
17322
|
+
this.requestRender();
|
|
17323
|
+
}
|
|
17324
|
+
}
|
|
17325
|
+
get scrollX() {
|
|
17326
|
+
return this._scrollX;
|
|
17327
|
+
}
|
|
17328
|
+
set scrollX(value) {
|
|
17329
|
+
const maxScrollX = Math.max(0, this.scrollWidth - this.width);
|
|
17330
|
+
const clamped = Math.max(0, Math.min(value, maxScrollX));
|
|
17331
|
+
if (this._scrollX !== clamped) {
|
|
17332
|
+
this._scrollX = clamped;
|
|
17333
|
+
this.updateViewportOffset();
|
|
17334
|
+
this.requestRender();
|
|
17335
|
+
}
|
|
17336
|
+
}
|
|
17337
|
+
get scrollWidth() {
|
|
17338
|
+
return this.lineInfo.lineWidthColsMax;
|
|
17339
|
+
}
|
|
17340
|
+
get scrollHeight() {
|
|
17341
|
+
return this.lineInfo.lineStartCols.length;
|
|
17342
|
+
}
|
|
17343
|
+
get maxScrollY() {
|
|
17344
|
+
return Math.max(0, this.scrollHeight - this.height);
|
|
17345
|
+
}
|
|
17346
|
+
get maxScrollX() {
|
|
17347
|
+
return Math.max(0, this.scrollWidth - this.width);
|
|
17348
|
+
}
|
|
17349
|
+
updateViewportOffset() {
|
|
17350
|
+
if (this.width > 0 && this.height > 0) {
|
|
17351
|
+
this.textBufferView.setViewport(this._scrollX, this._scrollY, this.width, this.height);
|
|
17352
|
+
}
|
|
17353
|
+
}
|
|
17354
|
+
get plainText() {
|
|
17355
|
+
return this.textBuffer.getPlainText();
|
|
17356
|
+
}
|
|
17357
|
+
get textLength() {
|
|
17358
|
+
return this.textBuffer.length;
|
|
17359
|
+
}
|
|
17360
|
+
get fg() {
|
|
17361
|
+
return this._defaultFg;
|
|
17362
|
+
}
|
|
17363
|
+
set fg(value) {
|
|
17364
|
+
const newColor = parseColor(value ?? this._defaultOptions.fg);
|
|
17365
|
+
if (this._defaultFg !== newColor) {
|
|
17366
|
+
this._defaultFg = newColor;
|
|
17367
|
+
this.textBuffer.setDefaultFg(this._defaultFg);
|
|
17368
|
+
this.onFgChanged(newColor);
|
|
17369
|
+
this.requestRender();
|
|
17370
|
+
}
|
|
17371
|
+
}
|
|
17372
|
+
get selectionBg() {
|
|
17373
|
+
return this._selectionBg;
|
|
17374
|
+
}
|
|
17375
|
+
set selectionBg(value) {
|
|
17376
|
+
const newColor = value ? parseColor(value) : this._defaultOptions.selectionBg;
|
|
17377
|
+
if (this._selectionBg !== newColor) {
|
|
17378
|
+
this._selectionBg = newColor;
|
|
17379
|
+
if (this.lastLocalSelection) {
|
|
17380
|
+
this.updateLocalSelection(this.lastLocalSelection);
|
|
17381
|
+
}
|
|
17382
|
+
this.requestRender();
|
|
17383
|
+
}
|
|
17384
|
+
}
|
|
17385
|
+
get selectionFg() {
|
|
17386
|
+
return this._selectionFg;
|
|
17387
|
+
}
|
|
17388
|
+
set selectionFg(value) {
|
|
17389
|
+
const newColor = value ? parseColor(value) : this._defaultOptions.selectionFg;
|
|
17390
|
+
if (this._selectionFg !== newColor) {
|
|
17391
|
+
this._selectionFg = newColor;
|
|
17392
|
+
if (this.lastLocalSelection) {
|
|
17393
|
+
this.updateLocalSelection(this.lastLocalSelection);
|
|
17394
|
+
}
|
|
17395
|
+
this.requestRender();
|
|
17396
|
+
}
|
|
17397
|
+
}
|
|
17398
|
+
get bg() {
|
|
17399
|
+
return this._defaultBg;
|
|
17400
|
+
}
|
|
17401
|
+
set bg(value) {
|
|
17402
|
+
const newColor = parseColor(value ?? this._defaultOptions.bg);
|
|
17403
|
+
if (this._defaultBg !== newColor) {
|
|
17404
|
+
this._defaultBg = newColor;
|
|
17405
|
+
this.textBuffer.setDefaultBg(this._defaultBg);
|
|
17406
|
+
this.onBgChanged(newColor);
|
|
17407
|
+
this.requestRender();
|
|
17408
|
+
}
|
|
17409
|
+
}
|
|
17410
|
+
get attributes() {
|
|
17411
|
+
return this._defaultAttributes;
|
|
17412
|
+
}
|
|
17413
|
+
set attributes(value) {
|
|
17414
|
+
if (this._defaultAttributes !== value) {
|
|
17415
|
+
this._defaultAttributes = value;
|
|
17416
|
+
this.textBuffer.setDefaultAttributes(this._defaultAttributes);
|
|
17417
|
+
this.onAttributesChanged(value);
|
|
17418
|
+
this.requestRender();
|
|
17419
|
+
}
|
|
17420
|
+
}
|
|
17421
|
+
get wrapMode() {
|
|
17422
|
+
return this._wrapMode;
|
|
17423
|
+
}
|
|
17424
|
+
set wrapMode(value) {
|
|
17425
|
+
if (this._wrapMode !== value) {
|
|
17426
|
+
this._wrapMode = value;
|
|
17427
|
+
this.textBufferView.setWrapMode(this._wrapMode);
|
|
17428
|
+
if (value !== "none" && this.width > 0) {
|
|
17429
|
+
this.textBufferView.setWrapWidth(this.width);
|
|
17430
|
+
}
|
|
17431
|
+
this.yogaNode.markDirty();
|
|
17432
|
+
this.requestRender();
|
|
17433
|
+
}
|
|
17434
|
+
}
|
|
17435
|
+
get tabIndicator() {
|
|
17436
|
+
return this._tabIndicator;
|
|
17437
|
+
}
|
|
17438
|
+
set tabIndicator(value) {
|
|
17439
|
+
if (this._tabIndicator !== value) {
|
|
17440
|
+
this._tabIndicator = value;
|
|
17441
|
+
if (value !== undefined) {
|
|
17442
|
+
this.textBufferView.setTabIndicator(value);
|
|
17443
|
+
}
|
|
17444
|
+
this.requestRender();
|
|
17445
|
+
}
|
|
17446
|
+
}
|
|
17447
|
+
get tabIndicatorColor() {
|
|
17448
|
+
return this._tabIndicatorColor;
|
|
17449
|
+
}
|
|
17450
|
+
set tabIndicatorColor(value) {
|
|
17451
|
+
const newColor = value ? parseColor(value) : undefined;
|
|
17452
|
+
if (this._tabIndicatorColor !== newColor) {
|
|
17453
|
+
this._tabIndicatorColor = newColor;
|
|
17454
|
+
if (newColor !== undefined) {
|
|
17455
|
+
this.textBufferView.setTabIndicatorColor(newColor);
|
|
17456
|
+
}
|
|
17457
|
+
this.requestRender();
|
|
17458
|
+
}
|
|
17459
|
+
}
|
|
17460
|
+
get truncate() {
|
|
17461
|
+
return this._truncate;
|
|
17462
|
+
}
|
|
17463
|
+
set truncate(value) {
|
|
17464
|
+
if (this._truncate !== value) {
|
|
17465
|
+
this._truncate = value;
|
|
17466
|
+
this.textBufferView.setTruncate(value);
|
|
17467
|
+
this.requestRender();
|
|
17468
|
+
}
|
|
17469
|
+
}
|
|
17470
|
+
onResize(width, height) {
|
|
17471
|
+
this.textBufferView.setViewport(this._scrollX, this._scrollY, width, height);
|
|
17472
|
+
this.yogaNode.markDirty();
|
|
17473
|
+
this.requestRender();
|
|
17474
|
+
this.emit("line-info-change");
|
|
17475
|
+
}
|
|
17476
|
+
refreshLocalSelection() {
|
|
17477
|
+
if (this.lastLocalSelection) {
|
|
17478
|
+
return this.updateLocalSelection(this.lastLocalSelection);
|
|
17479
|
+
}
|
|
17480
|
+
return false;
|
|
17481
|
+
}
|
|
17482
|
+
updateLocalSelection(localSelection) {
|
|
17483
|
+
if (!localSelection?.isActive) {
|
|
17484
|
+
this.textBufferView.resetLocalSelection();
|
|
17485
|
+
return true;
|
|
17486
|
+
}
|
|
17487
|
+
return this.textBufferView.setLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg);
|
|
17488
|
+
}
|
|
17489
|
+
updateTextInfo() {
|
|
17490
|
+
if (this.lastLocalSelection) {
|
|
17491
|
+
this.updateLocalSelection(this.lastLocalSelection);
|
|
17492
|
+
}
|
|
17493
|
+
this.yogaNode.markDirty();
|
|
17494
|
+
this.requestRender();
|
|
17495
|
+
this.emit("line-info-change");
|
|
17496
|
+
}
|
|
17497
|
+
setupMeasureFunc() {
|
|
17498
|
+
const measureFunc = (width, widthMode, height, heightMode) => {
|
|
17499
|
+
let effectiveWidth;
|
|
17500
|
+
if (widthMode === MeasureMode.Undefined || isNaN(width)) {
|
|
17501
|
+
effectiveWidth = 0;
|
|
17502
|
+
} else {
|
|
17503
|
+
effectiveWidth = width;
|
|
17504
|
+
}
|
|
17505
|
+
const effectiveHeight = isNaN(height) ? 1 : height;
|
|
17506
|
+
const measureResult = this.textBufferView.measureForDimensions(Math.floor(effectiveWidth), Math.floor(effectiveHeight));
|
|
17507
|
+
const measuredWidth = measureResult ? Math.max(1, measureResult.widthColsMax) : 1;
|
|
17508
|
+
const measuredHeight = measureResult ? Math.max(1, measureResult.lineCount) : 1;
|
|
17509
|
+
if (widthMode === MeasureMode.AtMost && this._positionType !== "absolute") {
|
|
17510
|
+
return {
|
|
17511
|
+
width: Math.min(effectiveWidth, measuredWidth),
|
|
17512
|
+
height: Math.min(effectiveHeight, measuredHeight)
|
|
17513
|
+
};
|
|
17514
|
+
}
|
|
17515
|
+
return {
|
|
17516
|
+
width: measuredWidth,
|
|
17517
|
+
height: measuredHeight
|
|
17518
|
+
};
|
|
17519
|
+
};
|
|
17520
|
+
this.yogaNode.setMeasureFunc(measureFunc);
|
|
17521
|
+
}
|
|
17522
|
+
shouldStartSelection(x, y) {
|
|
17523
|
+
if (!this.selectable)
|
|
17524
|
+
return false;
|
|
17525
|
+
const localX = x - this.x;
|
|
17526
|
+
const localY = y - this.y;
|
|
17527
|
+
return localX >= 0 && localX < this.width && localY >= 0 && localY < this.height;
|
|
17528
|
+
}
|
|
17529
|
+
onSelectionChanged(selection2) {
|
|
17530
|
+
const localSelection = convertGlobalToLocalSelection(selection2, this.x, this.y);
|
|
17531
|
+
this.lastLocalSelection = localSelection;
|
|
17532
|
+
let changed;
|
|
17533
|
+
if (!localSelection?.isActive) {
|
|
17534
|
+
this.textBufferView.resetLocalSelection();
|
|
17535
|
+
changed = true;
|
|
17536
|
+
} else if (selection2?.isStart) {
|
|
17537
|
+
changed = this.textBufferView.setLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg);
|
|
17538
|
+
} else {
|
|
17539
|
+
changed = this.textBufferView.updateLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg);
|
|
17540
|
+
}
|
|
17541
|
+
if (changed) {
|
|
17542
|
+
this.requestRender();
|
|
17543
|
+
}
|
|
17544
|
+
return this.hasSelection();
|
|
17545
|
+
}
|
|
17546
|
+
getSelectedText() {
|
|
17547
|
+
return this.textBufferView.getSelectedText();
|
|
17548
|
+
}
|
|
17549
|
+
hasSelection() {
|
|
17550
|
+
return this.textBufferView.hasSelection();
|
|
17551
|
+
}
|
|
17552
|
+
getSelection() {
|
|
17553
|
+
return this.textBufferView.getSelection();
|
|
17554
|
+
}
|
|
17555
|
+
render(buffer, deltaTime) {
|
|
17556
|
+
if (!this.visible)
|
|
17557
|
+
return;
|
|
17558
|
+
const screenX = this._screenX;
|
|
17559
|
+
const screenY = this._screenY;
|
|
17560
|
+
this.markClean();
|
|
17561
|
+
this._ctx.addToHitGrid(screenX, screenY, this.width, this.height, this.num);
|
|
17562
|
+
this.renderSelf(buffer);
|
|
17563
|
+
if (this.buffered && this.frameBuffer) {
|
|
17564
|
+
buffer.drawFrameBuffer(screenX, screenY, this.frameBuffer);
|
|
17565
|
+
}
|
|
17566
|
+
}
|
|
17567
|
+
renderSelf(buffer) {
|
|
17568
|
+
if (this.textBuffer.ptr) {
|
|
17569
|
+
buffer.drawTextBuffer(this.textBufferView, this._screenX, this._screenY);
|
|
17570
|
+
}
|
|
17571
|
+
}
|
|
17572
|
+
destroy() {
|
|
17573
|
+
if (this.isDestroyed)
|
|
17574
|
+
return;
|
|
17575
|
+
this.textBuffer.setSyntaxStyle(null);
|
|
17576
|
+
this._textBufferSyntaxStyle.destroy();
|
|
17577
|
+
this.textBufferView.destroy();
|
|
17578
|
+
this.textBuffer.destroy();
|
|
17579
|
+
super.destroy();
|
|
17580
|
+
}
|
|
17581
|
+
onFgChanged(newColor) {}
|
|
17582
|
+
onBgChanged(newColor) {}
|
|
17583
|
+
onAttributesChanged(newAttributes) {}
|
|
17584
|
+
}
|
|
17585
|
+
|
|
17586
|
+
// src/renderables/Code.ts
|
|
17587
|
+
class CodeRenderable extends TextBufferRenderable {
|
|
17588
|
+
_content;
|
|
17589
|
+
_filetype;
|
|
17590
|
+
_syntaxStyle;
|
|
17591
|
+
_isHighlighting = false;
|
|
17592
|
+
_treeSitterClient;
|
|
17593
|
+
_highlightsDirty = false;
|
|
17594
|
+
_highlightSnapshotId = 0;
|
|
17595
|
+
_conceal;
|
|
17596
|
+
_drawUnstyledText;
|
|
17597
|
+
_shouldRenderTextBuffer = true;
|
|
17598
|
+
_streaming;
|
|
17599
|
+
_hadInitialContent = false;
|
|
17600
|
+
_lastHighlights = [];
|
|
17601
|
+
_onHighlight;
|
|
17602
|
+
_onChunks;
|
|
17603
|
+
_highlightingPromise = Promise.resolve();
|
|
17604
|
+
_contentDefaultOptions = {
|
|
17605
|
+
content: "",
|
|
17606
|
+
conceal: true,
|
|
17607
|
+
drawUnstyledText: true,
|
|
17608
|
+
streaming: false
|
|
17609
|
+
};
|
|
17610
|
+
constructor(ctx, options) {
|
|
17611
|
+
super(ctx, options);
|
|
17612
|
+
this._content = options.content ?? this._contentDefaultOptions.content;
|
|
17613
|
+
this._filetype = options.filetype;
|
|
17614
|
+
this._syntaxStyle = options.syntaxStyle;
|
|
17615
|
+
this._treeSitterClient = options.treeSitterClient ?? getTreeSitterClient();
|
|
17616
|
+
this._conceal = options.conceal ?? this._contentDefaultOptions.conceal;
|
|
17617
|
+
this._drawUnstyledText = options.drawUnstyledText ?? this._contentDefaultOptions.drawUnstyledText;
|
|
17618
|
+
this._streaming = options.streaming ?? this._contentDefaultOptions.streaming;
|
|
17619
|
+
this._onHighlight = options.onHighlight;
|
|
17620
|
+
this._onChunks = options.onChunks;
|
|
17621
|
+
if (this._content.length > 0) {
|
|
17622
|
+
this.textBuffer.setText(this._content);
|
|
17623
|
+
this.updateTextInfo();
|
|
17624
|
+
this._shouldRenderTextBuffer = this._drawUnstyledText || !this._filetype;
|
|
17625
|
+
}
|
|
17626
|
+
this._highlightsDirty = this._content.length > 0;
|
|
17627
|
+
}
|
|
17628
|
+
get content() {
|
|
17629
|
+
return this._content;
|
|
17630
|
+
}
|
|
17631
|
+
set content(value) {
|
|
17632
|
+
if (this._content !== value) {
|
|
17633
|
+
this._content = value;
|
|
17634
|
+
this._highlightsDirty = true;
|
|
17635
|
+
this._highlightSnapshotId++;
|
|
17636
|
+
if (this._streaming && !this._drawUnstyledText && this._filetype) {
|
|
17637
|
+
return;
|
|
17638
|
+
}
|
|
17639
|
+
this.textBuffer.setText(value);
|
|
17640
|
+
this.updateTextInfo();
|
|
17641
|
+
}
|
|
17642
|
+
}
|
|
17643
|
+
get filetype() {
|
|
17644
|
+
return this._filetype;
|
|
17645
|
+
}
|
|
17646
|
+
set filetype(value) {
|
|
17647
|
+
if (this._filetype !== value) {
|
|
17648
|
+
this._filetype = value;
|
|
17649
|
+
this._highlightsDirty = true;
|
|
17650
|
+
}
|
|
17651
|
+
}
|
|
17652
|
+
get syntaxStyle() {
|
|
17653
|
+
return this._syntaxStyle;
|
|
17654
|
+
}
|
|
17655
|
+
set syntaxStyle(value) {
|
|
17656
|
+
if (this._syntaxStyle !== value) {
|
|
17657
|
+
this._syntaxStyle = value;
|
|
17658
|
+
this._highlightsDirty = true;
|
|
17659
|
+
}
|
|
17660
|
+
}
|
|
17661
|
+
get conceal() {
|
|
17662
|
+
return this._conceal;
|
|
17663
|
+
}
|
|
17664
|
+
set conceal(value) {
|
|
17665
|
+
if (this._conceal !== value) {
|
|
17666
|
+
this._conceal = value;
|
|
17667
|
+
this._highlightsDirty = true;
|
|
17668
|
+
}
|
|
17669
|
+
}
|
|
17670
|
+
get drawUnstyledText() {
|
|
17671
|
+
return this._drawUnstyledText;
|
|
17672
|
+
}
|
|
17673
|
+
set drawUnstyledText(value) {
|
|
17674
|
+
if (this._drawUnstyledText !== value) {
|
|
17675
|
+
this._drawUnstyledText = value;
|
|
17676
|
+
this._highlightsDirty = true;
|
|
17677
|
+
}
|
|
17678
|
+
}
|
|
17679
|
+
get streaming() {
|
|
17680
|
+
return this._streaming;
|
|
17681
|
+
}
|
|
17682
|
+
set streaming(value) {
|
|
17683
|
+
if (this._streaming !== value) {
|
|
17684
|
+
this._streaming = value;
|
|
17685
|
+
this._hadInitialContent = false;
|
|
17686
|
+
this._lastHighlights = [];
|
|
17687
|
+
this._highlightsDirty = true;
|
|
17688
|
+
}
|
|
17689
|
+
}
|
|
17690
|
+
get treeSitterClient() {
|
|
17691
|
+
return this._treeSitterClient;
|
|
17692
|
+
}
|
|
17693
|
+
set treeSitterClient(value) {
|
|
17694
|
+
if (this._treeSitterClient !== value) {
|
|
17695
|
+
this._treeSitterClient = value;
|
|
17696
|
+
this._highlightsDirty = true;
|
|
17697
|
+
}
|
|
17698
|
+
}
|
|
17699
|
+
get onHighlight() {
|
|
17700
|
+
return this._onHighlight;
|
|
17701
|
+
}
|
|
17702
|
+
set onHighlight(value) {
|
|
17703
|
+
if (this._onHighlight !== value) {
|
|
17704
|
+
this._onHighlight = value;
|
|
17705
|
+
this._highlightsDirty = true;
|
|
17706
|
+
}
|
|
17707
|
+
}
|
|
17708
|
+
get onChunks() {
|
|
17709
|
+
return this._onChunks;
|
|
17710
|
+
}
|
|
17711
|
+
set onChunks(value) {
|
|
17712
|
+
if (this._onChunks !== value) {
|
|
17713
|
+
this._onChunks = value;
|
|
17714
|
+
this._highlightsDirty = true;
|
|
17715
|
+
}
|
|
17716
|
+
}
|
|
17717
|
+
get isHighlighting() {
|
|
17718
|
+
return this._isHighlighting;
|
|
17719
|
+
}
|
|
17720
|
+
get highlightingDone() {
|
|
17721
|
+
return this._highlightingPromise;
|
|
17722
|
+
}
|
|
17723
|
+
async transformChunks(chunks, context) {
|
|
17724
|
+
if (!this._onChunks)
|
|
17725
|
+
return chunks;
|
|
17726
|
+
const modified = await this._onChunks(chunks, context);
|
|
17727
|
+
return modified ?? chunks;
|
|
17728
|
+
}
|
|
17729
|
+
ensureVisibleTextBeforeHighlight() {
|
|
17730
|
+
if (this.isDestroyed)
|
|
17731
|
+
return;
|
|
17732
|
+
const content = this._content;
|
|
17733
|
+
if (!this._filetype) {
|
|
17734
|
+
this._shouldRenderTextBuffer = true;
|
|
17735
|
+
return;
|
|
17736
|
+
}
|
|
17737
|
+
const isInitialContent = this._streaming && !this._hadInitialContent;
|
|
17738
|
+
const shouldDrawUnstyledNow = this._streaming ? isInitialContent && this._drawUnstyledText : this._drawUnstyledText;
|
|
17739
|
+
if (this._streaming && !isInitialContent) {
|
|
17740
|
+
this._shouldRenderTextBuffer = true;
|
|
17741
|
+
} else if (shouldDrawUnstyledNow) {
|
|
17742
|
+
this.textBuffer.setText(content);
|
|
17743
|
+
this._shouldRenderTextBuffer = true;
|
|
17744
|
+
} else {
|
|
17745
|
+
this._shouldRenderTextBuffer = false;
|
|
17746
|
+
}
|
|
17747
|
+
}
|
|
17748
|
+
async startHighlight() {
|
|
17749
|
+
const content = this._content;
|
|
17750
|
+
const filetype = this._filetype;
|
|
17751
|
+
const snapshotId = ++this._highlightSnapshotId;
|
|
17752
|
+
if (!filetype)
|
|
17753
|
+
return;
|
|
17754
|
+
const isInitialContent = this._streaming && !this._hadInitialContent;
|
|
17755
|
+
if (isInitialContent) {
|
|
17756
|
+
this._hadInitialContent = true;
|
|
17757
|
+
}
|
|
17758
|
+
this._isHighlighting = true;
|
|
17759
|
+
try {
|
|
17760
|
+
const result = await this._treeSitterClient.highlightOnce(content, filetype);
|
|
17761
|
+
if (snapshotId !== this._highlightSnapshotId) {
|
|
17762
|
+
return;
|
|
17763
|
+
}
|
|
17764
|
+
if (this.isDestroyed)
|
|
17765
|
+
return;
|
|
17766
|
+
let highlights = result.highlights ?? [];
|
|
17767
|
+
if (this._onHighlight && highlights.length >= 0) {
|
|
17768
|
+
const context = {
|
|
17769
|
+
content,
|
|
17770
|
+
filetype,
|
|
17771
|
+
syntaxStyle: this._syntaxStyle
|
|
17772
|
+
};
|
|
17773
|
+
const modified = await this._onHighlight(highlights, context);
|
|
17774
|
+
if (modified !== undefined) {
|
|
17775
|
+
highlights = modified;
|
|
17776
|
+
}
|
|
17777
|
+
}
|
|
17778
|
+
if (snapshotId !== this._highlightSnapshotId) {
|
|
17779
|
+
return;
|
|
17780
|
+
}
|
|
17781
|
+
if (this.isDestroyed)
|
|
17782
|
+
return;
|
|
17783
|
+
if (highlights.length > 0) {
|
|
17784
|
+
if (this._streaming) {
|
|
17785
|
+
this._lastHighlights = highlights;
|
|
17786
|
+
}
|
|
17787
|
+
}
|
|
17788
|
+
if (highlights.length > 0 || this._onChunks) {
|
|
17789
|
+
const context = {
|
|
17790
|
+
content,
|
|
17791
|
+
filetype,
|
|
17792
|
+
syntaxStyle: this._syntaxStyle,
|
|
17793
|
+
highlights
|
|
17794
|
+
};
|
|
17795
|
+
let chunks = treeSitterToTextChunks(content, highlights, this._syntaxStyle, {
|
|
17796
|
+
enabled: this._conceal
|
|
17797
|
+
});
|
|
17798
|
+
chunks = await this.transformChunks(chunks, context);
|
|
17799
|
+
if (snapshotId !== this._highlightSnapshotId) {
|
|
17800
|
+
return;
|
|
17801
|
+
}
|
|
17802
|
+
if (this.isDestroyed)
|
|
17803
|
+
return;
|
|
17804
|
+
const styledText = new StyledText(chunks);
|
|
17805
|
+
this.textBuffer.setStyledText(styledText);
|
|
17806
|
+
} else {
|
|
17807
|
+
this.textBuffer.setText(content);
|
|
17808
|
+
}
|
|
17809
|
+
this._shouldRenderTextBuffer = true;
|
|
17810
|
+
this._isHighlighting = false;
|
|
17811
|
+
this._highlightsDirty = false;
|
|
17812
|
+
this.updateTextInfo();
|
|
17813
|
+
this.requestRender();
|
|
17814
|
+
} catch (error) {
|
|
17815
|
+
if (snapshotId !== this._highlightSnapshotId) {
|
|
17816
|
+
return;
|
|
17817
|
+
}
|
|
17818
|
+
console.warn("Code highlighting failed, falling back to plain text:", error);
|
|
17819
|
+
if (this.isDestroyed)
|
|
17820
|
+
return;
|
|
17821
|
+
this.textBuffer.setText(content);
|
|
17822
|
+
this._shouldRenderTextBuffer = true;
|
|
17823
|
+
this._isHighlighting = false;
|
|
17824
|
+
this._highlightsDirty = false;
|
|
17825
|
+
this.updateTextInfo();
|
|
17826
|
+
this.requestRender();
|
|
17827
|
+
}
|
|
17828
|
+
}
|
|
17829
|
+
getLineHighlights(lineIdx) {
|
|
17830
|
+
return this.textBuffer.getLineHighlights(lineIdx);
|
|
17831
|
+
}
|
|
17832
|
+
renderSelf(buffer) {
|
|
17833
|
+
if (this._highlightsDirty) {
|
|
17834
|
+
if (this.isDestroyed)
|
|
17835
|
+
return;
|
|
17836
|
+
if (this._content.length === 0) {
|
|
17837
|
+
this._shouldRenderTextBuffer = false;
|
|
17838
|
+
this._highlightsDirty = false;
|
|
17839
|
+
} else if (!this._filetype) {
|
|
17840
|
+
this._shouldRenderTextBuffer = true;
|
|
17841
|
+
this._highlightsDirty = false;
|
|
17842
|
+
} else {
|
|
17843
|
+
this.ensureVisibleTextBeforeHighlight();
|
|
17844
|
+
this._highlightsDirty = false;
|
|
17845
|
+
this._highlightingPromise = this.startHighlight();
|
|
17846
|
+
}
|
|
17847
|
+
}
|
|
17848
|
+
if (!this._shouldRenderTextBuffer)
|
|
17849
|
+
return;
|
|
17850
|
+
super.renderSelf(buffer);
|
|
17851
|
+
}
|
|
17852
|
+
}
|
|
17853
|
+
|
|
17854
|
+
// src/renderables/TextNode.ts
|
|
17855
|
+
var BrandedTextNodeRenderable = Symbol.for("@opentui/core/TextNodeRenderable");
|
|
17856
|
+
function isTextNodeRenderable(obj) {
|
|
17857
|
+
return !!obj?.[BrandedTextNodeRenderable];
|
|
17858
|
+
}
|
|
17859
|
+
function styledTextToTextNodes(styledText) {
|
|
17860
|
+
return styledText.chunks.map((chunk) => {
|
|
17861
|
+
const node = new TextNodeRenderable({
|
|
17862
|
+
fg: chunk.fg,
|
|
17863
|
+
bg: chunk.bg,
|
|
17864
|
+
attributes: chunk.attributes,
|
|
17865
|
+
link: chunk.link
|
|
17866
|
+
});
|
|
17867
|
+
node.add(chunk.text);
|
|
17868
|
+
return node;
|
|
17869
|
+
});
|
|
17870
|
+
}
|
|
17871
|
+
|
|
17872
|
+
class TextNodeRenderable extends BaseRenderable {
|
|
17873
|
+
[BrandedTextNodeRenderable] = true;
|
|
17874
|
+
_fg;
|
|
17875
|
+
_bg;
|
|
17876
|
+
_attributes;
|
|
17877
|
+
_link;
|
|
17878
|
+
_children = [];
|
|
17879
|
+
parent = null;
|
|
17880
|
+
constructor(options) {
|
|
17881
|
+
super(options);
|
|
17882
|
+
this._fg = options.fg ? parseColor(options.fg) : undefined;
|
|
17883
|
+
this._bg = options.bg ? parseColor(options.bg) : undefined;
|
|
17884
|
+
this._attributes = options.attributes ?? 0;
|
|
17885
|
+
this._link = options.link;
|
|
17886
|
+
}
|
|
17887
|
+
get children() {
|
|
17888
|
+
return this._children;
|
|
17889
|
+
}
|
|
17890
|
+
set children(children) {
|
|
17891
|
+
this._children = children;
|
|
17892
|
+
this.requestRender();
|
|
17893
|
+
}
|
|
17894
|
+
requestRender() {
|
|
17895
|
+
this.markDirty();
|
|
17896
|
+
this.parent?.requestRender();
|
|
17897
|
+
}
|
|
17898
|
+
add(obj, index) {
|
|
17899
|
+
if (typeof obj === "string") {
|
|
17900
|
+
if (index !== undefined) {
|
|
17901
|
+
this._children.splice(index, 0, obj);
|
|
17902
|
+
this.requestRender();
|
|
17903
|
+
return index;
|
|
17904
|
+
}
|
|
17905
|
+
const insertIndex = this._children.length;
|
|
17906
|
+
this._children.push(obj);
|
|
17907
|
+
this.requestRender();
|
|
17908
|
+
return insertIndex;
|
|
17909
|
+
}
|
|
17910
|
+
if (isTextNodeRenderable(obj)) {
|
|
17911
|
+
if (index !== undefined) {
|
|
17912
|
+
this._children.splice(index, 0, obj);
|
|
17913
|
+
obj.parent = this;
|
|
17914
|
+
this.requestRender();
|
|
17915
|
+
return index;
|
|
17916
|
+
}
|
|
17917
|
+
const insertIndex = this._children.length;
|
|
17918
|
+
this._children.push(obj);
|
|
17919
|
+
obj.parent = this;
|
|
17920
|
+
this.requestRender();
|
|
17921
|
+
return insertIndex;
|
|
17922
|
+
}
|
|
17923
|
+
if (isStyledText(obj)) {
|
|
17924
|
+
const textNodes = styledTextToTextNodes(obj);
|
|
17925
|
+
if (index !== undefined) {
|
|
17926
|
+
this._children.splice(index, 0, ...textNodes);
|
|
17927
|
+
textNodes.forEach((node) => node.parent = this);
|
|
17928
|
+
this.requestRender();
|
|
17929
|
+
return index;
|
|
17930
|
+
}
|
|
17931
|
+
const insertIndex = this._children.length;
|
|
17932
|
+
this._children.push(...textNodes);
|
|
17933
|
+
textNodes.forEach((node) => node.parent = this);
|
|
17934
|
+
this.requestRender();
|
|
17935
|
+
return insertIndex;
|
|
17936
|
+
}
|
|
17937
|
+
throw new Error("TextNodeRenderable only accepts strings, TextNodeRenderable instances, or StyledText instances");
|
|
17938
|
+
}
|
|
17939
|
+
replace(obj, index) {
|
|
17940
|
+
this._children[index] = obj;
|
|
17941
|
+
if (typeof obj !== "string") {
|
|
17942
|
+
obj.parent = this;
|
|
17943
|
+
}
|
|
17944
|
+
this.requestRender();
|
|
17945
|
+
}
|
|
17946
|
+
insertBefore(child, anchorNode) {
|
|
17947
|
+
if (!anchorNode || !isTextNodeRenderable(anchorNode)) {
|
|
17948
|
+
throw new Error("Anchor must be a TextNodeRenderable");
|
|
17949
|
+
}
|
|
17950
|
+
const anchorIndex = this._children.indexOf(anchorNode);
|
|
17951
|
+
if (anchorIndex === -1) {
|
|
17952
|
+
throw new Error("Anchor node not found in children");
|
|
17953
|
+
}
|
|
17954
|
+
if (typeof child === "string") {
|
|
17955
|
+
this._children.splice(anchorIndex, 0, child);
|
|
17956
|
+
} else if (isTextNodeRenderable(child)) {
|
|
17957
|
+
this._children.splice(anchorIndex, 0, child);
|
|
17958
|
+
child.parent = this;
|
|
17959
|
+
} else if (child instanceof StyledText) {
|
|
17960
|
+
const textNodes = styledTextToTextNodes(child);
|
|
17961
|
+
this._children.splice(anchorIndex, 0, ...textNodes);
|
|
17962
|
+
textNodes.forEach((node) => node.parent = this);
|
|
17963
|
+
} else {
|
|
17964
|
+
throw new Error("Child must be a string, TextNodeRenderable, or StyledText instance");
|
|
17965
|
+
}
|
|
17966
|
+
this.requestRender();
|
|
17967
|
+
return this;
|
|
17968
|
+
}
|
|
17969
|
+
remove(id) {
|
|
17970
|
+
const childIndex = this.getRenderableIndex(id);
|
|
17971
|
+
if (childIndex === -1) {
|
|
17972
|
+
throw new Error("Child not found in children");
|
|
17973
|
+
}
|
|
17974
|
+
const child = this._children[childIndex];
|
|
17975
|
+
this._children.splice(childIndex, 1);
|
|
17976
|
+
child.parent = null;
|
|
17977
|
+
this.requestRender();
|
|
17978
|
+
return this;
|
|
17979
|
+
}
|
|
17980
|
+
clear() {
|
|
17981
|
+
this._children = [];
|
|
17982
|
+
this.requestRender();
|
|
17983
|
+
}
|
|
17984
|
+
mergeStyles(parentStyle) {
|
|
17985
|
+
return {
|
|
17986
|
+
fg: this._fg ?? parentStyle.fg,
|
|
17987
|
+
bg: this._bg ?? parentStyle.bg,
|
|
17988
|
+
attributes: this._attributes | parentStyle.attributes,
|
|
17989
|
+
link: this._link ?? parentStyle.link
|
|
17990
|
+
};
|
|
17991
|
+
}
|
|
17992
|
+
gatherWithInheritedStyle(parentStyle = {
|
|
17993
|
+
fg: undefined,
|
|
17994
|
+
bg: undefined,
|
|
17995
|
+
attributes: 0
|
|
17996
|
+
}) {
|
|
17997
|
+
const currentStyle = this.mergeStyles(parentStyle);
|
|
17998
|
+
const chunks = [];
|
|
17999
|
+
for (const child of this._children) {
|
|
18000
|
+
if (typeof child === "string") {
|
|
18001
|
+
chunks.push({
|
|
18002
|
+
__isChunk: true,
|
|
18003
|
+
text: child,
|
|
18004
|
+
fg: currentStyle.fg,
|
|
18005
|
+
bg: currentStyle.bg,
|
|
18006
|
+
attributes: currentStyle.attributes,
|
|
18007
|
+
link: currentStyle.link
|
|
18008
|
+
});
|
|
18009
|
+
} else {
|
|
18010
|
+
const childChunks = child.gatherWithInheritedStyle(currentStyle);
|
|
18011
|
+
chunks.push(...childChunks);
|
|
18012
|
+
}
|
|
18013
|
+
}
|
|
18014
|
+
this.markClean();
|
|
18015
|
+
return chunks;
|
|
18016
|
+
}
|
|
18017
|
+
static fromString(text, options = {}) {
|
|
18018
|
+
const node = new TextNodeRenderable(options);
|
|
18019
|
+
node.add(text);
|
|
18020
|
+
return node;
|
|
18021
|
+
}
|
|
18022
|
+
static fromNodes(nodes, options = {}) {
|
|
18023
|
+
const node = new TextNodeRenderable(options);
|
|
18024
|
+
for (const childNode of nodes) {
|
|
18025
|
+
node.add(childNode);
|
|
18026
|
+
}
|
|
18027
|
+
return node;
|
|
18028
|
+
}
|
|
18029
|
+
toChunks(parentStyle = {
|
|
18030
|
+
fg: undefined,
|
|
18031
|
+
bg: undefined,
|
|
18032
|
+
attributes: 0
|
|
18033
|
+
}) {
|
|
18034
|
+
return this.gatherWithInheritedStyle(parentStyle);
|
|
18035
|
+
}
|
|
18036
|
+
getChildren() {
|
|
18037
|
+
return this._children.filter((child) => typeof child !== "string");
|
|
18038
|
+
}
|
|
18039
|
+
getChildrenCount() {
|
|
18040
|
+
return this._children.length;
|
|
18041
|
+
}
|
|
18042
|
+
getRenderable(id) {
|
|
18043
|
+
return this._children.find((child) => typeof child !== "string" && child.id === id);
|
|
18044
|
+
}
|
|
18045
|
+
getRenderableIndex(id) {
|
|
18046
|
+
return this._children.findIndex((child) => isTextNodeRenderable(child) && child.id === id);
|
|
18047
|
+
}
|
|
18048
|
+
get fg() {
|
|
18049
|
+
return this._fg;
|
|
18050
|
+
}
|
|
18051
|
+
set fg(fg2) {
|
|
18052
|
+
if (!fg2) {
|
|
18053
|
+
this._fg = undefined;
|
|
18054
|
+
this.requestRender();
|
|
18055
|
+
return;
|
|
18056
|
+
}
|
|
18057
|
+
this._fg = parseColor(fg2);
|
|
18058
|
+
this.requestRender();
|
|
18059
|
+
}
|
|
18060
|
+
set bg(bg2) {
|
|
18061
|
+
if (!bg2) {
|
|
18062
|
+
this._bg = undefined;
|
|
18063
|
+
this.requestRender();
|
|
18064
|
+
return;
|
|
18065
|
+
}
|
|
18066
|
+
this._bg = parseColor(bg2);
|
|
18067
|
+
this.requestRender();
|
|
18068
|
+
}
|
|
18069
|
+
get bg() {
|
|
18070
|
+
return this._bg;
|
|
18071
|
+
}
|
|
18072
|
+
set attributes(attributes) {
|
|
18073
|
+
this._attributes = attributes;
|
|
18074
|
+
this.requestRender();
|
|
18075
|
+
}
|
|
18076
|
+
get attributes() {
|
|
18077
|
+
return this._attributes;
|
|
18078
|
+
}
|
|
18079
|
+
set link(link2) {
|
|
18080
|
+
this._link = link2;
|
|
18081
|
+
this.requestRender();
|
|
18082
|
+
}
|
|
18083
|
+
get link() {
|
|
18084
|
+
return this._link;
|
|
18085
|
+
}
|
|
18086
|
+
findDescendantById(id) {
|
|
18087
|
+
return;
|
|
18088
|
+
}
|
|
18089
|
+
}
|
|
18090
|
+
|
|
18091
|
+
class RootTextNodeRenderable extends TextNodeRenderable {
|
|
18092
|
+
ctx;
|
|
18093
|
+
textParent;
|
|
18094
|
+
constructor(ctx, options, textParent) {
|
|
18095
|
+
super(options);
|
|
18096
|
+
this.ctx = ctx;
|
|
18097
|
+
this.textParent = textParent;
|
|
18098
|
+
}
|
|
18099
|
+
requestRender() {
|
|
18100
|
+
this.markDirty();
|
|
18101
|
+
this.ctx.requestRender();
|
|
18102
|
+
}
|
|
18103
|
+
}
|
|
18104
|
+
|
|
18105
|
+
// src/renderables/Text.ts
|
|
18106
|
+
class TextRenderable extends TextBufferRenderable {
|
|
18107
|
+
_text;
|
|
18108
|
+
_hasManualStyledText = false;
|
|
18109
|
+
rootTextNode;
|
|
18110
|
+
_contentDefaultOptions = {
|
|
18111
|
+
content: ""
|
|
18112
|
+
};
|
|
18113
|
+
constructor(ctx, options) {
|
|
18114
|
+
super(ctx, options);
|
|
18115
|
+
const content = options.content ?? this._contentDefaultOptions.content;
|
|
18116
|
+
const styledText = typeof content === "string" ? stringToStyledText(content) : content;
|
|
18117
|
+
this._text = styledText;
|
|
18118
|
+
this._hasManualStyledText = options.content !== undefined && content !== "";
|
|
18119
|
+
this.rootTextNode = new RootTextNodeRenderable(ctx, {
|
|
18120
|
+
id: `${this.id}-root`,
|
|
18121
|
+
fg: this._defaultFg,
|
|
18122
|
+
bg: this._defaultBg,
|
|
18123
|
+
attributes: this._defaultAttributes
|
|
18124
|
+
}, this);
|
|
18125
|
+
this.updateTextBuffer(styledText);
|
|
18126
|
+
}
|
|
18127
|
+
updateTextBuffer(styledText) {
|
|
18128
|
+
this.textBuffer.setStyledText(styledText);
|
|
18129
|
+
this.clearChunks(styledText);
|
|
18130
|
+
}
|
|
18131
|
+
clearChunks(styledText) {}
|
|
18132
|
+
get content() {
|
|
18133
|
+
return this._text;
|
|
18134
|
+
}
|
|
18135
|
+
get chunks() {
|
|
18136
|
+
return this._text.chunks;
|
|
18137
|
+
}
|
|
18138
|
+
get textNode() {
|
|
18139
|
+
return this.rootTextNode;
|
|
18140
|
+
}
|
|
18141
|
+
set content(value) {
|
|
18142
|
+
this._hasManualStyledText = true;
|
|
18143
|
+
const styledText = typeof value === "string" ? stringToStyledText(value) : value;
|
|
18144
|
+
if (this._text !== styledText) {
|
|
18145
|
+
this._text = styledText;
|
|
18146
|
+
this.updateTextBuffer(styledText);
|
|
18147
|
+
this.updateTextInfo();
|
|
18148
|
+
}
|
|
18149
|
+
}
|
|
18150
|
+
updateTextFromNodes() {
|
|
18151
|
+
if (this.rootTextNode.isDirty && !this._hasManualStyledText) {
|
|
18152
|
+
const chunks = this.rootTextNode.gatherWithInheritedStyle({
|
|
18153
|
+
fg: this._defaultFg,
|
|
18154
|
+
bg: this._defaultBg,
|
|
18155
|
+
attributes: this._defaultAttributes,
|
|
18156
|
+
link: undefined
|
|
18157
|
+
});
|
|
18158
|
+
this.textBuffer.setStyledText(new StyledText(chunks));
|
|
18159
|
+
this.refreshLocalSelection();
|
|
18160
|
+
this.yogaNode.markDirty();
|
|
18161
|
+
}
|
|
18162
|
+
}
|
|
18163
|
+
add(obj, index) {
|
|
18164
|
+
return this.rootTextNode.add(obj, index);
|
|
18165
|
+
}
|
|
18166
|
+
remove(id) {
|
|
18167
|
+
this.rootTextNode.remove(id);
|
|
18168
|
+
}
|
|
18169
|
+
insertBefore(obj, anchor) {
|
|
18170
|
+
this.rootTextNode.insertBefore(obj, anchor);
|
|
18171
|
+
return this.rootTextNode.children.indexOf(obj);
|
|
18172
|
+
}
|
|
18173
|
+
getTextChildren() {
|
|
18174
|
+
return this.rootTextNode.getChildren();
|
|
18175
|
+
}
|
|
18176
|
+
clear() {
|
|
18177
|
+
this.rootTextNode.clear();
|
|
18178
|
+
const emptyStyledText = stringToStyledText("");
|
|
18179
|
+
this._text = emptyStyledText;
|
|
18180
|
+
this.updateTextBuffer(emptyStyledText);
|
|
18181
|
+
this.updateTextInfo();
|
|
18182
|
+
this.requestRender();
|
|
18183
|
+
}
|
|
18184
|
+
onLifecyclePass = () => {
|
|
18185
|
+
this.updateTextFromNodes();
|
|
18186
|
+
};
|
|
18187
|
+
onFgChanged(newColor) {
|
|
18188
|
+
this.rootTextNode.fg = newColor;
|
|
18189
|
+
}
|
|
18190
|
+
onBgChanged(newColor) {
|
|
18191
|
+
this.rootTextNode.bg = newColor;
|
|
18192
|
+
}
|
|
18193
|
+
onAttributesChanged(newAttributes) {
|
|
18194
|
+
this.rootTextNode.attributes = newAttributes;
|
|
18195
|
+
}
|
|
18196
|
+
destroy() {
|
|
18197
|
+
this.rootTextNode.children.length = 0;
|
|
18198
|
+
super.destroy();
|
|
18199
|
+
}
|
|
18200
|
+
}
|
|
18201
|
+
|
|
18202
|
+
// src/console.ts
|
|
18203
|
+
import { EventEmitter as EventEmitter8 } from "events";
|
|
18204
|
+
import { Console } from "console";
|
|
18205
|
+
import fs from "fs";
|
|
18206
|
+
import path5 from "path";
|
|
18207
|
+
import util2 from "util";
|
|
18208
|
+
|
|
18209
|
+
// src/lib/output.capture.ts
|
|
18210
|
+
import { Writable } from "stream";
|
|
18211
|
+
import { EventEmitter as EventEmitter7 } from "events";
|
|
18212
|
+
|
|
18213
|
+
class Capture extends EventEmitter7 {
|
|
18214
|
+
output = [];
|
|
18215
|
+
constructor() {
|
|
18216
|
+
super();
|
|
18217
|
+
}
|
|
18218
|
+
get size() {
|
|
18219
|
+
return this.output.length;
|
|
18220
|
+
}
|
|
18221
|
+
write(stream, data) {
|
|
18222
|
+
this.output.push({ stream, output: data });
|
|
18223
|
+
this.emit("write", stream, data);
|
|
18224
|
+
}
|
|
18225
|
+
claimOutput() {
|
|
18226
|
+
const output = this.output.map((o) => o.output).join("");
|
|
18227
|
+
this.clear();
|
|
18228
|
+
return output;
|
|
18229
|
+
}
|
|
18230
|
+
clear() {
|
|
18231
|
+
this.output = [];
|
|
18232
|
+
}
|
|
18233
|
+
}
|
|
18234
|
+
|
|
18235
|
+
class CapturedWritableStream extends Writable {
|
|
18236
|
+
stream;
|
|
18237
|
+
capture;
|
|
18238
|
+
isTTY = true;
|
|
18239
|
+
columns = process.stdout.columns || 80;
|
|
18240
|
+
rows = process.stdout.rows || 24;
|
|
18241
|
+
constructor(stream, capture) {
|
|
18242
|
+
super();
|
|
18243
|
+
this.stream = stream;
|
|
18244
|
+
this.capture = capture;
|
|
18245
|
+
}
|
|
18246
|
+
_write(chunk, encoding, callback) {
|
|
18247
|
+
const data = chunk.toString();
|
|
18248
|
+
this.capture.write(this.stream, data);
|
|
18249
|
+
callback();
|
|
18250
|
+
}
|
|
18251
|
+
getColorDepth() {
|
|
18252
|
+
return process.stdout.getColorDepth?.() || 8;
|
|
18253
|
+
}
|
|
18254
|
+
}
|
|
18255
|
+
|
|
18256
|
+
// src/lib/keymapping.ts
|
|
18257
|
+
var defaultKeyAliases = {
|
|
18258
|
+
enter: "return",
|
|
18259
|
+
esc: "escape",
|
|
18260
|
+
kp0: "0",
|
|
18261
|
+
kp1: "1",
|
|
18262
|
+
kp2: "2",
|
|
18263
|
+
kp3: "3",
|
|
18264
|
+
kp4: "4",
|
|
18265
|
+
kp5: "5",
|
|
18266
|
+
kp6: "6",
|
|
18267
|
+
kp7: "7",
|
|
18268
|
+
kp8: "8",
|
|
18269
|
+
kp9: "9",
|
|
18270
|
+
kpdecimal: ".",
|
|
18271
|
+
kpdivide: "/",
|
|
18272
|
+
kpmultiply: "*",
|
|
18273
|
+
kpminus: "-",
|
|
18274
|
+
kpplus: "+",
|
|
18275
|
+
kpenter: "enter",
|
|
18276
|
+
kpequal: "=",
|
|
18277
|
+
kpseparator: ",",
|
|
18278
|
+
kpleft: "left",
|
|
18279
|
+
kpright: "right",
|
|
18280
|
+
kpup: "up",
|
|
18281
|
+
kpdown: "down",
|
|
18282
|
+
kppageup: "pageup",
|
|
18283
|
+
kppagedown: "pagedown",
|
|
18284
|
+
kphome: "home",
|
|
18285
|
+
kpend: "end",
|
|
18286
|
+
kpinsert: "insert",
|
|
18287
|
+
kpdelete: "delete"
|
|
18288
|
+
};
|
|
18289
|
+
function mergeKeyAliases(defaults, custom) {
|
|
18290
|
+
return { ...defaults, ...custom };
|
|
18291
|
+
}
|
|
18292
|
+
function mergeKeyBindings(defaults, custom) {
|
|
18293
|
+
const map = new Map;
|
|
18294
|
+
for (const binding of defaults) {
|
|
18295
|
+
const key = getKeyBindingKey(binding);
|
|
18296
|
+
map.set(key, binding);
|
|
18297
|
+
}
|
|
18298
|
+
for (const binding of custom) {
|
|
18299
|
+
const key = getKeyBindingKey(binding);
|
|
18300
|
+
map.set(key, binding);
|
|
18301
|
+
}
|
|
18302
|
+
return Array.from(map.values());
|
|
18303
|
+
}
|
|
18304
|
+
function getKeyBindingKey(binding) {
|
|
18305
|
+
return `${binding.name}:${binding.ctrl ? 1 : 0}:${binding.shift ? 1 : 0}:${binding.meta ? 1 : 0}:${binding.super ? 1 : 0}`;
|
|
18306
|
+
}
|
|
18307
|
+
function getBaseCodeKeyName(baseCode) {
|
|
18308
|
+
if (baseCode === undefined || baseCode < 32 || baseCode === 127) {
|
|
16676
18309
|
return;
|
|
16677
18310
|
}
|
|
16678
18311
|
try {
|
|
@@ -18745,6 +20378,27 @@ function getObjectsInViewport(viewport, objects, direction = "column", padding =
|
|
|
18745
20378
|
return visibleChildren;
|
|
18746
20379
|
}
|
|
18747
20380
|
|
|
20381
|
+
// src/lib/render-geometry.ts
|
|
20382
|
+
function calculateRenderGeometry(screenMode, terminalWidth, terminalHeight, footerHeight) {
|
|
20383
|
+
const safeTerminalWidth = Math.max(terminalWidth, 0);
|
|
20384
|
+
const safeTerminalHeight = Math.max(terminalHeight, 0);
|
|
20385
|
+
if (screenMode !== "split-footer") {
|
|
20386
|
+
return {
|
|
20387
|
+
effectiveFooterHeight: 0,
|
|
20388
|
+
renderOffset: 0,
|
|
20389
|
+
renderWidth: safeTerminalWidth,
|
|
20390
|
+
renderHeight: safeTerminalHeight
|
|
20391
|
+
};
|
|
20392
|
+
}
|
|
20393
|
+
const effectiveFooterHeight = Math.min(footerHeight, safeTerminalHeight);
|
|
20394
|
+
return {
|
|
20395
|
+
effectiveFooterHeight,
|
|
20396
|
+
renderOffset: safeTerminalHeight - effectiveFooterHeight,
|
|
20397
|
+
renderWidth: safeTerminalWidth,
|
|
20398
|
+
renderHeight: effectiveFooterHeight
|
|
20399
|
+
};
|
|
20400
|
+
}
|
|
20401
|
+
|
|
18748
20402
|
// src/lib/terminal-capability-detection.ts
|
|
18749
20403
|
function isCapabilityResponse(sequence) {
|
|
18750
20404
|
if (/\x1b\[\?\d+(?:;\d+)*\$y/.test(sequence)) {
|
|
@@ -18782,6 +20436,26 @@ function parsePixelResolution(sequence) {
|
|
|
18782
20436
|
}
|
|
18783
20437
|
|
|
18784
20438
|
// src/renderer.ts
|
|
20439
|
+
var OSC_THEME_RESPONSE = /\x1b](10|11);(?:(?:rgb:)([0-9a-fA-F]+)\/([0-9a-fA-F]+)\/([0-9a-fA-F]+)|#([0-9a-fA-F]{6}))(?:\x07|\x1b\\)/g;
|
|
20440
|
+
function scaleOscThemeComponent(component) {
|
|
20441
|
+
const value = parseInt(component, 16);
|
|
20442
|
+
const maxValue = (1 << 4 * component.length) - 1;
|
|
20443
|
+
return Math.round(value / maxValue * 255).toString(16).padStart(2, "0");
|
|
20444
|
+
}
|
|
20445
|
+
function oscThemeColorToHex(r, g, b, hex6) {
|
|
20446
|
+
if (hex6) {
|
|
20447
|
+
return `#${hex6.toLowerCase()}`;
|
|
20448
|
+
}
|
|
20449
|
+
if (r && g && b) {
|
|
20450
|
+
return `#${scaleOscThemeComponent(r)}${scaleOscThemeComponent(g)}${scaleOscThemeComponent(b)}`;
|
|
20451
|
+
}
|
|
20452
|
+
return "#000000";
|
|
20453
|
+
}
|
|
20454
|
+
function inferThemeModeFromBackgroundColor(color) {
|
|
20455
|
+
const [r, g, b] = parseColor(color).toInts();
|
|
20456
|
+
const brightness = (r * 299 + g * 587 + b * 114) / 1000;
|
|
20457
|
+
return brightness > 128 ? "light" : "dark";
|
|
20458
|
+
}
|
|
18785
20459
|
registerEnvVar({
|
|
18786
20460
|
name: "OTUI_DUMP_CAPTURES",
|
|
18787
20461
|
description: "Dump captured stdout and console caches when the renderer exit handler runs.",
|
|
@@ -18819,6 +20493,9 @@ registerEnvVar({
|
|
|
18819
20493
|
default: false
|
|
18820
20494
|
});
|
|
18821
20495
|
var DEFAULT_FOOTER_HEIGHT = 12;
|
|
20496
|
+
var MAX_SCROLLBACK_SURFACE_HEIGHT_PASSES = 4;
|
|
20497
|
+
var TRANSPARENT_RGBA = RGBA.fromValues(0, 0, 0, 0);
|
|
20498
|
+
var scrollbackSurfaceCounter = 0;
|
|
18822
20499
|
function normalizeFooterHeight(footerHeight) {
|
|
18823
20500
|
if (footerHeight === undefined) {
|
|
18824
20501
|
return DEFAULT_FOOTER_HEIGHT;
|
|
@@ -18845,11 +20522,106 @@ function resolveModes(config) {
|
|
|
18845
20522
|
if (externalOutputMode === "capture-stdout" && screenMode !== "split-footer") {
|
|
18846
20523
|
throw new Error('externalOutputMode "capture-stdout" requires screenMode "split-footer"');
|
|
18847
20524
|
}
|
|
18848
|
-
return {
|
|
18849
|
-
screenMode,
|
|
18850
|
-
footerHeight,
|
|
18851
|
-
externalOutputMode
|
|
18852
|
-
};
|
|
20525
|
+
return {
|
|
20526
|
+
screenMode,
|
|
20527
|
+
footerHeight,
|
|
20528
|
+
externalOutputMode
|
|
20529
|
+
};
|
|
20530
|
+
}
|
|
20531
|
+
|
|
20532
|
+
class ExternalOutputQueue {
|
|
20533
|
+
commits = [];
|
|
20534
|
+
get size() {
|
|
20535
|
+
return this.commits.length;
|
|
20536
|
+
}
|
|
20537
|
+
writeSnapshot(commit) {
|
|
20538
|
+
this.commits.push(commit);
|
|
20539
|
+
}
|
|
20540
|
+
claim(limit = Number.POSITIVE_INFINITY) {
|
|
20541
|
+
if (this.commits.length === 0) {
|
|
20542
|
+
return [];
|
|
20543
|
+
}
|
|
20544
|
+
const clampedLimit = Number.isFinite(limit) ? Math.max(1, Math.trunc(limit)) : this.commits.length;
|
|
20545
|
+
if (clampedLimit >= this.commits.length) {
|
|
20546
|
+
const output2 = this.commits;
|
|
20547
|
+
this.commits = [];
|
|
20548
|
+
return output2;
|
|
20549
|
+
}
|
|
20550
|
+
const output = this.commits.slice(0, clampedLimit);
|
|
20551
|
+
this.commits = this.commits.slice(clampedLimit);
|
|
20552
|
+
return output;
|
|
20553
|
+
}
|
|
20554
|
+
clear() {
|
|
20555
|
+
for (const commit of this.commits) {
|
|
20556
|
+
commit.snapshot.destroy();
|
|
20557
|
+
}
|
|
20558
|
+
this.commits = [];
|
|
20559
|
+
}
|
|
20560
|
+
}
|
|
20561
|
+
var CHAR_FLAG_CONTINUATION = 3221225472 >>> 0;
|
|
20562
|
+
var CHAR_FLAG_MASK = 3221225472 >>> 0;
|
|
20563
|
+
|
|
20564
|
+
class ScrollbackSnapshotRenderContext extends EventEmitter9 {
|
|
20565
|
+
width;
|
|
20566
|
+
height;
|
|
20567
|
+
frameId = 0;
|
|
20568
|
+
widthMethod;
|
|
20569
|
+
capabilities = null;
|
|
20570
|
+
hasSelection = false;
|
|
20571
|
+
currentFocusedRenderable = null;
|
|
20572
|
+
keyInput;
|
|
20573
|
+
_internalKeyInput;
|
|
20574
|
+
lifecyclePasses = new Set;
|
|
20575
|
+
constructor(width, height, widthMethod) {
|
|
20576
|
+
super();
|
|
20577
|
+
this.width = width;
|
|
20578
|
+
this.height = height;
|
|
20579
|
+
this.widthMethod = widthMethod;
|
|
20580
|
+
this.keyInput = new KeyHandler;
|
|
20581
|
+
this._internalKeyInput = new InternalKeyHandler;
|
|
20582
|
+
}
|
|
20583
|
+
addToHitGrid(_x, _y, _width, _height, _id) {}
|
|
20584
|
+
pushHitGridScissorRect(_x, _y, _width, _height) {}
|
|
20585
|
+
popHitGridScissorRect() {}
|
|
20586
|
+
clearHitGridScissorRects() {}
|
|
20587
|
+
requestRender() {}
|
|
20588
|
+
setCursorPosition(_x, _y, _visible) {}
|
|
20589
|
+
setCursorStyle(_options) {}
|
|
20590
|
+
setCursorColor(_color) {}
|
|
20591
|
+
setMousePointer(_shape) {}
|
|
20592
|
+
requestLive() {}
|
|
20593
|
+
dropLive() {}
|
|
20594
|
+
getSelection() {
|
|
20595
|
+
return null;
|
|
20596
|
+
}
|
|
20597
|
+
get currentFocusedEditor() {
|
|
20598
|
+
if (!this.currentFocusedRenderable)
|
|
20599
|
+
return null;
|
|
20600
|
+
if (!isEditBufferRenderable(this.currentFocusedRenderable))
|
|
20601
|
+
return null;
|
|
20602
|
+
return this.currentFocusedRenderable;
|
|
20603
|
+
}
|
|
20604
|
+
requestSelectionUpdate() {}
|
|
20605
|
+
focusRenderable(renderable) {
|
|
20606
|
+
this.currentFocusedRenderable = renderable;
|
|
20607
|
+
}
|
|
20608
|
+
blurRenderable(renderable) {
|
|
20609
|
+
if (this.currentFocusedRenderable === renderable) {
|
|
20610
|
+
this.currentFocusedRenderable = null;
|
|
20611
|
+
}
|
|
20612
|
+
}
|
|
20613
|
+
registerLifecyclePass(renderable) {
|
|
20614
|
+
this.lifecyclePasses.add(renderable);
|
|
20615
|
+
}
|
|
20616
|
+
unregisterLifecyclePass(renderable) {
|
|
20617
|
+
this.lifecyclePasses.delete(renderable);
|
|
20618
|
+
}
|
|
20619
|
+
getLifecyclePasses() {
|
|
20620
|
+
return this.lifecyclePasses;
|
|
20621
|
+
}
|
|
20622
|
+
clearSelection() {}
|
|
20623
|
+
startSelection(_renderable, _x, _y) {}
|
|
20624
|
+
updateSelection(_currentRenderable, _x, _y, _options) {}
|
|
18853
20625
|
}
|
|
18854
20626
|
var DEFAULT_FORWARDED_ENV_KEYS = [
|
|
18855
20627
|
"TMUX",
|
|
@@ -18971,9 +20743,9 @@ async function createCliRenderer(config = {}) {
|
|
|
18971
20743
|
const { screenMode, footerHeight } = resolveModes(config);
|
|
18972
20744
|
const width = stdout.columns || 80;
|
|
18973
20745
|
const height = stdout.rows || 24;
|
|
18974
|
-
const
|
|
20746
|
+
const geometry = calculateRenderGeometry(screenMode, width, height, footerHeight);
|
|
18975
20747
|
const ziglib = resolveRenderLib();
|
|
18976
|
-
const rendererPtr = ziglib.createRenderer(
|
|
20748
|
+
const rendererPtr = ziglib.createRenderer(geometry.renderWidth, geometry.renderHeight, {
|
|
18977
20749
|
remote: config.remote ?? false,
|
|
18978
20750
|
testing: config.testing ?? false
|
|
18979
20751
|
});
|
|
@@ -19090,6 +20862,8 @@ class CliRenderer extends EventEmitter9 {
|
|
|
19090
20862
|
animationRequest = new Map;
|
|
19091
20863
|
resizeTimeoutId = null;
|
|
19092
20864
|
capabilityTimeoutId = null;
|
|
20865
|
+
splitStartupSeedTimeoutId = null;
|
|
20866
|
+
pendingSplitStartupCursorSeed = false;
|
|
19093
20867
|
resizeDebounceDelay = 100;
|
|
19094
20868
|
enableMouseMovement = false;
|
|
19095
20869
|
_useMouse = true;
|
|
@@ -19097,6 +20871,7 @@ class CliRenderer extends EventEmitter9 {
|
|
|
19097
20871
|
_screenMode = "alternate-screen";
|
|
19098
20872
|
_footerHeight = DEFAULT_FOOTER_HEIGHT;
|
|
19099
20873
|
_externalOutputMode = "passthrough";
|
|
20874
|
+
clearOnShutdown = true;
|
|
19100
20875
|
_suspendedMouseEnabled = false;
|
|
19101
20876
|
_previousControlState = "idle" /* IDLE */;
|
|
19102
20877
|
capturedRenderable;
|
|
@@ -19107,15 +20882,15 @@ class CliRenderer extends EventEmitter9 {
|
|
|
19107
20882
|
clipboard;
|
|
19108
20883
|
_splitHeight = 0;
|
|
19109
20884
|
renderOffset = 0;
|
|
20885
|
+
splitTailColumn = 0;
|
|
20886
|
+
pendingSplitFooterTransition = null;
|
|
20887
|
+
forceFullRepaintRequested = false;
|
|
20888
|
+
maxSplitCommitsPerFrame = 8;
|
|
19110
20889
|
_terminalWidth = 0;
|
|
19111
20890
|
_terminalHeight = 0;
|
|
19112
20891
|
_terminalIsSetup = false;
|
|
20892
|
+
externalOutputQueue = new ExternalOutputQueue;
|
|
19113
20893
|
realStdoutWrite;
|
|
19114
|
-
captureCallback = () => {
|
|
19115
|
-
if (this._splitHeight > 0) {
|
|
19116
|
-
this.requestRender();
|
|
19117
|
-
}
|
|
19118
|
-
};
|
|
19119
20894
|
_useConsole = true;
|
|
19120
20895
|
sigwinchHandler = (() => {
|
|
19121
20896
|
const width = this.stdout.columns || 80;
|
|
@@ -19139,6 +20914,10 @@ class CliRenderer extends EventEmitter9 {
|
|
|
19139
20914
|
_paletteDetectionPromise = null;
|
|
19140
20915
|
_onDestroy;
|
|
19141
20916
|
_themeMode = null;
|
|
20917
|
+
_themeModeSource = "none";
|
|
20918
|
+
_themeFallbackPending = true;
|
|
20919
|
+
_themeOscForeground = null;
|
|
20920
|
+
_themeOscBackground = null;
|
|
19142
20921
|
_terminalFocusState = null;
|
|
19143
20922
|
sequenceHandlers = [];
|
|
19144
20923
|
prependedInputHandlers = [];
|
|
@@ -19154,8 +20933,15 @@ class CliRenderer extends EventEmitter9 {
|
|
|
19154
20933
|
}).bind(this);
|
|
19155
20934
|
dumpOutputCache(optionalMessage = "") {
|
|
19156
20935
|
const cachedLogs = this.console.getCachedLogs();
|
|
19157
|
-
const
|
|
19158
|
-
|
|
20936
|
+
const capturedConsoleOutput = capture.claimOutput();
|
|
20937
|
+
const capturedExternalOutputCommits = this.externalOutputQueue.claim();
|
|
20938
|
+
let capturedExternalOutput = "";
|
|
20939
|
+
for (const commit of capturedExternalOutputCommits) {
|
|
20940
|
+
capturedExternalOutput += `[snapshot ${commit.snapshot.width}x${commit.snapshot.height}]
|
|
20941
|
+
`;
|
|
20942
|
+
commit.snapshot.destroy();
|
|
20943
|
+
}
|
|
20944
|
+
if (capturedConsoleOutput.length > 0 || capturedExternalOutput.length > 0 || cachedLogs.length > 0) {
|
|
19159
20945
|
this.realStdoutWrite.call(this.stdout, optionalMessage);
|
|
19160
20946
|
}
|
|
19161
20947
|
if (cachedLogs.length > 0) {
|
|
@@ -19163,11 +20949,18 @@ class CliRenderer extends EventEmitter9 {
|
|
|
19163
20949
|
`);
|
|
19164
20950
|
this.realStdoutWrite.call(this.stdout, cachedLogs);
|
|
19165
20951
|
}
|
|
19166
|
-
if (
|
|
20952
|
+
if (capturedConsoleOutput.length > 0) {
|
|
20953
|
+
this.realStdoutWrite.call(this.stdout, `
|
|
20954
|
+
Captured console output:
|
|
20955
|
+
`);
|
|
20956
|
+
this.realStdoutWrite.call(this.stdout, capturedConsoleOutput + `
|
|
20957
|
+
`);
|
|
20958
|
+
}
|
|
20959
|
+
if (capturedExternalOutput.length > 0) {
|
|
19167
20960
|
this.realStdoutWrite.call(this.stdout, `
|
|
19168
|
-
Captured output:
|
|
20961
|
+
Captured external output:
|
|
19169
20962
|
`);
|
|
19170
|
-
this.realStdoutWrite.call(this.stdout,
|
|
20963
|
+
this.realStdoutWrite.call(this.stdout, capturedExternalOutput + `
|
|
19171
20964
|
`);
|
|
19172
20965
|
}
|
|
19173
20966
|
this.realStdoutWrite.call(this.stdout, ANSI.reset);
|
|
@@ -19196,13 +20989,18 @@ Captured output:
|
|
|
19196
20989
|
this.lib = lib;
|
|
19197
20990
|
this._terminalWidth = stdout.columns ?? width;
|
|
19198
20991
|
this._terminalHeight = stdout.rows ?? height;
|
|
19199
|
-
this.width = width;
|
|
19200
|
-
this.height = height;
|
|
19201
20992
|
this._useThread = config.useThread === undefined ? false : config.useThread;
|
|
19202
20993
|
const { screenMode, footerHeight, externalOutputMode } = resolveModes(config);
|
|
20994
|
+
this._externalOutputMode = externalOutputMode;
|
|
20995
|
+
const initialGeometry = calculateRenderGeometry(screenMode, this._terminalWidth, this._terminalHeight, footerHeight);
|
|
20996
|
+
this.width = initialGeometry.renderWidth;
|
|
20997
|
+
this.height = initialGeometry.renderHeight;
|
|
20998
|
+
this._splitHeight = initialGeometry.effectiveFooterHeight;
|
|
20999
|
+
this.renderOffset = screenMode === "split-footer" ? 0 : initialGeometry.renderOffset;
|
|
19203
21000
|
this._footerHeight = footerHeight;
|
|
19204
|
-
this._screenMode = screenMode;
|
|
19205
21001
|
this.rendererPtr = rendererPtr;
|
|
21002
|
+
this.clearOnShutdown = config.clearOnShutdown ?? true;
|
|
21003
|
+
this.lib.setClearOnShutdown(this.rendererPtr, this.clearOnShutdown);
|
|
19206
21004
|
const forwardEnvKeys = config.forwardEnvKeys ?? [...DEFAULT_FORWARDED_ENV_KEYS];
|
|
19207
21005
|
for (const key of forwardEnvKeys) {
|
|
19208
21006
|
const value = process.env[key];
|
|
@@ -19237,7 +21035,6 @@ Captured output:
|
|
|
19237
21035
|
this.postProcessFns = config.postProcessFns || [];
|
|
19238
21036
|
this.prependedInputHandlers = config.prependInputHandlers || [];
|
|
19239
21037
|
this.root = new RootRenderable(this);
|
|
19240
|
-
this._openConsoleOnError = config.openConsoleOnError ?? false;
|
|
19241
21038
|
if (this.memorySnapshotInterval > 0) {
|
|
19242
21039
|
this.startMemorySnapshotTimer();
|
|
19243
21040
|
}
|
|
@@ -19271,7 +21068,8 @@ Captured output:
|
|
|
19271
21068
|
kittyKeyboardEnabled: useKittyForParsing,
|
|
19272
21069
|
privateCapabilityRepliesActive: false,
|
|
19273
21070
|
pixelResolutionQueryActive: false,
|
|
19274
|
-
explicitWidthCprActive: false
|
|
21071
|
+
explicitWidthCprActive: false,
|
|
21072
|
+
startupCursorCprActive: false
|
|
19275
21073
|
},
|
|
19276
21074
|
clock: this.clock
|
|
19277
21075
|
});
|
|
@@ -19281,7 +21079,8 @@ Captured output:
|
|
|
19281
21079
|
});
|
|
19282
21080
|
this.consoleMode = config.consoleMode ?? "console-overlay";
|
|
19283
21081
|
this.applyScreenMode(screenMode, false, false);
|
|
19284
|
-
this.
|
|
21082
|
+
this.stdout.write = externalOutputMode === "capture-stdout" ? this.interceptStdoutWrite : this.realStdoutWrite;
|
|
21083
|
+
this._openConsoleOnError = config.openConsoleOnError ?? false;
|
|
19285
21084
|
this._onDestroy = config.onDestroy;
|
|
19286
21085
|
global.requestAnimationFrame = (callback) => {
|
|
19287
21086
|
const id = CliRenderer.animationFrameId++;
|
|
@@ -19439,163 +21238,795 @@ Captured output:
|
|
|
19439
21238
|
return;
|
|
19440
21239
|
}
|
|
19441
21240
|
try {
|
|
19442
|
-
await this.loop();
|
|
21241
|
+
await this.loop();
|
|
21242
|
+
} finally {
|
|
21243
|
+
this.updateScheduled = false;
|
|
21244
|
+
this.resolveIdleIfNeeded();
|
|
21245
|
+
}
|
|
21246
|
+
}
|
|
21247
|
+
get consoleMode() {
|
|
21248
|
+
return this._useConsole ? "console-overlay" : "disabled";
|
|
21249
|
+
}
|
|
21250
|
+
set consoleMode(mode) {
|
|
21251
|
+
this._useConsole = mode === "console-overlay";
|
|
21252
|
+
if (this._useConsole) {
|
|
21253
|
+
this.console.activate();
|
|
21254
|
+
} else {
|
|
21255
|
+
this.console.deactivate();
|
|
21256
|
+
}
|
|
21257
|
+
}
|
|
21258
|
+
get isRunning() {
|
|
21259
|
+
return this._isRunning;
|
|
21260
|
+
}
|
|
21261
|
+
isIdleNow() {
|
|
21262
|
+
return !this._isRunning && !this.rendering && !this.renderTimeout && !this.updateScheduled && !this.immediateRerenderRequested;
|
|
21263
|
+
}
|
|
21264
|
+
resolveIdleIfNeeded() {
|
|
21265
|
+
if (!this.isIdleNow())
|
|
21266
|
+
return;
|
|
21267
|
+
const resolvers = this.idleResolvers.splice(0);
|
|
21268
|
+
for (const resolve4 of resolvers) {
|
|
21269
|
+
resolve4();
|
|
21270
|
+
}
|
|
21271
|
+
}
|
|
21272
|
+
idle() {
|
|
21273
|
+
if (this._isDestroyed)
|
|
21274
|
+
return Promise.resolve();
|
|
21275
|
+
if (this.isIdleNow())
|
|
21276
|
+
return Promise.resolve();
|
|
21277
|
+
return new Promise((resolve4) => {
|
|
21278
|
+
this.idleResolvers.push(resolve4);
|
|
21279
|
+
});
|
|
21280
|
+
}
|
|
21281
|
+
get resolution() {
|
|
21282
|
+
return this._resolution;
|
|
21283
|
+
}
|
|
21284
|
+
get console() {
|
|
21285
|
+
return this._console;
|
|
21286
|
+
}
|
|
21287
|
+
get keyInput() {
|
|
21288
|
+
return this._keyHandler;
|
|
21289
|
+
}
|
|
21290
|
+
get _internalKeyInput() {
|
|
21291
|
+
return this._keyHandler;
|
|
21292
|
+
}
|
|
21293
|
+
get terminalWidth() {
|
|
21294
|
+
return this._terminalWidth;
|
|
21295
|
+
}
|
|
21296
|
+
get terminalHeight() {
|
|
21297
|
+
return this._terminalHeight;
|
|
21298
|
+
}
|
|
21299
|
+
get useThread() {
|
|
21300
|
+
return this._useThread;
|
|
21301
|
+
}
|
|
21302
|
+
get targetFps() {
|
|
21303
|
+
return this._targetFps;
|
|
21304
|
+
}
|
|
21305
|
+
set targetFps(targetFps) {
|
|
21306
|
+
this._targetFps = targetFps;
|
|
21307
|
+
this.targetFrameTime = 1000 / this._targetFps;
|
|
21308
|
+
}
|
|
21309
|
+
get maxFps() {
|
|
21310
|
+
return this._maxFps;
|
|
21311
|
+
}
|
|
21312
|
+
set maxFps(maxFps) {
|
|
21313
|
+
this._maxFps = maxFps;
|
|
21314
|
+
this.minTargetFrameTime = 1000 / this._maxFps;
|
|
21315
|
+
}
|
|
21316
|
+
get useMouse() {
|
|
21317
|
+
return this._useMouse;
|
|
21318
|
+
}
|
|
21319
|
+
set useMouse(useMouse) {
|
|
21320
|
+
if (this._useMouse === useMouse)
|
|
21321
|
+
return;
|
|
21322
|
+
this._useMouse = useMouse;
|
|
21323
|
+
if (useMouse) {
|
|
21324
|
+
this.enableMouse();
|
|
21325
|
+
} else {
|
|
21326
|
+
this.disableMouse();
|
|
21327
|
+
}
|
|
21328
|
+
}
|
|
21329
|
+
get screenMode() {
|
|
21330
|
+
return this._screenMode;
|
|
21331
|
+
}
|
|
21332
|
+
set screenMode(mode) {
|
|
21333
|
+
if (this.externalOutputMode === "capture-stdout" && mode !== "split-footer") {
|
|
21334
|
+
throw new Error('externalOutputMode "capture-stdout" requires screenMode "split-footer"');
|
|
21335
|
+
}
|
|
21336
|
+
this.applyScreenMode(mode);
|
|
21337
|
+
}
|
|
21338
|
+
get footerHeight() {
|
|
21339
|
+
return this._footerHeight;
|
|
21340
|
+
}
|
|
21341
|
+
set footerHeight(footerHeight) {
|
|
21342
|
+
const normalizedFooterHeight = normalizeFooterHeight(footerHeight);
|
|
21343
|
+
if (normalizedFooterHeight === this._footerHeight) {
|
|
21344
|
+
return;
|
|
21345
|
+
}
|
|
21346
|
+
this._footerHeight = normalizedFooterHeight;
|
|
21347
|
+
if (this.screenMode === "split-footer") {
|
|
21348
|
+
this.applyScreenMode("split-footer");
|
|
21349
|
+
}
|
|
21350
|
+
}
|
|
21351
|
+
get externalOutputMode() {
|
|
21352
|
+
return this._externalOutputMode;
|
|
21353
|
+
}
|
|
21354
|
+
set externalOutputMode(mode) {
|
|
21355
|
+
if (mode === "capture-stdout" && this.screenMode !== "split-footer") {
|
|
21356
|
+
throw new Error('externalOutputMode "capture-stdout" requires screenMode "split-footer"');
|
|
21357
|
+
}
|
|
21358
|
+
const previousMode = this._externalOutputMode;
|
|
21359
|
+
if (previousMode === mode) {
|
|
21360
|
+
return;
|
|
21361
|
+
}
|
|
21362
|
+
if (previousMode === "capture-stdout" && mode === "passthrough" && this._splitHeight > 0) {
|
|
21363
|
+
this.flushPendingSplitOutputBeforeTransition();
|
|
21364
|
+
}
|
|
21365
|
+
this._externalOutputMode = mode;
|
|
21366
|
+
this.stdout.write = mode === "capture-stdout" ? this.interceptStdoutWrite : this.realStdoutWrite;
|
|
21367
|
+
if (this._screenMode === "split-footer" && this._splitHeight > 0 && mode === "capture-stdout") {
|
|
21368
|
+
this.clearPendingSplitFooterTransition();
|
|
21369
|
+
this.resetSplitScrollback(this.getSplitCursorSeedRows());
|
|
21370
|
+
return;
|
|
21371
|
+
}
|
|
21372
|
+
if (this._screenMode === "split-footer" && this._splitHeight > 0 && previousMode === "capture-stdout" && mode === "passthrough") {
|
|
21373
|
+
this.clearPendingSplitFooterTransition();
|
|
21374
|
+
return;
|
|
21375
|
+
}
|
|
21376
|
+
this.syncSplitFooterState();
|
|
21377
|
+
}
|
|
21378
|
+
get liveRequestCount() {
|
|
21379
|
+
return this.liveRequestCounter;
|
|
21380
|
+
}
|
|
21381
|
+
get currentControlState() {
|
|
21382
|
+
return this._controlState;
|
|
21383
|
+
}
|
|
21384
|
+
get capabilities() {
|
|
21385
|
+
return this._capabilities;
|
|
21386
|
+
}
|
|
21387
|
+
get themeMode() {
|
|
21388
|
+
return this._themeMode;
|
|
21389
|
+
}
|
|
21390
|
+
waitForThemeMode(timeoutMs = 1000) {
|
|
21391
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
|
|
21392
|
+
throw new Error("timeoutMs must be a non-negative finite number");
|
|
21393
|
+
}
|
|
21394
|
+
if (this._themeMode !== null || this._isDestroyed || timeoutMs === 0) {
|
|
21395
|
+
return Promise.resolve(this._themeMode);
|
|
21396
|
+
}
|
|
21397
|
+
return new Promise((resolve4) => {
|
|
21398
|
+
let timeoutHandle = null;
|
|
21399
|
+
const cleanup = () => {
|
|
21400
|
+
if (timeoutHandle !== null) {
|
|
21401
|
+
this.clock.clearTimeout(timeoutHandle);
|
|
21402
|
+
timeoutHandle = null;
|
|
21403
|
+
}
|
|
21404
|
+
this.off("theme_mode" /* THEME_MODE */, handleThemeMode);
|
|
21405
|
+
this.off("destroy" /* DESTROY */, handleDestroy);
|
|
21406
|
+
};
|
|
21407
|
+
const finish = () => {
|
|
21408
|
+
cleanup();
|
|
21409
|
+
resolve4(this._themeMode);
|
|
21410
|
+
};
|
|
21411
|
+
const handleThemeMode = () => {
|
|
21412
|
+
finish();
|
|
21413
|
+
};
|
|
21414
|
+
const handleDestroy = () => {
|
|
21415
|
+
finish();
|
|
21416
|
+
};
|
|
21417
|
+
this.on("theme_mode" /* THEME_MODE */, handleThemeMode);
|
|
21418
|
+
this.on("destroy" /* DESTROY */, handleDestroy);
|
|
21419
|
+
timeoutHandle = this.clock.setTimeout(finish, timeoutMs);
|
|
21420
|
+
});
|
|
21421
|
+
}
|
|
21422
|
+
getDebugInputs() {
|
|
21423
|
+
return [...this._debugInputs];
|
|
21424
|
+
}
|
|
21425
|
+
get useKittyKeyboard() {
|
|
21426
|
+
return this.lib.getKittyKeyboardFlags(this.rendererPtr) > 0;
|
|
21427
|
+
}
|
|
21428
|
+
set useKittyKeyboard(use) {
|
|
21429
|
+
const flags = use ? KITTY_FLAG_DISAMBIGUATE | KITTY_FLAG_ALTERNATE_KEYS : 0;
|
|
21430
|
+
this.lib.setKittyKeyboardFlags(this.rendererPtr, flags);
|
|
21431
|
+
}
|
|
21432
|
+
createScrollbackSurface(options = {}) {
|
|
21433
|
+
if (this._screenMode !== "split-footer" || this._externalOutputMode !== "capture-stdout") {
|
|
21434
|
+
throw new Error('createScrollbackSurface requires screenMode "split-footer" and externalOutputMode "capture-stdout"');
|
|
21435
|
+
}
|
|
21436
|
+
const renderer = this;
|
|
21437
|
+
const surfaceId = scrollbackSurfaceCounter++;
|
|
21438
|
+
const startOnNewLine = options.startOnNewLine ?? true;
|
|
21439
|
+
const firstLineOffset = !startOnNewLine && renderer.splitTailColumn > 0 && renderer.splitTailColumn < renderer.width ? renderer.splitTailColumn : 0;
|
|
21440
|
+
const snapshotContext = new ScrollbackSnapshotRenderContext(renderer.width, 1, renderer.widthMethod);
|
|
21441
|
+
let firstLineOffsetOwner = null;
|
|
21442
|
+
const renderContext = Object.create(snapshotContext);
|
|
21443
|
+
Object.defineProperty(renderContext, "claimFirstLineOffset", {
|
|
21444
|
+
value: (renderable) => {
|
|
21445
|
+
if (firstLineOffsetOwner?.isDestroyed) {
|
|
21446
|
+
firstLineOffsetOwner = null;
|
|
21447
|
+
}
|
|
21448
|
+
if (firstLineOffsetOwner) {
|
|
21449
|
+
return 0;
|
|
21450
|
+
}
|
|
21451
|
+
firstLineOffsetOwner = renderable ?? null;
|
|
21452
|
+
return firstLineOffset;
|
|
21453
|
+
},
|
|
21454
|
+
enumerable: true,
|
|
21455
|
+
configurable: true
|
|
21456
|
+
});
|
|
21457
|
+
const internalRoot = new RootRenderable(renderContext);
|
|
21458
|
+
const publicRoot = new BoxRenderable(renderContext, {
|
|
21459
|
+
id: `scrollback-surface-root-${surfaceId}`,
|
|
21460
|
+
position: "absolute",
|
|
21461
|
+
left: 0,
|
|
21462
|
+
top: 0,
|
|
21463
|
+
width: renderer.width,
|
|
21464
|
+
height: "auto",
|
|
21465
|
+
border: false,
|
|
21466
|
+
backgroundColor: "transparent",
|
|
21467
|
+
shouldFill: false,
|
|
21468
|
+
flexDirection: "column"
|
|
21469
|
+
});
|
|
21470
|
+
internalRoot.add(publicRoot);
|
|
21471
|
+
let surfaceWidth = renderer.width;
|
|
21472
|
+
let surfaceHeight = 1;
|
|
21473
|
+
let surfaceWidthMethod = renderer.widthMethod;
|
|
21474
|
+
let surfaceDestroyed = false;
|
|
21475
|
+
let hasRendered = false;
|
|
21476
|
+
let nextCommitStartOnNewLine = startOnNewLine;
|
|
21477
|
+
let backingBuffer = OptimizedBuffer.create(surfaceWidth, surfaceHeight, surfaceWidthMethod, {
|
|
21478
|
+
id: `scrollback-surface-buffer-${surfaceId}`
|
|
21479
|
+
});
|
|
21480
|
+
const destroyListener = () => {
|
|
21481
|
+
destroySurface();
|
|
21482
|
+
};
|
|
21483
|
+
const assertNotDestroyed = () => {
|
|
21484
|
+
if (surfaceDestroyed) {
|
|
21485
|
+
throw new Error("ScrollbackSurface is destroyed");
|
|
21486
|
+
}
|
|
21487
|
+
};
|
|
21488
|
+
const assertRendered = () => {
|
|
21489
|
+
if (!hasRendered) {
|
|
21490
|
+
throw new Error("ScrollbackSurface.commitRows requires render() before commitRows()");
|
|
21491
|
+
}
|
|
21492
|
+
};
|
|
21493
|
+
const assertGeometryStillCurrent = () => {
|
|
21494
|
+
if (renderer.width !== surfaceWidth || renderer.widthMethod !== surfaceWidthMethod) {
|
|
21495
|
+
throw new Error("ScrollbackSurface.commitRows requires render() after renderer geometry changes");
|
|
21496
|
+
}
|
|
21497
|
+
};
|
|
21498
|
+
const assertRowRange = (startRow, endRowExclusive) => {
|
|
21499
|
+
if (!Number.isInteger(startRow) || !Number.isInteger(endRowExclusive)) {
|
|
21500
|
+
throw new Error("ScrollbackSurface.commitRows requires finite integer row bounds");
|
|
21501
|
+
}
|
|
21502
|
+
if (startRow < 0) {
|
|
21503
|
+
throw new Error("ScrollbackSurface.commitRows requires startRow >= 0");
|
|
21504
|
+
}
|
|
21505
|
+
if (endRowExclusive < startRow) {
|
|
21506
|
+
throw new Error("ScrollbackSurface.commitRows requires endRowExclusive >= startRow");
|
|
21507
|
+
}
|
|
21508
|
+
if (endRowExclusive > surfaceHeight) {
|
|
21509
|
+
throw new Error("ScrollbackSurface.commitRows row range exceeds rendered surface height");
|
|
21510
|
+
}
|
|
21511
|
+
};
|
|
21512
|
+
const collectPendingCodeRenderables = (node) => {
|
|
21513
|
+
const pending = [];
|
|
21514
|
+
if (node instanceof CodeRenderable && node.isHighlighting) {
|
|
21515
|
+
pending.push(node);
|
|
21516
|
+
}
|
|
21517
|
+
for (const child of node.getChildren()) {
|
|
21518
|
+
pending.push(...collectPendingCodeRenderables(child));
|
|
21519
|
+
}
|
|
21520
|
+
return pending;
|
|
21521
|
+
};
|
|
21522
|
+
const waitForPendingHighlights = async (pending, timeoutMs) => {
|
|
21523
|
+
await new Promise((resolve4, reject) => {
|
|
21524
|
+
let settled = false;
|
|
21525
|
+
const timeoutHandle = renderer.clock.setTimeout(() => {
|
|
21526
|
+
if (settled) {
|
|
21527
|
+
return;
|
|
21528
|
+
}
|
|
21529
|
+
settled = true;
|
|
21530
|
+
reject(new Error("ScrollbackSurface.settle timed out waiting for CodeRenderable highlighting"));
|
|
21531
|
+
}, timeoutMs);
|
|
21532
|
+
Promise.all(pending.map((renderable) => renderable.highlightingDone)).then(() => {
|
|
21533
|
+
if (settled) {
|
|
21534
|
+
return;
|
|
21535
|
+
}
|
|
21536
|
+
settled = true;
|
|
21537
|
+
renderer.clock.clearTimeout(timeoutHandle);
|
|
21538
|
+
resolve4();
|
|
21539
|
+
}, (error) => {
|
|
21540
|
+
if (settled) {
|
|
21541
|
+
return;
|
|
21542
|
+
}
|
|
21543
|
+
settled = true;
|
|
21544
|
+
renderer.clock.clearTimeout(timeoutHandle);
|
|
21545
|
+
reject(error);
|
|
21546
|
+
});
|
|
21547
|
+
});
|
|
21548
|
+
};
|
|
21549
|
+
const renderSurface = () => {
|
|
21550
|
+
assertNotDestroyed();
|
|
21551
|
+
const width = renderer.width;
|
|
21552
|
+
const widthMethod = renderer.widthMethod;
|
|
21553
|
+
snapshotContext.width = width;
|
|
21554
|
+
snapshotContext.widthMethod = widthMethod;
|
|
21555
|
+
publicRoot.width = width;
|
|
21556
|
+
const renderPass = (height) => {
|
|
21557
|
+
snapshotContext.height = height;
|
|
21558
|
+
internalRoot.resize(width, height);
|
|
21559
|
+
backingBuffer.resize(width, height);
|
|
21560
|
+
backingBuffer.clear(TRANSPARENT_RGBA);
|
|
21561
|
+
snapshotContext.frameId += 1;
|
|
21562
|
+
internalRoot.render(backingBuffer, 0);
|
|
21563
|
+
};
|
|
21564
|
+
let targetHeight = Math.max(1, surfaceHeight);
|
|
21565
|
+
if (surfaceWidthMethod !== widthMethod) {
|
|
21566
|
+
backingBuffer.destroy();
|
|
21567
|
+
backingBuffer = OptimizedBuffer.create(width, targetHeight, widthMethod, {
|
|
21568
|
+
id: `scrollback-surface-buffer-${surfaceId}`
|
|
21569
|
+
});
|
|
21570
|
+
} else {
|
|
21571
|
+
backingBuffer.resize(width, targetHeight);
|
|
21572
|
+
}
|
|
21573
|
+
for (let pass = 0;pass < MAX_SCROLLBACK_SURFACE_HEIGHT_PASSES; pass += 1) {
|
|
21574
|
+
renderPass(targetHeight);
|
|
21575
|
+
const measuredHeight = Math.max(1, publicRoot.height);
|
|
21576
|
+
if (measuredHeight === targetHeight) {
|
|
21577
|
+
surfaceWidth = width;
|
|
21578
|
+
surfaceHeight = measuredHeight;
|
|
21579
|
+
surfaceWidthMethod = widthMethod;
|
|
21580
|
+
hasRendered = true;
|
|
21581
|
+
return;
|
|
21582
|
+
}
|
|
21583
|
+
targetHeight = measuredHeight;
|
|
21584
|
+
}
|
|
21585
|
+
renderPass(targetHeight);
|
|
21586
|
+
surfaceWidth = width;
|
|
21587
|
+
surfaceHeight = targetHeight;
|
|
21588
|
+
surfaceWidthMethod = widthMethod;
|
|
21589
|
+
hasRendered = true;
|
|
21590
|
+
};
|
|
21591
|
+
const settleSurface = async (timeoutMs = 2000) => {
|
|
21592
|
+
assertNotDestroyed();
|
|
21593
|
+
const startedAt = renderer.clock.now();
|
|
21594
|
+
renderSurface();
|
|
21595
|
+
while (true) {
|
|
21596
|
+
assertNotDestroyed();
|
|
21597
|
+
const pending = collectPendingCodeRenderables(publicRoot);
|
|
21598
|
+
if (pending.length === 0) {
|
|
21599
|
+
return;
|
|
21600
|
+
}
|
|
21601
|
+
const remainingMs = timeoutMs - (renderer.clock.now() - startedAt);
|
|
21602
|
+
if (remainingMs <= 0) {
|
|
21603
|
+
throw new Error("ScrollbackSurface.settle timed out waiting for CodeRenderable highlighting");
|
|
21604
|
+
}
|
|
21605
|
+
await waitForPendingHighlights(pending, remainingMs);
|
|
21606
|
+
assertNotDestroyed();
|
|
21607
|
+
renderSurface();
|
|
21608
|
+
}
|
|
21609
|
+
};
|
|
21610
|
+
const commitRows = (startRow, endRowExclusive, commitOptions = {}) => {
|
|
21611
|
+
assertNotDestroyed();
|
|
21612
|
+
assertRendered();
|
|
21613
|
+
assertGeometryStillCurrent();
|
|
21614
|
+
assertRowRange(startRow, endRowExclusive);
|
|
21615
|
+
if (startRow === endRowExclusive) {
|
|
21616
|
+
return;
|
|
21617
|
+
}
|
|
21618
|
+
const rowCount = endRowExclusive - startRow;
|
|
21619
|
+
const commitBuffer = OptimizedBuffer.create(surfaceWidth, rowCount, surfaceWidthMethod, {
|
|
21620
|
+
id: `scrollback-surface-commit-${surfaceId}`
|
|
21621
|
+
});
|
|
21622
|
+
try {
|
|
21623
|
+
commitBuffer.drawFrameBuffer(0, 0, backingBuffer, 0, startRow, surfaceWidth, rowCount);
|
|
21624
|
+
renderer.enqueueRenderedScrollbackCommit({
|
|
21625
|
+
snapshot: commitBuffer,
|
|
21626
|
+
rowColumns: commitOptions.rowColumns,
|
|
21627
|
+
startOnNewLine: nextCommitStartOnNewLine,
|
|
21628
|
+
trailingNewline: commitOptions.trailingNewline ?? false
|
|
21629
|
+
});
|
|
21630
|
+
nextCommitStartOnNewLine = false;
|
|
21631
|
+
} catch (error) {
|
|
21632
|
+
commitBuffer.destroy();
|
|
21633
|
+
throw error;
|
|
21634
|
+
}
|
|
21635
|
+
};
|
|
21636
|
+
const destroySurface = () => {
|
|
21637
|
+
if (surfaceDestroyed) {
|
|
21638
|
+
return;
|
|
21639
|
+
}
|
|
21640
|
+
surfaceDestroyed = true;
|
|
21641
|
+
renderer.off("destroy" /* DESTROY */, destroyListener);
|
|
21642
|
+
let destroyError = null;
|
|
21643
|
+
try {
|
|
21644
|
+
internalRoot.destroyRecursively();
|
|
21645
|
+
} catch (error) {
|
|
21646
|
+
destroyError = error;
|
|
21647
|
+
}
|
|
21648
|
+
try {
|
|
21649
|
+
backingBuffer.destroy();
|
|
21650
|
+
} catch (error) {
|
|
21651
|
+
if (destroyError === null) {
|
|
21652
|
+
destroyError = error;
|
|
21653
|
+
}
|
|
21654
|
+
}
|
|
21655
|
+
renderContext.removeAllListeners();
|
|
21656
|
+
snapshotContext.removeAllListeners();
|
|
21657
|
+
if (destroyError !== null) {
|
|
21658
|
+
throw destroyError;
|
|
21659
|
+
}
|
|
21660
|
+
};
|
|
21661
|
+
renderer.on("destroy" /* DESTROY */, destroyListener);
|
|
21662
|
+
return {
|
|
21663
|
+
get renderContext() {
|
|
21664
|
+
return renderContext;
|
|
21665
|
+
},
|
|
21666
|
+
get root() {
|
|
21667
|
+
return publicRoot;
|
|
21668
|
+
},
|
|
21669
|
+
get width() {
|
|
21670
|
+
return surfaceWidth;
|
|
21671
|
+
},
|
|
21672
|
+
get height() {
|
|
21673
|
+
return surfaceHeight;
|
|
21674
|
+
},
|
|
21675
|
+
get isDestroyed() {
|
|
21676
|
+
return surfaceDestroyed;
|
|
21677
|
+
},
|
|
21678
|
+
render: renderSurface,
|
|
21679
|
+
settle: settleSurface,
|
|
21680
|
+
commitRows,
|
|
21681
|
+
destroy: destroySurface
|
|
21682
|
+
};
|
|
21683
|
+
}
|
|
21684
|
+
writeToScrollback(write) {
|
|
21685
|
+
if (this._screenMode !== "split-footer" || this._externalOutputMode !== "capture-stdout") {
|
|
21686
|
+
throw new Error('writeToScrollback requires screenMode "split-footer" and externalOutputMode "capture-stdout"');
|
|
21687
|
+
}
|
|
21688
|
+
const snapshotContext = new ScrollbackSnapshotRenderContext(this.width, this.height, this.widthMethod);
|
|
21689
|
+
const snapshot = write({
|
|
21690
|
+
width: this.width,
|
|
21691
|
+
widthMethod: this.widthMethod,
|
|
21692
|
+
tailColumn: this.splitTailColumn,
|
|
21693
|
+
renderContext: snapshotContext
|
|
21694
|
+
});
|
|
21695
|
+
if (!snapshot || !snapshot.root) {
|
|
21696
|
+
throw new Error("writeToScrollback must return a snapshot root renderable");
|
|
21697
|
+
}
|
|
21698
|
+
let renderFailed = false;
|
|
21699
|
+
let snapshotRoot = null;
|
|
21700
|
+
let snapshotBuffer = null;
|
|
21701
|
+
try {
|
|
21702
|
+
const rootRenderable = snapshot.root;
|
|
21703
|
+
const snapshotWidth = this.getSnapshotWidth(snapshot.width, rootRenderable.width);
|
|
21704
|
+
const snapshotHeight = this.getSnapshotHeight(snapshot.height, rootRenderable.height);
|
|
21705
|
+
snapshotContext.width = snapshotWidth;
|
|
21706
|
+
snapshotContext.height = snapshotHeight;
|
|
21707
|
+
snapshotContext.widthMethod = this.widthMethod;
|
|
21708
|
+
snapshotRoot = new RootRenderable(snapshotContext);
|
|
21709
|
+
snapshotBuffer = OptimizedBuffer.create(snapshotWidth, snapshotHeight, this.widthMethod, {
|
|
21710
|
+
id: "scrollback-snapshot-commit"
|
|
21711
|
+
});
|
|
21712
|
+
snapshotRoot.add(rootRenderable);
|
|
21713
|
+
snapshotRoot.render(snapshotBuffer, 0);
|
|
21714
|
+
this.enqueueRenderedScrollbackCommit({
|
|
21715
|
+
snapshot: snapshotBuffer,
|
|
21716
|
+
rowColumns: snapshot.rowColumns,
|
|
21717
|
+
startOnNewLine: snapshot.startOnNewLine,
|
|
21718
|
+
trailingNewline: snapshot.trailingNewline
|
|
21719
|
+
});
|
|
21720
|
+
} catch (error) {
|
|
21721
|
+
renderFailed = true;
|
|
21722
|
+
snapshotBuffer?.destroy();
|
|
21723
|
+
throw error;
|
|
19443
21724
|
} finally {
|
|
19444
|
-
|
|
19445
|
-
|
|
21725
|
+
let cleanupError = null;
|
|
21726
|
+
try {
|
|
21727
|
+
if (snapshotRoot) {
|
|
21728
|
+
snapshotRoot.destroyRecursively();
|
|
21729
|
+
} else {
|
|
21730
|
+
snapshot.root.destroyRecursively();
|
|
21731
|
+
}
|
|
21732
|
+
} catch (error) {
|
|
21733
|
+
cleanupError = error;
|
|
21734
|
+
}
|
|
21735
|
+
try {
|
|
21736
|
+
snapshot.teardown?.();
|
|
21737
|
+
} catch (error) {
|
|
21738
|
+
if (cleanupError === null) {
|
|
21739
|
+
cleanupError = error;
|
|
21740
|
+
}
|
|
21741
|
+
}
|
|
21742
|
+
if (!renderFailed && cleanupError) {
|
|
21743
|
+
throw cleanupError;
|
|
21744
|
+
}
|
|
19446
21745
|
}
|
|
19447
21746
|
}
|
|
19448
|
-
|
|
19449
|
-
|
|
19450
|
-
|
|
19451
|
-
|
|
19452
|
-
this._useConsole = mode === "console-overlay";
|
|
19453
|
-
if (this._useConsole) {
|
|
19454
|
-
this.console.activate();
|
|
19455
|
-
} else {
|
|
19456
|
-
this.console.deactivate();
|
|
21747
|
+
getSnapshotWidth(value, fallback) {
|
|
21748
|
+
const rawValue = value ?? fallback;
|
|
21749
|
+
if (!Number.isFinite(rawValue)) {
|
|
21750
|
+
throw new Error("writeToScrollback produced a non-finite width");
|
|
19457
21751
|
}
|
|
21752
|
+
return Math.min(Math.max(Math.trunc(rawValue), 1), Math.max(this.width, 1));
|
|
19458
21753
|
}
|
|
19459
|
-
|
|
19460
|
-
|
|
21754
|
+
getSnapshotHeight(value, fallback) {
|
|
21755
|
+
const rawValue = value ?? fallback;
|
|
21756
|
+
if (!Number.isFinite(rawValue)) {
|
|
21757
|
+
throw new Error("writeToScrollback produced a non-finite height");
|
|
21758
|
+
}
|
|
21759
|
+
return Math.max(Math.trunc(rawValue), 1);
|
|
19461
21760
|
}
|
|
19462
|
-
|
|
19463
|
-
|
|
21761
|
+
getSnapshotRowWidths(snapshot, rowColumns) {
|
|
21762
|
+
const widths = [];
|
|
21763
|
+
const limit = Math.min(Math.max(Math.trunc(rowColumns), 0), snapshot.width);
|
|
21764
|
+
const chars = snapshot.buffers.char;
|
|
21765
|
+
for (let y = 0;y < snapshot.height; y += 1) {
|
|
21766
|
+
let x = limit;
|
|
21767
|
+
while (x > 0) {
|
|
21768
|
+
const cp = chars[y * snapshot.width + x - 1];
|
|
21769
|
+
if (cp === 0 || (cp & CHAR_FLAG_MASK) === CHAR_FLAG_CONTINUATION) {
|
|
21770
|
+
x -= 1;
|
|
21771
|
+
continue;
|
|
21772
|
+
}
|
|
21773
|
+
break;
|
|
21774
|
+
}
|
|
21775
|
+
widths.push(x);
|
|
21776
|
+
}
|
|
21777
|
+
return widths;
|
|
19464
21778
|
}
|
|
19465
|
-
|
|
19466
|
-
if (
|
|
21779
|
+
publishSplitTailColumns(columns) {
|
|
21780
|
+
if (columns <= 0) {
|
|
19467
21781
|
return;
|
|
19468
|
-
const resolvers = this.idleResolvers.splice(0);
|
|
19469
|
-
for (const resolve4 of resolvers) {
|
|
19470
|
-
resolve4();
|
|
19471
21782
|
}
|
|
21783
|
+
const width = Math.max(this.width, 1);
|
|
21784
|
+
let tail = this.splitTailColumn;
|
|
21785
|
+
let remaining = columns;
|
|
21786
|
+
while (remaining > 0) {
|
|
21787
|
+
if (tail >= width) {
|
|
21788
|
+
tail = 0;
|
|
21789
|
+
}
|
|
21790
|
+
const step = Math.min(remaining, width - tail);
|
|
21791
|
+
tail += step;
|
|
21792
|
+
remaining -= step;
|
|
21793
|
+
if (remaining > 0 && tail >= width) {
|
|
21794
|
+
tail = 0;
|
|
21795
|
+
}
|
|
21796
|
+
}
|
|
21797
|
+
this.splitTailColumn = tail;
|
|
19472
21798
|
}
|
|
19473
|
-
|
|
19474
|
-
if (this.
|
|
19475
|
-
|
|
19476
|
-
|
|
19477
|
-
|
|
19478
|
-
|
|
19479
|
-
this.
|
|
19480
|
-
|
|
21799
|
+
recordSplitCommit(commit) {
|
|
21800
|
+
if (commit.startOnNewLine && this.splitTailColumn > 0) {
|
|
21801
|
+
this.splitTailColumn = 0;
|
|
21802
|
+
}
|
|
21803
|
+
const rowWidths = this.getSnapshotRowWidths(commit.snapshot, commit.rowColumns);
|
|
21804
|
+
for (const [index, rowWidth] of rowWidths.entries()) {
|
|
21805
|
+
this.publishSplitTailColumns(rowWidth);
|
|
21806
|
+
if (index < rowWidths.length - 1 || commit.trailingNewline) {
|
|
21807
|
+
this.splitTailColumn = 0;
|
|
21808
|
+
}
|
|
21809
|
+
}
|
|
19481
21810
|
}
|
|
19482
|
-
|
|
19483
|
-
|
|
21811
|
+
enqueueRenderedScrollbackCommit(options) {
|
|
21812
|
+
if (this._screenMode !== "split-footer" || this._externalOutputMode !== "capture-stdout") {
|
|
21813
|
+
throw new Error('scrollback commit requires screenMode "split-footer" and externalOutputMode "capture-stdout"');
|
|
21814
|
+
}
|
|
21815
|
+
const rowColumns = Math.min(Math.max(Math.trunc(options.rowColumns ?? options.snapshot.width), 0), options.snapshot.width);
|
|
21816
|
+
this.enqueueSplitCommit({
|
|
21817
|
+
snapshot: options.snapshot,
|
|
21818
|
+
rowColumns,
|
|
21819
|
+
startOnNewLine: options.startOnNewLine ?? true,
|
|
21820
|
+
trailingNewline: options.trailingNewline ?? true
|
|
21821
|
+
});
|
|
21822
|
+
this.requestRender();
|
|
19484
21823
|
}
|
|
19485
|
-
|
|
19486
|
-
|
|
21824
|
+
enqueueSplitCommit(commit) {
|
|
21825
|
+
this.recordSplitCommit(commit);
|
|
21826
|
+
this.externalOutputQueue.writeSnapshot(commit);
|
|
21827
|
+
}
|
|
21828
|
+
createStdoutSnapshotCommit(line, trailingNewline) {
|
|
21829
|
+
const snapshotContext = new ScrollbackSnapshotRenderContext(this.width, 1, this.widthMethod);
|
|
21830
|
+
const maxWidth = Math.max(1, this.width);
|
|
21831
|
+
const lineCells = [...line];
|
|
21832
|
+
const rowColumns = Math.min(lineCells.length, maxWidth);
|
|
21833
|
+
const renderedLine = lineCells.slice(0, maxWidth).join("");
|
|
21834
|
+
const snapshotRoot = new RootRenderable(snapshotContext);
|
|
21835
|
+
const snapshotRenderable = new TextRenderable(snapshotContext, {
|
|
21836
|
+
id: "captured-stdout-snapshot",
|
|
21837
|
+
position: "absolute",
|
|
21838
|
+
left: 0,
|
|
21839
|
+
top: 0,
|
|
21840
|
+
width: Math.max(1, rowColumns),
|
|
21841
|
+
height: 1,
|
|
21842
|
+
content: renderedLine
|
|
21843
|
+
});
|
|
21844
|
+
const snapshotBuffer = OptimizedBuffer.create(Math.max(1, rowColumns), 1, this.widthMethod, {
|
|
21845
|
+
id: "captured-stdout-snapshot"
|
|
21846
|
+
});
|
|
21847
|
+
try {
|
|
21848
|
+
snapshotRoot.add(snapshotRenderable);
|
|
21849
|
+
snapshotRoot.render(snapshotBuffer, 0);
|
|
21850
|
+
return {
|
|
21851
|
+
snapshot: snapshotBuffer,
|
|
21852
|
+
rowColumns,
|
|
21853
|
+
startOnNewLine: false,
|
|
21854
|
+
trailingNewline
|
|
21855
|
+
};
|
|
21856
|
+
} catch (error) {
|
|
21857
|
+
snapshotBuffer.destroy();
|
|
21858
|
+
throw error;
|
|
21859
|
+
} finally {
|
|
21860
|
+
snapshotRoot.destroyRecursively();
|
|
21861
|
+
}
|
|
19487
21862
|
}
|
|
19488
|
-
|
|
19489
|
-
|
|
21863
|
+
splitStdoutRows(text) {
|
|
21864
|
+
const rows = [];
|
|
21865
|
+
let current = "";
|
|
21866
|
+
for (const char of text) {
|
|
21867
|
+
if (char === "\r") {
|
|
21868
|
+
current = "";
|
|
21869
|
+
continue;
|
|
21870
|
+
}
|
|
21871
|
+
if (char === `
|
|
21872
|
+
`) {
|
|
21873
|
+
rows.push({ line: current, trailingNewline: true });
|
|
21874
|
+
current = "";
|
|
21875
|
+
continue;
|
|
21876
|
+
}
|
|
21877
|
+
current += char;
|
|
21878
|
+
}
|
|
21879
|
+
if (current.length > 0) {
|
|
21880
|
+
rows.push({ line: current, trailingNewline: false });
|
|
21881
|
+
}
|
|
21882
|
+
return rows;
|
|
19490
21883
|
}
|
|
19491
|
-
|
|
19492
|
-
|
|
21884
|
+
createStdoutSnapshotCommits(text) {
|
|
21885
|
+
if (text.length === 0) {
|
|
21886
|
+
return [];
|
|
21887
|
+
}
|
|
21888
|
+
const commits = [];
|
|
21889
|
+
const chunkWidth = Math.max(1, this.width);
|
|
21890
|
+
for (const row of this.splitStdoutRows(text)) {
|
|
21891
|
+
const rowCells = [...row.line];
|
|
21892
|
+
if (rowCells.length === 0) {
|
|
21893
|
+
commits.push(this.createStdoutSnapshotCommit("", row.trailingNewline));
|
|
21894
|
+
continue;
|
|
21895
|
+
}
|
|
21896
|
+
let offset = 0;
|
|
21897
|
+
while (offset < rowCells.length) {
|
|
21898
|
+
const chunk = rowCells.slice(offset, offset + chunkWidth).join("");
|
|
21899
|
+
offset += chunkWidth;
|
|
21900
|
+
const isLastChunk = offset >= rowCells.length;
|
|
21901
|
+
commits.push(this.createStdoutSnapshotCommit(chunk, isLastChunk ? row.trailingNewline : false));
|
|
21902
|
+
}
|
|
21903
|
+
}
|
|
21904
|
+
return commits;
|
|
19493
21905
|
}
|
|
19494
|
-
|
|
19495
|
-
|
|
21906
|
+
flushPendingSplitCommits(forceFooterRepaint = false) {
|
|
21907
|
+
const commits = this.externalOutputQueue.claim(this.maxSplitCommitsPerFrame);
|
|
21908
|
+
let hasCommittedOutput = false;
|
|
21909
|
+
const lastCommitIndex = commits.length - 1;
|
|
21910
|
+
for (const [index, commit] of commits.entries()) {
|
|
21911
|
+
const forceCommit = forceFooterRepaint && index === lastCommitIndex;
|
|
21912
|
+
const beginFrame = index === 0;
|
|
21913
|
+
const finalizeFrame = index === lastCommitIndex;
|
|
21914
|
+
try {
|
|
21915
|
+
this.renderOffset = this.lib.commitSplitFooterSnapshot(this.rendererPtr, commit.snapshot, commit.rowColumns, commit.startOnNewLine, commit.trailingNewline, this.getSplitPinnedRenderOffset(), forceCommit, beginFrame, finalizeFrame);
|
|
21916
|
+
hasCommittedOutput = true;
|
|
21917
|
+
} finally {
|
|
21918
|
+
commit.snapshot.destroy();
|
|
21919
|
+
}
|
|
21920
|
+
}
|
|
21921
|
+
if (!hasCommittedOutput) {
|
|
21922
|
+
this.renderOffset = this.lib.repaintSplitFooter(this.rendererPtr, this.getSplitPinnedRenderOffset(), forceFooterRepaint);
|
|
21923
|
+
}
|
|
21924
|
+
this.pendingSplitFooterTransition = null;
|
|
21925
|
+
if (this.externalOutputQueue.size > 0) {
|
|
21926
|
+
this.requestRender();
|
|
21927
|
+
}
|
|
19496
21928
|
}
|
|
19497
|
-
|
|
19498
|
-
|
|
21929
|
+
interceptStdoutWrite = (chunk, encoding, callback) => {
|
|
21930
|
+
const resolvedCallback = typeof encoding === "function" ? encoding : callback;
|
|
21931
|
+
const resolvedEncoding = typeof encoding === "string" ? encoding : undefined;
|
|
21932
|
+
const text = typeof chunk === "string" ? chunk : chunk?.toString(resolvedEncoding) ?? "";
|
|
21933
|
+
if (this._externalOutputMode === "capture-stdout" && this._screenMode === "split-footer" && this._splitHeight > 0) {
|
|
21934
|
+
const commits = this.createStdoutSnapshotCommits(text);
|
|
21935
|
+
for (const commit of commits) {
|
|
21936
|
+
this.enqueueSplitCommit(commit);
|
|
21937
|
+
}
|
|
21938
|
+
if (commits.length > 0) {
|
|
21939
|
+
this.requestRender();
|
|
21940
|
+
}
|
|
21941
|
+
}
|
|
21942
|
+
if (typeof resolvedCallback === "function") {
|
|
21943
|
+
process.nextTick(resolvedCallback);
|
|
21944
|
+
}
|
|
21945
|
+
return true;
|
|
21946
|
+
};
|
|
21947
|
+
getSplitPinnedRenderOffset() {
|
|
21948
|
+
return this._screenMode === "split-footer" ? Math.max(this._terminalHeight - this._splitHeight, 0) : 0;
|
|
19499
21949
|
}
|
|
19500
|
-
|
|
19501
|
-
|
|
21950
|
+
getSplitCursorSeedRows() {
|
|
21951
|
+
const cursorState = this.lib.getCursorState(this.rendererPtr);
|
|
21952
|
+
const cursorRow = Number.isFinite(cursorState.y) ? Math.max(Math.trunc(cursorState.y), 1) : 1;
|
|
21953
|
+
return Math.min(cursorRow, Math.max(this._terminalHeight, 1));
|
|
19502
21954
|
}
|
|
19503
|
-
|
|
19504
|
-
|
|
21955
|
+
flushPendingSplitOutputBeforeTransition(forceFooterRepaint = false) {
|
|
21956
|
+
if (this._screenMode !== "split-footer" || this._splitHeight <= 0 || this._externalOutputMode !== "capture-stdout") {
|
|
21957
|
+
return;
|
|
21958
|
+
}
|
|
21959
|
+
if (this.externalOutputQueue.size === 0 && !forceFooterRepaint) {
|
|
21960
|
+
return;
|
|
21961
|
+
}
|
|
21962
|
+
this.flushPendingSplitCommits(forceFooterRepaint);
|
|
19505
21963
|
}
|
|
19506
|
-
|
|
19507
|
-
this.
|
|
19508
|
-
this.
|
|
21964
|
+
resetSplitScrollback(seedRows = 0) {
|
|
21965
|
+
this.splitTailColumn = 0;
|
|
21966
|
+
this.renderOffset = this.lib.resetSplitScrollback(this.rendererPtr, seedRows, this.getSplitPinnedRenderOffset());
|
|
19509
21967
|
}
|
|
19510
|
-
|
|
19511
|
-
|
|
21968
|
+
syncSplitScrollback() {
|
|
21969
|
+
this.renderOffset = this.lib.syncSplitScrollback(this.rendererPtr, this.getSplitPinnedRenderOffset());
|
|
19512
21970
|
}
|
|
19513
|
-
|
|
19514
|
-
this.
|
|
19515
|
-
|
|
21971
|
+
clearPendingSplitFooterTransition() {
|
|
21972
|
+
if (this.pendingSplitFooterTransition === null) {
|
|
21973
|
+
return;
|
|
21974
|
+
}
|
|
21975
|
+
this.pendingSplitFooterTransition = null;
|
|
21976
|
+
this.lib.clearPendingSplitFooterTransition(this.rendererPtr);
|
|
19516
21977
|
}
|
|
19517
|
-
|
|
19518
|
-
|
|
21978
|
+
setPendingSplitFooterTransition(transition) {
|
|
21979
|
+
this.pendingSplitFooterTransition = transition;
|
|
21980
|
+
this.lib.setPendingSplitFooterTransition(this.rendererPtr, transition.mode === "viewport-scroll" ? 1 : 2, transition.sourceTopLine, transition.sourceHeight, transition.targetTopLine, transition.targetHeight);
|
|
19519
21981
|
}
|
|
19520
|
-
|
|
19521
|
-
|
|
21982
|
+
syncSplitFooterState() {
|
|
21983
|
+
const splitActive = this._screenMode === "split-footer" && this._splitHeight > 0;
|
|
21984
|
+
if (!splitActive) {
|
|
21985
|
+
this.clearPendingSplitFooterTransition();
|
|
21986
|
+
this.splitTailColumn = 0;
|
|
21987
|
+
this.lib.resetSplitScrollback(this.rendererPtr, 0, 0);
|
|
21988
|
+
this.renderOffset = 0;
|
|
21989
|
+
this.lib.setRenderOffset(this.rendererPtr, this.renderOffset);
|
|
19522
21990
|
return;
|
|
19523
|
-
|
|
19524
|
-
if (
|
|
19525
|
-
this.
|
|
21991
|
+
}
|
|
21992
|
+
if (this._externalOutputMode === "capture-stdout") {
|
|
21993
|
+
this.syncSplitScrollback();
|
|
19526
21994
|
} else {
|
|
19527
|
-
this.
|
|
21995
|
+
this.clearPendingSplitFooterTransition();
|
|
21996
|
+
this.splitTailColumn = 0;
|
|
21997
|
+
this.lib.resetSplitScrollback(this.rendererPtr, 0, 0);
|
|
21998
|
+
this.renderOffset = this.getSplitPinnedRenderOffset();
|
|
21999
|
+
this.lib.setRenderOffset(this.rendererPtr, this.renderOffset);
|
|
19528
22000
|
}
|
|
19529
22001
|
}
|
|
19530
|
-
|
|
19531
|
-
|
|
19532
|
-
|
|
19533
|
-
set screenMode(mode) {
|
|
19534
|
-
if (this.externalOutputMode === "capture-stdout" && mode !== "split-footer") {
|
|
19535
|
-
throw new Error('externalOutputMode "capture-stdout" requires screenMode "split-footer"');
|
|
22002
|
+
clearStaleSplitSurfaceRows(previousTopLine, previousHeight, nextTopLine, nextHeight) {
|
|
22003
|
+
if (!this._terminalIsSetup || previousHeight <= 0 || this._terminalHeight <= 0) {
|
|
22004
|
+
return;
|
|
19536
22005
|
}
|
|
19537
|
-
this.
|
|
19538
|
-
|
|
19539
|
-
|
|
19540
|
-
|
|
19541
|
-
}
|
|
19542
|
-
set footerHeight(footerHeight) {
|
|
19543
|
-
const normalizedFooterHeight = normalizeFooterHeight(footerHeight);
|
|
19544
|
-
if (normalizedFooterHeight === this._footerHeight) {
|
|
22006
|
+
const terminalBottom = this._terminalHeight;
|
|
22007
|
+
const previousStart = Math.max(1, previousTopLine);
|
|
22008
|
+
const previousEnd = Math.min(terminalBottom, previousTopLine + previousHeight - 1);
|
|
22009
|
+
if (previousEnd < previousStart) {
|
|
19545
22010
|
return;
|
|
19546
22011
|
}
|
|
19547
|
-
|
|
19548
|
-
|
|
19549
|
-
|
|
22012
|
+
const nextStart = Math.max(1, nextTopLine);
|
|
22013
|
+
const nextEnd = Math.min(terminalBottom, nextTopLine + Math.max(nextHeight, 0) - 1);
|
|
22014
|
+
let clear = "";
|
|
22015
|
+
for (let line = previousStart;line <= previousEnd; line += 1) {
|
|
22016
|
+
if (line >= nextStart && line <= nextEnd) {
|
|
22017
|
+
continue;
|
|
22018
|
+
}
|
|
22019
|
+
clear += `${ANSI.moveCursor(line, 1)}\x1B[2K`;
|
|
19550
22020
|
}
|
|
19551
|
-
|
|
19552
|
-
|
|
19553
|
-
return this._externalOutputMode;
|
|
19554
|
-
}
|
|
19555
|
-
set externalOutputMode(mode) {
|
|
19556
|
-
if (mode === "capture-stdout" && this.screenMode !== "split-footer") {
|
|
19557
|
-
throw new Error('externalOutputMode "capture-stdout" requires screenMode "split-footer"');
|
|
22021
|
+
if (clear.length > 0) {
|
|
22022
|
+
this.writeOut(clear);
|
|
19558
22023
|
}
|
|
19559
|
-
this._externalOutputMode = mode;
|
|
19560
|
-
this.stdout.write = mode === "capture-stdout" ? this.interceptStdoutWrite : this.realStdoutWrite;
|
|
19561
|
-
}
|
|
19562
|
-
get liveRequestCount() {
|
|
19563
|
-
return this.liveRequestCounter;
|
|
19564
|
-
}
|
|
19565
|
-
get currentControlState() {
|
|
19566
|
-
return this._controlState;
|
|
19567
|
-
}
|
|
19568
|
-
get capabilities() {
|
|
19569
|
-
return this._capabilities;
|
|
19570
|
-
}
|
|
19571
|
-
get themeMode() {
|
|
19572
|
-
return this._themeMode;
|
|
19573
|
-
}
|
|
19574
|
-
getDebugInputs() {
|
|
19575
|
-
return [...this._debugInputs];
|
|
19576
|
-
}
|
|
19577
|
-
get useKittyKeyboard() {
|
|
19578
|
-
return this.lib.getKittyKeyboardFlags(this.rendererPtr) > 0;
|
|
19579
|
-
}
|
|
19580
|
-
set useKittyKeyboard(use) {
|
|
19581
|
-
const flags = use ? KITTY_FLAG_DISAMBIGUATE | KITTY_FLAG_ALTERNATE_KEYS : 0;
|
|
19582
|
-
this.lib.setKittyKeyboardFlags(this.rendererPtr, flags);
|
|
19583
22024
|
}
|
|
19584
|
-
interceptStdoutWrite = (chunk, encoding, callback) => {
|
|
19585
|
-
const text = chunk.toString();
|
|
19586
|
-
capture.write("stdout", text);
|
|
19587
|
-
if (this._splitHeight > 0) {
|
|
19588
|
-
this.requestRender();
|
|
19589
|
-
}
|
|
19590
|
-
if (typeof callback === "function") {
|
|
19591
|
-
process.nextTick(callback);
|
|
19592
|
-
}
|
|
19593
|
-
return true;
|
|
19594
|
-
};
|
|
19595
22025
|
applyScreenMode(screenMode, emitResize = true, requestRender = true) {
|
|
19596
22026
|
const prevScreenMode = this._screenMode;
|
|
19597
22027
|
const prevSplitHeight = this._splitHeight;
|
|
19598
|
-
const
|
|
22028
|
+
const nextGeometry = calculateRenderGeometry(screenMode, this._terminalWidth, this._terminalHeight, this._footerHeight);
|
|
22029
|
+
const nextSplitHeight = nextGeometry.effectiveFooterHeight;
|
|
19599
22030
|
if (prevScreenMode === screenMode && prevSplitHeight === nextSplitHeight) {
|
|
19600
22031
|
return;
|
|
19601
22032
|
}
|
|
@@ -19603,10 +22034,24 @@ Captured output:
|
|
|
19603
22034
|
const nextUseAlternateScreen = screenMode === "alternate-screen";
|
|
19604
22035
|
const terminalScreenModeChanged = this._terminalIsSetup && prevUseAlternateScreen !== nextUseAlternateScreen;
|
|
19605
22036
|
const leavingSplitFooter = prevSplitHeight > 0 && nextSplitHeight === 0;
|
|
22037
|
+
if (this._terminalIsSetup && prevSplitHeight > 0) {
|
|
22038
|
+
this.flushPendingSplitOutputBeforeTransition();
|
|
22039
|
+
}
|
|
22040
|
+
const previousSurfaceTopLine = this.renderOffset + 1;
|
|
22041
|
+
const previousPinnedRenderOffset = Math.max(this._terminalHeight - prevSplitHeight, 0);
|
|
22042
|
+
const splitWasSettled = prevSplitHeight === 0 || this.renderOffset >= previousPinnedRenderOffset;
|
|
22043
|
+
const shouldUseViewportScrollTransitions = this._externalOutputMode !== "capture-stdout" || splitWasSettled;
|
|
22044
|
+
const shouldDeferSplitFooterResizeTransition = this._terminalIsSetup && prevScreenMode === "split-footer" && screenMode === "split-footer" && this._externalOutputMode === "capture-stdout" && prevSplitHeight > 0 && nextSplitHeight > 0 && !terminalScreenModeChanged;
|
|
22045
|
+
const splitStartupSeedBlocksFirstNativeFrame = this.pendingSplitStartupCursorSeed && this.splitStartupSeedTimeoutId !== null;
|
|
22046
|
+
const splitTransitionSourceTopLine = this.pendingSplitFooterTransition?.sourceTopLine ?? previousSurfaceTopLine;
|
|
22047
|
+
const splitTransitionSourceHeight = this.pendingSplitFooterTransition?.sourceHeight ?? prevSplitHeight;
|
|
22048
|
+
const splitTransitionMode = this.pendingSplitFooterTransition?.mode ?? (splitWasSettled ? "viewport-scroll" : "clear-stale-rows");
|
|
19606
22049
|
if (this._terminalIsSetup && leavingSplitFooter) {
|
|
19607
|
-
this.
|
|
22050
|
+
this.clearPendingSplitFooterTransition();
|
|
22051
|
+
this.renderOffset = 0;
|
|
22052
|
+
this.lib.setRenderOffset(this.rendererPtr, 0);
|
|
19608
22053
|
}
|
|
19609
|
-
if (this._terminalIsSetup && !terminalScreenModeChanged) {
|
|
22054
|
+
if (this._terminalIsSetup && !terminalScreenModeChanged && shouldUseViewportScrollTransitions && !shouldDeferSplitFooterResizeTransition) {
|
|
19610
22055
|
if (prevSplitHeight === 0 && nextSplitHeight > 0) {
|
|
19611
22056
|
const freedLines = this._terminalHeight - nextSplitHeight;
|
|
19612
22057
|
const scrollDown = ANSI.scrollDown(freedLines);
|
|
@@ -19621,18 +22066,39 @@ Captured output:
|
|
|
19621
22066
|
this.writeOut(scrollUp);
|
|
19622
22067
|
}
|
|
19623
22068
|
}
|
|
19624
|
-
if (prevSplitHeight === 0 && nextSplitHeight > 0) {
|
|
19625
|
-
capture.on("write", this.captureCallback);
|
|
19626
|
-
} else if (prevSplitHeight > 0 && nextSplitHeight === 0) {
|
|
19627
|
-
capture.off("write", this.captureCallback);
|
|
19628
|
-
}
|
|
19629
22069
|
this._screenMode = screenMode;
|
|
19630
22070
|
this._splitHeight = nextSplitHeight;
|
|
19631
|
-
this.
|
|
19632
|
-
this.
|
|
19633
|
-
this.height = nextSplitHeight > 0 ? nextSplitHeight : this._terminalHeight;
|
|
19634
|
-
this.lib.setRenderOffset(this.rendererPtr, this.renderOffset);
|
|
22071
|
+
this.width = nextGeometry.renderWidth;
|
|
22072
|
+
this.height = nextGeometry.renderHeight;
|
|
19635
22073
|
this.lib.resizeRenderer(this.rendererPtr, this.width, this.height);
|
|
22074
|
+
if (this._screenMode === "split-footer" && this._externalOutputMode === "capture-stdout") {
|
|
22075
|
+
if (prevScreenMode !== "split-footer") {
|
|
22076
|
+
this.resetSplitScrollback(this.getSplitCursorSeedRows());
|
|
22077
|
+
} else {
|
|
22078
|
+
this.syncSplitScrollback();
|
|
22079
|
+
}
|
|
22080
|
+
if (shouldDeferSplitFooterResizeTransition) {
|
|
22081
|
+
if (splitStartupSeedBlocksFirstNativeFrame) {
|
|
22082
|
+
this.clearPendingSplitFooterTransition();
|
|
22083
|
+
} else {
|
|
22084
|
+
this.setPendingSplitFooterTransition({
|
|
22085
|
+
mode: splitTransitionMode,
|
|
22086
|
+
sourceTopLine: splitTransitionSourceTopLine,
|
|
22087
|
+
sourceHeight: splitTransitionSourceHeight,
|
|
22088
|
+
targetTopLine: this.renderOffset + 1,
|
|
22089
|
+
targetHeight: nextSplitHeight
|
|
22090
|
+
});
|
|
22091
|
+
}
|
|
22092
|
+
this.forceFullRepaintRequested = true;
|
|
22093
|
+
} else if (!shouldUseViewportScrollTransitions && prevSplitHeight > 0 && nextSplitHeight > 0) {
|
|
22094
|
+
this.clearPendingSplitFooterTransition();
|
|
22095
|
+
this.clearStaleSplitSurfaceRows(previousSurfaceTopLine, prevSplitHeight, this.renderOffset + 1, nextSplitHeight);
|
|
22096
|
+
} else {
|
|
22097
|
+
this.clearPendingSplitFooterTransition();
|
|
22098
|
+
}
|
|
22099
|
+
} else {
|
|
22100
|
+
this.syncSplitFooterState();
|
|
22101
|
+
}
|
|
19636
22102
|
this.nextRenderBuffer = this.lib.getNextBuffer(this.rendererPtr);
|
|
19637
22103
|
this.currentRenderBuffer = this.lib.getCurrentBuffer(this.rendererPtr);
|
|
19638
22104
|
this._console.resize(this.width, this.height);
|
|
@@ -19652,12 +22118,18 @@ Captured output:
|
|
|
19652
22118
|
}
|
|
19653
22119
|
}
|
|
19654
22120
|
flushStdoutCache(space, force = false) {
|
|
19655
|
-
if (
|
|
22121
|
+
if (this.externalOutputQueue.size === 0 && !force)
|
|
19656
22122
|
return false;
|
|
19657
|
-
const
|
|
19658
|
-
|
|
22123
|
+
const outputCommits = this.externalOutputQueue.claim();
|
|
22124
|
+
let output = "";
|
|
22125
|
+
for (const commit of outputCommits) {
|
|
22126
|
+
output += `[snapshot ${commit.snapshot.width}x${commit.snapshot.height}]
|
|
22127
|
+
`;
|
|
22128
|
+
commit.snapshot.destroy();
|
|
22129
|
+
}
|
|
22130
|
+
const rendererStartLine = this.renderOffset + 1;
|
|
19659
22131
|
const flush = ANSI.moveCursorAndClear(rendererStartLine, 1);
|
|
19660
|
-
const outputLine = this.
|
|
22132
|
+
const outputLine = this.renderOffset + 1;
|
|
19661
22133
|
const move = ANSI.moveCursor(outputLine, 1);
|
|
19662
22134
|
let clear = "";
|
|
19663
22135
|
if (space > 0) {
|
|
@@ -19699,9 +22171,11 @@ Captured output:
|
|
|
19699
22171
|
if (this._terminalIsSetup)
|
|
19700
22172
|
return;
|
|
19701
22173
|
this._terminalIsSetup = true;
|
|
22174
|
+
const startupCursorCprActive = this._screenMode === "split-footer" && this._externalOutputMode === "capture-stdout";
|
|
19702
22175
|
this.updateStdinParserProtocolContext({
|
|
19703
22176
|
privateCapabilityRepliesActive: true,
|
|
19704
|
-
explicitWidthCprActive: true
|
|
22177
|
+
explicitWidthCprActive: true,
|
|
22178
|
+
startupCursorCprActive
|
|
19705
22179
|
});
|
|
19706
22180
|
this.lib.setupTerminal(this.rendererPtr, this._screenMode === "alternate-screen");
|
|
19707
22181
|
this._capabilities = this.lib.getTerminalCapabilities(this.rendererPtr);
|
|
@@ -19715,15 +22189,40 @@ Captured output:
|
|
|
19715
22189
|
}
|
|
19716
22190
|
this.capabilityTimeoutId = this.clock.setTimeout(() => {
|
|
19717
22191
|
this.capabilityTimeoutId = null;
|
|
22192
|
+
this.pendingSplitStartupCursorSeed = false;
|
|
22193
|
+
if (this.splitStartupSeedTimeoutId !== null) {
|
|
22194
|
+
this.clock.clearTimeout(this.splitStartupSeedTimeoutId);
|
|
22195
|
+
this.splitStartupSeedTimeoutId = null;
|
|
22196
|
+
}
|
|
22197
|
+
if (this._screenMode === "split-footer" && this._externalOutputMode === "capture-stdout") {
|
|
22198
|
+
this.requestRender();
|
|
22199
|
+
}
|
|
19718
22200
|
this.removeInputHandler(this.capabilityHandler);
|
|
19719
22201
|
this.updateStdinParserProtocolContext({
|
|
19720
22202
|
privateCapabilityRepliesActive: false,
|
|
19721
|
-
explicitWidthCprActive: false
|
|
22203
|
+
explicitWidthCprActive: false,
|
|
22204
|
+
startupCursorCprActive: false
|
|
19722
22205
|
}, true);
|
|
19723
22206
|
}, 5000);
|
|
19724
22207
|
if (this._useMouse) {
|
|
19725
22208
|
this.enableMouse();
|
|
19726
22209
|
}
|
|
22210
|
+
if (this._screenMode === "split-footer" && this._externalOutputMode === "capture-stdout") {
|
|
22211
|
+
this.pendingSplitStartupCursorSeed = true;
|
|
22212
|
+
if (this.splitStartupSeedTimeoutId !== null) {
|
|
22213
|
+
this.clock.clearTimeout(this.splitStartupSeedTimeoutId);
|
|
22214
|
+
}
|
|
22215
|
+
this.splitStartupSeedTimeoutId = this.clock.setTimeout(() => {
|
|
22216
|
+
this.splitStartupSeedTimeoutId = null;
|
|
22217
|
+
if (!this.pendingSplitStartupCursorSeed) {
|
|
22218
|
+
return;
|
|
22219
|
+
}
|
|
22220
|
+
this.updateStdinParserProtocolContext({ startupCursorCprActive: false });
|
|
22221
|
+
if (this._screenMode === "split-footer" && this._externalOutputMode === "capture-stdout") {
|
|
22222
|
+
this.requestRender();
|
|
22223
|
+
}
|
|
22224
|
+
}, 120);
|
|
22225
|
+
}
|
|
19727
22226
|
this.queryPixelResolution();
|
|
19728
22227
|
}
|
|
19729
22228
|
stdinListener = ((chunk) => {
|
|
@@ -19759,14 +22258,32 @@ Captured output:
|
|
|
19759
22258
|
this.oscSubscribers.delete(handler);
|
|
19760
22259
|
};
|
|
19761
22260
|
}
|
|
19762
|
-
|
|
19763
|
-
|
|
19764
|
-
|
|
19765
|
-
|
|
19766
|
-
|
|
19767
|
-
return true;
|
|
22261
|
+
processCapabilitySequence(sequence, hasCursorReport) {
|
|
22262
|
+
const hasStandardCapabilitySignature = isCapabilityResponse(sequence);
|
|
22263
|
+
const shouldProcessAsCapability = hasStandardCapabilitySignature || hasCursorReport && this.capabilityTimeoutId !== null;
|
|
22264
|
+
if (!shouldProcessAsCapability) {
|
|
22265
|
+
return false;
|
|
19768
22266
|
}
|
|
19769
|
-
|
|
22267
|
+
this.lib.processCapabilityResponse(this.rendererPtr, sequence);
|
|
22268
|
+
this._capabilities = this.lib.getTerminalCapabilities(this.rendererPtr);
|
|
22269
|
+
this.emit("capabilities" /* CAPABILITIES */, this._capabilities);
|
|
22270
|
+
const hadPendingSplitStartupCursorSeed = this.pendingSplitStartupCursorSeed;
|
|
22271
|
+
if (hadPendingSplitStartupCursorSeed && hasCursorReport && this._screenMode === "split-footer" && this._externalOutputMode === "capture-stdout") {
|
|
22272
|
+
this.resetSplitScrollback(this.getSplitCursorSeedRows());
|
|
22273
|
+
this.clearPendingSplitFooterTransition();
|
|
22274
|
+
this.pendingSplitStartupCursorSeed = false;
|
|
22275
|
+
this.updateStdinParserProtocolContext({ startupCursorCprActive: false });
|
|
22276
|
+
if (this.splitStartupSeedTimeoutId !== null) {
|
|
22277
|
+
this.clock.clearTimeout(this.splitStartupSeedTimeoutId);
|
|
22278
|
+
this.splitStartupSeedTimeoutId = null;
|
|
22279
|
+
}
|
|
22280
|
+
this.requestRender();
|
|
22281
|
+
}
|
|
22282
|
+
const consumeStartupCursorReport = hadPendingSplitStartupCursorSeed && hasCursorReport && this.splitStartupSeedTimeoutId !== null;
|
|
22283
|
+
return hasStandardCapabilitySignature || consumeStartupCursorReport;
|
|
22284
|
+
}
|
|
22285
|
+
capabilityHandler = ((sequence) => {
|
|
22286
|
+
return this.processCapabilitySequence(sequence, false);
|
|
19770
22287
|
}).bind(this);
|
|
19771
22288
|
focusHandler = ((sequence) => {
|
|
19772
22289
|
if (sequence === "\x1B[I") {
|
|
@@ -19792,21 +22309,50 @@ Captured output:
|
|
|
19792
22309
|
}).bind(this);
|
|
19793
22310
|
themeModeHandler = ((sequence) => {
|
|
19794
22311
|
if (sequence === "\x1B[?997;1n") {
|
|
19795
|
-
|
|
19796
|
-
|
|
19797
|
-
this.emit("theme_mode" /* THEME_MODE */, "dark");
|
|
19798
|
-
}
|
|
22312
|
+
this.applyThemeMode("dark", "csi");
|
|
22313
|
+
this._themeFallbackPending = false;
|
|
19799
22314
|
return true;
|
|
19800
22315
|
}
|
|
19801
22316
|
if (sequence === "\x1B[?997;2n") {
|
|
19802
|
-
|
|
19803
|
-
|
|
19804
|
-
|
|
22317
|
+
this.applyThemeMode("light", "csi");
|
|
22318
|
+
this._themeFallbackPending = false;
|
|
22319
|
+
return true;
|
|
22320
|
+
}
|
|
22321
|
+
let handledOscThemeResponse = false;
|
|
22322
|
+
let match;
|
|
22323
|
+
OSC_THEME_RESPONSE.lastIndex = 0;
|
|
22324
|
+
while (match = OSC_THEME_RESPONSE.exec(sequence)) {
|
|
22325
|
+
handledOscThemeResponse = true;
|
|
22326
|
+
const color = oscThemeColorToHex(match[2], match[3], match[4], match[5]);
|
|
22327
|
+
if (match[1] === "10") {
|
|
22328
|
+
this._themeOscForeground = color;
|
|
22329
|
+
} else {
|
|
22330
|
+
this._themeOscBackground = color;
|
|
19805
22331
|
}
|
|
22332
|
+
}
|
|
22333
|
+
if (!handledOscThemeResponse) {
|
|
22334
|
+
return false;
|
|
22335
|
+
}
|
|
22336
|
+
if (!this._themeFallbackPending) {
|
|
19806
22337
|
return true;
|
|
19807
22338
|
}
|
|
19808
|
-
|
|
22339
|
+
if (this._themeOscForeground && this._themeOscBackground) {
|
|
22340
|
+
this.applyThemeMode(inferThemeModeFromBackgroundColor(this._themeOscBackground), "osc");
|
|
22341
|
+
this._themeFallbackPending = false;
|
|
22342
|
+
}
|
|
22343
|
+
return true;
|
|
19809
22344
|
}).bind(this);
|
|
22345
|
+
applyThemeMode(mode, source) {
|
|
22346
|
+
if (source === "osc" && this._themeModeSource === "csi") {
|
|
22347
|
+
return;
|
|
22348
|
+
}
|
|
22349
|
+
const changed = this._themeMode !== mode;
|
|
22350
|
+
this._themeMode = mode;
|
|
22351
|
+
this._themeModeSource = source;
|
|
22352
|
+
if (changed) {
|
|
22353
|
+
this.emit("theme_mode" /* THEME_MODE */, mode);
|
|
22354
|
+
}
|
|
22355
|
+
}
|
|
19810
22356
|
dispatchSequenceHandlers(sequence) {
|
|
19811
22357
|
if (this._debugModeEnabled) {
|
|
19812
22358
|
this._debugInputs.push({
|
|
@@ -19851,6 +22397,9 @@ Captured output:
|
|
|
19851
22397
|
subscriber(event.sequence);
|
|
19852
22398
|
}
|
|
19853
22399
|
}
|
|
22400
|
+
if (event.protocol === "cpr" && this.processCapabilitySequence(event.sequence, true)) {
|
|
22401
|
+
return;
|
|
22402
|
+
}
|
|
19854
22403
|
this.dispatchSequenceHandlers(event.sequence);
|
|
19855
22404
|
return;
|
|
19856
22405
|
}
|
|
@@ -20137,28 +22686,45 @@ Captured output:
|
|
|
20137
22686
|
processResize(width, height) {
|
|
20138
22687
|
if (width === this._terminalWidth && height === this._terminalHeight)
|
|
20139
22688
|
return;
|
|
22689
|
+
if (this._terminalIsSetup && this._controlState !== "explicit_suspended" /* EXPLICIT_SUSPENDED */) {
|
|
22690
|
+
this.flushPendingSplitOutputBeforeTransition();
|
|
22691
|
+
}
|
|
22692
|
+
const pendingSplitFooterTransition = this.pendingSplitFooterTransition;
|
|
22693
|
+
const previousGeometry = calculateRenderGeometry(this._screenMode, this._terminalWidth, this._terminalHeight, this._footerHeight);
|
|
20140
22694
|
const prevWidth = this._terminalWidth;
|
|
22695
|
+
const previousTerminalHeight = this._terminalHeight;
|
|
22696
|
+
const visiblePreviousSplitHeight = pendingSplitFooterTransition?.sourceHeight ?? previousGeometry.effectiveFooterHeight;
|
|
20141
22697
|
this._terminalWidth = width;
|
|
20142
22698
|
this._terminalHeight = height;
|
|
20143
22699
|
this.queryPixelResolution();
|
|
20144
22700
|
this.setCapturedRenderable(undefined);
|
|
20145
22701
|
this.stdinParser?.resetMouseState();
|
|
20146
|
-
|
|
20147
|
-
|
|
20148
|
-
|
|
20149
|
-
|
|
22702
|
+
const nextGeometry = calculateRenderGeometry(this._screenMode, this._terminalWidth, this._terminalHeight, this._footerHeight);
|
|
22703
|
+
const splitFooterActive = this._screenMode === "split-footer";
|
|
22704
|
+
if (splitFooterActive) {
|
|
22705
|
+
let clearStart = null;
|
|
22706
|
+
if (width < prevWidth && visiblePreviousSplitHeight > 0) {
|
|
22707
|
+
clearStart = Math.max(previousTerminalHeight - visiblePreviousSplitHeight * 2, 1);
|
|
22708
|
+
}
|
|
22709
|
+
if (pendingSplitFooterTransition !== null) {
|
|
22710
|
+
clearStart = clearStart === null ? pendingSplitFooterTransition.sourceTopLine : Math.min(clearStart, pendingSplitFooterTransition.sourceTopLine);
|
|
22711
|
+
}
|
|
22712
|
+
if (clearStart !== null) {
|
|
22713
|
+
const flush = ANSI.moveCursorAndClear(clearStart, 1);
|
|
20150
22714
|
this.writeOut(flush);
|
|
20151
22715
|
}
|
|
20152
|
-
this.renderOffset = height - this._splitHeight;
|
|
20153
|
-
this.width = width;
|
|
20154
|
-
this.height = this._splitHeight;
|
|
20155
22716
|
this.currentRenderBuffer.clear(this.backgroundColor);
|
|
20156
|
-
this.lib.setRenderOffset(this.rendererPtr, this.renderOffset);
|
|
20157
|
-
} else {
|
|
20158
|
-
this.width = width;
|
|
20159
|
-
this.height = height;
|
|
20160
22717
|
}
|
|
22718
|
+
this.clearPendingSplitFooterTransition();
|
|
22719
|
+
this._splitHeight = nextGeometry.effectiveFooterHeight;
|
|
22720
|
+
this.width = nextGeometry.renderWidth;
|
|
22721
|
+
this.height = nextGeometry.renderHeight;
|
|
20161
22722
|
this.lib.resizeRenderer(this.rendererPtr, this.width, this.height);
|
|
22723
|
+
if (this._screenMode === "split-footer" && this._externalOutputMode === "capture-stdout") {
|
|
22724
|
+
this.syncSplitScrollback();
|
|
22725
|
+
} else {
|
|
22726
|
+
this.syncSplitFooterState();
|
|
22727
|
+
}
|
|
20162
22728
|
this.nextRenderBuffer = this.lib.getNextBuffer(this.rendererPtr);
|
|
20163
22729
|
this.currentRenderBuffer = this.lib.getCurrentBuffer(this.rendererPtr);
|
|
20164
22730
|
this._console.resize(this.width, this.height);
|
|
@@ -20306,6 +22872,9 @@ Captured output:
|
|
|
20306
22872
|
this._previousControlState = this._controlState;
|
|
20307
22873
|
this._controlState = "explicit_suspended" /* EXPLICIT_SUSPENDED */;
|
|
20308
22874
|
this.internalPause();
|
|
22875
|
+
if (this._terminalIsSetup) {
|
|
22876
|
+
this.flushPendingSplitOutputBeforeTransition(true);
|
|
22877
|
+
}
|
|
20309
22878
|
this._suspendedMouseEnabled = this._useMouse;
|
|
20310
22879
|
this.disableMouse();
|
|
20311
22880
|
this.removeExitListeners();
|
|
@@ -20313,7 +22882,8 @@ Captured output:
|
|
|
20313
22882
|
this.updateStdinParserProtocolContext({
|
|
20314
22883
|
privateCapabilityRepliesActive: false,
|
|
20315
22884
|
pixelResolutionQueryActive: false,
|
|
20316
|
-
explicitWidthCprActive: false
|
|
22885
|
+
explicitWidthCprActive: false,
|
|
22886
|
+
startupCursorCprActive: false
|
|
20317
22887
|
});
|
|
20318
22888
|
this.stdinParser?.reset();
|
|
20319
22889
|
this.stdin.removeListener("data", this.stdinListener);
|
|
@@ -20332,6 +22902,9 @@ Captured output:
|
|
|
20332
22902
|
this.stdin.resume();
|
|
20333
22903
|
this.addExitListeners();
|
|
20334
22904
|
this.lib.resumeRenderer(this.rendererPtr);
|
|
22905
|
+
if (this._screenMode === "split-footer" && this._splitHeight > 0) {
|
|
22906
|
+
this.syncSplitFooterState();
|
|
22907
|
+
}
|
|
20335
22908
|
if (this._suspendedMouseEnabled) {
|
|
20336
22909
|
this.enableMouse();
|
|
20337
22910
|
}
|
|
@@ -20393,7 +22966,6 @@ Captured output:
|
|
|
20393
22966
|
process.removeListener("unhandledRejection", this.handleError);
|
|
20394
22967
|
process.removeListener("warning", this.warningHandler);
|
|
20395
22968
|
process.removeListener("beforeExit", this.exitHandler);
|
|
20396
|
-
capture.removeListener("write", this.captureCallback);
|
|
20397
22969
|
this.removeExitListeners();
|
|
20398
22970
|
if (this.resizeTimeoutId !== null) {
|
|
20399
22971
|
this.clock.clearTimeout(this.resizeTimeoutId);
|
|
@@ -20403,6 +22975,10 @@ Captured output:
|
|
|
20403
22975
|
this.clock.clearTimeout(this.capabilityTimeoutId);
|
|
20404
22976
|
this.capabilityTimeoutId = null;
|
|
20405
22977
|
}
|
|
22978
|
+
if (this.splitStartupSeedTimeoutId !== null) {
|
|
22979
|
+
this.clock.clearTimeout(this.splitStartupSeedTimeoutId);
|
|
22980
|
+
this.splitStartupSeedTimeoutId = null;
|
|
22981
|
+
}
|
|
20406
22982
|
if (this.memorySnapshotTimer) {
|
|
20407
22983
|
this.clock.clearInterval(this.memorySnapshotTimer);
|
|
20408
22984
|
this.memorySnapshotTimer = null;
|
|
@@ -20416,7 +22992,8 @@ Captured output:
|
|
|
20416
22992
|
this.updateStdinParserProtocolContext({
|
|
20417
22993
|
privateCapabilityRepliesActive: false,
|
|
20418
22994
|
pixelResolutionQueryActive: false,
|
|
20419
|
-
explicitWidthCprActive: false
|
|
22995
|
+
explicitWidthCprActive: false,
|
|
22996
|
+
startupCursorCprActive: false
|
|
20420
22997
|
}, true);
|
|
20421
22998
|
this._useMouse = false;
|
|
20422
22999
|
this.setCapturedRenderable(undefined);
|
|
@@ -20458,6 +23035,16 @@ Captured output:
|
|
|
20458
23035
|
this.stdinParser = null;
|
|
20459
23036
|
this.oscSubscribers.clear();
|
|
20460
23037
|
this._console.destroy();
|
|
23038
|
+
if (this._splitHeight > 0 && this._terminalIsSetup && this._controlState !== "explicit_suspended" /* EXPLICIT_SUSPENDED */) {
|
|
23039
|
+
this.flushPendingSplitOutputBeforeTransition(true);
|
|
23040
|
+
this.renderOffset = 0;
|
|
23041
|
+
if (this.clearOnShutdown) {
|
|
23042
|
+
this.lib.setRenderOffset(this.rendererPtr, 0);
|
|
23043
|
+
}
|
|
23044
|
+
}
|
|
23045
|
+
this._externalOutputMode = "passthrough";
|
|
23046
|
+
this.stdout.write = this.realStdoutWrite;
|
|
23047
|
+
this.externalOutputQueue.clear();
|
|
20461
23048
|
this.lib.destroyRenderer(this.rendererPtr);
|
|
20462
23049
|
rendererTracker.removeRenderer(this);
|
|
20463
23050
|
if (this._onDestroy) {
|
|
@@ -20566,12 +23153,21 @@ Captured output:
|
|
|
20566
23153
|
console.error("Rendering called concurrently");
|
|
20567
23154
|
throw new Error("Rendering called concurrently");
|
|
20568
23155
|
}
|
|
20569
|
-
let force = false;
|
|
20570
|
-
if (this._splitHeight > 0) {
|
|
20571
|
-
force = this.flushStdoutCache(this._splitHeight);
|
|
20572
|
-
}
|
|
20573
23156
|
this.renderingNative = true;
|
|
20574
|
-
this.
|
|
23157
|
+
if (this.pendingSplitStartupCursorSeed && this.splitStartupSeedTimeoutId !== null && this._splitHeight > 0 && this._externalOutputMode === "capture-stdout") {
|
|
23158
|
+
this.renderingNative = false;
|
|
23159
|
+
return;
|
|
23160
|
+
}
|
|
23161
|
+
if (this._splitHeight > 0 && this._externalOutputMode === "capture-stdout") {
|
|
23162
|
+
const forceSplitRepaint = this.forceFullRepaintRequested;
|
|
23163
|
+
this.forceFullRepaintRequested = false;
|
|
23164
|
+
this.flushPendingSplitCommits(forceSplitRepaint);
|
|
23165
|
+
this.pendingSplitFooterTransition = null;
|
|
23166
|
+
} else {
|
|
23167
|
+
this.forceFullRepaintRequested = false;
|
|
23168
|
+
this.pendingSplitFooterTransition = null;
|
|
23169
|
+
this.lib.render(this.rendererPtr, false);
|
|
23170
|
+
}
|
|
20575
23171
|
this.renderingNative = false;
|
|
20576
23172
|
}
|
|
20577
23173
|
collectStatSample(frameTime) {
|
|
@@ -20753,7 +23349,7 @@ Captured output:
|
|
|
20753
23349
|
}
|
|
20754
23350
|
}
|
|
20755
23351
|
|
|
20756
|
-
export { __toESM, __commonJS, __export, __require,
|
|
23352
|
+
export { __toESM, __commonJS, __export, __require, MeasureMode, exports_src, isValidBorderStyle, parseBorderStyle, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, KeyEvent, PasteEvent, KeyHandler, InternalKeyHandler, RGBA, hexToRgb, rgbToHex, hsvToRgb, parseColor, fonts, measureText, getCharacterPositions, coordinateToCharacterIndex, renderFontToFrameBuffer, TextAttributes, ATTRIBUTE_BASE_BITS, ATTRIBUTE_BASE_MASK, getBaseAttributes, DebugOverlayCorner, TargetChannel, createTextAttributes, attributesWithLink, getLinkId, visualizeRenderableTree, isStyledText, StyledText, stringToStyledText, black, red, green, yellow, blue, magenta, cyan, white, brightBlack, brightRed, brightGreen, brightYellow, brightBlue, brightMagenta, brightCyan, brightWhite, bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite, bold, italic, underline, strikethrough, dim, reverse, blink, fg, bg, link, t, hastToStyledText, SystemClock, nonAlphanumericKeys, parseKeypress, LinearScrollAccel, MacOSScrollAccel, parseAlign, parseAlignItems, parseBoxSizing, parseDimension, parseDirection, parseDisplay, parseEdge, parseFlexDirection, parseGutter, parseJustify, parseLogLevel, parseMeasureMode, parseOverflow, parsePositionType, parseUnit, parseWrap, MouseParser, Selection, convertGlobalToLocalSelection, ASCIIFontSelectionHelper, envRegistry, registerEnvVar, clearEnvCache, generateEnvMarkdown, generateEnvColored, env, StdinParser, treeSitterToTextChunks, treeSitterToStyledText, addDefaultParsers, TreeSitterClient, DataPathsManager, getDataPaths, extensionToFiletype, basenameToFiletype, extToFiletype, pathToFiletype, infoStringToFiletype, main, getTreeSitterClient, ExtmarksController, createExtmarksController, TerminalPalette, createTerminalPalette, decodePasteBytes, stripAnsiSequences, detectLinks, TextBuffer, SpanInfoStruct, LogLevel2 as LogLevel, setRenderLibPath, resolveRenderLib, OptimizedBuffer, h, isVNode, maybeMakeRenderable, wrapWithDelegates, instantiate, delegate, LayoutEvents, RenderableEvents, isRenderable, BaseRenderable, Renderable, RootRenderable, TextBufferView, EditBuffer, EditorView, convertThemeToStyles, SyntaxStyle, ANSI, BoxRenderable, TextBufferRenderable, CodeRenderable, isTextNodeRenderable, TextNodeRenderable, RootTextNodeRenderable, TextRenderable, defaultKeyAliases, mergeKeyAliases, mergeKeyBindings, getKeyBindingAction, buildKeyBindingsMap, capture, ConsolePosition, TerminalConsole, getObjectsInViewport, EditBufferRenderableEvents, isEditBufferRenderable, EditBufferRenderable, calculateRenderGeometry, buildKittyKeyboardFlags, MouseEvent, MouseButton, createCliRenderer, CliRenderEvents, RendererControlState, CliRenderer };
|
|
20757
23353
|
|
|
20758
|
-
//# debugId=
|
|
20759
|
-
//# sourceMappingURL=index-
|
|
23354
|
+
//# debugId=8C02D415BAC7A02B64756E2164756E21
|
|
23355
|
+
//# sourceMappingURL=index-t3rrpex7.js.map
|