@fairyhunter13/opentui-core 0.1.129 → 0.1.131
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-kwnan0ww.js → index-gwfqqvw5.js} +335 -1663
- package/index-gwfqqvw5.js.map +35 -0
- package/{index-w7h7gtsh.js → index-t3rrpex7.js} +2897 -299
- package/{index-w7h7gtsh.js.map → index-t3rrpex7.js.map} +15 -7
- package/{index-gxgq40nk.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-kwnan0ww.js.map +0 -42
- /package/{index-gxgq40nk.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
|
}
|
|
@@ -7088,6 +7101,8 @@ function canCompleteDeferredPrivateReplyCsi(state, byte, context) {
|
|
|
7088
7101
|
return state.hasDigit && byte === 121;
|
|
7089
7102
|
if (byte === 99)
|
|
7090
7103
|
return state.hasDigit || state.semicolons > 0;
|
|
7104
|
+
if (byte === 110)
|
|
7105
|
+
return state.hasDigit;
|
|
7091
7106
|
return state.hasDigit && byte === 117;
|
|
7092
7107
|
}
|
|
7093
7108
|
function concatBytes(left, right) {
|
|
@@ -7182,7 +7197,8 @@ class StdinParser {
|
|
|
7182
7197
|
kittyKeyboardEnabled: options.protocolContext?.kittyKeyboardEnabled ?? false,
|
|
7183
7198
|
privateCapabilityRepliesActive: options.protocolContext?.privateCapabilityRepliesActive ?? false,
|
|
7184
7199
|
pixelResolutionQueryActive: options.protocolContext?.pixelResolutionQueryActive ?? false,
|
|
7185
|
-
explicitWidthCprActive: options.protocolContext?.explicitWidthCprActive ?? false
|
|
7200
|
+
explicitWidthCprActive: options.protocolContext?.explicitWidthCprActive ?? false,
|
|
7201
|
+
startupCursorCprActive: options.protocolContext?.startupCursorCprActive ?? false
|
|
7186
7202
|
};
|
|
7187
7203
|
}
|
|
7188
7204
|
get bufferCapacity() {
|
|
@@ -7684,7 +7700,8 @@ class StdinParser {
|
|
|
7684
7700
|
}
|
|
7685
7701
|
if (byte >= 64 && byte <= 126) {
|
|
7686
7702
|
const end = this.cursor + 1;
|
|
7687
|
-
|
|
7703
|
+
const protocol = classifyParametricCsiProtocol(this.state, byte);
|
|
7704
|
+
this.emitKeyOrResponse(protocol, decodeUtf8(bytes.subarray(this.unitStart, end)));
|
|
7688
7705
|
this.state = { tag: "ground" };
|
|
7689
7706
|
this.consumePrefix(end);
|
|
7690
7707
|
continue;
|
|
@@ -7789,7 +7806,7 @@ class StdinParser {
|
|
|
7789
7806
|
}
|
|
7790
7807
|
if (byte >= 64 && byte <= 126) {
|
|
7791
7808
|
const end = this.cursor + 1;
|
|
7792
|
-
this.
|
|
7809
|
+
this.emitOpaqueResponse("csi", bytes.subarray(this.unitStart, end));
|
|
7793
7810
|
this.state = { tag: "ground" };
|
|
7794
7811
|
this.consumePrefix(end);
|
|
7795
7812
|
continue;
|
|
@@ -11893,6 +11910,10 @@ function getOpenTUILib(libPath) {
|
|
|
11893
11910
|
args: ["ptr", "bool"],
|
|
11894
11911
|
returns: "void"
|
|
11895
11912
|
},
|
|
11913
|
+
setClearOnShutdown: {
|
|
11914
|
+
args: ["ptr", "bool"],
|
|
11915
|
+
returns: "void"
|
|
11916
|
+
},
|
|
11896
11917
|
setBackgroundColor: {
|
|
11897
11918
|
args: ["ptr", "ptr"],
|
|
11898
11919
|
returns: "void"
|
|
@@ -11901,6 +11922,22 @@ function getOpenTUILib(libPath) {
|
|
|
11901
11922
|
args: ["ptr", "u32"],
|
|
11902
11923
|
returns: "void"
|
|
11903
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
|
+
},
|
|
11904
11941
|
updateStats: {
|
|
11905
11942
|
args: ["ptr", "f64", "u32", "f64"],
|
|
11906
11943
|
returns: "void"
|
|
@@ -11913,6 +11950,14 @@ function getOpenTUILib(libPath) {
|
|
|
11913
11950
|
args: ["ptr", "bool"],
|
|
11914
11951
|
returns: "void"
|
|
11915
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
|
+
},
|
|
11916
11961
|
getNextBuffer: {
|
|
11917
11962
|
args: ["ptr"],
|
|
11918
11963
|
returns: "ptr"
|
|
@@ -12385,6 +12430,10 @@ function getOpenTUILib(libPath) {
|
|
|
12385
12430
|
args: ["ptr", "u8"],
|
|
12386
12431
|
returns: "void"
|
|
12387
12432
|
},
|
|
12433
|
+
textBufferViewSetFirstLineOffset: {
|
|
12434
|
+
args: ["ptr", "u32"],
|
|
12435
|
+
returns: "void"
|
|
12436
|
+
},
|
|
12388
12437
|
textBufferViewSetViewportSize: {
|
|
12389
12438
|
args: ["ptr", "u32", "u32"],
|
|
12390
12439
|
returns: "void"
|
|
@@ -13122,12 +13171,27 @@ class FFIRenderLib {
|
|
|
13122
13171
|
setUseThread(renderer, useThread) {
|
|
13123
13172
|
this.opentui.symbols.setUseThread(renderer, useThread);
|
|
13124
13173
|
}
|
|
13174
|
+
setClearOnShutdown(renderer, clear) {
|
|
13175
|
+
this.opentui.symbols.setClearOnShutdown(renderer, clear);
|
|
13176
|
+
}
|
|
13125
13177
|
setBackgroundColor(renderer, color) {
|
|
13126
13178
|
this.opentui.symbols.setBackgroundColor(renderer, color.buffer);
|
|
13127
13179
|
}
|
|
13128
13180
|
setRenderOffset(renderer, offset) {
|
|
13129
13181
|
this.opentui.symbols.setRenderOffset(renderer, offset);
|
|
13130
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
|
+
}
|
|
13131
13195
|
updateStats(renderer, time, fps, frameCallbackTime) {
|
|
13132
13196
|
this.opentui.symbols.updateStats(renderer, time, fps, frameCallbackTime);
|
|
13133
13197
|
}
|
|
@@ -13317,6 +13381,12 @@ class FFIRenderLib {
|
|
|
13317
13381
|
render(renderer, force) {
|
|
13318
13382
|
this.opentui.symbols.render(renderer, force);
|
|
13319
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
|
+
}
|
|
13320
13390
|
createOptimizedBuffer(width, height, widthMethod, respectAlpha = false, id) {
|
|
13321
13391
|
if (Number.isNaN(width) || Number.isNaN(height)) {
|
|
13322
13392
|
console.error(new Error(`Invalid dimensions for OptimizedBuffer: ${width}x${height}`).stack);
|
|
@@ -13596,6 +13666,9 @@ class FFIRenderLib {
|
|
|
13596
13666
|
const modeValue = mode === "none" ? 0 : mode === "char" ? 1 : 2;
|
|
13597
13667
|
this.opentui.symbols.textBufferViewSetWrapMode(view, modeValue);
|
|
13598
13668
|
}
|
|
13669
|
+
textBufferViewSetFirstLineOffset(view, offset) {
|
|
13670
|
+
this.opentui.symbols.textBufferViewSetFirstLineOffset(view, offset);
|
|
13671
|
+
}
|
|
13599
13672
|
textBufferViewSetViewportSize(view, width, height) {
|
|
13600
13673
|
this.opentui.symbols.textBufferViewSetViewportSize(view, width, height);
|
|
13601
13674
|
}
|
|
@@ -16060,6 +16133,139 @@ function delegate(mapping, vnode) {
|
|
|
16060
16133
|
return vnode;
|
|
16061
16134
|
}
|
|
16062
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
|
+
|
|
16063
16269
|
// src/edit-buffer.ts
|
|
16064
16270
|
import { EventEmitter as EventEmitter6 } from "events";
|
|
16065
16271
|
|
|
@@ -16564,113 +16770,1542 @@ class EditorView {
|
|
|
16564
16770
|
}
|
|
16565
16771
|
}
|
|
16566
16772
|
|
|
16567
|
-
// src/
|
|
16568
|
-
|
|
16569
|
-
|
|
16570
|
-
|
|
16571
|
-
|
|
16572
|
-
|
|
16573
|
-
|
|
16574
|
-
|
|
16575
|
-
|
|
16576
|
-
|
|
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
|
+
}
|
|
16577
16802
|
|
|
16578
|
-
class
|
|
16579
|
-
|
|
16580
|
-
|
|
16581
|
-
|
|
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;
|
|
16582
16813
|
}
|
|
16583
|
-
|
|
16584
|
-
|
|
16814
|
+
static create() {
|
|
16815
|
+
const lib = resolveRenderLib();
|
|
16816
|
+
const ptr5 = lib.createSyntaxStyle();
|
|
16817
|
+
return new SyntaxStyle(lib, ptr5);
|
|
16585
16818
|
}
|
|
16586
|
-
|
|
16587
|
-
|
|
16588
|
-
|
|
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;
|
|
16589
16826
|
}
|
|
16590
|
-
|
|
16591
|
-
const
|
|
16592
|
-
|
|
16593
|
-
|
|
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;
|
|
16594
16833
|
}
|
|
16595
|
-
|
|
16596
|
-
this.
|
|
16834
|
+
guard() {
|
|
16835
|
+
if (this._destroyed)
|
|
16836
|
+
throw new Error("NativeSyntaxStyle is destroyed");
|
|
16597
16837
|
}
|
|
16598
|
-
|
|
16599
|
-
|
|
16600
|
-
|
|
16601
|
-
|
|
16602
|
-
|
|
16603
|
-
|
|
16604
|
-
|
|
16605
|
-
|
|
16606
|
-
|
|
16607
|
-
|
|
16608
|
-
this.
|
|
16609
|
-
|
|
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;
|
|
16610
16850
|
}
|
|
16611
|
-
|
|
16612
|
-
|
|
16613
|
-
this.
|
|
16614
|
-
|
|
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;
|
|
16615
16861
|
}
|
|
16616
|
-
|
|
16617
|
-
|
|
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;
|
|
16618
16872
|
}
|
|
16619
|
-
|
|
16620
|
-
|
|
16621
|
-
|
|
16622
|
-
var defaultKeyAliases = {
|
|
16623
|
-
enter: "return",
|
|
16624
|
-
esc: "escape",
|
|
16625
|
-
kp0: "0",
|
|
16626
|
-
kp1: "1",
|
|
16627
|
-
kp2: "2",
|
|
16628
|
-
kp3: "3",
|
|
16629
|
-
kp4: "4",
|
|
16630
|
-
kp5: "5",
|
|
16631
|
-
kp6: "6",
|
|
16632
|
-
kp7: "7",
|
|
16633
|
-
kp8: "8",
|
|
16634
|
-
kp9: "9",
|
|
16635
|
-
kpdecimal: ".",
|
|
16636
|
-
kpdivide: "/",
|
|
16637
|
-
kpmultiply: "*",
|
|
16638
|
-
kpminus: "-",
|
|
16639
|
-
kpplus: "+",
|
|
16640
|
-
kpenter: "enter",
|
|
16641
|
-
kpequal: "=",
|
|
16642
|
-
kpseparator: ",",
|
|
16643
|
-
kpleft: "left",
|
|
16644
|
-
kpright: "right",
|
|
16645
|
-
kpup: "up",
|
|
16646
|
-
kpdown: "down",
|
|
16647
|
-
kppageup: "pageup",
|
|
16648
|
-
kppagedown: "pagedown",
|
|
16649
|
-
kphome: "home",
|
|
16650
|
-
kpend: "end",
|
|
16651
|
-
kpinsert: "insert",
|
|
16652
|
-
kpdelete: "delete"
|
|
16653
|
-
};
|
|
16654
|
-
function mergeKeyAliases(defaults, custom) {
|
|
16655
|
-
return { ...defaults, ...custom };
|
|
16656
|
-
}
|
|
16657
|
-
function mergeKeyBindings(defaults, custom) {
|
|
16658
|
-
const map = new Map;
|
|
16659
|
-
for (const binding of defaults) {
|
|
16660
|
-
const key = getKeyBindingKey(binding);
|
|
16661
|
-
map.set(key, binding);
|
|
16873
|
+
get ptr() {
|
|
16874
|
+
this.guard();
|
|
16875
|
+
return this.stylePtr;
|
|
16662
16876
|
}
|
|
16663
|
-
|
|
16664
|
-
|
|
16665
|
-
|
|
16877
|
+
getStyleCount() {
|
|
16878
|
+
this.guard();
|
|
16879
|
+
return this.lib.syntaxStyleGetStyleCount(this.stylePtr);
|
|
16666
16880
|
}
|
|
16667
|
-
|
|
16668
|
-
|
|
16669
|
-
|
|
16670
|
-
|
|
16671
|
-
|
|
16672
|
-
|
|
16673
|
-
|
|
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) {
|
|
16674
18309
|
return;
|
|
16675
18310
|
}
|
|
16676
18311
|
try {
|
|
@@ -18743,6 +20378,27 @@ function getObjectsInViewport(viewport, objects, direction = "column", padding =
|
|
|
18743
20378
|
return visibleChildren;
|
|
18744
20379
|
}
|
|
18745
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
|
+
|
|
18746
20402
|
// src/lib/terminal-capability-detection.ts
|
|
18747
20403
|
function isCapabilityResponse(sequence) {
|
|
18748
20404
|
if (/\x1b\[\?\d+(?:;\d+)*\$y/.test(sequence)) {
|
|
@@ -18780,6 +20436,26 @@ function parsePixelResolution(sequence) {
|
|
|
18780
20436
|
}
|
|
18781
20437
|
|
|
18782
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
|
+
}
|
|
18783
20459
|
registerEnvVar({
|
|
18784
20460
|
name: "OTUI_DUMP_CAPTURES",
|
|
18785
20461
|
description: "Dump captured stdout and console caches when the renderer exit handler runs.",
|
|
@@ -18817,6 +20493,9 @@ registerEnvVar({
|
|
|
18817
20493
|
default: false
|
|
18818
20494
|
});
|
|
18819
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;
|
|
18820
20499
|
function normalizeFooterHeight(footerHeight) {
|
|
18821
20500
|
if (footerHeight === undefined) {
|
|
18822
20501
|
return DEFAULT_FOOTER_HEIGHT;
|
|
@@ -18843,11 +20522,106 @@ function resolveModes(config) {
|
|
|
18843
20522
|
if (externalOutputMode === "capture-stdout" && screenMode !== "split-footer") {
|
|
18844
20523
|
throw new Error('externalOutputMode "capture-stdout" requires screenMode "split-footer"');
|
|
18845
20524
|
}
|
|
18846
|
-
return {
|
|
18847
|
-
screenMode,
|
|
18848
|
-
footerHeight,
|
|
18849
|
-
externalOutputMode
|
|
18850
|
-
};
|
|
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) {}
|
|
18851
20625
|
}
|
|
18852
20626
|
var DEFAULT_FORWARDED_ENV_KEYS = [
|
|
18853
20627
|
"TMUX",
|
|
@@ -18969,9 +20743,9 @@ async function createCliRenderer(config = {}) {
|
|
|
18969
20743
|
const { screenMode, footerHeight } = resolveModes(config);
|
|
18970
20744
|
const width = stdout.columns || 80;
|
|
18971
20745
|
const height = stdout.rows || 24;
|
|
18972
|
-
const
|
|
20746
|
+
const geometry = calculateRenderGeometry(screenMode, width, height, footerHeight);
|
|
18973
20747
|
const ziglib = resolveRenderLib();
|
|
18974
|
-
const rendererPtr = ziglib.createRenderer(
|
|
20748
|
+
const rendererPtr = ziglib.createRenderer(geometry.renderWidth, geometry.renderHeight, {
|
|
18975
20749
|
remote: config.remote ?? false,
|
|
18976
20750
|
testing: config.testing ?? false
|
|
18977
20751
|
});
|
|
@@ -19088,6 +20862,8 @@ class CliRenderer extends EventEmitter9 {
|
|
|
19088
20862
|
animationRequest = new Map;
|
|
19089
20863
|
resizeTimeoutId = null;
|
|
19090
20864
|
capabilityTimeoutId = null;
|
|
20865
|
+
splitStartupSeedTimeoutId = null;
|
|
20866
|
+
pendingSplitStartupCursorSeed = false;
|
|
19091
20867
|
resizeDebounceDelay = 100;
|
|
19092
20868
|
enableMouseMovement = false;
|
|
19093
20869
|
_useMouse = true;
|
|
@@ -19095,6 +20871,7 @@ class CliRenderer extends EventEmitter9 {
|
|
|
19095
20871
|
_screenMode = "alternate-screen";
|
|
19096
20872
|
_footerHeight = DEFAULT_FOOTER_HEIGHT;
|
|
19097
20873
|
_externalOutputMode = "passthrough";
|
|
20874
|
+
clearOnShutdown = true;
|
|
19098
20875
|
_suspendedMouseEnabled = false;
|
|
19099
20876
|
_previousControlState = "idle" /* IDLE */;
|
|
19100
20877
|
capturedRenderable;
|
|
@@ -19105,15 +20882,15 @@ class CliRenderer extends EventEmitter9 {
|
|
|
19105
20882
|
clipboard;
|
|
19106
20883
|
_splitHeight = 0;
|
|
19107
20884
|
renderOffset = 0;
|
|
20885
|
+
splitTailColumn = 0;
|
|
20886
|
+
pendingSplitFooterTransition = null;
|
|
20887
|
+
forceFullRepaintRequested = false;
|
|
20888
|
+
maxSplitCommitsPerFrame = 8;
|
|
19108
20889
|
_terminalWidth = 0;
|
|
19109
20890
|
_terminalHeight = 0;
|
|
19110
20891
|
_terminalIsSetup = false;
|
|
20892
|
+
externalOutputQueue = new ExternalOutputQueue;
|
|
19111
20893
|
realStdoutWrite;
|
|
19112
|
-
captureCallback = () => {
|
|
19113
|
-
if (this._splitHeight > 0) {
|
|
19114
|
-
this.requestRender();
|
|
19115
|
-
}
|
|
19116
|
-
};
|
|
19117
20894
|
_useConsole = true;
|
|
19118
20895
|
sigwinchHandler = (() => {
|
|
19119
20896
|
const width = this.stdout.columns || 80;
|
|
@@ -19137,6 +20914,10 @@ class CliRenderer extends EventEmitter9 {
|
|
|
19137
20914
|
_paletteDetectionPromise = null;
|
|
19138
20915
|
_onDestroy;
|
|
19139
20916
|
_themeMode = null;
|
|
20917
|
+
_themeModeSource = "none";
|
|
20918
|
+
_themeFallbackPending = true;
|
|
20919
|
+
_themeOscForeground = null;
|
|
20920
|
+
_themeOscBackground = null;
|
|
19140
20921
|
_terminalFocusState = null;
|
|
19141
20922
|
sequenceHandlers = [];
|
|
19142
20923
|
prependedInputHandlers = [];
|
|
@@ -19152,8 +20933,15 @@ class CliRenderer extends EventEmitter9 {
|
|
|
19152
20933
|
}).bind(this);
|
|
19153
20934
|
dumpOutputCache(optionalMessage = "") {
|
|
19154
20935
|
const cachedLogs = this.console.getCachedLogs();
|
|
19155
|
-
const
|
|
19156
|
-
|
|
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) {
|
|
19157
20945
|
this.realStdoutWrite.call(this.stdout, optionalMessage);
|
|
19158
20946
|
}
|
|
19159
20947
|
if (cachedLogs.length > 0) {
|
|
@@ -19161,11 +20949,18 @@ class CliRenderer extends EventEmitter9 {
|
|
|
19161
20949
|
`);
|
|
19162
20950
|
this.realStdoutWrite.call(this.stdout, cachedLogs);
|
|
19163
20951
|
}
|
|
19164
|
-
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) {
|
|
19165
20960
|
this.realStdoutWrite.call(this.stdout, `
|
|
19166
|
-
Captured output:
|
|
20961
|
+
Captured external output:
|
|
19167
20962
|
`);
|
|
19168
|
-
this.realStdoutWrite.call(this.stdout,
|
|
20963
|
+
this.realStdoutWrite.call(this.stdout, capturedExternalOutput + `
|
|
19169
20964
|
`);
|
|
19170
20965
|
}
|
|
19171
20966
|
this.realStdoutWrite.call(this.stdout, ANSI.reset);
|
|
@@ -19194,13 +20989,18 @@ Captured output:
|
|
|
19194
20989
|
this.lib = lib;
|
|
19195
20990
|
this._terminalWidth = stdout.columns ?? width;
|
|
19196
20991
|
this._terminalHeight = stdout.rows ?? height;
|
|
19197
|
-
this.width = width;
|
|
19198
|
-
this.height = height;
|
|
19199
20992
|
this._useThread = config.useThread === undefined ? false : config.useThread;
|
|
19200
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;
|
|
19201
21000
|
this._footerHeight = footerHeight;
|
|
19202
|
-
this._screenMode = screenMode;
|
|
19203
21001
|
this.rendererPtr = rendererPtr;
|
|
21002
|
+
this.clearOnShutdown = config.clearOnShutdown ?? true;
|
|
21003
|
+
this.lib.setClearOnShutdown(this.rendererPtr, this.clearOnShutdown);
|
|
19204
21004
|
const forwardEnvKeys = config.forwardEnvKeys ?? [...DEFAULT_FORWARDED_ENV_KEYS];
|
|
19205
21005
|
for (const key of forwardEnvKeys) {
|
|
19206
21006
|
const value = process.env[key];
|
|
@@ -19235,7 +21035,6 @@ Captured output:
|
|
|
19235
21035
|
this.postProcessFns = config.postProcessFns || [];
|
|
19236
21036
|
this.prependedInputHandlers = config.prependInputHandlers || [];
|
|
19237
21037
|
this.root = new RootRenderable(this);
|
|
19238
|
-
this._openConsoleOnError = config.openConsoleOnError ?? false;
|
|
19239
21038
|
if (this.memorySnapshotInterval > 0) {
|
|
19240
21039
|
this.startMemorySnapshotTimer();
|
|
19241
21040
|
}
|
|
@@ -19269,7 +21068,8 @@ Captured output:
|
|
|
19269
21068
|
kittyKeyboardEnabled: useKittyForParsing,
|
|
19270
21069
|
privateCapabilityRepliesActive: false,
|
|
19271
21070
|
pixelResolutionQueryActive: false,
|
|
19272
|
-
explicitWidthCprActive: false
|
|
21071
|
+
explicitWidthCprActive: false,
|
|
21072
|
+
startupCursorCprActive: false
|
|
19273
21073
|
},
|
|
19274
21074
|
clock: this.clock
|
|
19275
21075
|
});
|
|
@@ -19279,7 +21079,8 @@ Captured output:
|
|
|
19279
21079
|
});
|
|
19280
21080
|
this.consoleMode = config.consoleMode ?? "console-overlay";
|
|
19281
21081
|
this.applyScreenMode(screenMode, false, false);
|
|
19282
|
-
this.
|
|
21082
|
+
this.stdout.write = externalOutputMode === "capture-stdout" ? this.interceptStdoutWrite : this.realStdoutWrite;
|
|
21083
|
+
this._openConsoleOnError = config.openConsoleOnError ?? false;
|
|
19283
21084
|
this._onDestroy = config.onDestroy;
|
|
19284
21085
|
global.requestAnimationFrame = (callback) => {
|
|
19285
21086
|
const id = CliRenderer.animationFrameId++;
|
|
@@ -19437,163 +21238,795 @@ Captured output:
|
|
|
19437
21238
|
return;
|
|
19438
21239
|
}
|
|
19439
21240
|
try {
|
|
19440
|
-
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;
|
|
19441
21724
|
} finally {
|
|
19442
|
-
|
|
19443
|
-
|
|
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
|
+
}
|
|
19444
21745
|
}
|
|
19445
21746
|
}
|
|
19446
|
-
|
|
19447
|
-
|
|
19448
|
-
|
|
19449
|
-
|
|
19450
|
-
this._useConsole = mode === "console-overlay";
|
|
19451
|
-
if (this._useConsole) {
|
|
19452
|
-
this.console.activate();
|
|
19453
|
-
} else {
|
|
19454
|
-
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");
|
|
19455
21751
|
}
|
|
21752
|
+
return Math.min(Math.max(Math.trunc(rawValue), 1), Math.max(this.width, 1));
|
|
19456
21753
|
}
|
|
19457
|
-
|
|
19458
|
-
|
|
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);
|
|
19459
21760
|
}
|
|
19460
|
-
|
|
19461
|
-
|
|
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;
|
|
19462
21778
|
}
|
|
19463
|
-
|
|
19464
|
-
if (
|
|
21779
|
+
publishSplitTailColumns(columns) {
|
|
21780
|
+
if (columns <= 0) {
|
|
19465
21781
|
return;
|
|
19466
|
-
const resolvers = this.idleResolvers.splice(0);
|
|
19467
|
-
for (const resolve4 of resolvers) {
|
|
19468
|
-
resolve4();
|
|
19469
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;
|
|
19470
21798
|
}
|
|
19471
|
-
|
|
19472
|
-
if (this.
|
|
19473
|
-
|
|
19474
|
-
|
|
19475
|
-
|
|
19476
|
-
|
|
19477
|
-
this.
|
|
19478
|
-
|
|
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
|
+
}
|
|
19479
21810
|
}
|
|
19480
|
-
|
|
19481
|
-
|
|
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();
|
|
19482
21823
|
}
|
|
19483
|
-
|
|
19484
|
-
|
|
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
|
+
}
|
|
19485
21862
|
}
|
|
19486
|
-
|
|
19487
|
-
|
|
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;
|
|
19488
21883
|
}
|
|
19489
|
-
|
|
19490
|
-
|
|
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;
|
|
19491
21905
|
}
|
|
19492
|
-
|
|
19493
|
-
|
|
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
|
+
}
|
|
19494
21928
|
}
|
|
19495
|
-
|
|
19496
|
-
|
|
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;
|
|
19497
21949
|
}
|
|
19498
|
-
|
|
19499
|
-
|
|
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));
|
|
19500
21954
|
}
|
|
19501
|
-
|
|
19502
|
-
|
|
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);
|
|
19503
21963
|
}
|
|
19504
|
-
|
|
19505
|
-
this.
|
|
19506
|
-
this.
|
|
21964
|
+
resetSplitScrollback(seedRows = 0) {
|
|
21965
|
+
this.splitTailColumn = 0;
|
|
21966
|
+
this.renderOffset = this.lib.resetSplitScrollback(this.rendererPtr, seedRows, this.getSplitPinnedRenderOffset());
|
|
19507
21967
|
}
|
|
19508
|
-
|
|
19509
|
-
|
|
21968
|
+
syncSplitScrollback() {
|
|
21969
|
+
this.renderOffset = this.lib.syncSplitScrollback(this.rendererPtr, this.getSplitPinnedRenderOffset());
|
|
19510
21970
|
}
|
|
19511
|
-
|
|
19512
|
-
this.
|
|
19513
|
-
|
|
21971
|
+
clearPendingSplitFooterTransition() {
|
|
21972
|
+
if (this.pendingSplitFooterTransition === null) {
|
|
21973
|
+
return;
|
|
21974
|
+
}
|
|
21975
|
+
this.pendingSplitFooterTransition = null;
|
|
21976
|
+
this.lib.clearPendingSplitFooterTransition(this.rendererPtr);
|
|
19514
21977
|
}
|
|
19515
|
-
|
|
19516
|
-
|
|
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);
|
|
19517
21981
|
}
|
|
19518
|
-
|
|
19519
|
-
|
|
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);
|
|
19520
21990
|
return;
|
|
19521
|
-
|
|
19522
|
-
if (
|
|
19523
|
-
this.
|
|
21991
|
+
}
|
|
21992
|
+
if (this._externalOutputMode === "capture-stdout") {
|
|
21993
|
+
this.syncSplitScrollback();
|
|
19524
21994
|
} else {
|
|
19525
|
-
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);
|
|
19526
22000
|
}
|
|
19527
22001
|
}
|
|
19528
|
-
|
|
19529
|
-
|
|
19530
|
-
|
|
19531
|
-
set screenMode(mode) {
|
|
19532
|
-
if (this.externalOutputMode === "capture-stdout" && mode !== "split-footer") {
|
|
19533
|
-
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;
|
|
19534
22005
|
}
|
|
19535
|
-
this.
|
|
19536
|
-
|
|
19537
|
-
|
|
19538
|
-
|
|
19539
|
-
}
|
|
19540
|
-
set footerHeight(footerHeight) {
|
|
19541
|
-
const normalizedFooterHeight = normalizeFooterHeight(footerHeight);
|
|
19542
|
-
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) {
|
|
19543
22010
|
return;
|
|
19544
22011
|
}
|
|
19545
|
-
|
|
19546
|
-
|
|
19547
|
-
|
|
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`;
|
|
19548
22020
|
}
|
|
19549
|
-
|
|
19550
|
-
|
|
19551
|
-
return this._externalOutputMode;
|
|
19552
|
-
}
|
|
19553
|
-
set externalOutputMode(mode) {
|
|
19554
|
-
if (mode === "capture-stdout" && this.screenMode !== "split-footer") {
|
|
19555
|
-
throw new Error('externalOutputMode "capture-stdout" requires screenMode "split-footer"');
|
|
22021
|
+
if (clear.length > 0) {
|
|
22022
|
+
this.writeOut(clear);
|
|
19556
22023
|
}
|
|
19557
|
-
this._externalOutputMode = mode;
|
|
19558
|
-
this.stdout.write = mode === "capture-stdout" ? this.interceptStdoutWrite : this.realStdoutWrite;
|
|
19559
|
-
}
|
|
19560
|
-
get liveRequestCount() {
|
|
19561
|
-
return this.liveRequestCounter;
|
|
19562
|
-
}
|
|
19563
|
-
get currentControlState() {
|
|
19564
|
-
return this._controlState;
|
|
19565
|
-
}
|
|
19566
|
-
get capabilities() {
|
|
19567
|
-
return this._capabilities;
|
|
19568
|
-
}
|
|
19569
|
-
get themeMode() {
|
|
19570
|
-
return this._themeMode;
|
|
19571
|
-
}
|
|
19572
|
-
getDebugInputs() {
|
|
19573
|
-
return [...this._debugInputs];
|
|
19574
|
-
}
|
|
19575
|
-
get useKittyKeyboard() {
|
|
19576
|
-
return this.lib.getKittyKeyboardFlags(this.rendererPtr) > 0;
|
|
19577
|
-
}
|
|
19578
|
-
set useKittyKeyboard(use) {
|
|
19579
|
-
const flags = use ? KITTY_FLAG_DISAMBIGUATE | KITTY_FLAG_ALTERNATE_KEYS : 0;
|
|
19580
|
-
this.lib.setKittyKeyboardFlags(this.rendererPtr, flags);
|
|
19581
22024
|
}
|
|
19582
|
-
interceptStdoutWrite = (chunk, encoding, callback) => {
|
|
19583
|
-
const text = chunk.toString();
|
|
19584
|
-
capture.write("stdout", text);
|
|
19585
|
-
if (this._splitHeight > 0) {
|
|
19586
|
-
this.requestRender();
|
|
19587
|
-
}
|
|
19588
|
-
if (typeof callback === "function") {
|
|
19589
|
-
process.nextTick(callback);
|
|
19590
|
-
}
|
|
19591
|
-
return true;
|
|
19592
|
-
};
|
|
19593
22025
|
applyScreenMode(screenMode, emitResize = true, requestRender = true) {
|
|
19594
22026
|
const prevScreenMode = this._screenMode;
|
|
19595
22027
|
const prevSplitHeight = this._splitHeight;
|
|
19596
|
-
const
|
|
22028
|
+
const nextGeometry = calculateRenderGeometry(screenMode, this._terminalWidth, this._terminalHeight, this._footerHeight);
|
|
22029
|
+
const nextSplitHeight = nextGeometry.effectiveFooterHeight;
|
|
19597
22030
|
if (prevScreenMode === screenMode && prevSplitHeight === nextSplitHeight) {
|
|
19598
22031
|
return;
|
|
19599
22032
|
}
|
|
@@ -19601,10 +22034,24 @@ Captured output:
|
|
|
19601
22034
|
const nextUseAlternateScreen = screenMode === "alternate-screen";
|
|
19602
22035
|
const terminalScreenModeChanged = this._terminalIsSetup && prevUseAlternateScreen !== nextUseAlternateScreen;
|
|
19603
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");
|
|
19604
22049
|
if (this._terminalIsSetup && leavingSplitFooter) {
|
|
19605
|
-
this.
|
|
22050
|
+
this.clearPendingSplitFooterTransition();
|
|
22051
|
+
this.renderOffset = 0;
|
|
22052
|
+
this.lib.setRenderOffset(this.rendererPtr, 0);
|
|
19606
22053
|
}
|
|
19607
|
-
if (this._terminalIsSetup && !terminalScreenModeChanged) {
|
|
22054
|
+
if (this._terminalIsSetup && !terminalScreenModeChanged && shouldUseViewportScrollTransitions && !shouldDeferSplitFooterResizeTransition) {
|
|
19608
22055
|
if (prevSplitHeight === 0 && nextSplitHeight > 0) {
|
|
19609
22056
|
const freedLines = this._terminalHeight - nextSplitHeight;
|
|
19610
22057
|
const scrollDown = ANSI.scrollDown(freedLines);
|
|
@@ -19619,18 +22066,39 @@ Captured output:
|
|
|
19619
22066
|
this.writeOut(scrollUp);
|
|
19620
22067
|
}
|
|
19621
22068
|
}
|
|
19622
|
-
if (prevSplitHeight === 0 && nextSplitHeight > 0) {
|
|
19623
|
-
capture.on("write", this.captureCallback);
|
|
19624
|
-
} else if (prevSplitHeight > 0 && nextSplitHeight === 0) {
|
|
19625
|
-
capture.off("write", this.captureCallback);
|
|
19626
|
-
}
|
|
19627
22069
|
this._screenMode = screenMode;
|
|
19628
22070
|
this._splitHeight = nextSplitHeight;
|
|
19629
|
-
this.
|
|
19630
|
-
this.
|
|
19631
|
-
this.height = nextSplitHeight > 0 ? nextSplitHeight : this._terminalHeight;
|
|
19632
|
-
this.lib.setRenderOffset(this.rendererPtr, this.renderOffset);
|
|
22071
|
+
this.width = nextGeometry.renderWidth;
|
|
22072
|
+
this.height = nextGeometry.renderHeight;
|
|
19633
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
|
+
}
|
|
19634
22102
|
this.nextRenderBuffer = this.lib.getNextBuffer(this.rendererPtr);
|
|
19635
22103
|
this.currentRenderBuffer = this.lib.getCurrentBuffer(this.rendererPtr);
|
|
19636
22104
|
this._console.resize(this.width, this.height);
|
|
@@ -19650,12 +22118,18 @@ Captured output:
|
|
|
19650
22118
|
}
|
|
19651
22119
|
}
|
|
19652
22120
|
flushStdoutCache(space, force = false) {
|
|
19653
|
-
if (
|
|
22121
|
+
if (this.externalOutputQueue.size === 0 && !force)
|
|
19654
22122
|
return false;
|
|
19655
|
-
const
|
|
19656
|
-
|
|
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;
|
|
19657
22131
|
const flush = ANSI.moveCursorAndClear(rendererStartLine, 1);
|
|
19658
|
-
const outputLine = this.
|
|
22132
|
+
const outputLine = this.renderOffset + 1;
|
|
19659
22133
|
const move = ANSI.moveCursor(outputLine, 1);
|
|
19660
22134
|
let clear = "";
|
|
19661
22135
|
if (space > 0) {
|
|
@@ -19697,9 +22171,11 @@ Captured output:
|
|
|
19697
22171
|
if (this._terminalIsSetup)
|
|
19698
22172
|
return;
|
|
19699
22173
|
this._terminalIsSetup = true;
|
|
22174
|
+
const startupCursorCprActive = this._screenMode === "split-footer" && this._externalOutputMode === "capture-stdout";
|
|
19700
22175
|
this.updateStdinParserProtocolContext({
|
|
19701
22176
|
privateCapabilityRepliesActive: true,
|
|
19702
|
-
explicitWidthCprActive: true
|
|
22177
|
+
explicitWidthCprActive: true,
|
|
22178
|
+
startupCursorCprActive
|
|
19703
22179
|
});
|
|
19704
22180
|
this.lib.setupTerminal(this.rendererPtr, this._screenMode === "alternate-screen");
|
|
19705
22181
|
this._capabilities = this.lib.getTerminalCapabilities(this.rendererPtr);
|
|
@@ -19713,15 +22189,40 @@ Captured output:
|
|
|
19713
22189
|
}
|
|
19714
22190
|
this.capabilityTimeoutId = this.clock.setTimeout(() => {
|
|
19715
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
|
+
}
|
|
19716
22200
|
this.removeInputHandler(this.capabilityHandler);
|
|
19717
22201
|
this.updateStdinParserProtocolContext({
|
|
19718
22202
|
privateCapabilityRepliesActive: false,
|
|
19719
|
-
explicitWidthCprActive: false
|
|
22203
|
+
explicitWidthCprActive: false,
|
|
22204
|
+
startupCursorCprActive: false
|
|
19720
22205
|
}, true);
|
|
19721
22206
|
}, 5000);
|
|
19722
22207
|
if (this._useMouse) {
|
|
19723
22208
|
this.enableMouse();
|
|
19724
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
|
+
}
|
|
19725
22226
|
this.queryPixelResolution();
|
|
19726
22227
|
}
|
|
19727
22228
|
stdinListener = ((chunk) => {
|
|
@@ -19757,14 +22258,32 @@ Captured output:
|
|
|
19757
22258
|
this.oscSubscribers.delete(handler);
|
|
19758
22259
|
};
|
|
19759
22260
|
}
|
|
19760
|
-
|
|
19761
|
-
|
|
19762
|
-
|
|
19763
|
-
|
|
19764
|
-
|
|
19765
|
-
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;
|
|
19766
22266
|
}
|
|
19767
|
-
|
|
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);
|
|
19768
22287
|
}).bind(this);
|
|
19769
22288
|
focusHandler = ((sequence) => {
|
|
19770
22289
|
if (sequence === "\x1B[I") {
|
|
@@ -19790,21 +22309,50 @@ Captured output:
|
|
|
19790
22309
|
}).bind(this);
|
|
19791
22310
|
themeModeHandler = ((sequence) => {
|
|
19792
22311
|
if (sequence === "\x1B[?997;1n") {
|
|
19793
|
-
|
|
19794
|
-
|
|
19795
|
-
this.emit("theme_mode" /* THEME_MODE */, "dark");
|
|
19796
|
-
}
|
|
22312
|
+
this.applyThemeMode("dark", "csi");
|
|
22313
|
+
this._themeFallbackPending = false;
|
|
19797
22314
|
return true;
|
|
19798
22315
|
}
|
|
19799
22316
|
if (sequence === "\x1B[?997;2n") {
|
|
19800
|
-
|
|
19801
|
-
|
|
19802
|
-
|
|
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;
|
|
19803
22331
|
}
|
|
22332
|
+
}
|
|
22333
|
+
if (!handledOscThemeResponse) {
|
|
22334
|
+
return false;
|
|
22335
|
+
}
|
|
22336
|
+
if (!this._themeFallbackPending) {
|
|
19804
22337
|
return true;
|
|
19805
22338
|
}
|
|
19806
|
-
|
|
22339
|
+
if (this._themeOscForeground && this._themeOscBackground) {
|
|
22340
|
+
this.applyThemeMode(inferThemeModeFromBackgroundColor(this._themeOscBackground), "osc");
|
|
22341
|
+
this._themeFallbackPending = false;
|
|
22342
|
+
}
|
|
22343
|
+
return true;
|
|
19807
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
|
+
}
|
|
19808
22356
|
dispatchSequenceHandlers(sequence) {
|
|
19809
22357
|
if (this._debugModeEnabled) {
|
|
19810
22358
|
this._debugInputs.push({
|
|
@@ -19849,6 +22397,9 @@ Captured output:
|
|
|
19849
22397
|
subscriber(event.sequence);
|
|
19850
22398
|
}
|
|
19851
22399
|
}
|
|
22400
|
+
if (event.protocol === "cpr" && this.processCapabilitySequence(event.sequence, true)) {
|
|
22401
|
+
return;
|
|
22402
|
+
}
|
|
19852
22403
|
this.dispatchSequenceHandlers(event.sequence);
|
|
19853
22404
|
return;
|
|
19854
22405
|
}
|
|
@@ -20135,28 +22686,45 @@ Captured output:
|
|
|
20135
22686
|
processResize(width, height) {
|
|
20136
22687
|
if (width === this._terminalWidth && height === this._terminalHeight)
|
|
20137
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);
|
|
20138
22694
|
const prevWidth = this._terminalWidth;
|
|
22695
|
+
const previousTerminalHeight = this._terminalHeight;
|
|
22696
|
+
const visiblePreviousSplitHeight = pendingSplitFooterTransition?.sourceHeight ?? previousGeometry.effectiveFooterHeight;
|
|
20139
22697
|
this._terminalWidth = width;
|
|
20140
22698
|
this._terminalHeight = height;
|
|
20141
22699
|
this.queryPixelResolution();
|
|
20142
22700
|
this.setCapturedRenderable(undefined);
|
|
20143
22701
|
this.stdinParser?.resetMouseState();
|
|
20144
|
-
|
|
20145
|
-
|
|
20146
|
-
|
|
20147
|
-
|
|
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);
|
|
20148
22714
|
this.writeOut(flush);
|
|
20149
22715
|
}
|
|
20150
|
-
this.renderOffset = height - this._splitHeight;
|
|
20151
|
-
this.width = width;
|
|
20152
|
-
this.height = this._splitHeight;
|
|
20153
22716
|
this.currentRenderBuffer.clear(this.backgroundColor);
|
|
20154
|
-
this.lib.setRenderOffset(this.rendererPtr, this.renderOffset);
|
|
20155
|
-
} else {
|
|
20156
|
-
this.width = width;
|
|
20157
|
-
this.height = height;
|
|
20158
22717
|
}
|
|
22718
|
+
this.clearPendingSplitFooterTransition();
|
|
22719
|
+
this._splitHeight = nextGeometry.effectiveFooterHeight;
|
|
22720
|
+
this.width = nextGeometry.renderWidth;
|
|
22721
|
+
this.height = nextGeometry.renderHeight;
|
|
20159
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
|
+
}
|
|
20160
22728
|
this.nextRenderBuffer = this.lib.getNextBuffer(this.rendererPtr);
|
|
20161
22729
|
this.currentRenderBuffer = this.lib.getCurrentBuffer(this.rendererPtr);
|
|
20162
22730
|
this._console.resize(this.width, this.height);
|
|
@@ -20304,6 +22872,9 @@ Captured output:
|
|
|
20304
22872
|
this._previousControlState = this._controlState;
|
|
20305
22873
|
this._controlState = "explicit_suspended" /* EXPLICIT_SUSPENDED */;
|
|
20306
22874
|
this.internalPause();
|
|
22875
|
+
if (this._terminalIsSetup) {
|
|
22876
|
+
this.flushPendingSplitOutputBeforeTransition(true);
|
|
22877
|
+
}
|
|
20307
22878
|
this._suspendedMouseEnabled = this._useMouse;
|
|
20308
22879
|
this.disableMouse();
|
|
20309
22880
|
this.removeExitListeners();
|
|
@@ -20311,7 +22882,8 @@ Captured output:
|
|
|
20311
22882
|
this.updateStdinParserProtocolContext({
|
|
20312
22883
|
privateCapabilityRepliesActive: false,
|
|
20313
22884
|
pixelResolutionQueryActive: false,
|
|
20314
|
-
explicitWidthCprActive: false
|
|
22885
|
+
explicitWidthCprActive: false,
|
|
22886
|
+
startupCursorCprActive: false
|
|
20315
22887
|
});
|
|
20316
22888
|
this.stdinParser?.reset();
|
|
20317
22889
|
this.stdin.removeListener("data", this.stdinListener);
|
|
@@ -20330,6 +22902,9 @@ Captured output:
|
|
|
20330
22902
|
this.stdin.resume();
|
|
20331
22903
|
this.addExitListeners();
|
|
20332
22904
|
this.lib.resumeRenderer(this.rendererPtr);
|
|
22905
|
+
if (this._screenMode === "split-footer" && this._splitHeight > 0) {
|
|
22906
|
+
this.syncSplitFooterState();
|
|
22907
|
+
}
|
|
20333
22908
|
if (this._suspendedMouseEnabled) {
|
|
20334
22909
|
this.enableMouse();
|
|
20335
22910
|
}
|
|
@@ -20391,7 +22966,6 @@ Captured output:
|
|
|
20391
22966
|
process.removeListener("unhandledRejection", this.handleError);
|
|
20392
22967
|
process.removeListener("warning", this.warningHandler);
|
|
20393
22968
|
process.removeListener("beforeExit", this.exitHandler);
|
|
20394
|
-
capture.removeListener("write", this.captureCallback);
|
|
20395
22969
|
this.removeExitListeners();
|
|
20396
22970
|
if (this.resizeTimeoutId !== null) {
|
|
20397
22971
|
this.clock.clearTimeout(this.resizeTimeoutId);
|
|
@@ -20401,6 +22975,10 @@ Captured output:
|
|
|
20401
22975
|
this.clock.clearTimeout(this.capabilityTimeoutId);
|
|
20402
22976
|
this.capabilityTimeoutId = null;
|
|
20403
22977
|
}
|
|
22978
|
+
if (this.splitStartupSeedTimeoutId !== null) {
|
|
22979
|
+
this.clock.clearTimeout(this.splitStartupSeedTimeoutId);
|
|
22980
|
+
this.splitStartupSeedTimeoutId = null;
|
|
22981
|
+
}
|
|
20404
22982
|
if (this.memorySnapshotTimer) {
|
|
20405
22983
|
this.clock.clearInterval(this.memorySnapshotTimer);
|
|
20406
22984
|
this.memorySnapshotTimer = null;
|
|
@@ -20414,7 +22992,8 @@ Captured output:
|
|
|
20414
22992
|
this.updateStdinParserProtocolContext({
|
|
20415
22993
|
privateCapabilityRepliesActive: false,
|
|
20416
22994
|
pixelResolutionQueryActive: false,
|
|
20417
|
-
explicitWidthCprActive: false
|
|
22995
|
+
explicitWidthCprActive: false,
|
|
22996
|
+
startupCursorCprActive: false
|
|
20418
22997
|
}, true);
|
|
20419
22998
|
this._useMouse = false;
|
|
20420
22999
|
this.setCapturedRenderable(undefined);
|
|
@@ -20456,6 +23035,16 @@ Captured output:
|
|
|
20456
23035
|
this.stdinParser = null;
|
|
20457
23036
|
this.oscSubscribers.clear();
|
|
20458
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();
|
|
20459
23048
|
this.lib.destroyRenderer(this.rendererPtr);
|
|
20460
23049
|
rendererTracker.removeRenderer(this);
|
|
20461
23050
|
if (this._onDestroy) {
|
|
@@ -20564,12 +23153,21 @@ Captured output:
|
|
|
20564
23153
|
console.error("Rendering called concurrently");
|
|
20565
23154
|
throw new Error("Rendering called concurrently");
|
|
20566
23155
|
}
|
|
20567
|
-
let force = false;
|
|
20568
|
-
if (this._splitHeight > 0) {
|
|
20569
|
-
force = this.flushStdoutCache(this._splitHeight);
|
|
20570
|
-
}
|
|
20571
23156
|
this.renderingNative = true;
|
|
20572
|
-
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
|
+
}
|
|
20573
23171
|
this.renderingNative = false;
|
|
20574
23172
|
}
|
|
20575
23173
|
collectStatSample(frameTime) {
|
|
@@ -20751,7 +23349,7 @@ Captured output:
|
|
|
20751
23349
|
}
|
|
20752
23350
|
}
|
|
20753
23351
|
|
|
20754
|
-
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 };
|
|
20755
23353
|
|
|
20756
|
-
//# debugId=
|
|
20757
|
-
//# sourceMappingURL=index-
|
|
23354
|
+
//# debugId=8C02D415BAC7A02B64756E2164756E21
|
|
23355
|
+
//# sourceMappingURL=index-t3rrpex7.js.map
|