@opentui/core 0.1.101 → 0.1.103
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/3d.js +1 -1
- package/buffer.d.ts +3 -0
- package/{index-xsfpee0k.js → index-4pvh4sbk.js} +3221 -312
- package/index-4pvh4sbk.js.map +76 -0
- package/{index-9qfn9g6r.js → index-bmcatvmp.js} +3 -3
- package/{index-ekbq0zm9.js → index-gw3ynrc0.js} +357 -1671
- package/index-gw3ynrc0.js.map +35 -0
- package/index.js +33 -13
- package/index.js.map +1 -1
- package/lib/RGBA.d.ts +27 -3
- package/lib/render-geometry.d.ts +8 -0
- package/lib/stdin-parser.d.ts +2 -1
- package/lib/terminal-palette.d.ts +8 -0
- 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-theme-mode.d.ts +29 -0
- package/renderer.d.ts +77 -8
- 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-structs.d.ts +7 -1
- package/zig.d.ts +12 -0
- package/index-ekbq0zm9.js.map +0 -42
- package/index-xsfpee0k.js.map +0 -67
- /package/{index-9qfn9g6r.js.map → index-bmcatvmp.js.map} +0 -0
|
@@ -1969,23 +1969,126 @@ class InternalKeyHandler extends KeyHandler {
|
|
|
1969
1969
|
}
|
|
1970
1970
|
|
|
1971
1971
|
// src/lib/RGBA.ts
|
|
1972
|
+
var COLOR_TAG_RGB = 256;
|
|
1973
|
+
var COLOR_TAG_DEFAULT = 257;
|
|
1974
|
+
var DEFAULT_FOREGROUND_RGB = [255, 255, 255];
|
|
1975
|
+
var DEFAULT_BACKGROUND_RGB = [0, 0, 0];
|
|
1976
|
+
var RGBA_BUFFER_STRIDE = 5;
|
|
1977
|
+
var ANSI16_RGB = [
|
|
1978
|
+
[0, 0, 0],
|
|
1979
|
+
[128, 0, 0],
|
|
1980
|
+
[0, 128, 0],
|
|
1981
|
+
[128, 128, 0],
|
|
1982
|
+
[0, 0, 128],
|
|
1983
|
+
[128, 0, 128],
|
|
1984
|
+
[0, 128, 128],
|
|
1985
|
+
[192, 192, 192],
|
|
1986
|
+
[128, 128, 128],
|
|
1987
|
+
[255, 0, 0],
|
|
1988
|
+
[0, 255, 0],
|
|
1989
|
+
[255, 255, 0],
|
|
1990
|
+
[0, 0, 255],
|
|
1991
|
+
[255, 0, 255],
|
|
1992
|
+
[0, 255, 255],
|
|
1993
|
+
[255, 255, 255]
|
|
1994
|
+
];
|
|
1995
|
+
var ANSI_256_CUBE_LEVELS = [0, 95, 135, 175, 215, 255];
|
|
1996
|
+
function normalizeColorTag(tag) {
|
|
1997
|
+
const normalizedTag = tag != null && Number.isFinite(tag) ? Math.round(tag) : COLOR_TAG_RGB;
|
|
1998
|
+
if (normalizedTag === COLOR_TAG_RGB || normalizedTag === COLOR_TAG_DEFAULT) {
|
|
1999
|
+
return normalizedTag;
|
|
2000
|
+
}
|
|
2001
|
+
if (Number.isInteger(normalizedTag) && normalizedTag >= 0 && normalizedTag <= 255) {
|
|
2002
|
+
return normalizedTag;
|
|
2003
|
+
}
|
|
2004
|
+
return COLOR_TAG_RGB;
|
|
2005
|
+
}
|
|
2006
|
+
function normalizeRGBABuffer(buffer) {
|
|
2007
|
+
if (buffer.length === RGBA_BUFFER_STRIDE) {
|
|
2008
|
+
buffer[4] = normalizeColorTag(buffer[4]);
|
|
2009
|
+
return buffer;
|
|
2010
|
+
}
|
|
2011
|
+
const normalized = new Float32Array(RGBA_BUFFER_STRIDE);
|
|
2012
|
+
normalized[0] = buffer[0] ?? 0;
|
|
2013
|
+
normalized[1] = buffer[1] ?? 0;
|
|
2014
|
+
normalized[2] = buffer[2] ?? 0;
|
|
2015
|
+
normalized[3] = buffer[3] ?? 0;
|
|
2016
|
+
normalized[4] = COLOR_TAG_RGB;
|
|
2017
|
+
return normalized;
|
|
2018
|
+
}
|
|
2019
|
+
function withTag(rgba, tag) {
|
|
2020
|
+
const tagged = RGBA.clone(rgba);
|
|
2021
|
+
tagged.tag = tag;
|
|
2022
|
+
return tagged;
|
|
2023
|
+
}
|
|
2024
|
+
function rgbaForAnsi256Index(index) {
|
|
2025
|
+
const [r, g, b] = ansi256IndexToRgb(index);
|
|
2026
|
+
return RGBA.fromInts(r, g, b);
|
|
2027
|
+
}
|
|
2028
|
+
function normalizeIndexedColorIndex(index) {
|
|
2029
|
+
if (!Number.isInteger(index) || index < 0 || index > 255) {
|
|
2030
|
+
throw new RangeError(`Indexed color must be an integer in the range 0..255, got ${index}`);
|
|
2031
|
+
}
|
|
2032
|
+
return index;
|
|
2033
|
+
}
|
|
2034
|
+
function ansi256IndexToRgb(index) {
|
|
2035
|
+
const normalizedIndex = normalizeIndexedColorIndex(index);
|
|
2036
|
+
if (normalizedIndex < ANSI16_RGB.length) {
|
|
2037
|
+
return ANSI16_RGB[normalizedIndex];
|
|
2038
|
+
}
|
|
2039
|
+
if (normalizedIndex < 232) {
|
|
2040
|
+
const cubeIndex = normalizedIndex - 16;
|
|
2041
|
+
const r = Math.floor(cubeIndex / 36);
|
|
2042
|
+
const g = Math.floor(cubeIndex / 6) % 6;
|
|
2043
|
+
const b = cubeIndex % 6;
|
|
2044
|
+
return [ANSI_256_CUBE_LEVELS[r], ANSI_256_CUBE_LEVELS[g], ANSI_256_CUBE_LEVELS[b]];
|
|
2045
|
+
}
|
|
2046
|
+
const value = 8 + (normalizedIndex - 232) * 10;
|
|
2047
|
+
return [value, value, value];
|
|
2048
|
+
}
|
|
2049
|
+
function decodeColorTag(tag) {
|
|
2050
|
+
if (tag === COLOR_TAG_DEFAULT) {
|
|
2051
|
+
return { kind: "default" };
|
|
2052
|
+
}
|
|
2053
|
+
if (tag === COLOR_TAG_RGB) {
|
|
2054
|
+
return { kind: "rgb" };
|
|
2055
|
+
}
|
|
2056
|
+
return { kind: "indexed", index: normalizeIndexedColorIndex(tag) };
|
|
2057
|
+
}
|
|
2058
|
+
|
|
1972
2059
|
class RGBA {
|
|
1973
2060
|
buffer;
|
|
1974
2061
|
constructor(buffer) {
|
|
1975
|
-
this.buffer = buffer;
|
|
2062
|
+
this.buffer = normalizeRGBABuffer(buffer);
|
|
1976
2063
|
}
|
|
1977
2064
|
static fromArray(array) {
|
|
1978
2065
|
return new RGBA(array);
|
|
1979
2066
|
}
|
|
1980
|
-
static fromValues(r, g, b, a = 1) {
|
|
1981
|
-
return new RGBA(new Float32Array([r, g, b, a]));
|
|
2067
|
+
static fromValues(r, g, b, a = 1, tag = COLOR_TAG_RGB) {
|
|
2068
|
+
return new RGBA(new Float32Array([r, g, b, a, normalizeColorTag(tag)]));
|
|
1982
2069
|
}
|
|
1983
|
-
static
|
|
1984
|
-
return
|
|
2070
|
+
static clone(rgba) {
|
|
2071
|
+
return RGBA.fromValues(rgba.r, rgba.g, rgba.b, rgba.a, rgba.tag);
|
|
2072
|
+
}
|
|
2073
|
+
static fromInts(r, g, b, a = 255, tag = COLOR_TAG_RGB) {
|
|
2074
|
+
return new RGBA(new Float32Array([r / 255, g / 255, b / 255, a / 255, normalizeColorTag(tag)]));
|
|
1985
2075
|
}
|
|
1986
2076
|
static fromHex(hex) {
|
|
1987
2077
|
return hexToRgb(hex);
|
|
1988
2078
|
}
|
|
2079
|
+
static fromIndex(index, snapshot) {
|
|
2080
|
+
const normalizedIndex = normalizeIndexedColorIndex(index);
|
|
2081
|
+
return withTag(snapshot ? parseColor(snapshot) : rgbaForAnsi256Index(normalizedIndex), normalizedIndex);
|
|
2082
|
+
}
|
|
2083
|
+
static defaultForeground(snapshot) {
|
|
2084
|
+
return withTag(snapshot ? parseColor(snapshot) : RGBA.fromInts(...DEFAULT_FOREGROUND_RGB), COLOR_TAG_DEFAULT);
|
|
2085
|
+
}
|
|
2086
|
+
static defaultBackground(snapshot) {
|
|
2087
|
+
return withTag(snapshot ? parseColor(snapshot) : RGBA.fromInts(...DEFAULT_BACKGROUND_RGB), COLOR_TAG_DEFAULT);
|
|
2088
|
+
}
|
|
2089
|
+
static getIntentTag(rgba) {
|
|
2090
|
+
return rgba.tag;
|
|
2091
|
+
}
|
|
1989
2092
|
toInts() {
|
|
1990
2093
|
return [Math.round(this.r * 255), Math.round(this.g * 255), Math.round(this.b * 255), Math.round(this.a * 255)];
|
|
1991
2094
|
}
|
|
@@ -2013,6 +2116,12 @@ class RGBA {
|
|
|
2013
2116
|
set a(value) {
|
|
2014
2117
|
this.buffer[3] = value;
|
|
2015
2118
|
}
|
|
2119
|
+
get tag() {
|
|
2120
|
+
return normalizeColorTag(this.buffer[4]);
|
|
2121
|
+
}
|
|
2122
|
+
set tag(value) {
|
|
2123
|
+
this.buffer[4] = normalizeColorTag(value);
|
|
2124
|
+
}
|
|
2016
2125
|
map(fn) {
|
|
2017
2126
|
return [fn(this.r), fn(this.g), fn(this.b), fn(this.a)];
|
|
2018
2127
|
}
|
|
@@ -2022,9 +2131,15 @@ class RGBA {
|
|
|
2022
2131
|
equals(other) {
|
|
2023
2132
|
if (!other)
|
|
2024
2133
|
return false;
|
|
2025
|
-
return this.r === other.r && this.g === other.g && this.b === other.b && this.a === other.a;
|
|
2134
|
+
return this.r === other.r && this.g === other.g && this.b === other.b && this.a === other.a && this.tag === other.tag;
|
|
2026
2135
|
}
|
|
2027
2136
|
}
|
|
2137
|
+
function normalizeColorValue(value) {
|
|
2138
|
+
if (value == null)
|
|
2139
|
+
return null;
|
|
2140
|
+
const rgba = parseColor(value);
|
|
2141
|
+
return { rgba, tag: rgba.tag };
|
|
2142
|
+
}
|
|
2028
2143
|
function hexToRgb(hex) {
|
|
2029
2144
|
hex = hex.replace(/^#/, "");
|
|
2030
2145
|
if (hex.length === 3) {
|
|
@@ -6867,7 +6982,8 @@ var DEFAULT_PROTOCOL_CONTEXT = {
|
|
|
6867
6982
|
kittyKeyboardEnabled: false,
|
|
6868
6983
|
privateCapabilityRepliesActive: false,
|
|
6869
6984
|
pixelResolutionQueryActive: false,
|
|
6870
|
-
explicitWidthCprActive: false
|
|
6985
|
+
explicitWidthCprActive: false,
|
|
6986
|
+
startupCursorCprActive: false
|
|
6871
6987
|
};
|
|
6872
6988
|
var RXVT_DOLLAR_CSI_RE = /^\x1b\[\d+\$$/;
|
|
6873
6989
|
var SYSTEM_CLOCK = new SystemClock;
|
|
@@ -7056,11 +7172,14 @@ function canStillBeKittySpecial(state) {
|
|
|
7056
7172
|
function canStillBeExplicitWidthCpr(state) {
|
|
7057
7173
|
return state.firstParamValue === 1 && state.semicolons === 1;
|
|
7058
7174
|
}
|
|
7175
|
+
function canStillBeStartupCursorCpr(state) {
|
|
7176
|
+
return state.semicolons === 1;
|
|
7177
|
+
}
|
|
7059
7178
|
function canStillBePixelResolution(state) {
|
|
7060
7179
|
return state.firstParamValue === 4 && state.semicolons === 2;
|
|
7061
7180
|
}
|
|
7062
7181
|
function canDeferParametricCsi(state, context) {
|
|
7063
|
-
return context.kittyKeyboardEnabled && (canStillBeKittyU(state) || canStillBeKittySpecial(state)) || context.explicitWidthCprActive && canStillBeExplicitWidthCpr(state) || context.pixelResolutionQueryActive && canStillBePixelResolution(state);
|
|
7182
|
+
return context.kittyKeyboardEnabled && (canStillBeKittyU(state) || canStillBeKittySpecial(state)) || context.explicitWidthCprActive && canStillBeExplicitWidthCpr(state) || context.startupCursorCprActive && canStillBeStartupCursorCpr(state) || context.pixelResolutionQueryActive && canStillBePixelResolution(state);
|
|
7064
7183
|
}
|
|
7065
7184
|
function canCompleteDeferredParametricCsi(state, byte, context) {
|
|
7066
7185
|
if (context.kittyKeyboardEnabled) {
|
|
@@ -7073,11 +7192,20 @@ function canCompleteDeferredParametricCsi(state, byte, context) {
|
|
|
7073
7192
|
if (context.explicitWidthCprActive && state.hasDigit && state.firstParamValue === 1 && state.semicolons === 1 && byte === 82) {
|
|
7074
7193
|
return true;
|
|
7075
7194
|
}
|
|
7195
|
+
if (context.startupCursorCprActive && state.hasDigit && state.semicolons === 1 && byte === 82) {
|
|
7196
|
+
return true;
|
|
7197
|
+
}
|
|
7076
7198
|
if (context.pixelResolutionQueryActive && state.hasDigit && state.firstParamValue === 4 && state.semicolons === 2 && byte === 116) {
|
|
7077
7199
|
return true;
|
|
7078
7200
|
}
|
|
7079
7201
|
return false;
|
|
7080
7202
|
}
|
|
7203
|
+
function classifyParametricCsiProtocol(state, finalByte) {
|
|
7204
|
+
if (finalByte === 82 && state.semicolons === 1 && state.segments === 1 && state.hasDigit) {
|
|
7205
|
+
return "cpr";
|
|
7206
|
+
}
|
|
7207
|
+
return "csi";
|
|
7208
|
+
}
|
|
7081
7209
|
function canDeferPrivateReplyCsi(context) {
|
|
7082
7210
|
return context.privateCapabilityRepliesActive;
|
|
7083
7211
|
}
|
|
@@ -7184,7 +7312,8 @@ class StdinParser {
|
|
|
7184
7312
|
kittyKeyboardEnabled: options.protocolContext?.kittyKeyboardEnabled ?? false,
|
|
7185
7313
|
privateCapabilityRepliesActive: options.protocolContext?.privateCapabilityRepliesActive ?? false,
|
|
7186
7314
|
pixelResolutionQueryActive: options.protocolContext?.pixelResolutionQueryActive ?? false,
|
|
7187
|
-
explicitWidthCprActive: options.protocolContext?.explicitWidthCprActive ?? false
|
|
7315
|
+
explicitWidthCprActive: options.protocolContext?.explicitWidthCprActive ?? false,
|
|
7316
|
+
startupCursorCprActive: options.protocolContext?.startupCursorCprActive ?? false
|
|
7188
7317
|
};
|
|
7189
7318
|
}
|
|
7190
7319
|
get bufferCapacity() {
|
|
@@ -7686,7 +7815,8 @@ class StdinParser {
|
|
|
7686
7815
|
}
|
|
7687
7816
|
if (byte >= 64 && byte <= 126) {
|
|
7688
7817
|
const end = this.cursor + 1;
|
|
7689
|
-
|
|
7818
|
+
const protocol = classifyParametricCsiProtocol(this.state, byte);
|
|
7819
|
+
this.emitKeyOrResponse(protocol, decodeUtf8(bytes.subarray(this.unitStart, end)));
|
|
7690
7820
|
this.state = { tag: "ground" };
|
|
7691
7821
|
this.consumePrefix(end);
|
|
7692
7822
|
continue;
|
|
@@ -10648,6 +10778,38 @@ class TerminalPalette {
|
|
|
10648
10778
|
function createTerminalPalette(stdin, stdout, writeFn, isLegacyTmux, oscSource, clock) {
|
|
10649
10779
|
return new TerminalPalette(stdin, stdout, writeFn, isLegacyTmux, oscSource, clock);
|
|
10650
10780
|
}
|
|
10781
|
+
var DEFAULT_FOREGROUND_FALLBACK = RGBA.fromInts(...DEFAULT_FOREGROUND_RGB);
|
|
10782
|
+
var DEFAULT_BACKGROUND_FALLBACK = RGBA.fromInts(...DEFAULT_BACKGROUND_RGB);
|
|
10783
|
+
var fallbackAnsi256Palette = null;
|
|
10784
|
+
function getFallbackAnsi256Palette() {
|
|
10785
|
+
if (!fallbackAnsi256Palette) {
|
|
10786
|
+
fallbackAnsi256Palette = Array.from({ length: 256 }, (_, index) => {
|
|
10787
|
+
const [r, g, b] = ansi256IndexToRgb(index);
|
|
10788
|
+
return RGBA.fromInts(r, g, b);
|
|
10789
|
+
});
|
|
10790
|
+
}
|
|
10791
|
+
return fallbackAnsi256Palette;
|
|
10792
|
+
}
|
|
10793
|
+
function normalizeTerminalPalette(colors) {
|
|
10794
|
+
const fallbackPalette = getFallbackAnsi256Palette();
|
|
10795
|
+
return {
|
|
10796
|
+
palette: Array.from({ length: 256 }, (_, index) => {
|
|
10797
|
+
const detected = colors?.palette[index];
|
|
10798
|
+
return detected ? RGBA.fromHex(detected) : RGBA.clone(fallbackPalette[index]);
|
|
10799
|
+
}),
|
|
10800
|
+
defaultForeground: colors?.defaultForeground ? RGBA.fromHex(colors.defaultForeground) : RGBA.clone(DEFAULT_FOREGROUND_FALLBACK),
|
|
10801
|
+
defaultBackground: colors?.defaultBackground ? RGBA.fromHex(colors.defaultBackground) : RGBA.clone(DEFAULT_BACKGROUND_FALLBACK)
|
|
10802
|
+
};
|
|
10803
|
+
}
|
|
10804
|
+
function buildTerminalPaletteSignature(colors) {
|
|
10805
|
+
const normalized = normalizeTerminalPalette(colors);
|
|
10806
|
+
const paletteSignature = normalized.palette.map((color) => color.toInts().join(",")).join(";");
|
|
10807
|
+
return [
|
|
10808
|
+
paletteSignature,
|
|
10809
|
+
normalized.defaultForeground.toInts().join(","),
|
|
10810
|
+
normalized.defaultBackground.toInts().join(",")
|
|
10811
|
+
].join("|");
|
|
10812
|
+
}
|
|
10651
10813
|
|
|
10652
10814
|
// src/lib/paste.ts
|
|
10653
10815
|
var PASTE_TEXT_DECODER = new TextDecoder;
|
|
@@ -10745,6 +10907,7 @@ class OptimizedBuffer {
|
|
|
10745
10907
|
_widthMethod;
|
|
10746
10908
|
respectAlpha = false;
|
|
10747
10909
|
_rawBuffers = null;
|
|
10910
|
+
_rawColorTags = null;
|
|
10748
10911
|
_destroyed = false;
|
|
10749
10912
|
get ptr() {
|
|
10750
10913
|
return this.bufferPtr;
|
|
@@ -10753,23 +10916,38 @@ class OptimizedBuffer {
|
|
|
10753
10916
|
if (this._destroyed)
|
|
10754
10917
|
throw new Error(`Buffer ${this.id} is destroyed`);
|
|
10755
10918
|
}
|
|
10919
|
+
ensureRawBufferViews() {
|
|
10920
|
+
if (this._rawBuffers !== null && this._rawColorTags !== null) {
|
|
10921
|
+
return;
|
|
10922
|
+
}
|
|
10923
|
+
const size = this._width * this._height;
|
|
10924
|
+
const charPtr = this.lib.bufferGetCharPtr(this.bufferPtr);
|
|
10925
|
+
const fgPtr = this.lib.bufferGetFgPtr(this.bufferPtr);
|
|
10926
|
+
const bgPtr = this.lib.bufferGetBgPtr(this.bufferPtr);
|
|
10927
|
+
const fgTagPtr = this.lib.bufferGetFgTagPtr(this.bufferPtr);
|
|
10928
|
+
const bgTagPtr = this.lib.bufferGetBgTagPtr(this.bufferPtr);
|
|
10929
|
+
const attributesPtr = this.lib.bufferGetAttributesPtr(this.bufferPtr);
|
|
10930
|
+
this._rawBuffers = {
|
|
10931
|
+
char: new Uint32Array(toArrayBuffer(charPtr, 0, size * 4)),
|
|
10932
|
+
fg: new Float32Array(toArrayBuffer(fgPtr, 0, size * 4 * 4)),
|
|
10933
|
+
bg: new Float32Array(toArrayBuffer(bgPtr, 0, size * 4 * 4)),
|
|
10934
|
+
attributes: new Uint32Array(toArrayBuffer(attributesPtr, 0, size * 4))
|
|
10935
|
+
};
|
|
10936
|
+
this._rawColorTags = {
|
|
10937
|
+
fg: new Uint16Array(toArrayBuffer(fgTagPtr, 0, size * 2)),
|
|
10938
|
+
bg: new Uint16Array(toArrayBuffer(bgTagPtr, 0, size * 2))
|
|
10939
|
+
};
|
|
10940
|
+
}
|
|
10756
10941
|
get buffers() {
|
|
10757
10942
|
this.guard();
|
|
10758
|
-
|
|
10759
|
-
const size = this._width * this._height;
|
|
10760
|
-
const charPtr = this.lib.bufferGetCharPtr(this.bufferPtr);
|
|
10761
|
-
const fgPtr = this.lib.bufferGetFgPtr(this.bufferPtr);
|
|
10762
|
-
const bgPtr = this.lib.bufferGetBgPtr(this.bufferPtr);
|
|
10763
|
-
const attributesPtr = this.lib.bufferGetAttributesPtr(this.bufferPtr);
|
|
10764
|
-
this._rawBuffers = {
|
|
10765
|
-
char: new Uint32Array(toArrayBuffer(charPtr, 0, size * 4)),
|
|
10766
|
-
fg: new Float32Array(toArrayBuffer(fgPtr, 0, size * 4 * 4)),
|
|
10767
|
-
bg: new Float32Array(toArrayBuffer(bgPtr, 0, size * 4 * 4)),
|
|
10768
|
-
attributes: new Uint32Array(toArrayBuffer(attributesPtr, 0, size * 4))
|
|
10769
|
-
};
|
|
10770
|
-
}
|
|
10943
|
+
this.ensureRawBufferViews();
|
|
10771
10944
|
return this._rawBuffers;
|
|
10772
10945
|
}
|
|
10946
|
+
get rawColorTags() {
|
|
10947
|
+
this.guard();
|
|
10948
|
+
this.ensureRawBufferViews();
|
|
10949
|
+
return this._rawColorTags;
|
|
10950
|
+
}
|
|
10773
10951
|
constructor(lib, ptr2, width, height, options) {
|
|
10774
10952
|
this.id = options.id || `fb_${OptimizedBuffer.fbIdCounter++}`;
|
|
10775
10953
|
this.lib = lib;
|
|
@@ -10814,6 +10992,7 @@ class OptimizedBuffer {
|
|
|
10814
10992
|
getSpanLines() {
|
|
10815
10993
|
this.guard();
|
|
10816
10994
|
const { char, fg: fg2, bg: bg2, attributes } = this.buffers;
|
|
10995
|
+
const { fg: fgTag, bg: bgTag } = this.rawColorTags;
|
|
10817
10996
|
const lines = [];
|
|
10818
10997
|
const CHAR_FLAG_CONTINUATION = 3221225472 | 0;
|
|
10819
10998
|
const CHAR_FLAG_MASK = 3221225472 | 0;
|
|
@@ -10828,8 +11007,8 @@ class OptimizedBuffer {
|
|
|
10828
11007
|
for (let x = 0;x < this._width; x++) {
|
|
10829
11008
|
const i = y * this._width + x;
|
|
10830
11009
|
const cp = char[i];
|
|
10831
|
-
const cellFg = RGBA.fromValues(fg2[i * 4], fg2[i * 4 + 1], fg2[i * 4 + 2], fg2[i * 4 + 3]);
|
|
10832
|
-
const cellBg = RGBA.fromValues(bg2[i * 4], bg2[i * 4 + 1], bg2[i * 4 + 2], bg2[i * 4 + 3]);
|
|
11010
|
+
const cellFg = RGBA.fromValues(fg2[i * 4], fg2[i * 4 + 1], fg2[i * 4 + 2], fg2[i * 4 + 3], fgTag[i]);
|
|
11011
|
+
const cellBg = RGBA.fromValues(bg2[i * 4], bg2[i * 4 + 1], bg2[i * 4 + 2], bg2[i * 4 + 3], bgTag[i]);
|
|
10833
11012
|
const cellAttrs = attributes[i] & 255;
|
|
10834
11013
|
const isContinuation = (cp & CHAR_FLAG_MASK) === CHAR_FLAG_CONTINUATION;
|
|
10835
11014
|
const cellChar = isContinuation ? "" : lineChars[charIdx++] ?? " ";
|
|
@@ -10957,6 +11136,7 @@ class OptimizedBuffer {
|
|
|
10957
11136
|
this._width = width;
|
|
10958
11137
|
this._height = height;
|
|
10959
11138
|
this._rawBuffers = null;
|
|
11139
|
+
this._rawColorTags = null;
|
|
10960
11140
|
this.lib.bufferResize(this.bufferPtr, width, height);
|
|
10961
11141
|
}
|
|
10962
11142
|
drawBox(options) {
|
|
@@ -11650,16 +11830,30 @@ var StyledChunkStruct = defineStruct([
|
|
|
11650
11830
|
unpackTransform: rgbaUnpackTransform
|
|
11651
11831
|
}
|
|
11652
11832
|
],
|
|
11833
|
+
["fg_tag", "u16", { default: COLOR_TAG_RGB }],
|
|
11834
|
+
["bg_tag", "u16", { default: COLOR_TAG_RGB }],
|
|
11653
11835
|
["attributes", "u32", { default: 0 }],
|
|
11654
11836
|
["link", "char*", { default: "" }],
|
|
11655
11837
|
["link_len", "u64", { lengthOf: "link" }]
|
|
11656
11838
|
], {
|
|
11657
11839
|
mapValue: (chunk) => {
|
|
11840
|
+
const normalizedFg = normalizeColorValue(chunk.fg ?? null);
|
|
11841
|
+
const normalizedBg = normalizeColorValue(chunk.bg ?? null);
|
|
11658
11842
|
if (!chunk.link || typeof chunk.link === "string") {
|
|
11659
|
-
return
|
|
11843
|
+
return {
|
|
11844
|
+
...chunk,
|
|
11845
|
+
fg: normalizedFg?.rgba ?? null,
|
|
11846
|
+
bg: normalizedBg?.rgba ?? null,
|
|
11847
|
+
fg_tag: normalizedFg?.tag ?? COLOR_TAG_RGB,
|
|
11848
|
+
bg_tag: normalizedBg?.tag ?? COLOR_TAG_RGB
|
|
11849
|
+
};
|
|
11660
11850
|
}
|
|
11661
11851
|
return {
|
|
11662
11852
|
...chunk,
|
|
11853
|
+
fg: normalizedFg?.rgba ?? null,
|
|
11854
|
+
bg: normalizedBg?.rgba ?? null,
|
|
11855
|
+
fg_tag: normalizedFg?.tag ?? COLOR_TAG_RGB,
|
|
11856
|
+
bg_tag: normalizedBg?.tag ?? COLOR_TAG_RGB,
|
|
11663
11857
|
link: chunk.link.url
|
|
11664
11858
|
};
|
|
11665
11859
|
}
|
|
@@ -11688,6 +11882,7 @@ var TerminalCapabilitiesStruct = defineStruct([
|
|
|
11688
11882
|
["kitty_keyboard", "bool_u8"],
|
|
11689
11883
|
["kitty_graphics", "bool_u8"],
|
|
11690
11884
|
["rgb", "bool_u8"],
|
|
11885
|
+
["ansi256", "bool_u8"],
|
|
11691
11886
|
["unicode", UnicodeMethodEnum],
|
|
11692
11887
|
["sgr_pixels", "bool_u8"],
|
|
11693
11888
|
["color_scheme_updates", "bool_u8"],
|
|
@@ -11895,6 +12090,10 @@ function getOpenTUILib(libPath) {
|
|
|
11895
12090
|
args: ["ptr", "bool"],
|
|
11896
12091
|
returns: "void"
|
|
11897
12092
|
},
|
|
12093
|
+
setClearOnShutdown: {
|
|
12094
|
+
args: ["ptr", "bool"],
|
|
12095
|
+
returns: "void"
|
|
12096
|
+
},
|
|
11898
12097
|
setBackgroundColor: {
|
|
11899
12098
|
args: ["ptr", "ptr"],
|
|
11900
12099
|
returns: "void"
|
|
@@ -11903,6 +12102,22 @@ function getOpenTUILib(libPath) {
|
|
|
11903
12102
|
args: ["ptr", "u32"],
|
|
11904
12103
|
returns: "void"
|
|
11905
12104
|
},
|
|
12105
|
+
resetSplitScrollback: {
|
|
12106
|
+
args: ["ptr", "u32", "u32"],
|
|
12107
|
+
returns: "u32"
|
|
12108
|
+
},
|
|
12109
|
+
syncSplitScrollback: {
|
|
12110
|
+
args: ["ptr", "u32"],
|
|
12111
|
+
returns: "u32"
|
|
12112
|
+
},
|
|
12113
|
+
setPendingSplitFooterTransition: {
|
|
12114
|
+
args: ["ptr", "u8", "u32", "u32", "u32", "u32"],
|
|
12115
|
+
returns: "void"
|
|
12116
|
+
},
|
|
12117
|
+
clearPendingSplitFooterTransition: {
|
|
12118
|
+
args: ["ptr"],
|
|
12119
|
+
returns: "void"
|
|
12120
|
+
},
|
|
11906
12121
|
updateStats: {
|
|
11907
12122
|
args: ["ptr", "f64", "u32", "f64"],
|
|
11908
12123
|
returns: "void"
|
|
@@ -11915,6 +12130,14 @@ function getOpenTUILib(libPath) {
|
|
|
11915
12130
|
args: ["ptr", "bool"],
|
|
11916
12131
|
returns: "void"
|
|
11917
12132
|
},
|
|
12133
|
+
repaintSplitFooter: {
|
|
12134
|
+
args: ["ptr", "u32", "bool"],
|
|
12135
|
+
returns: "u32"
|
|
12136
|
+
},
|
|
12137
|
+
commitSplitFooterSnapshot: {
|
|
12138
|
+
args: ["ptr", "ptr", "u32", "bool", "bool", "u32", "bool", "bool", "bool"],
|
|
12139
|
+
returns: "u32"
|
|
12140
|
+
},
|
|
11918
12141
|
getNextBuffer: {
|
|
11919
12142
|
args: ["ptr"],
|
|
11920
12143
|
returns: "ptr"
|
|
@@ -11923,10 +12146,18 @@ function getOpenTUILib(libPath) {
|
|
|
11923
12146
|
args: ["ptr"],
|
|
11924
12147
|
returns: "ptr"
|
|
11925
12148
|
},
|
|
12149
|
+
rendererSetPaletteState: {
|
|
12150
|
+
args: ["ptr", "ptr", "usize", "ptr", "ptr", "u32"],
|
|
12151
|
+
returns: "void"
|
|
12152
|
+
},
|
|
11926
12153
|
queryPixelResolution: {
|
|
11927
12154
|
args: ["ptr"],
|
|
11928
12155
|
returns: "void"
|
|
11929
12156
|
},
|
|
12157
|
+
queryThemeColors: {
|
|
12158
|
+
args: ["ptr"],
|
|
12159
|
+
returns: "void"
|
|
12160
|
+
},
|
|
11930
12161
|
createOptimizedBuffer: {
|
|
11931
12162
|
args: ["u32", "u32", "bool", "u8", "ptr", "usize"],
|
|
11932
12163
|
returns: "ptr"
|
|
@@ -11963,6 +12194,14 @@ function getOpenTUILib(libPath) {
|
|
|
11963
12194
|
args: ["ptr"],
|
|
11964
12195
|
returns: "ptr"
|
|
11965
12196
|
},
|
|
12197
|
+
bufferGetFgTagPtr: {
|
|
12198
|
+
args: ["ptr"],
|
|
12199
|
+
returns: "ptr"
|
|
12200
|
+
},
|
|
12201
|
+
bufferGetBgTagPtr: {
|
|
12202
|
+
args: ["ptr"],
|
|
12203
|
+
returns: "ptr"
|
|
12204
|
+
},
|
|
11966
12205
|
bufferGetAttributesPtr: {
|
|
11967
12206
|
args: ["ptr"],
|
|
11968
12207
|
returns: "ptr"
|
|
@@ -12387,6 +12626,10 @@ function getOpenTUILib(libPath) {
|
|
|
12387
12626
|
args: ["ptr", "u8"],
|
|
12388
12627
|
returns: "void"
|
|
12389
12628
|
},
|
|
12629
|
+
textBufferViewSetFirstLineOffset: {
|
|
12630
|
+
args: ["ptr", "u32"],
|
|
12631
|
+
returns: "void"
|
|
12632
|
+
},
|
|
12390
12633
|
textBufferViewSetViewportSize: {
|
|
12391
12634
|
args: ["ptr", "u32", "u32"],
|
|
12392
12635
|
returns: "void"
|
|
@@ -12760,7 +13003,7 @@ function getOpenTUILib(libPath) {
|
|
|
12760
13003
|
returns: "void"
|
|
12761
13004
|
},
|
|
12762
13005
|
syntaxStyleRegister: {
|
|
12763
|
-
args: ["ptr", "ptr", "usize", "ptr", "ptr", "
|
|
13006
|
+
args: ["ptr", "ptr", "usize", "ptr", "ptr", "u32"],
|
|
12764
13007
|
returns: "u32"
|
|
12765
13008
|
},
|
|
12766
13009
|
syntaxStyleResolveByName: {
|
|
@@ -13124,12 +13367,27 @@ class FFIRenderLib {
|
|
|
13124
13367
|
setUseThread(renderer, useThread) {
|
|
13125
13368
|
this.opentui.symbols.setUseThread(renderer, useThread);
|
|
13126
13369
|
}
|
|
13370
|
+
setClearOnShutdown(renderer, clear) {
|
|
13371
|
+
this.opentui.symbols.setClearOnShutdown(renderer, clear);
|
|
13372
|
+
}
|
|
13127
13373
|
setBackgroundColor(renderer, color) {
|
|
13128
13374
|
this.opentui.symbols.setBackgroundColor(renderer, color.buffer);
|
|
13129
13375
|
}
|
|
13130
13376
|
setRenderOffset(renderer, offset) {
|
|
13131
13377
|
this.opentui.symbols.setRenderOffset(renderer, offset);
|
|
13132
13378
|
}
|
|
13379
|
+
resetSplitScrollback(renderer, seedRows, pinnedRenderOffset) {
|
|
13380
|
+
return this.opentui.symbols.resetSplitScrollback(renderer, seedRows, pinnedRenderOffset);
|
|
13381
|
+
}
|
|
13382
|
+
syncSplitScrollback(renderer, pinnedRenderOffset) {
|
|
13383
|
+
return this.opentui.symbols.syncSplitScrollback(renderer, pinnedRenderOffset);
|
|
13384
|
+
}
|
|
13385
|
+
setPendingSplitFooterTransition(renderer, mode, sourceTopLine, sourceHeight, targetTopLine, targetHeight) {
|
|
13386
|
+
this.opentui.symbols.setPendingSplitFooterTransition(renderer, mode, sourceTopLine, sourceHeight, targetTopLine, targetHeight);
|
|
13387
|
+
}
|
|
13388
|
+
clearPendingSplitFooterTransition(renderer) {
|
|
13389
|
+
this.opentui.symbols.clearPendingSplitFooterTransition(renderer);
|
|
13390
|
+
}
|
|
13133
13391
|
updateStats(renderer, time, fps, frameCallbackTime) {
|
|
13134
13392
|
this.opentui.symbols.updateStats(renderer, time, fps, frameCallbackTime);
|
|
13135
13393
|
}
|
|
@@ -13154,6 +13412,18 @@ class FFIRenderLib {
|
|
|
13154
13412
|
const height = this.opentui.symbols.getBufferHeight(bufferPtr);
|
|
13155
13413
|
return new OptimizedBuffer(this, bufferPtr, width, height, { id: "current buffer", widthMethod: "unicode" });
|
|
13156
13414
|
}
|
|
13415
|
+
rendererSetPaletteState(renderer, palette, defaultForeground, defaultBackground, paletteEpoch) {
|
|
13416
|
+
const paletteBuffer = new Float32Array(palette.length * 4);
|
|
13417
|
+
for (let index = 0;index < palette.length; index++) {
|
|
13418
|
+
const color = palette[index];
|
|
13419
|
+
const base = index * 4;
|
|
13420
|
+
paletteBuffer[base] = color.r;
|
|
13421
|
+
paletteBuffer[base + 1] = color.g;
|
|
13422
|
+
paletteBuffer[base + 2] = color.b;
|
|
13423
|
+
paletteBuffer[base + 3] = color.a;
|
|
13424
|
+
}
|
|
13425
|
+
this.opentui.symbols.rendererSetPaletteState(renderer, paletteBuffer, paletteBuffer.length, defaultForeground.buffer, defaultBackground.buffer, paletteEpoch >>> 0);
|
|
13426
|
+
}
|
|
13157
13427
|
bufferGetCharPtr(buffer) {
|
|
13158
13428
|
const ptr5 = this.opentui.symbols.bufferGetCharPtr(buffer);
|
|
13159
13429
|
if (!ptr5) {
|
|
@@ -13175,6 +13445,20 @@ class FFIRenderLib {
|
|
|
13175
13445
|
}
|
|
13176
13446
|
return ptr5;
|
|
13177
13447
|
}
|
|
13448
|
+
bufferGetFgTagPtr(buffer) {
|
|
13449
|
+
const ptr5 = this.opentui.symbols.bufferGetFgTagPtr(buffer);
|
|
13450
|
+
if (!ptr5) {
|
|
13451
|
+
throw new Error("Failed to get fg tag pointer");
|
|
13452
|
+
}
|
|
13453
|
+
return ptr5;
|
|
13454
|
+
}
|
|
13455
|
+
bufferGetBgTagPtr(buffer) {
|
|
13456
|
+
const ptr5 = this.opentui.symbols.bufferGetBgTagPtr(buffer);
|
|
13457
|
+
if (!ptr5) {
|
|
13458
|
+
throw new Error("Failed to get bg tag pointer");
|
|
13459
|
+
}
|
|
13460
|
+
return ptr5;
|
|
13461
|
+
}
|
|
13178
13462
|
bufferGetAttributesPtr(buffer) {
|
|
13179
13463
|
const ptr5 = this.opentui.symbols.bufferGetAttributesPtr(buffer);
|
|
13180
13464
|
if (!ptr5) {
|
|
@@ -13319,6 +13603,12 @@ class FFIRenderLib {
|
|
|
13319
13603
|
render(renderer, force) {
|
|
13320
13604
|
this.opentui.symbols.render(renderer, force);
|
|
13321
13605
|
}
|
|
13606
|
+
repaintSplitFooter(renderer, pinnedRenderOffset, force) {
|
|
13607
|
+
return this.opentui.symbols.repaintSplitFooter(renderer, pinnedRenderOffset, force);
|
|
13608
|
+
}
|
|
13609
|
+
commitSplitFooterSnapshot(renderer, snapshot, rowColumns, startOnNewLine, trailingNewline, pinnedRenderOffset, force, beginFrame = true, finalizeFrame = true) {
|
|
13610
|
+
return this.opentui.symbols.commitSplitFooterSnapshot(renderer, snapshot.ptr, rowColumns, startOnNewLine, trailingNewline, pinnedRenderOffset, force, beginFrame, finalizeFrame);
|
|
13611
|
+
}
|
|
13322
13612
|
createOptimizedBuffer(width, height, widthMethod, respectAlpha = false, id) {
|
|
13323
13613
|
if (Number.isNaN(width) || Number.isNaN(height)) {
|
|
13324
13614
|
console.error(new Error(`Invalid dimensions for OptimizedBuffer: ${width}x${height}`).stack);
|
|
@@ -13426,6 +13716,9 @@ class FFIRenderLib {
|
|
|
13426
13716
|
queryPixelResolution(renderer) {
|
|
13427
13717
|
this.opentui.symbols.queryPixelResolution(renderer);
|
|
13428
13718
|
}
|
|
13719
|
+
queryThemeColors(renderer) {
|
|
13720
|
+
this.opentui.symbols.queryThemeColors(renderer);
|
|
13721
|
+
}
|
|
13429
13722
|
writeOut(renderer, data) {
|
|
13430
13723
|
const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data;
|
|
13431
13724
|
if (bytes.length === 0)
|
|
@@ -13598,6 +13891,9 @@ class FFIRenderLib {
|
|
|
13598
13891
|
const modeValue = mode === "none" ? 0 : mode === "char" ? 1 : 2;
|
|
13599
13892
|
this.opentui.symbols.textBufferViewSetWrapMode(view, modeValue);
|
|
13600
13893
|
}
|
|
13894
|
+
textBufferViewSetFirstLineOffset(view, offset) {
|
|
13895
|
+
this.opentui.symbols.textBufferViewSetFirstLineOffset(view, offset);
|
|
13896
|
+
}
|
|
13601
13897
|
textBufferViewSetViewportSize(view, width, height) {
|
|
13602
13898
|
this.opentui.symbols.textBufferViewSetViewportSize(view, width, height);
|
|
13603
13899
|
}
|
|
@@ -14127,6 +14423,7 @@ class FFIRenderLib {
|
|
|
14127
14423
|
kitty_keyboard: caps.kitty_keyboard,
|
|
14128
14424
|
kitty_graphics: caps.kitty_graphics,
|
|
14129
14425
|
rgb: caps.rgb,
|
|
14426
|
+
ansi256: caps.ansi256,
|
|
14130
14427
|
unicode: caps.unicode,
|
|
14131
14428
|
sgr_pixels: caps.sgr_pixels,
|
|
14132
14429
|
color_scheme_updates: caps.color_scheme_updates,
|
|
@@ -16051,6 +16348,139 @@ function delegate(mapping, vnode) {
|
|
|
16051
16348
|
return vnode;
|
|
16052
16349
|
}
|
|
16053
16350
|
|
|
16351
|
+
// src/text-buffer-view.ts
|
|
16352
|
+
class TextBufferView {
|
|
16353
|
+
lib;
|
|
16354
|
+
viewPtr;
|
|
16355
|
+
textBuffer;
|
|
16356
|
+
_destroyed = false;
|
|
16357
|
+
constructor(lib, ptr5, textBuffer) {
|
|
16358
|
+
this.lib = lib;
|
|
16359
|
+
this.viewPtr = ptr5;
|
|
16360
|
+
this.textBuffer = textBuffer;
|
|
16361
|
+
}
|
|
16362
|
+
static create(textBuffer) {
|
|
16363
|
+
const lib = resolveRenderLib();
|
|
16364
|
+
const viewPtr = lib.createTextBufferView(textBuffer.ptr);
|
|
16365
|
+
return new TextBufferView(lib, viewPtr, textBuffer);
|
|
16366
|
+
}
|
|
16367
|
+
guard() {
|
|
16368
|
+
if (this._destroyed)
|
|
16369
|
+
throw new Error("TextBufferView is destroyed");
|
|
16370
|
+
}
|
|
16371
|
+
get ptr() {
|
|
16372
|
+
this.guard();
|
|
16373
|
+
return this.viewPtr;
|
|
16374
|
+
}
|
|
16375
|
+
setSelection(start, end, bgColor, fgColor) {
|
|
16376
|
+
this.guard();
|
|
16377
|
+
this.lib.textBufferViewSetSelection(this.viewPtr, start, end, bgColor || null, fgColor || null);
|
|
16378
|
+
}
|
|
16379
|
+
updateSelection(end, bgColor, fgColor) {
|
|
16380
|
+
this.guard();
|
|
16381
|
+
this.lib.textBufferViewUpdateSelection(this.viewPtr, end, bgColor || null, fgColor || null);
|
|
16382
|
+
}
|
|
16383
|
+
resetSelection() {
|
|
16384
|
+
this.guard();
|
|
16385
|
+
this.lib.textBufferViewResetSelection(this.viewPtr);
|
|
16386
|
+
}
|
|
16387
|
+
getSelection() {
|
|
16388
|
+
this.guard();
|
|
16389
|
+
return this.lib.textBufferViewGetSelection(this.viewPtr);
|
|
16390
|
+
}
|
|
16391
|
+
hasSelection() {
|
|
16392
|
+
this.guard();
|
|
16393
|
+
return this.getSelection() !== null;
|
|
16394
|
+
}
|
|
16395
|
+
setLocalSelection(anchorX, anchorY, focusX, focusY, bgColor, fgColor) {
|
|
16396
|
+
this.guard();
|
|
16397
|
+
return this.lib.textBufferViewSetLocalSelection(this.viewPtr, anchorX, anchorY, focusX, focusY, bgColor || null, fgColor || null);
|
|
16398
|
+
}
|
|
16399
|
+
updateLocalSelection(anchorX, anchorY, focusX, focusY, bgColor, fgColor) {
|
|
16400
|
+
this.guard();
|
|
16401
|
+
return this.lib.textBufferViewUpdateLocalSelection(this.viewPtr, anchorX, anchorY, focusX, focusY, bgColor || null, fgColor || null);
|
|
16402
|
+
}
|
|
16403
|
+
resetLocalSelection() {
|
|
16404
|
+
this.guard();
|
|
16405
|
+
this.lib.textBufferViewResetLocalSelection(this.viewPtr);
|
|
16406
|
+
}
|
|
16407
|
+
setWrapWidth(width) {
|
|
16408
|
+
this.guard();
|
|
16409
|
+
this.lib.textBufferViewSetWrapWidth(this.viewPtr, width ?? 0);
|
|
16410
|
+
}
|
|
16411
|
+
setWrapMode(mode) {
|
|
16412
|
+
this.guard();
|
|
16413
|
+
this.lib.textBufferViewSetWrapMode(this.viewPtr, mode);
|
|
16414
|
+
}
|
|
16415
|
+
setFirstLineOffset(offset) {
|
|
16416
|
+
this.guard();
|
|
16417
|
+
this.lib.textBufferViewSetFirstLineOffset(this.viewPtr, offset);
|
|
16418
|
+
}
|
|
16419
|
+
setViewportSize(width, height) {
|
|
16420
|
+
this.guard();
|
|
16421
|
+
this.lib.textBufferViewSetViewportSize(this.viewPtr, width, height);
|
|
16422
|
+
}
|
|
16423
|
+
setViewport(x, y, width, height) {
|
|
16424
|
+
this.guard();
|
|
16425
|
+
this.lib.textBufferViewSetViewport(this.viewPtr, x, y, width, height);
|
|
16426
|
+
}
|
|
16427
|
+
get lineInfo() {
|
|
16428
|
+
this.guard();
|
|
16429
|
+
return this.lib.textBufferViewGetLineInfo(this.viewPtr);
|
|
16430
|
+
}
|
|
16431
|
+
get logicalLineInfo() {
|
|
16432
|
+
this.guard();
|
|
16433
|
+
return this.lib.textBufferViewGetLogicalLineInfo(this.viewPtr);
|
|
16434
|
+
}
|
|
16435
|
+
getSelectedText() {
|
|
16436
|
+
this.guard();
|
|
16437
|
+
const byteSize = this.textBuffer.byteSize;
|
|
16438
|
+
if (byteSize === 0)
|
|
16439
|
+
return "";
|
|
16440
|
+
const selectedBytes = this.lib.textBufferViewGetSelectedTextBytes(this.viewPtr, byteSize);
|
|
16441
|
+
if (!selectedBytes)
|
|
16442
|
+
return "";
|
|
16443
|
+
return this.lib.decoder.decode(selectedBytes);
|
|
16444
|
+
}
|
|
16445
|
+
getPlainText() {
|
|
16446
|
+
this.guard();
|
|
16447
|
+
const byteSize = this.textBuffer.byteSize;
|
|
16448
|
+
if (byteSize === 0)
|
|
16449
|
+
return "";
|
|
16450
|
+
const plainBytes = this.lib.textBufferViewGetPlainTextBytes(this.viewPtr, byteSize);
|
|
16451
|
+
if (!plainBytes)
|
|
16452
|
+
return "";
|
|
16453
|
+
return this.lib.decoder.decode(plainBytes);
|
|
16454
|
+
}
|
|
16455
|
+
setTabIndicator(indicator) {
|
|
16456
|
+
this.guard();
|
|
16457
|
+
const codePoint = typeof indicator === "string" ? indicator.codePointAt(0) ?? 0 : indicator;
|
|
16458
|
+
this.lib.textBufferViewSetTabIndicator(this.viewPtr, codePoint);
|
|
16459
|
+
}
|
|
16460
|
+
setTabIndicatorColor(color) {
|
|
16461
|
+
this.guard();
|
|
16462
|
+
this.lib.textBufferViewSetTabIndicatorColor(this.viewPtr, color);
|
|
16463
|
+
}
|
|
16464
|
+
setTruncate(truncate) {
|
|
16465
|
+
this.guard();
|
|
16466
|
+
this.lib.textBufferViewSetTruncate(this.viewPtr, truncate);
|
|
16467
|
+
}
|
|
16468
|
+
measureForDimensions(width, height) {
|
|
16469
|
+
this.guard();
|
|
16470
|
+
return this.lib.textBufferViewMeasureForDimensions(this.viewPtr, width, height);
|
|
16471
|
+
}
|
|
16472
|
+
getVirtualLineCount() {
|
|
16473
|
+
this.guard();
|
|
16474
|
+
return this.lib.textBufferViewGetVirtualLineCount(this.viewPtr);
|
|
16475
|
+
}
|
|
16476
|
+
destroy() {
|
|
16477
|
+
if (this._destroyed)
|
|
16478
|
+
return;
|
|
16479
|
+
this._destroyed = true;
|
|
16480
|
+
this.lib.destroyTextBufferView(this.viewPtr);
|
|
16481
|
+
}
|
|
16482
|
+
}
|
|
16483
|
+
|
|
16054
16484
|
// src/edit-buffer.ts
|
|
16055
16485
|
import { EventEmitter as EventEmitter6 } from "events";
|
|
16056
16486
|
|
|
@@ -16555,54 +16985,1490 @@ class EditorView {
|
|
|
16555
16985
|
}
|
|
16556
16986
|
}
|
|
16557
16987
|
|
|
16558
|
-
// src/
|
|
16559
|
-
|
|
16560
|
-
|
|
16561
|
-
|
|
16562
|
-
|
|
16563
|
-
|
|
16564
|
-
|
|
16565
|
-
|
|
16566
|
-
|
|
16567
|
-
|
|
16988
|
+
// src/syntax-style.ts
|
|
16989
|
+
function convertThemeToStyles(theme) {
|
|
16990
|
+
const flatStyles = {};
|
|
16991
|
+
for (const tokenStyle of theme) {
|
|
16992
|
+
const styleDefinition = {};
|
|
16993
|
+
if (tokenStyle.style.foreground) {
|
|
16994
|
+
styleDefinition.fg = parseColor(tokenStyle.style.foreground);
|
|
16995
|
+
}
|
|
16996
|
+
if (tokenStyle.style.background) {
|
|
16997
|
+
styleDefinition.bg = parseColor(tokenStyle.style.background);
|
|
16998
|
+
}
|
|
16999
|
+
if (tokenStyle.style.bold !== undefined) {
|
|
17000
|
+
styleDefinition.bold = tokenStyle.style.bold;
|
|
17001
|
+
}
|
|
17002
|
+
if (tokenStyle.style.italic !== undefined) {
|
|
17003
|
+
styleDefinition.italic = tokenStyle.style.italic;
|
|
17004
|
+
}
|
|
17005
|
+
if (tokenStyle.style.underline !== undefined) {
|
|
17006
|
+
styleDefinition.underline = tokenStyle.style.underline;
|
|
17007
|
+
}
|
|
17008
|
+
if (tokenStyle.style.dim !== undefined) {
|
|
17009
|
+
styleDefinition.dim = tokenStyle.style.dim;
|
|
17010
|
+
}
|
|
17011
|
+
for (const scope of tokenStyle.scope) {
|
|
17012
|
+
flatStyles[scope] = styleDefinition;
|
|
17013
|
+
}
|
|
17014
|
+
}
|
|
17015
|
+
return flatStyles;
|
|
17016
|
+
}
|
|
16568
17017
|
|
|
16569
|
-
class
|
|
16570
|
-
|
|
16571
|
-
|
|
16572
|
-
|
|
17018
|
+
class SyntaxStyle {
|
|
17019
|
+
lib;
|
|
17020
|
+
stylePtr;
|
|
17021
|
+
_destroyed = false;
|
|
17022
|
+
nameCache = new Map;
|
|
17023
|
+
styleDefs = new Map;
|
|
17024
|
+
mergedCache = new Map;
|
|
17025
|
+
constructor(lib, ptr5) {
|
|
17026
|
+
this.lib = lib;
|
|
17027
|
+
this.stylePtr = ptr5;
|
|
16573
17028
|
}
|
|
16574
|
-
|
|
16575
|
-
|
|
17029
|
+
static create() {
|
|
17030
|
+
const lib = resolveRenderLib();
|
|
17031
|
+
const ptr5 = lib.createSyntaxStyle();
|
|
17032
|
+
return new SyntaxStyle(lib, ptr5);
|
|
16576
17033
|
}
|
|
16577
|
-
|
|
16578
|
-
|
|
16579
|
-
|
|
17034
|
+
static fromTheme(theme) {
|
|
17035
|
+
const style = SyntaxStyle.create();
|
|
17036
|
+
const flatStyles = convertThemeToStyles(theme);
|
|
17037
|
+
for (const [name, styleDef] of Object.entries(flatStyles)) {
|
|
17038
|
+
style.registerStyle(name, styleDef);
|
|
17039
|
+
}
|
|
17040
|
+
return style;
|
|
16580
17041
|
}
|
|
16581
|
-
|
|
16582
|
-
const
|
|
16583
|
-
|
|
16584
|
-
|
|
17042
|
+
static fromStyles(styles) {
|
|
17043
|
+
const style = SyntaxStyle.create();
|
|
17044
|
+
for (const [name, styleDef] of Object.entries(styles)) {
|
|
17045
|
+
style.registerStyle(name, styleDef);
|
|
17046
|
+
}
|
|
17047
|
+
return style;
|
|
16585
17048
|
}
|
|
16586
|
-
|
|
16587
|
-
this.
|
|
17049
|
+
guard() {
|
|
17050
|
+
if (this._destroyed)
|
|
17051
|
+
throw new Error("NativeSyntaxStyle is destroyed");
|
|
16588
17052
|
}
|
|
16589
|
-
|
|
16590
|
-
|
|
16591
|
-
|
|
16592
|
-
|
|
16593
|
-
|
|
16594
|
-
|
|
16595
|
-
|
|
16596
|
-
|
|
16597
|
-
|
|
16598
|
-
|
|
16599
|
-
this.
|
|
16600
|
-
|
|
17053
|
+
registerStyle(name, style) {
|
|
17054
|
+
this.guard();
|
|
17055
|
+
const attributes = createTextAttributes({
|
|
17056
|
+
bold: style.bold,
|
|
17057
|
+
italic: style.italic,
|
|
17058
|
+
underline: style.underline,
|
|
17059
|
+
dim: style.dim
|
|
17060
|
+
});
|
|
17061
|
+
const id = this.lib.syntaxStyleRegister(this.stylePtr, name, style.fg || null, style.bg || null, attributes);
|
|
17062
|
+
this.nameCache.set(name, id);
|
|
17063
|
+
this.styleDefs.set(name, style);
|
|
17064
|
+
return id;
|
|
16601
17065
|
}
|
|
16602
|
-
|
|
16603
|
-
|
|
16604
|
-
this.
|
|
16605
|
-
|
|
17066
|
+
resolveStyleId(name) {
|
|
17067
|
+
this.guard();
|
|
17068
|
+
const cached = this.nameCache.get(name);
|
|
17069
|
+
if (cached !== undefined)
|
|
17070
|
+
return cached;
|
|
17071
|
+
const id = this.lib.syntaxStyleResolveByName(this.stylePtr, name);
|
|
17072
|
+
if (id !== null) {
|
|
17073
|
+
this.nameCache.set(name, id);
|
|
17074
|
+
}
|
|
17075
|
+
return id;
|
|
17076
|
+
}
|
|
17077
|
+
getStyleId(name) {
|
|
17078
|
+
this.guard();
|
|
17079
|
+
const id = this.resolveStyleId(name);
|
|
17080
|
+
if (id !== null)
|
|
17081
|
+
return id;
|
|
17082
|
+
if (name.includes(".")) {
|
|
17083
|
+
const baseName = name.split(".")[0];
|
|
17084
|
+
return this.resolveStyleId(baseName);
|
|
17085
|
+
}
|
|
17086
|
+
return null;
|
|
17087
|
+
}
|
|
17088
|
+
get ptr() {
|
|
17089
|
+
this.guard();
|
|
17090
|
+
return this.stylePtr;
|
|
17091
|
+
}
|
|
17092
|
+
getStyleCount() {
|
|
17093
|
+
this.guard();
|
|
17094
|
+
return this.lib.syntaxStyleGetStyleCount(this.stylePtr);
|
|
17095
|
+
}
|
|
17096
|
+
clearNameCache() {
|
|
17097
|
+
this.nameCache.clear();
|
|
17098
|
+
}
|
|
17099
|
+
getStyle(name) {
|
|
17100
|
+
this.guard();
|
|
17101
|
+
if (Object.prototype.hasOwnProperty.call(this.styleDefs, name)) {
|
|
17102
|
+
return;
|
|
17103
|
+
}
|
|
17104
|
+
const style = this.styleDefs.get(name);
|
|
17105
|
+
if (style)
|
|
17106
|
+
return style;
|
|
17107
|
+
if (name.includes(".")) {
|
|
17108
|
+
const baseName = name.split(".")[0];
|
|
17109
|
+
if (Object.prototype.hasOwnProperty.call(this.styleDefs, baseName)) {
|
|
17110
|
+
return;
|
|
17111
|
+
}
|
|
17112
|
+
return this.styleDefs.get(baseName);
|
|
17113
|
+
}
|
|
17114
|
+
return;
|
|
17115
|
+
}
|
|
17116
|
+
mergeStyles(...styleNames) {
|
|
17117
|
+
this.guard();
|
|
17118
|
+
const cacheKey = styleNames.join(":");
|
|
17119
|
+
const cached = this.mergedCache.get(cacheKey);
|
|
17120
|
+
if (cached)
|
|
17121
|
+
return cached;
|
|
17122
|
+
const styleDefinition = {};
|
|
17123
|
+
for (const name of styleNames) {
|
|
17124
|
+
const style = this.getStyle(name);
|
|
17125
|
+
if (!style)
|
|
17126
|
+
continue;
|
|
17127
|
+
if (style.fg)
|
|
17128
|
+
styleDefinition.fg = style.fg;
|
|
17129
|
+
if (style.bg)
|
|
17130
|
+
styleDefinition.bg = style.bg;
|
|
17131
|
+
if (style.bold !== undefined)
|
|
17132
|
+
styleDefinition.bold = style.bold;
|
|
17133
|
+
if (style.italic !== undefined)
|
|
17134
|
+
styleDefinition.italic = style.italic;
|
|
17135
|
+
if (style.underline !== undefined)
|
|
17136
|
+
styleDefinition.underline = style.underline;
|
|
17137
|
+
if (style.dim !== undefined)
|
|
17138
|
+
styleDefinition.dim = style.dim;
|
|
17139
|
+
}
|
|
17140
|
+
const attributes = createTextAttributes({
|
|
17141
|
+
bold: styleDefinition.bold,
|
|
17142
|
+
italic: styleDefinition.italic,
|
|
17143
|
+
underline: styleDefinition.underline,
|
|
17144
|
+
dim: styleDefinition.dim
|
|
17145
|
+
});
|
|
17146
|
+
const merged = {
|
|
17147
|
+
fg: styleDefinition.fg,
|
|
17148
|
+
bg: styleDefinition.bg,
|
|
17149
|
+
attributes
|
|
17150
|
+
};
|
|
17151
|
+
this.mergedCache.set(cacheKey, merged);
|
|
17152
|
+
return merged;
|
|
17153
|
+
}
|
|
17154
|
+
clearCache() {
|
|
17155
|
+
this.guard();
|
|
17156
|
+
this.mergedCache.clear();
|
|
17157
|
+
}
|
|
17158
|
+
getCacheSize() {
|
|
17159
|
+
this.guard();
|
|
17160
|
+
return this.mergedCache.size;
|
|
17161
|
+
}
|
|
17162
|
+
getAllStyles() {
|
|
17163
|
+
this.guard();
|
|
17164
|
+
return new Map(this.styleDefs);
|
|
17165
|
+
}
|
|
17166
|
+
getRegisteredNames() {
|
|
17167
|
+
this.guard();
|
|
17168
|
+
return Array.from(this.styleDefs.keys());
|
|
17169
|
+
}
|
|
17170
|
+
destroy() {
|
|
17171
|
+
if (this._destroyed)
|
|
17172
|
+
return;
|
|
17173
|
+
this._destroyed = true;
|
|
17174
|
+
this.nameCache.clear();
|
|
17175
|
+
this.styleDefs.clear();
|
|
17176
|
+
this.mergedCache.clear();
|
|
17177
|
+
this.lib.destroySyntaxStyle(this.stylePtr);
|
|
17178
|
+
}
|
|
17179
|
+
}
|
|
17180
|
+
|
|
17181
|
+
// src/renderables/Box.ts
|
|
17182
|
+
function isGapType(value) {
|
|
17183
|
+
if (value === undefined) {
|
|
17184
|
+
return true;
|
|
17185
|
+
}
|
|
17186
|
+
if (typeof value === "number" && !Number.isNaN(value)) {
|
|
17187
|
+
return true;
|
|
17188
|
+
}
|
|
17189
|
+
return isValidPercentage(value);
|
|
17190
|
+
}
|
|
17191
|
+
|
|
17192
|
+
class BoxRenderable extends Renderable {
|
|
17193
|
+
_backgroundColor;
|
|
17194
|
+
_border;
|
|
17195
|
+
_borderStyle;
|
|
17196
|
+
_borderColor;
|
|
17197
|
+
_focusedBorderColor;
|
|
17198
|
+
_customBorderCharsObj;
|
|
17199
|
+
_customBorderChars;
|
|
17200
|
+
borderSides;
|
|
17201
|
+
shouldFill;
|
|
17202
|
+
_title;
|
|
17203
|
+
_titleAlignment;
|
|
17204
|
+
_bottomTitle;
|
|
17205
|
+
_bottomTitleAlignment;
|
|
17206
|
+
_defaultOptions = {
|
|
17207
|
+
backgroundColor: "transparent",
|
|
17208
|
+
borderStyle: "single",
|
|
17209
|
+
border: false,
|
|
17210
|
+
borderColor: "#FFFFFF",
|
|
17211
|
+
shouldFill: true,
|
|
17212
|
+
titleAlignment: "left",
|
|
17213
|
+
bottomTitleAlignment: "left",
|
|
17214
|
+
focusedBorderColor: "#00AAFF"
|
|
17215
|
+
};
|
|
17216
|
+
constructor(ctx, options) {
|
|
17217
|
+
super(ctx, options);
|
|
17218
|
+
if (options.focusable === true) {
|
|
17219
|
+
this._focusable = true;
|
|
17220
|
+
}
|
|
17221
|
+
this._backgroundColor = parseColor(options.backgroundColor || this._defaultOptions.backgroundColor);
|
|
17222
|
+
this._border = options.border ?? this._defaultOptions.border;
|
|
17223
|
+
if (!options.border && (options.borderStyle || options.borderColor || options.focusedBorderColor || options.customBorderChars)) {
|
|
17224
|
+
this._border = true;
|
|
17225
|
+
}
|
|
17226
|
+
this._borderStyle = parseBorderStyle(options.borderStyle, this._defaultOptions.borderStyle);
|
|
17227
|
+
this._borderColor = parseColor(options.borderColor || this._defaultOptions.borderColor);
|
|
17228
|
+
this._focusedBorderColor = parseColor(options.focusedBorderColor || this._defaultOptions.focusedBorderColor);
|
|
17229
|
+
this._customBorderCharsObj = options.customBorderChars;
|
|
17230
|
+
this._customBorderChars = this._customBorderCharsObj ? borderCharsToArray(this._customBorderCharsObj) : undefined;
|
|
17231
|
+
this.borderSides = getBorderSides(this._border);
|
|
17232
|
+
this.shouldFill = options.shouldFill ?? this._defaultOptions.shouldFill;
|
|
17233
|
+
this._title = options.title;
|
|
17234
|
+
this._titleAlignment = options.titleAlignment || this._defaultOptions.titleAlignment;
|
|
17235
|
+
this._bottomTitle = options.bottomTitle;
|
|
17236
|
+
this._bottomTitleAlignment = options.bottomTitleAlignment || this._defaultOptions.bottomTitleAlignment;
|
|
17237
|
+
this.applyYogaBorders();
|
|
17238
|
+
const hasInitialGapProps = options.gap !== undefined || options.rowGap !== undefined || options.columnGap !== undefined;
|
|
17239
|
+
if (hasInitialGapProps) {
|
|
17240
|
+
this.applyYogaGap(options);
|
|
17241
|
+
}
|
|
17242
|
+
}
|
|
17243
|
+
initializeBorder() {
|
|
17244
|
+
if (this._border === false) {
|
|
17245
|
+
this._border = true;
|
|
17246
|
+
this.borderSides = getBorderSides(this._border);
|
|
17247
|
+
this.applyYogaBorders();
|
|
17248
|
+
}
|
|
17249
|
+
}
|
|
17250
|
+
get customBorderChars() {
|
|
17251
|
+
return this._customBorderCharsObj;
|
|
17252
|
+
}
|
|
17253
|
+
set customBorderChars(value) {
|
|
17254
|
+
this._customBorderCharsObj = value;
|
|
17255
|
+
this._customBorderChars = value ? borderCharsToArray(value) : undefined;
|
|
17256
|
+
this.requestRender();
|
|
17257
|
+
}
|
|
17258
|
+
get backgroundColor() {
|
|
17259
|
+
return this._backgroundColor;
|
|
17260
|
+
}
|
|
17261
|
+
set backgroundColor(value) {
|
|
17262
|
+
const newColor = parseColor(value ?? this._defaultOptions.backgroundColor);
|
|
17263
|
+
if (this._backgroundColor !== newColor) {
|
|
17264
|
+
this._backgroundColor = newColor;
|
|
17265
|
+
this.requestRender();
|
|
17266
|
+
}
|
|
17267
|
+
}
|
|
17268
|
+
get border() {
|
|
17269
|
+
return this._border;
|
|
17270
|
+
}
|
|
17271
|
+
set border(value) {
|
|
17272
|
+
if (this._border !== value) {
|
|
17273
|
+
this._border = value;
|
|
17274
|
+
this.borderSides = getBorderSides(value);
|
|
17275
|
+
this.applyYogaBorders();
|
|
17276
|
+
this.requestRender();
|
|
17277
|
+
}
|
|
17278
|
+
}
|
|
17279
|
+
get borderStyle() {
|
|
17280
|
+
return this._borderStyle;
|
|
17281
|
+
}
|
|
17282
|
+
set borderStyle(value) {
|
|
17283
|
+
const _value = parseBorderStyle(value, this._defaultOptions.borderStyle);
|
|
17284
|
+
if (this._borderStyle !== _value || !this._border) {
|
|
17285
|
+
this._borderStyle = _value;
|
|
17286
|
+
this._customBorderChars = undefined;
|
|
17287
|
+
this.initializeBorder();
|
|
17288
|
+
this.requestRender();
|
|
17289
|
+
}
|
|
17290
|
+
}
|
|
17291
|
+
get borderColor() {
|
|
17292
|
+
return this._borderColor;
|
|
17293
|
+
}
|
|
17294
|
+
set borderColor(value) {
|
|
17295
|
+
const newColor = parseColor(value ?? this._defaultOptions.borderColor);
|
|
17296
|
+
if (this._borderColor !== newColor) {
|
|
17297
|
+
this._borderColor = newColor;
|
|
17298
|
+
this.initializeBorder();
|
|
17299
|
+
this.requestRender();
|
|
17300
|
+
}
|
|
17301
|
+
}
|
|
17302
|
+
get focusedBorderColor() {
|
|
17303
|
+
return this._focusedBorderColor;
|
|
17304
|
+
}
|
|
17305
|
+
set focusedBorderColor(value) {
|
|
17306
|
+
const newColor = parseColor(value ?? this._defaultOptions.focusedBorderColor);
|
|
17307
|
+
if (this._focusedBorderColor !== newColor) {
|
|
17308
|
+
this._focusedBorderColor = newColor;
|
|
17309
|
+
this.initializeBorder();
|
|
17310
|
+
if (this._focused) {
|
|
17311
|
+
this.requestRender();
|
|
17312
|
+
}
|
|
17313
|
+
}
|
|
17314
|
+
}
|
|
17315
|
+
get title() {
|
|
17316
|
+
return this._title;
|
|
17317
|
+
}
|
|
17318
|
+
set title(value) {
|
|
17319
|
+
if (this._title !== value) {
|
|
17320
|
+
this._title = value;
|
|
17321
|
+
this.requestRender();
|
|
17322
|
+
}
|
|
17323
|
+
}
|
|
17324
|
+
get titleAlignment() {
|
|
17325
|
+
return this._titleAlignment;
|
|
17326
|
+
}
|
|
17327
|
+
set titleAlignment(value) {
|
|
17328
|
+
if (this._titleAlignment !== value) {
|
|
17329
|
+
this._titleAlignment = value;
|
|
17330
|
+
this.requestRender();
|
|
17331
|
+
}
|
|
17332
|
+
}
|
|
17333
|
+
get bottomTitle() {
|
|
17334
|
+
return this._bottomTitle;
|
|
17335
|
+
}
|
|
17336
|
+
set bottomTitle(value) {
|
|
17337
|
+
if (this._bottomTitle !== value) {
|
|
17338
|
+
this._bottomTitle = value;
|
|
17339
|
+
this.requestRender();
|
|
17340
|
+
}
|
|
17341
|
+
}
|
|
17342
|
+
get bottomTitleAlignment() {
|
|
17343
|
+
return this._bottomTitleAlignment;
|
|
17344
|
+
}
|
|
17345
|
+
set bottomTitleAlignment(value) {
|
|
17346
|
+
if (this._bottomTitleAlignment !== value) {
|
|
17347
|
+
this._bottomTitleAlignment = value;
|
|
17348
|
+
this.requestRender();
|
|
17349
|
+
}
|
|
17350
|
+
}
|
|
17351
|
+
renderSelf(buffer) {
|
|
17352
|
+
const hasBorder = this.borderSides.top || this.borderSides.right || this.borderSides.bottom || this.borderSides.left;
|
|
17353
|
+
const hasVisibleFill = this.shouldFill && this._backgroundColor.a > 0;
|
|
17354
|
+
if (!hasBorder && !hasVisibleFill) {
|
|
17355
|
+
return;
|
|
17356
|
+
}
|
|
17357
|
+
const hasFocusWithin = this._focusable && (this._focused || this._hasFocusedDescendant);
|
|
17358
|
+
const currentBorderColor = hasFocusWithin ? this._focusedBorderColor : this._borderColor;
|
|
17359
|
+
const screenX = this._screenX;
|
|
17360
|
+
const screenY = this._screenY;
|
|
17361
|
+
buffer.drawBox({
|
|
17362
|
+
x: screenX,
|
|
17363
|
+
y: screenY,
|
|
17364
|
+
width: this.width,
|
|
17365
|
+
height: this.height,
|
|
17366
|
+
borderStyle: this._borderStyle,
|
|
17367
|
+
customBorderChars: this._customBorderChars,
|
|
17368
|
+
border: this._border,
|
|
17369
|
+
borderColor: currentBorderColor,
|
|
17370
|
+
backgroundColor: this._backgroundColor,
|
|
17371
|
+
shouldFill: this.shouldFill,
|
|
17372
|
+
title: this._title,
|
|
17373
|
+
titleAlignment: this._titleAlignment,
|
|
17374
|
+
bottomTitle: this._bottomTitle,
|
|
17375
|
+
bottomTitleAlignment: this._bottomTitleAlignment
|
|
17376
|
+
});
|
|
17377
|
+
}
|
|
17378
|
+
getScissorRect() {
|
|
17379
|
+
const baseRect = super.getScissorRect();
|
|
17380
|
+
if (!this.borderSides.top && !this.borderSides.right && !this.borderSides.bottom && !this.borderSides.left) {
|
|
17381
|
+
return baseRect;
|
|
17382
|
+
}
|
|
17383
|
+
const leftInset = this.borderSides.left ? 1 : 0;
|
|
17384
|
+
const rightInset = this.borderSides.right ? 1 : 0;
|
|
17385
|
+
const topInset = this.borderSides.top ? 1 : 0;
|
|
17386
|
+
const bottomInset = this.borderSides.bottom ? 1 : 0;
|
|
17387
|
+
return {
|
|
17388
|
+
x: baseRect.x + leftInset,
|
|
17389
|
+
y: baseRect.y + topInset,
|
|
17390
|
+
width: Math.max(0, baseRect.width - leftInset - rightInset),
|
|
17391
|
+
height: Math.max(0, baseRect.height - topInset - bottomInset)
|
|
17392
|
+
};
|
|
17393
|
+
}
|
|
17394
|
+
applyYogaBorders() {
|
|
17395
|
+
const node = this.yogaNode;
|
|
17396
|
+
node.setBorder(Edge.Left, this.borderSides.left ? 1 : 0);
|
|
17397
|
+
node.setBorder(Edge.Right, this.borderSides.right ? 1 : 0);
|
|
17398
|
+
node.setBorder(Edge.Top, this.borderSides.top ? 1 : 0);
|
|
17399
|
+
node.setBorder(Edge.Bottom, this.borderSides.bottom ? 1 : 0);
|
|
17400
|
+
this.requestRender();
|
|
17401
|
+
}
|
|
17402
|
+
applyYogaGap(options) {
|
|
17403
|
+
const node = this.yogaNode;
|
|
17404
|
+
if (isGapType(options.gap)) {
|
|
17405
|
+
node.setGap(Gutter.All, options.gap);
|
|
17406
|
+
}
|
|
17407
|
+
if (isGapType(options.rowGap)) {
|
|
17408
|
+
node.setGap(Gutter.Row, options.rowGap);
|
|
17409
|
+
}
|
|
17410
|
+
if (isGapType(options.columnGap)) {
|
|
17411
|
+
node.setGap(Gutter.Column, options.columnGap);
|
|
17412
|
+
}
|
|
17413
|
+
}
|
|
17414
|
+
set gap(gap) {
|
|
17415
|
+
if (isGapType(gap)) {
|
|
17416
|
+
this.yogaNode.setGap(Gutter.All, gap);
|
|
17417
|
+
this.requestRender();
|
|
17418
|
+
}
|
|
17419
|
+
}
|
|
17420
|
+
set rowGap(rowGap) {
|
|
17421
|
+
if (isGapType(rowGap)) {
|
|
17422
|
+
this.yogaNode.setGap(Gutter.Row, rowGap);
|
|
17423
|
+
this.requestRender();
|
|
17424
|
+
}
|
|
17425
|
+
}
|
|
17426
|
+
set columnGap(columnGap) {
|
|
17427
|
+
if (isGapType(columnGap)) {
|
|
17428
|
+
this.yogaNode.setGap(Gutter.Column, columnGap);
|
|
17429
|
+
this.requestRender();
|
|
17430
|
+
}
|
|
17431
|
+
}
|
|
17432
|
+
}
|
|
17433
|
+
|
|
17434
|
+
// src/renderables/TextBufferRenderable.ts
|
|
17435
|
+
class TextBufferRenderable extends Renderable {
|
|
17436
|
+
selectable = true;
|
|
17437
|
+
_defaultFg;
|
|
17438
|
+
_defaultBg;
|
|
17439
|
+
_defaultAttributes;
|
|
17440
|
+
_selectionBg;
|
|
17441
|
+
_selectionFg;
|
|
17442
|
+
_wrapMode = "word";
|
|
17443
|
+
lastLocalSelection = null;
|
|
17444
|
+
_tabIndicator;
|
|
17445
|
+
_tabIndicatorColor;
|
|
17446
|
+
_scrollX = 0;
|
|
17447
|
+
_scrollY = 0;
|
|
17448
|
+
_truncate = false;
|
|
17449
|
+
_firstLineOffset = 0;
|
|
17450
|
+
textBuffer;
|
|
17451
|
+
textBufferView;
|
|
17452
|
+
_textBufferSyntaxStyle;
|
|
17453
|
+
_defaultOptions = {
|
|
17454
|
+
fg: RGBA.fromValues(1, 1, 1, 1),
|
|
17455
|
+
bg: RGBA.fromValues(0, 0, 0, 0),
|
|
17456
|
+
selectionBg: undefined,
|
|
17457
|
+
selectionFg: undefined,
|
|
17458
|
+
selectable: true,
|
|
17459
|
+
attributes: 0,
|
|
17460
|
+
wrapMode: "word",
|
|
17461
|
+
tabIndicator: undefined,
|
|
17462
|
+
tabIndicatorColor: undefined,
|
|
17463
|
+
truncate: false
|
|
17464
|
+
};
|
|
17465
|
+
constructor(ctx, options) {
|
|
17466
|
+
super(ctx, options);
|
|
17467
|
+
this._defaultFg = parseColor(options.fg ?? this._defaultOptions.fg);
|
|
17468
|
+
this._defaultBg = parseColor(options.bg ?? this._defaultOptions.bg);
|
|
17469
|
+
this._defaultAttributes = options.attributes ?? this._defaultOptions.attributes;
|
|
17470
|
+
this._selectionBg = options.selectionBg ? parseColor(options.selectionBg) : this._defaultOptions.selectionBg;
|
|
17471
|
+
this._selectionFg = options.selectionFg ? parseColor(options.selectionFg) : this._defaultOptions.selectionFg;
|
|
17472
|
+
this.selectable = options.selectable ?? this._defaultOptions.selectable;
|
|
17473
|
+
this._wrapMode = options.wrapMode ?? this._defaultOptions.wrapMode;
|
|
17474
|
+
this._tabIndicator = options.tabIndicator ?? this._defaultOptions.tabIndicator;
|
|
17475
|
+
this._tabIndicatorColor = options.tabIndicatorColor ? parseColor(options.tabIndicatorColor) : this._defaultOptions.tabIndicatorColor;
|
|
17476
|
+
this._truncate = options.truncate ?? this._defaultOptions.truncate;
|
|
17477
|
+
this.textBuffer = TextBuffer.create(this._ctx.widthMethod);
|
|
17478
|
+
this.textBufferView = TextBufferView.create(this.textBuffer);
|
|
17479
|
+
this._firstLineOffset = ctx.claimFirstLineOffset?.(this) ?? 0;
|
|
17480
|
+
this._textBufferSyntaxStyle = SyntaxStyle.create();
|
|
17481
|
+
this.textBuffer.setSyntaxStyle(this._textBufferSyntaxStyle);
|
|
17482
|
+
this.textBufferView.setWrapMode(this._wrapMode);
|
|
17483
|
+
this.textBufferView.setFirstLineOffset(this._firstLineOffset);
|
|
17484
|
+
this.setupMeasureFunc();
|
|
17485
|
+
this.textBuffer.setDefaultFg(this._defaultFg);
|
|
17486
|
+
this.textBuffer.setDefaultBg(this._defaultBg);
|
|
17487
|
+
this.textBuffer.setDefaultAttributes(this._defaultAttributes);
|
|
17488
|
+
if (this._tabIndicator !== undefined) {
|
|
17489
|
+
this.textBufferView.setTabIndicator(this._tabIndicator);
|
|
17490
|
+
}
|
|
17491
|
+
if (this._tabIndicatorColor !== undefined) {
|
|
17492
|
+
this.textBufferView.setTabIndicatorColor(this._tabIndicatorColor);
|
|
17493
|
+
}
|
|
17494
|
+
if (this._wrapMode !== "none" && this.width > 0) {
|
|
17495
|
+
this.textBufferView.setWrapWidth(this.width);
|
|
17496
|
+
}
|
|
17497
|
+
if (this.width > 0 && this.height > 0) {
|
|
17498
|
+
this.textBufferView.setViewport(this._scrollX, this._scrollY, this.width, this.height);
|
|
17499
|
+
}
|
|
17500
|
+
this.textBufferView.setTruncate(this._truncate);
|
|
17501
|
+
this.updateTextInfo();
|
|
17502
|
+
}
|
|
17503
|
+
onMouseEvent(event) {
|
|
17504
|
+
if (event.type === "scroll") {
|
|
17505
|
+
this.handleScroll(event);
|
|
17506
|
+
}
|
|
17507
|
+
}
|
|
17508
|
+
handleScroll(event) {
|
|
17509
|
+
if (!event.scroll)
|
|
17510
|
+
return;
|
|
17511
|
+
const { direction, delta } = event.scroll;
|
|
17512
|
+
if (direction === "up") {
|
|
17513
|
+
this.scrollY -= delta;
|
|
17514
|
+
} else if (direction === "down") {
|
|
17515
|
+
this.scrollY += delta;
|
|
17516
|
+
}
|
|
17517
|
+
if (this._wrapMode === "none") {
|
|
17518
|
+
if (direction === "left") {
|
|
17519
|
+
this.scrollX -= delta;
|
|
17520
|
+
} else if (direction === "right") {
|
|
17521
|
+
this.scrollX += delta;
|
|
17522
|
+
}
|
|
17523
|
+
}
|
|
17524
|
+
}
|
|
17525
|
+
get lineInfo() {
|
|
17526
|
+
return this.textBufferView.logicalLineInfo;
|
|
17527
|
+
}
|
|
17528
|
+
get lineCount() {
|
|
17529
|
+
return this.textBuffer.getLineCount();
|
|
17530
|
+
}
|
|
17531
|
+
get virtualLineCount() {
|
|
17532
|
+
return this.textBufferView.getVirtualLineCount();
|
|
17533
|
+
}
|
|
17534
|
+
get scrollY() {
|
|
17535
|
+
return this._scrollY;
|
|
17536
|
+
}
|
|
17537
|
+
set scrollY(value) {
|
|
17538
|
+
const maxScrollY = Math.max(0, this.scrollHeight - this.height);
|
|
17539
|
+
const clamped = Math.max(0, Math.min(value, maxScrollY));
|
|
17540
|
+
if (this._scrollY !== clamped) {
|
|
17541
|
+
this._scrollY = clamped;
|
|
17542
|
+
this.updateViewportOffset();
|
|
17543
|
+
this.requestRender();
|
|
17544
|
+
}
|
|
17545
|
+
}
|
|
17546
|
+
get scrollX() {
|
|
17547
|
+
return this._scrollX;
|
|
17548
|
+
}
|
|
17549
|
+
set scrollX(value) {
|
|
17550
|
+
const maxScrollX = Math.max(0, this.scrollWidth - this.width);
|
|
17551
|
+
const clamped = Math.max(0, Math.min(value, maxScrollX));
|
|
17552
|
+
if (this._scrollX !== clamped) {
|
|
17553
|
+
this._scrollX = clamped;
|
|
17554
|
+
this.updateViewportOffset();
|
|
17555
|
+
this.requestRender();
|
|
17556
|
+
}
|
|
17557
|
+
}
|
|
17558
|
+
get scrollWidth() {
|
|
17559
|
+
return this.lineInfo.lineWidthColsMax;
|
|
17560
|
+
}
|
|
17561
|
+
get scrollHeight() {
|
|
17562
|
+
return this.lineInfo.lineStartCols.length;
|
|
17563
|
+
}
|
|
17564
|
+
get maxScrollY() {
|
|
17565
|
+
return Math.max(0, this.scrollHeight - this.height);
|
|
17566
|
+
}
|
|
17567
|
+
get maxScrollX() {
|
|
17568
|
+
return Math.max(0, this.scrollWidth - this.width);
|
|
17569
|
+
}
|
|
17570
|
+
updateViewportOffset() {
|
|
17571
|
+
if (this.width > 0 && this.height > 0) {
|
|
17572
|
+
this.textBufferView.setViewport(this._scrollX, this._scrollY, this.width, this.height);
|
|
17573
|
+
}
|
|
17574
|
+
}
|
|
17575
|
+
get plainText() {
|
|
17576
|
+
return this.textBuffer.getPlainText();
|
|
17577
|
+
}
|
|
17578
|
+
get textLength() {
|
|
17579
|
+
return this.textBuffer.length;
|
|
17580
|
+
}
|
|
17581
|
+
get fg() {
|
|
17582
|
+
return this._defaultFg;
|
|
17583
|
+
}
|
|
17584
|
+
set fg(value) {
|
|
17585
|
+
const newColor = parseColor(value ?? this._defaultOptions.fg);
|
|
17586
|
+
if (this._defaultFg !== newColor) {
|
|
17587
|
+
this._defaultFg = newColor;
|
|
17588
|
+
this.textBuffer.setDefaultFg(this._defaultFg);
|
|
17589
|
+
this.onFgChanged(newColor);
|
|
17590
|
+
this.requestRender();
|
|
17591
|
+
}
|
|
17592
|
+
}
|
|
17593
|
+
get selectionBg() {
|
|
17594
|
+
return this._selectionBg;
|
|
17595
|
+
}
|
|
17596
|
+
set selectionBg(value) {
|
|
17597
|
+
const newColor = value ? parseColor(value) : this._defaultOptions.selectionBg;
|
|
17598
|
+
if (this._selectionBg !== newColor) {
|
|
17599
|
+
this._selectionBg = newColor;
|
|
17600
|
+
if (this.lastLocalSelection) {
|
|
17601
|
+
this.updateLocalSelection(this.lastLocalSelection);
|
|
17602
|
+
}
|
|
17603
|
+
this.requestRender();
|
|
17604
|
+
}
|
|
17605
|
+
}
|
|
17606
|
+
get selectionFg() {
|
|
17607
|
+
return this._selectionFg;
|
|
17608
|
+
}
|
|
17609
|
+
set selectionFg(value) {
|
|
17610
|
+
const newColor = value ? parseColor(value) : this._defaultOptions.selectionFg;
|
|
17611
|
+
if (this._selectionFg !== newColor) {
|
|
17612
|
+
this._selectionFg = newColor;
|
|
17613
|
+
if (this.lastLocalSelection) {
|
|
17614
|
+
this.updateLocalSelection(this.lastLocalSelection);
|
|
17615
|
+
}
|
|
17616
|
+
this.requestRender();
|
|
17617
|
+
}
|
|
17618
|
+
}
|
|
17619
|
+
get bg() {
|
|
17620
|
+
return this._defaultBg;
|
|
17621
|
+
}
|
|
17622
|
+
set bg(value) {
|
|
17623
|
+
const newColor = parseColor(value ?? this._defaultOptions.bg);
|
|
17624
|
+
if (this._defaultBg !== newColor) {
|
|
17625
|
+
this._defaultBg = newColor;
|
|
17626
|
+
this.textBuffer.setDefaultBg(this._defaultBg);
|
|
17627
|
+
this.onBgChanged(newColor);
|
|
17628
|
+
this.requestRender();
|
|
17629
|
+
}
|
|
17630
|
+
}
|
|
17631
|
+
get attributes() {
|
|
17632
|
+
return this._defaultAttributes;
|
|
17633
|
+
}
|
|
17634
|
+
set attributes(value) {
|
|
17635
|
+
if (this._defaultAttributes !== value) {
|
|
17636
|
+
this._defaultAttributes = value;
|
|
17637
|
+
this.textBuffer.setDefaultAttributes(this._defaultAttributes);
|
|
17638
|
+
this.onAttributesChanged(value);
|
|
17639
|
+
this.requestRender();
|
|
17640
|
+
}
|
|
17641
|
+
}
|
|
17642
|
+
get wrapMode() {
|
|
17643
|
+
return this._wrapMode;
|
|
17644
|
+
}
|
|
17645
|
+
set wrapMode(value) {
|
|
17646
|
+
if (this._wrapMode !== value) {
|
|
17647
|
+
this._wrapMode = value;
|
|
17648
|
+
this.textBufferView.setWrapMode(this._wrapMode);
|
|
17649
|
+
if (value !== "none" && this.width > 0) {
|
|
17650
|
+
this.textBufferView.setWrapWidth(this.width);
|
|
17651
|
+
}
|
|
17652
|
+
this.yogaNode.markDirty();
|
|
17653
|
+
this.requestRender();
|
|
17654
|
+
}
|
|
17655
|
+
}
|
|
17656
|
+
get tabIndicator() {
|
|
17657
|
+
return this._tabIndicator;
|
|
17658
|
+
}
|
|
17659
|
+
set tabIndicator(value) {
|
|
17660
|
+
if (this._tabIndicator !== value) {
|
|
17661
|
+
this._tabIndicator = value;
|
|
17662
|
+
if (value !== undefined) {
|
|
17663
|
+
this.textBufferView.setTabIndicator(value);
|
|
17664
|
+
}
|
|
17665
|
+
this.requestRender();
|
|
17666
|
+
}
|
|
17667
|
+
}
|
|
17668
|
+
get tabIndicatorColor() {
|
|
17669
|
+
return this._tabIndicatorColor;
|
|
17670
|
+
}
|
|
17671
|
+
set tabIndicatorColor(value) {
|
|
17672
|
+
const newColor = value ? parseColor(value) : undefined;
|
|
17673
|
+
if (this._tabIndicatorColor !== newColor) {
|
|
17674
|
+
this._tabIndicatorColor = newColor;
|
|
17675
|
+
if (newColor !== undefined) {
|
|
17676
|
+
this.textBufferView.setTabIndicatorColor(newColor);
|
|
17677
|
+
}
|
|
17678
|
+
this.requestRender();
|
|
17679
|
+
}
|
|
17680
|
+
}
|
|
17681
|
+
get truncate() {
|
|
17682
|
+
return this._truncate;
|
|
17683
|
+
}
|
|
17684
|
+
set truncate(value) {
|
|
17685
|
+
if (this._truncate !== value) {
|
|
17686
|
+
this._truncate = value;
|
|
17687
|
+
this.textBufferView.setTruncate(value);
|
|
17688
|
+
this.requestRender();
|
|
17689
|
+
}
|
|
17690
|
+
}
|
|
17691
|
+
onResize(width, height) {
|
|
17692
|
+
this.textBufferView.setViewport(this._scrollX, this._scrollY, width, height);
|
|
17693
|
+
this.yogaNode.markDirty();
|
|
17694
|
+
this.requestRender();
|
|
17695
|
+
this.emit("line-info-change");
|
|
17696
|
+
}
|
|
17697
|
+
refreshLocalSelection() {
|
|
17698
|
+
if (this.lastLocalSelection) {
|
|
17699
|
+
return this.updateLocalSelection(this.lastLocalSelection);
|
|
17700
|
+
}
|
|
17701
|
+
return false;
|
|
17702
|
+
}
|
|
17703
|
+
updateLocalSelection(localSelection) {
|
|
17704
|
+
if (!localSelection?.isActive) {
|
|
17705
|
+
this.textBufferView.resetLocalSelection();
|
|
17706
|
+
return true;
|
|
17707
|
+
}
|
|
17708
|
+
return this.textBufferView.setLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg);
|
|
17709
|
+
}
|
|
17710
|
+
updateTextInfo() {
|
|
17711
|
+
if (this.lastLocalSelection) {
|
|
17712
|
+
this.updateLocalSelection(this.lastLocalSelection);
|
|
17713
|
+
}
|
|
17714
|
+
this.yogaNode.markDirty();
|
|
17715
|
+
this.requestRender();
|
|
17716
|
+
this.emit("line-info-change");
|
|
17717
|
+
}
|
|
17718
|
+
setupMeasureFunc() {
|
|
17719
|
+
const measureFunc = (width, widthMode, height, heightMode) => {
|
|
17720
|
+
let effectiveWidth;
|
|
17721
|
+
if (widthMode === MeasureMode.Undefined || isNaN(width)) {
|
|
17722
|
+
effectiveWidth = 0;
|
|
17723
|
+
} else {
|
|
17724
|
+
effectiveWidth = width;
|
|
17725
|
+
}
|
|
17726
|
+
const effectiveHeight = isNaN(height) ? 1 : height;
|
|
17727
|
+
const measureResult = this.textBufferView.measureForDimensions(Math.floor(effectiveWidth), Math.floor(effectiveHeight));
|
|
17728
|
+
const measuredWidth = measureResult ? Math.max(1, measureResult.widthColsMax) : 1;
|
|
17729
|
+
const measuredHeight = measureResult ? Math.max(1, measureResult.lineCount) : 1;
|
|
17730
|
+
if (widthMode === MeasureMode.AtMost && this._positionType !== "absolute") {
|
|
17731
|
+
return {
|
|
17732
|
+
width: Math.min(effectiveWidth, measuredWidth),
|
|
17733
|
+
height: Math.min(effectiveHeight, measuredHeight)
|
|
17734
|
+
};
|
|
17735
|
+
}
|
|
17736
|
+
return {
|
|
17737
|
+
width: measuredWidth,
|
|
17738
|
+
height: measuredHeight
|
|
17739
|
+
};
|
|
17740
|
+
};
|
|
17741
|
+
this.yogaNode.setMeasureFunc(measureFunc);
|
|
17742
|
+
}
|
|
17743
|
+
shouldStartSelection(x, y) {
|
|
17744
|
+
if (!this.selectable)
|
|
17745
|
+
return false;
|
|
17746
|
+
const localX = x - this.x;
|
|
17747
|
+
const localY = y - this.y;
|
|
17748
|
+
return localX >= 0 && localX < this.width && localY >= 0 && localY < this.height;
|
|
17749
|
+
}
|
|
17750
|
+
onSelectionChanged(selection2) {
|
|
17751
|
+
const localSelection = convertGlobalToLocalSelection(selection2, this.x, this.y);
|
|
17752
|
+
this.lastLocalSelection = localSelection;
|
|
17753
|
+
let changed;
|
|
17754
|
+
if (!localSelection?.isActive) {
|
|
17755
|
+
this.textBufferView.resetLocalSelection();
|
|
17756
|
+
changed = true;
|
|
17757
|
+
} else if (selection2?.isStart) {
|
|
17758
|
+
changed = this.textBufferView.setLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg);
|
|
17759
|
+
} else {
|
|
17760
|
+
changed = this.textBufferView.updateLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg);
|
|
17761
|
+
}
|
|
17762
|
+
if (changed) {
|
|
17763
|
+
this.requestRender();
|
|
17764
|
+
}
|
|
17765
|
+
return this.hasSelection();
|
|
17766
|
+
}
|
|
17767
|
+
getSelectedText() {
|
|
17768
|
+
return this.textBufferView.getSelectedText();
|
|
17769
|
+
}
|
|
17770
|
+
hasSelection() {
|
|
17771
|
+
return this.textBufferView.hasSelection();
|
|
17772
|
+
}
|
|
17773
|
+
getSelection() {
|
|
17774
|
+
return this.textBufferView.getSelection();
|
|
17775
|
+
}
|
|
17776
|
+
render(buffer, deltaTime) {
|
|
17777
|
+
if (!this.visible)
|
|
17778
|
+
return;
|
|
17779
|
+
const screenX = this._screenX;
|
|
17780
|
+
const screenY = this._screenY;
|
|
17781
|
+
this.markClean();
|
|
17782
|
+
this._ctx.addToHitGrid(screenX, screenY, this.width, this.height, this.num);
|
|
17783
|
+
this.renderSelf(buffer);
|
|
17784
|
+
if (this.buffered && this.frameBuffer) {
|
|
17785
|
+
buffer.drawFrameBuffer(screenX, screenY, this.frameBuffer);
|
|
17786
|
+
}
|
|
17787
|
+
}
|
|
17788
|
+
renderSelf(buffer) {
|
|
17789
|
+
if (this.textBuffer.ptr) {
|
|
17790
|
+
buffer.drawTextBuffer(this.textBufferView, this._screenX, this._screenY);
|
|
17791
|
+
}
|
|
17792
|
+
}
|
|
17793
|
+
destroy() {
|
|
17794
|
+
if (this.isDestroyed)
|
|
17795
|
+
return;
|
|
17796
|
+
this.textBuffer.setSyntaxStyle(null);
|
|
17797
|
+
this._textBufferSyntaxStyle.destroy();
|
|
17798
|
+
this.textBufferView.destroy();
|
|
17799
|
+
this.textBuffer.destroy();
|
|
17800
|
+
super.destroy();
|
|
17801
|
+
}
|
|
17802
|
+
onFgChanged(newColor) {}
|
|
17803
|
+
onBgChanged(newColor) {}
|
|
17804
|
+
onAttributesChanged(newAttributes) {}
|
|
17805
|
+
}
|
|
17806
|
+
|
|
17807
|
+
// src/renderables/Code.ts
|
|
17808
|
+
class CodeRenderable extends TextBufferRenderable {
|
|
17809
|
+
_content;
|
|
17810
|
+
_filetype;
|
|
17811
|
+
_syntaxStyle;
|
|
17812
|
+
_isHighlighting = false;
|
|
17813
|
+
_treeSitterClient;
|
|
17814
|
+
_highlightsDirty = false;
|
|
17815
|
+
_highlightSnapshotId = 0;
|
|
17816
|
+
_conceal;
|
|
17817
|
+
_drawUnstyledText;
|
|
17818
|
+
_shouldRenderTextBuffer = true;
|
|
17819
|
+
_streaming;
|
|
17820
|
+
_hadInitialContent = false;
|
|
17821
|
+
_lastHighlights = [];
|
|
17822
|
+
_onHighlight;
|
|
17823
|
+
_onChunks;
|
|
17824
|
+
_highlightingPromise = Promise.resolve();
|
|
17825
|
+
_contentDefaultOptions = {
|
|
17826
|
+
content: "",
|
|
17827
|
+
conceal: true,
|
|
17828
|
+
drawUnstyledText: true,
|
|
17829
|
+
streaming: false
|
|
17830
|
+
};
|
|
17831
|
+
constructor(ctx, options) {
|
|
17832
|
+
super(ctx, options);
|
|
17833
|
+
this._content = options.content ?? this._contentDefaultOptions.content;
|
|
17834
|
+
this._filetype = options.filetype;
|
|
17835
|
+
this._syntaxStyle = options.syntaxStyle;
|
|
17836
|
+
this._treeSitterClient = options.treeSitterClient ?? getTreeSitterClient();
|
|
17837
|
+
this._conceal = options.conceal ?? this._contentDefaultOptions.conceal;
|
|
17838
|
+
this._drawUnstyledText = options.drawUnstyledText ?? this._contentDefaultOptions.drawUnstyledText;
|
|
17839
|
+
this._streaming = options.streaming ?? this._contentDefaultOptions.streaming;
|
|
17840
|
+
this._onHighlight = options.onHighlight;
|
|
17841
|
+
this._onChunks = options.onChunks;
|
|
17842
|
+
if (this._content.length > 0) {
|
|
17843
|
+
this.textBuffer.setText(this._content);
|
|
17844
|
+
this.updateTextInfo();
|
|
17845
|
+
this._shouldRenderTextBuffer = this._drawUnstyledText || !this._filetype;
|
|
17846
|
+
}
|
|
17847
|
+
this._highlightsDirty = this._content.length > 0;
|
|
17848
|
+
}
|
|
17849
|
+
get content() {
|
|
17850
|
+
return this._content;
|
|
17851
|
+
}
|
|
17852
|
+
set content(value) {
|
|
17853
|
+
if (this._content !== value) {
|
|
17854
|
+
this._content = value;
|
|
17855
|
+
this._highlightsDirty = true;
|
|
17856
|
+
this._highlightSnapshotId++;
|
|
17857
|
+
if (this._streaming && !this._drawUnstyledText && this._filetype) {
|
|
17858
|
+
this.requestRender();
|
|
17859
|
+
return;
|
|
17860
|
+
}
|
|
17861
|
+
this.textBuffer.setText(value);
|
|
17862
|
+
this.updateTextInfo();
|
|
17863
|
+
}
|
|
17864
|
+
}
|
|
17865
|
+
get filetype() {
|
|
17866
|
+
return this._filetype;
|
|
17867
|
+
}
|
|
17868
|
+
set filetype(value) {
|
|
17869
|
+
if (this._filetype !== value) {
|
|
17870
|
+
this._filetype = value;
|
|
17871
|
+
this._highlightsDirty = true;
|
|
17872
|
+
}
|
|
17873
|
+
}
|
|
17874
|
+
get syntaxStyle() {
|
|
17875
|
+
return this._syntaxStyle;
|
|
17876
|
+
}
|
|
17877
|
+
set syntaxStyle(value) {
|
|
17878
|
+
if (this._syntaxStyle !== value) {
|
|
17879
|
+
this._syntaxStyle = value;
|
|
17880
|
+
this._highlightsDirty = true;
|
|
17881
|
+
}
|
|
17882
|
+
}
|
|
17883
|
+
get conceal() {
|
|
17884
|
+
return this._conceal;
|
|
17885
|
+
}
|
|
17886
|
+
set conceal(value) {
|
|
17887
|
+
if (this._conceal !== value) {
|
|
17888
|
+
this._conceal = value;
|
|
17889
|
+
this._highlightsDirty = true;
|
|
17890
|
+
}
|
|
17891
|
+
}
|
|
17892
|
+
get drawUnstyledText() {
|
|
17893
|
+
return this._drawUnstyledText;
|
|
17894
|
+
}
|
|
17895
|
+
set drawUnstyledText(value) {
|
|
17896
|
+
if (this._drawUnstyledText !== value) {
|
|
17897
|
+
this._drawUnstyledText = value;
|
|
17898
|
+
this._highlightsDirty = true;
|
|
17899
|
+
}
|
|
17900
|
+
}
|
|
17901
|
+
get streaming() {
|
|
17902
|
+
return this._streaming;
|
|
17903
|
+
}
|
|
17904
|
+
set streaming(value) {
|
|
17905
|
+
if (this._streaming !== value) {
|
|
17906
|
+
this._streaming = value;
|
|
17907
|
+
this._hadInitialContent = false;
|
|
17908
|
+
this._lastHighlights = [];
|
|
17909
|
+
this._highlightsDirty = true;
|
|
17910
|
+
}
|
|
17911
|
+
}
|
|
17912
|
+
get treeSitterClient() {
|
|
17913
|
+
return this._treeSitterClient;
|
|
17914
|
+
}
|
|
17915
|
+
set treeSitterClient(value) {
|
|
17916
|
+
if (this._treeSitterClient !== value) {
|
|
17917
|
+
this._treeSitterClient = value;
|
|
17918
|
+
this._highlightsDirty = true;
|
|
17919
|
+
}
|
|
17920
|
+
}
|
|
17921
|
+
get onHighlight() {
|
|
17922
|
+
return this._onHighlight;
|
|
17923
|
+
}
|
|
17924
|
+
set onHighlight(value) {
|
|
17925
|
+
if (this._onHighlight !== value) {
|
|
17926
|
+
this._onHighlight = value;
|
|
17927
|
+
this._highlightsDirty = true;
|
|
17928
|
+
}
|
|
17929
|
+
}
|
|
17930
|
+
get onChunks() {
|
|
17931
|
+
return this._onChunks;
|
|
17932
|
+
}
|
|
17933
|
+
set onChunks(value) {
|
|
17934
|
+
if (this._onChunks !== value) {
|
|
17935
|
+
this._onChunks = value;
|
|
17936
|
+
this._highlightsDirty = true;
|
|
17937
|
+
}
|
|
17938
|
+
}
|
|
17939
|
+
get isHighlighting() {
|
|
17940
|
+
return this._isHighlighting;
|
|
17941
|
+
}
|
|
17942
|
+
get highlightingDone() {
|
|
17943
|
+
return this._highlightingPromise;
|
|
17944
|
+
}
|
|
17945
|
+
async transformChunks(chunks, context) {
|
|
17946
|
+
if (!this._onChunks)
|
|
17947
|
+
return chunks;
|
|
17948
|
+
const modified = await this._onChunks(chunks, context);
|
|
17949
|
+
return modified ?? chunks;
|
|
17950
|
+
}
|
|
17951
|
+
ensureVisibleTextBeforeHighlight() {
|
|
17952
|
+
if (this.isDestroyed)
|
|
17953
|
+
return;
|
|
17954
|
+
const content = this._content;
|
|
17955
|
+
if (!this._filetype) {
|
|
17956
|
+
this._shouldRenderTextBuffer = true;
|
|
17957
|
+
return;
|
|
17958
|
+
}
|
|
17959
|
+
const isInitialContent = this._streaming && !this._hadInitialContent;
|
|
17960
|
+
const shouldDrawUnstyledNow = this._streaming ? isInitialContent && this._drawUnstyledText : this._drawUnstyledText;
|
|
17961
|
+
if (this._streaming && !isInitialContent) {
|
|
17962
|
+
this._shouldRenderTextBuffer = true;
|
|
17963
|
+
} else if (shouldDrawUnstyledNow) {
|
|
17964
|
+
this.textBuffer.setText(content);
|
|
17965
|
+
this._shouldRenderTextBuffer = true;
|
|
17966
|
+
} else {
|
|
17967
|
+
this._shouldRenderTextBuffer = false;
|
|
17968
|
+
}
|
|
17969
|
+
}
|
|
17970
|
+
async startHighlight() {
|
|
17971
|
+
const content = this._content;
|
|
17972
|
+
const filetype = this._filetype;
|
|
17973
|
+
const snapshotId = ++this._highlightSnapshotId;
|
|
17974
|
+
if (!filetype)
|
|
17975
|
+
return;
|
|
17976
|
+
const isInitialContent = this._streaming && !this._hadInitialContent;
|
|
17977
|
+
if (isInitialContent) {
|
|
17978
|
+
this._hadInitialContent = true;
|
|
17979
|
+
}
|
|
17980
|
+
this._isHighlighting = true;
|
|
17981
|
+
try {
|
|
17982
|
+
const result = await this._treeSitterClient.highlightOnce(content, filetype);
|
|
17983
|
+
if (snapshotId !== this._highlightSnapshotId) {
|
|
17984
|
+
return;
|
|
17985
|
+
}
|
|
17986
|
+
if (this.isDestroyed)
|
|
17987
|
+
return;
|
|
17988
|
+
let highlights = result.highlights ?? [];
|
|
17989
|
+
if (this._onHighlight && highlights.length >= 0) {
|
|
17990
|
+
const context = {
|
|
17991
|
+
content,
|
|
17992
|
+
filetype,
|
|
17993
|
+
syntaxStyle: this._syntaxStyle
|
|
17994
|
+
};
|
|
17995
|
+
const modified = await this._onHighlight(highlights, context);
|
|
17996
|
+
if (modified !== undefined) {
|
|
17997
|
+
highlights = modified;
|
|
17998
|
+
}
|
|
17999
|
+
}
|
|
18000
|
+
if (snapshotId !== this._highlightSnapshotId) {
|
|
18001
|
+
return;
|
|
18002
|
+
}
|
|
18003
|
+
if (this.isDestroyed)
|
|
18004
|
+
return;
|
|
18005
|
+
if (highlights.length > 0) {
|
|
18006
|
+
if (this._streaming) {
|
|
18007
|
+
this._lastHighlights = highlights;
|
|
18008
|
+
}
|
|
18009
|
+
}
|
|
18010
|
+
if (highlights.length > 0 || this._onChunks) {
|
|
18011
|
+
const context = {
|
|
18012
|
+
content,
|
|
18013
|
+
filetype,
|
|
18014
|
+
syntaxStyle: this._syntaxStyle,
|
|
18015
|
+
highlights
|
|
18016
|
+
};
|
|
18017
|
+
let chunks = treeSitterToTextChunks(content, highlights, this._syntaxStyle, {
|
|
18018
|
+
enabled: this._conceal
|
|
18019
|
+
});
|
|
18020
|
+
chunks = await this.transformChunks(chunks, context);
|
|
18021
|
+
if (snapshotId !== this._highlightSnapshotId) {
|
|
18022
|
+
return;
|
|
18023
|
+
}
|
|
18024
|
+
if (this.isDestroyed)
|
|
18025
|
+
return;
|
|
18026
|
+
const styledText = new StyledText(chunks);
|
|
18027
|
+
this.textBuffer.setStyledText(styledText);
|
|
18028
|
+
} else {
|
|
18029
|
+
this.textBuffer.setText(content);
|
|
18030
|
+
}
|
|
18031
|
+
this._shouldRenderTextBuffer = true;
|
|
18032
|
+
this._isHighlighting = false;
|
|
18033
|
+
this._highlightsDirty = false;
|
|
18034
|
+
this.updateTextInfo();
|
|
18035
|
+
this.requestRender();
|
|
18036
|
+
} catch (error) {
|
|
18037
|
+
if (snapshotId !== this._highlightSnapshotId) {
|
|
18038
|
+
return;
|
|
18039
|
+
}
|
|
18040
|
+
console.warn("Code highlighting failed, falling back to plain text:", error);
|
|
18041
|
+
if (this.isDestroyed)
|
|
18042
|
+
return;
|
|
18043
|
+
this.textBuffer.setText(content);
|
|
18044
|
+
this._shouldRenderTextBuffer = true;
|
|
18045
|
+
this._isHighlighting = false;
|
|
18046
|
+
this._highlightsDirty = false;
|
|
18047
|
+
this.updateTextInfo();
|
|
18048
|
+
this.requestRender();
|
|
18049
|
+
}
|
|
18050
|
+
}
|
|
18051
|
+
getLineHighlights(lineIdx) {
|
|
18052
|
+
return this.textBuffer.getLineHighlights(lineIdx);
|
|
18053
|
+
}
|
|
18054
|
+
renderSelf(buffer) {
|
|
18055
|
+
if (this._highlightsDirty) {
|
|
18056
|
+
if (this.isDestroyed)
|
|
18057
|
+
return;
|
|
18058
|
+
if (this._content.length === 0) {
|
|
18059
|
+
this._shouldRenderTextBuffer = false;
|
|
18060
|
+
this._highlightsDirty = false;
|
|
18061
|
+
} else if (!this._filetype) {
|
|
18062
|
+
this._shouldRenderTextBuffer = true;
|
|
18063
|
+
this._highlightsDirty = false;
|
|
18064
|
+
} else {
|
|
18065
|
+
this.ensureVisibleTextBeforeHighlight();
|
|
18066
|
+
this._highlightsDirty = false;
|
|
18067
|
+
this._highlightingPromise = this.startHighlight();
|
|
18068
|
+
}
|
|
18069
|
+
}
|
|
18070
|
+
if (!this._shouldRenderTextBuffer)
|
|
18071
|
+
return;
|
|
18072
|
+
super.renderSelf(buffer);
|
|
18073
|
+
}
|
|
18074
|
+
}
|
|
18075
|
+
|
|
18076
|
+
// src/renderables/TextNode.ts
|
|
18077
|
+
var BrandedTextNodeRenderable = Symbol.for("@opentui/core/TextNodeRenderable");
|
|
18078
|
+
function isTextNodeRenderable(obj) {
|
|
18079
|
+
return !!obj?.[BrandedTextNodeRenderable];
|
|
18080
|
+
}
|
|
18081
|
+
function styledTextToTextNodes(styledText) {
|
|
18082
|
+
return styledText.chunks.map((chunk) => {
|
|
18083
|
+
const node = new TextNodeRenderable({
|
|
18084
|
+
fg: chunk.fg,
|
|
18085
|
+
bg: chunk.bg,
|
|
18086
|
+
attributes: chunk.attributes,
|
|
18087
|
+
link: chunk.link
|
|
18088
|
+
});
|
|
18089
|
+
node.add(chunk.text);
|
|
18090
|
+
return node;
|
|
18091
|
+
});
|
|
18092
|
+
}
|
|
18093
|
+
|
|
18094
|
+
class TextNodeRenderable extends BaseRenderable {
|
|
18095
|
+
[BrandedTextNodeRenderable] = true;
|
|
18096
|
+
_fg;
|
|
18097
|
+
_bg;
|
|
18098
|
+
_attributes;
|
|
18099
|
+
_link;
|
|
18100
|
+
_children = [];
|
|
18101
|
+
parent = null;
|
|
18102
|
+
constructor(options) {
|
|
18103
|
+
super(options);
|
|
18104
|
+
this._fg = options.fg ? parseColor(options.fg) : undefined;
|
|
18105
|
+
this._bg = options.bg ? parseColor(options.bg) : undefined;
|
|
18106
|
+
this._attributes = options.attributes ?? 0;
|
|
18107
|
+
this._link = options.link;
|
|
18108
|
+
}
|
|
18109
|
+
get children() {
|
|
18110
|
+
return this._children;
|
|
18111
|
+
}
|
|
18112
|
+
set children(children) {
|
|
18113
|
+
this._children = children;
|
|
18114
|
+
this.requestRender();
|
|
18115
|
+
}
|
|
18116
|
+
requestRender() {
|
|
18117
|
+
this.markDirty();
|
|
18118
|
+
this.parent?.requestRender();
|
|
18119
|
+
}
|
|
18120
|
+
add(obj, index) {
|
|
18121
|
+
if (typeof obj === "string") {
|
|
18122
|
+
if (index !== undefined) {
|
|
18123
|
+
this._children.splice(index, 0, obj);
|
|
18124
|
+
this.requestRender();
|
|
18125
|
+
return index;
|
|
18126
|
+
}
|
|
18127
|
+
const insertIndex = this._children.length;
|
|
18128
|
+
this._children.push(obj);
|
|
18129
|
+
this.requestRender();
|
|
18130
|
+
return insertIndex;
|
|
18131
|
+
}
|
|
18132
|
+
if (isTextNodeRenderable(obj)) {
|
|
18133
|
+
if (index !== undefined) {
|
|
18134
|
+
this._children.splice(index, 0, obj);
|
|
18135
|
+
obj.parent = this;
|
|
18136
|
+
this.requestRender();
|
|
18137
|
+
return index;
|
|
18138
|
+
}
|
|
18139
|
+
const insertIndex = this._children.length;
|
|
18140
|
+
this._children.push(obj);
|
|
18141
|
+
obj.parent = this;
|
|
18142
|
+
this.requestRender();
|
|
18143
|
+
return insertIndex;
|
|
18144
|
+
}
|
|
18145
|
+
if (isStyledText(obj)) {
|
|
18146
|
+
const textNodes = styledTextToTextNodes(obj);
|
|
18147
|
+
if (index !== undefined) {
|
|
18148
|
+
this._children.splice(index, 0, ...textNodes);
|
|
18149
|
+
textNodes.forEach((node) => node.parent = this);
|
|
18150
|
+
this.requestRender();
|
|
18151
|
+
return index;
|
|
18152
|
+
}
|
|
18153
|
+
const insertIndex = this._children.length;
|
|
18154
|
+
this._children.push(...textNodes);
|
|
18155
|
+
textNodes.forEach((node) => node.parent = this);
|
|
18156
|
+
this.requestRender();
|
|
18157
|
+
return insertIndex;
|
|
18158
|
+
}
|
|
18159
|
+
throw new Error("TextNodeRenderable only accepts strings, TextNodeRenderable instances, or StyledText instances");
|
|
18160
|
+
}
|
|
18161
|
+
replace(obj, index) {
|
|
18162
|
+
this._children[index] = obj;
|
|
18163
|
+
if (typeof obj !== "string") {
|
|
18164
|
+
obj.parent = this;
|
|
18165
|
+
}
|
|
18166
|
+
this.requestRender();
|
|
18167
|
+
}
|
|
18168
|
+
insertBefore(child, anchorNode) {
|
|
18169
|
+
if (!anchorNode || !isTextNodeRenderable(anchorNode)) {
|
|
18170
|
+
throw new Error("Anchor must be a TextNodeRenderable");
|
|
18171
|
+
}
|
|
18172
|
+
const anchorIndex = this._children.indexOf(anchorNode);
|
|
18173
|
+
if (anchorIndex === -1) {
|
|
18174
|
+
throw new Error("Anchor node not found in children");
|
|
18175
|
+
}
|
|
18176
|
+
if (typeof child === "string") {
|
|
18177
|
+
this._children.splice(anchorIndex, 0, child);
|
|
18178
|
+
} else if (isTextNodeRenderable(child)) {
|
|
18179
|
+
this._children.splice(anchorIndex, 0, child);
|
|
18180
|
+
child.parent = this;
|
|
18181
|
+
} else if (child instanceof StyledText) {
|
|
18182
|
+
const textNodes = styledTextToTextNodes(child);
|
|
18183
|
+
this._children.splice(anchorIndex, 0, ...textNodes);
|
|
18184
|
+
textNodes.forEach((node) => node.parent = this);
|
|
18185
|
+
} else {
|
|
18186
|
+
throw new Error("Child must be a string, TextNodeRenderable, or StyledText instance");
|
|
18187
|
+
}
|
|
18188
|
+
this.requestRender();
|
|
18189
|
+
return this;
|
|
18190
|
+
}
|
|
18191
|
+
remove(id) {
|
|
18192
|
+
const childIndex = this.getRenderableIndex(id);
|
|
18193
|
+
if (childIndex === -1) {
|
|
18194
|
+
throw new Error("Child not found in children");
|
|
18195
|
+
}
|
|
18196
|
+
const child = this._children[childIndex];
|
|
18197
|
+
this._children.splice(childIndex, 1);
|
|
18198
|
+
child.parent = null;
|
|
18199
|
+
this.requestRender();
|
|
18200
|
+
return this;
|
|
18201
|
+
}
|
|
18202
|
+
clear() {
|
|
18203
|
+
this._children = [];
|
|
18204
|
+
this.requestRender();
|
|
18205
|
+
}
|
|
18206
|
+
mergeStyles(parentStyle) {
|
|
18207
|
+
return {
|
|
18208
|
+
fg: this._fg ?? parentStyle.fg,
|
|
18209
|
+
bg: this._bg ?? parentStyle.bg,
|
|
18210
|
+
attributes: this._attributes | parentStyle.attributes,
|
|
18211
|
+
link: this._link ?? parentStyle.link
|
|
18212
|
+
};
|
|
18213
|
+
}
|
|
18214
|
+
gatherWithInheritedStyle(parentStyle = {
|
|
18215
|
+
fg: undefined,
|
|
18216
|
+
bg: undefined,
|
|
18217
|
+
attributes: 0
|
|
18218
|
+
}) {
|
|
18219
|
+
const currentStyle = this.mergeStyles(parentStyle);
|
|
18220
|
+
const chunks = [];
|
|
18221
|
+
for (const child of this._children) {
|
|
18222
|
+
if (typeof child === "string") {
|
|
18223
|
+
chunks.push({
|
|
18224
|
+
__isChunk: true,
|
|
18225
|
+
text: child,
|
|
18226
|
+
fg: currentStyle.fg,
|
|
18227
|
+
bg: currentStyle.bg,
|
|
18228
|
+
attributes: currentStyle.attributes,
|
|
18229
|
+
link: currentStyle.link
|
|
18230
|
+
});
|
|
18231
|
+
} else {
|
|
18232
|
+
const childChunks = child.gatherWithInheritedStyle(currentStyle);
|
|
18233
|
+
chunks.push(...childChunks);
|
|
18234
|
+
}
|
|
18235
|
+
}
|
|
18236
|
+
this.markClean();
|
|
18237
|
+
return chunks;
|
|
18238
|
+
}
|
|
18239
|
+
static fromString(text, options = {}) {
|
|
18240
|
+
const node = new TextNodeRenderable(options);
|
|
18241
|
+
node.add(text);
|
|
18242
|
+
return node;
|
|
18243
|
+
}
|
|
18244
|
+
static fromNodes(nodes, options = {}) {
|
|
18245
|
+
const node = new TextNodeRenderable(options);
|
|
18246
|
+
for (const childNode of nodes) {
|
|
18247
|
+
node.add(childNode);
|
|
18248
|
+
}
|
|
18249
|
+
return node;
|
|
18250
|
+
}
|
|
18251
|
+
toChunks(parentStyle = {
|
|
18252
|
+
fg: undefined,
|
|
18253
|
+
bg: undefined,
|
|
18254
|
+
attributes: 0
|
|
18255
|
+
}) {
|
|
18256
|
+
return this.gatherWithInheritedStyle(parentStyle);
|
|
18257
|
+
}
|
|
18258
|
+
getChildren() {
|
|
18259
|
+
return this._children.filter((child) => typeof child !== "string");
|
|
18260
|
+
}
|
|
18261
|
+
getChildrenCount() {
|
|
18262
|
+
return this._children.length;
|
|
18263
|
+
}
|
|
18264
|
+
getRenderable(id) {
|
|
18265
|
+
return this._children.find((child) => typeof child !== "string" && child.id === id);
|
|
18266
|
+
}
|
|
18267
|
+
getRenderableIndex(id) {
|
|
18268
|
+
return this._children.findIndex((child) => isTextNodeRenderable(child) && child.id === id);
|
|
18269
|
+
}
|
|
18270
|
+
get fg() {
|
|
18271
|
+
return this._fg;
|
|
18272
|
+
}
|
|
18273
|
+
set fg(fg2) {
|
|
18274
|
+
if (!fg2) {
|
|
18275
|
+
this._fg = undefined;
|
|
18276
|
+
this.requestRender();
|
|
18277
|
+
return;
|
|
18278
|
+
}
|
|
18279
|
+
this._fg = parseColor(fg2);
|
|
18280
|
+
this.requestRender();
|
|
18281
|
+
}
|
|
18282
|
+
set bg(bg2) {
|
|
18283
|
+
if (!bg2) {
|
|
18284
|
+
this._bg = undefined;
|
|
18285
|
+
this.requestRender();
|
|
18286
|
+
return;
|
|
18287
|
+
}
|
|
18288
|
+
this._bg = parseColor(bg2);
|
|
18289
|
+
this.requestRender();
|
|
18290
|
+
}
|
|
18291
|
+
get bg() {
|
|
18292
|
+
return this._bg;
|
|
18293
|
+
}
|
|
18294
|
+
set attributes(attributes) {
|
|
18295
|
+
this._attributes = attributes;
|
|
18296
|
+
this.requestRender();
|
|
18297
|
+
}
|
|
18298
|
+
get attributes() {
|
|
18299
|
+
return this._attributes;
|
|
18300
|
+
}
|
|
18301
|
+
set link(link2) {
|
|
18302
|
+
this._link = link2;
|
|
18303
|
+
this.requestRender();
|
|
18304
|
+
}
|
|
18305
|
+
get link() {
|
|
18306
|
+
return this._link;
|
|
18307
|
+
}
|
|
18308
|
+
findDescendantById(id) {
|
|
18309
|
+
return;
|
|
18310
|
+
}
|
|
18311
|
+
}
|
|
18312
|
+
|
|
18313
|
+
class RootTextNodeRenderable extends TextNodeRenderable {
|
|
18314
|
+
ctx;
|
|
18315
|
+
textParent;
|
|
18316
|
+
constructor(ctx, options, textParent) {
|
|
18317
|
+
super(options);
|
|
18318
|
+
this.ctx = ctx;
|
|
18319
|
+
this.textParent = textParent;
|
|
18320
|
+
}
|
|
18321
|
+
requestRender() {
|
|
18322
|
+
this.markDirty();
|
|
18323
|
+
this.ctx.requestRender();
|
|
18324
|
+
}
|
|
18325
|
+
}
|
|
18326
|
+
|
|
18327
|
+
// src/renderables/Text.ts
|
|
18328
|
+
class TextRenderable extends TextBufferRenderable {
|
|
18329
|
+
_text;
|
|
18330
|
+
_hasManualStyledText = false;
|
|
18331
|
+
rootTextNode;
|
|
18332
|
+
_contentDefaultOptions = {
|
|
18333
|
+
content: ""
|
|
18334
|
+
};
|
|
18335
|
+
constructor(ctx, options) {
|
|
18336
|
+
super(ctx, options);
|
|
18337
|
+
const content = options.content ?? this._contentDefaultOptions.content;
|
|
18338
|
+
const styledText = typeof content === "string" ? stringToStyledText(content) : content;
|
|
18339
|
+
this._text = styledText;
|
|
18340
|
+
this._hasManualStyledText = options.content !== undefined && content !== "";
|
|
18341
|
+
this.rootTextNode = new RootTextNodeRenderable(ctx, {
|
|
18342
|
+
id: `${this.id}-root`,
|
|
18343
|
+
fg: this._defaultFg,
|
|
18344
|
+
bg: this._defaultBg,
|
|
18345
|
+
attributes: this._defaultAttributes
|
|
18346
|
+
}, this);
|
|
18347
|
+
this.updateTextBuffer(styledText);
|
|
18348
|
+
}
|
|
18349
|
+
updateTextBuffer(styledText) {
|
|
18350
|
+
this.textBuffer.setStyledText(styledText);
|
|
18351
|
+
this.clearChunks(styledText);
|
|
18352
|
+
}
|
|
18353
|
+
clearChunks(styledText) {}
|
|
18354
|
+
get content() {
|
|
18355
|
+
return this._text;
|
|
18356
|
+
}
|
|
18357
|
+
get chunks() {
|
|
18358
|
+
return this._text.chunks;
|
|
18359
|
+
}
|
|
18360
|
+
get textNode() {
|
|
18361
|
+
return this.rootTextNode;
|
|
18362
|
+
}
|
|
18363
|
+
set content(value) {
|
|
18364
|
+
this._hasManualStyledText = true;
|
|
18365
|
+
const styledText = typeof value === "string" ? stringToStyledText(value) : value;
|
|
18366
|
+
if (this._text !== styledText) {
|
|
18367
|
+
this._text = styledText;
|
|
18368
|
+
this.updateTextBuffer(styledText);
|
|
18369
|
+
this.updateTextInfo();
|
|
18370
|
+
}
|
|
18371
|
+
}
|
|
18372
|
+
updateTextFromNodes() {
|
|
18373
|
+
if (this.rootTextNode.isDirty && !this._hasManualStyledText) {
|
|
18374
|
+
const chunks = this.rootTextNode.gatherWithInheritedStyle({
|
|
18375
|
+
fg: this._defaultFg,
|
|
18376
|
+
bg: this._defaultBg,
|
|
18377
|
+
attributes: this._defaultAttributes,
|
|
18378
|
+
link: undefined
|
|
18379
|
+
});
|
|
18380
|
+
this.textBuffer.setStyledText(new StyledText(chunks));
|
|
18381
|
+
this.refreshLocalSelection();
|
|
18382
|
+
this.yogaNode.markDirty();
|
|
18383
|
+
}
|
|
18384
|
+
}
|
|
18385
|
+
add(obj, index) {
|
|
18386
|
+
return this.rootTextNode.add(obj, index);
|
|
18387
|
+
}
|
|
18388
|
+
remove(id) {
|
|
18389
|
+
this.rootTextNode.remove(id);
|
|
18390
|
+
}
|
|
18391
|
+
insertBefore(obj, anchor) {
|
|
18392
|
+
this.rootTextNode.insertBefore(obj, anchor);
|
|
18393
|
+
return this.rootTextNode.children.indexOf(obj);
|
|
18394
|
+
}
|
|
18395
|
+
getTextChildren() {
|
|
18396
|
+
return this.rootTextNode.getChildren();
|
|
18397
|
+
}
|
|
18398
|
+
clear() {
|
|
18399
|
+
this.rootTextNode.clear();
|
|
18400
|
+
const emptyStyledText = stringToStyledText("");
|
|
18401
|
+
this._text = emptyStyledText;
|
|
18402
|
+
this.updateTextBuffer(emptyStyledText);
|
|
18403
|
+
this.updateTextInfo();
|
|
18404
|
+
this.requestRender();
|
|
18405
|
+
}
|
|
18406
|
+
onLifecyclePass = () => {
|
|
18407
|
+
this.updateTextFromNodes();
|
|
18408
|
+
};
|
|
18409
|
+
onFgChanged(newColor) {
|
|
18410
|
+
this.rootTextNode.fg = newColor;
|
|
18411
|
+
}
|
|
18412
|
+
onBgChanged(newColor) {
|
|
18413
|
+
this.rootTextNode.bg = newColor;
|
|
18414
|
+
}
|
|
18415
|
+
onAttributesChanged(newAttributes) {
|
|
18416
|
+
this.rootTextNode.attributes = newAttributes;
|
|
18417
|
+
}
|
|
18418
|
+
destroy() {
|
|
18419
|
+
this.rootTextNode.children.length = 0;
|
|
18420
|
+
super.destroy();
|
|
18421
|
+
}
|
|
18422
|
+
}
|
|
18423
|
+
|
|
18424
|
+
// src/console.ts
|
|
18425
|
+
import { EventEmitter as EventEmitter8 } from "events";
|
|
18426
|
+
import { Console } from "console";
|
|
18427
|
+
import fs from "fs";
|
|
18428
|
+
import path5 from "path";
|
|
18429
|
+
import util2 from "util";
|
|
18430
|
+
|
|
18431
|
+
// src/lib/output.capture.ts
|
|
18432
|
+
import { Writable } from "stream";
|
|
18433
|
+
import { EventEmitter as EventEmitter7 } from "events";
|
|
18434
|
+
|
|
18435
|
+
class Capture extends EventEmitter7 {
|
|
18436
|
+
output = [];
|
|
18437
|
+
constructor() {
|
|
18438
|
+
super();
|
|
18439
|
+
}
|
|
18440
|
+
get size() {
|
|
18441
|
+
return this.output.length;
|
|
18442
|
+
}
|
|
18443
|
+
write(stream, data) {
|
|
18444
|
+
this.output.push({ stream, output: data });
|
|
18445
|
+
this.emit("write", stream, data);
|
|
18446
|
+
}
|
|
18447
|
+
claimOutput() {
|
|
18448
|
+
const output = this.output.map((o) => o.output).join("");
|
|
18449
|
+
this.clear();
|
|
18450
|
+
return output;
|
|
18451
|
+
}
|
|
18452
|
+
clear() {
|
|
18453
|
+
this.output = [];
|
|
18454
|
+
}
|
|
18455
|
+
}
|
|
18456
|
+
|
|
18457
|
+
class CapturedWritableStream extends Writable {
|
|
18458
|
+
stream;
|
|
18459
|
+
capture;
|
|
18460
|
+
isTTY = true;
|
|
18461
|
+
columns = process.stdout.columns || 80;
|
|
18462
|
+
rows = process.stdout.rows || 24;
|
|
18463
|
+
constructor(stream, capture) {
|
|
18464
|
+
super();
|
|
18465
|
+
this.stream = stream;
|
|
18466
|
+
this.capture = capture;
|
|
18467
|
+
}
|
|
18468
|
+
_write(chunk, encoding, callback) {
|
|
18469
|
+
const data = chunk.toString();
|
|
18470
|
+
this.capture.write(this.stream, data);
|
|
18471
|
+
callback();
|
|
16606
18472
|
}
|
|
16607
18473
|
getColorDepth() {
|
|
16608
18474
|
return process.stdout.getColorDepth?.() || 8;
|
|
@@ -18734,6 +20600,27 @@ function getObjectsInViewport(viewport, objects, direction = "column", padding =
|
|
|
18734
20600
|
return visibleChildren;
|
|
18735
20601
|
}
|
|
18736
20602
|
|
|
20603
|
+
// src/lib/render-geometry.ts
|
|
20604
|
+
function calculateRenderGeometry(screenMode, terminalWidth, terminalHeight, footerHeight) {
|
|
20605
|
+
const safeTerminalWidth = Math.max(terminalWidth, 0);
|
|
20606
|
+
const safeTerminalHeight = Math.max(terminalHeight, 0);
|
|
20607
|
+
if (screenMode !== "split-footer") {
|
|
20608
|
+
return {
|
|
20609
|
+
effectiveFooterHeight: 0,
|
|
20610
|
+
renderOffset: 0,
|
|
20611
|
+
renderWidth: safeTerminalWidth,
|
|
20612
|
+
renderHeight: safeTerminalHeight
|
|
20613
|
+
};
|
|
20614
|
+
}
|
|
20615
|
+
const effectiveFooterHeight = Math.min(footerHeight, safeTerminalHeight);
|
|
20616
|
+
return {
|
|
20617
|
+
effectiveFooterHeight,
|
|
20618
|
+
renderOffset: safeTerminalHeight - effectiveFooterHeight,
|
|
20619
|
+
renderWidth: safeTerminalWidth,
|
|
20620
|
+
renderHeight: effectiveFooterHeight
|
|
20621
|
+
};
|
|
20622
|
+
}
|
|
20623
|
+
|
|
18737
20624
|
// src/lib/terminal-capability-detection.ts
|
|
18738
20625
|
function isCapabilityResponse(sequence) {
|
|
18739
20626
|
if (/\x1b\[\?\d+(?:;\d+)*\$y/.test(sequence)) {
|
|
@@ -18767,30 +20654,155 @@ function parsePixelResolution(sequence) {
|
|
|
18767
20654
|
height: parseInt(match[1])
|
|
18768
20655
|
};
|
|
18769
20656
|
}
|
|
18770
|
-
return null;
|
|
20657
|
+
return null;
|
|
20658
|
+
}
|
|
20659
|
+
|
|
20660
|
+
// src/renderer-theme-mode.ts
|
|
20661
|
+
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;
|
|
20662
|
+
function scaleOscThemeComponent(component) {
|
|
20663
|
+
const value = parseInt(component, 16);
|
|
20664
|
+
const maxValue = (1 << 4 * component.length) - 1;
|
|
20665
|
+
return Math.round(value / maxValue * 255).toString(16).padStart(2, "0");
|
|
20666
|
+
}
|
|
20667
|
+
function oscThemeColorToHex(r, g, b, hex6) {
|
|
20668
|
+
if (hex6) {
|
|
20669
|
+
return `#${hex6.toLowerCase()}`;
|
|
20670
|
+
}
|
|
20671
|
+
if (r && g && b) {
|
|
20672
|
+
return `#${scaleOscThemeComponent(r)}${scaleOscThemeComponent(g)}${scaleOscThemeComponent(b)}`;
|
|
20673
|
+
}
|
|
20674
|
+
return "#000000";
|
|
20675
|
+
}
|
|
20676
|
+
function inferThemeModeFromBackgroundColor(color) {
|
|
20677
|
+
const [r, g, b] = parseColor(color).toInts();
|
|
20678
|
+
const brightness = (r * 299 + g * 587 + b * 114) / 1000;
|
|
20679
|
+
return brightness > 128 ? "light" : "dark";
|
|
20680
|
+
}
|
|
20681
|
+
|
|
20682
|
+
class RendererThemeMode {
|
|
20683
|
+
host;
|
|
20684
|
+
clock;
|
|
20685
|
+
static QUERY_TIMEOUT_MS = 250;
|
|
20686
|
+
_themeMode = null;
|
|
20687
|
+
themeQueryPending = true;
|
|
20688
|
+
themeOscForeground = null;
|
|
20689
|
+
themeOscBackground = null;
|
|
20690
|
+
themeRefreshTimeoutId = null;
|
|
20691
|
+
waiters = new Set;
|
|
20692
|
+
constructor(host, clock2) {
|
|
20693
|
+
this.host = host;
|
|
20694
|
+
this.clock = clock2;
|
|
20695
|
+
}
|
|
20696
|
+
get themeMode() {
|
|
20697
|
+
return this._themeMode;
|
|
20698
|
+
}
|
|
20699
|
+
waitForThemeMode(timeoutMs, isDestroyed) {
|
|
20700
|
+
if (this._themeMode !== null || isDestroyed || timeoutMs === 0) {
|
|
20701
|
+
return Promise.resolve(this._themeMode);
|
|
20702
|
+
}
|
|
20703
|
+
return new Promise((resolve4) => {
|
|
20704
|
+
const waiter = {
|
|
20705
|
+
resolve: resolve4,
|
|
20706
|
+
timeoutHandle: null
|
|
20707
|
+
};
|
|
20708
|
+
if (timeoutMs > 0) {
|
|
20709
|
+
waiter.timeoutHandle = this.clock.setTimeout(() => {
|
|
20710
|
+
this.waiters.delete(waiter);
|
|
20711
|
+
waiter.timeoutHandle = null;
|
|
20712
|
+
resolve4(this._themeMode);
|
|
20713
|
+
}, timeoutMs);
|
|
20714
|
+
}
|
|
20715
|
+
this.waiters.add(waiter);
|
|
20716
|
+
});
|
|
20717
|
+
}
|
|
20718
|
+
cancelRefresh() {
|
|
20719
|
+
if (this.themeRefreshTimeoutId === null) {
|
|
20720
|
+
return;
|
|
20721
|
+
}
|
|
20722
|
+
this.clock.clearTimeout(this.themeRefreshTimeoutId);
|
|
20723
|
+
this.themeRefreshTimeoutId = null;
|
|
20724
|
+
this.themeQueryPending = false;
|
|
20725
|
+
}
|
|
20726
|
+
dispose() {
|
|
20727
|
+
this.cancelRefresh();
|
|
20728
|
+
for (const waiter of this.waiters) {
|
|
20729
|
+
if (waiter.timeoutHandle !== null) {
|
|
20730
|
+
this.clock.clearTimeout(waiter.timeoutHandle);
|
|
20731
|
+
}
|
|
20732
|
+
waiter.resolve(this._themeMode);
|
|
20733
|
+
}
|
|
20734
|
+
this.waiters.clear();
|
|
20735
|
+
}
|
|
20736
|
+
handleSequence(sequence) {
|
|
20737
|
+
if (sequence === "\x1B[?997;1n" || sequence === "\x1B[?997;2n") {
|
|
20738
|
+
this.requestThemeOscColors();
|
|
20739
|
+
return { handled: true, changedMode: null };
|
|
20740
|
+
}
|
|
20741
|
+
let handledOscThemeResponse = false;
|
|
20742
|
+
let match;
|
|
20743
|
+
OSC_THEME_RESPONSE.lastIndex = 0;
|
|
20744
|
+
while (match = OSC_THEME_RESPONSE.exec(sequence)) {
|
|
20745
|
+
handledOscThemeResponse = true;
|
|
20746
|
+
const color = oscThemeColorToHex(match[2], match[3], match[4], match[5]);
|
|
20747
|
+
if (match[1] === "10") {
|
|
20748
|
+
this.themeOscForeground = color;
|
|
20749
|
+
} else {
|
|
20750
|
+
this.themeOscBackground = color;
|
|
20751
|
+
}
|
|
20752
|
+
}
|
|
20753
|
+
if (!handledOscThemeResponse) {
|
|
20754
|
+
return { handled: false, changedMode: null };
|
|
20755
|
+
}
|
|
20756
|
+
if (!this.themeQueryPending) {
|
|
20757
|
+
return { handled: true, changedMode: null };
|
|
20758
|
+
}
|
|
20759
|
+
if (!this.themeOscForeground || !this.themeOscBackground) {
|
|
20760
|
+
return { handled: true, changedMode: null };
|
|
20761
|
+
}
|
|
20762
|
+
const nextMode = inferThemeModeFromBackgroundColor(this.themeOscBackground);
|
|
20763
|
+
const changedMode = this.applyThemeMode(nextMode);
|
|
20764
|
+
this.completeThemeQuery();
|
|
20765
|
+
return { handled: true, changedMode };
|
|
20766
|
+
}
|
|
20767
|
+
clearThemeRefreshTimeout() {
|
|
20768
|
+
if (this.themeRefreshTimeoutId === null) {
|
|
20769
|
+
return;
|
|
20770
|
+
}
|
|
20771
|
+
this.clock.clearTimeout(this.themeRefreshTimeoutId);
|
|
20772
|
+
this.themeRefreshTimeoutId = null;
|
|
20773
|
+
}
|
|
20774
|
+
completeThemeQuery() {
|
|
20775
|
+
this.clearThemeRefreshTimeout();
|
|
20776
|
+
this.themeQueryPending = false;
|
|
20777
|
+
}
|
|
20778
|
+
requestThemeOscColors() {
|
|
20779
|
+
this.themeQueryPending = true;
|
|
20780
|
+
this.themeOscForeground = null;
|
|
20781
|
+
this.themeOscBackground = null;
|
|
20782
|
+
this.host.queryThemeColors();
|
|
20783
|
+
this.clearThemeRefreshTimeout();
|
|
20784
|
+
this.themeRefreshTimeoutId = this.clock.setTimeout(() => {
|
|
20785
|
+
this.completeThemeQuery();
|
|
20786
|
+
}, RendererThemeMode.QUERY_TIMEOUT_MS);
|
|
20787
|
+
}
|
|
20788
|
+
applyThemeMode(mode) {
|
|
20789
|
+
const changed = this._themeMode !== mode;
|
|
20790
|
+
this._themeMode = mode;
|
|
20791
|
+
if (!changed) {
|
|
20792
|
+
return null;
|
|
20793
|
+
}
|
|
20794
|
+
for (const waiter of this.waiters) {
|
|
20795
|
+
if (waiter.timeoutHandle !== null) {
|
|
20796
|
+
this.clock.clearTimeout(waiter.timeoutHandle);
|
|
20797
|
+
}
|
|
20798
|
+
waiter.resolve(mode);
|
|
20799
|
+
}
|
|
20800
|
+
this.waiters.clear();
|
|
20801
|
+
return mode;
|
|
20802
|
+
}
|
|
18771
20803
|
}
|
|
18772
20804
|
|
|
18773
20805
|
// src/renderer.ts
|
|
18774
|
-
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;
|
|
18775
|
-
function scaleOscThemeComponent(component) {
|
|
18776
|
-
const value = parseInt(component, 16);
|
|
18777
|
-
const maxValue = (1 << 4 * component.length) - 1;
|
|
18778
|
-
return Math.round(value / maxValue * 255).toString(16).padStart(2, "0");
|
|
18779
|
-
}
|
|
18780
|
-
function oscThemeColorToHex(r, g, b, hex6) {
|
|
18781
|
-
if (hex6) {
|
|
18782
|
-
return `#${hex6.toLowerCase()}`;
|
|
18783
|
-
}
|
|
18784
|
-
if (r && g && b) {
|
|
18785
|
-
return `#${scaleOscThemeComponent(r)}${scaleOscThemeComponent(g)}${scaleOscThemeComponent(b)}`;
|
|
18786
|
-
}
|
|
18787
|
-
return "#000000";
|
|
18788
|
-
}
|
|
18789
|
-
function inferThemeModeFromBackgroundColor(color) {
|
|
18790
|
-
const [r, g, b] = parseColor(color).toInts();
|
|
18791
|
-
const brightness = (r * 299 + g * 587 + b * 114) / 1000;
|
|
18792
|
-
return brightness > 128 ? "light" : "dark";
|
|
18793
|
-
}
|
|
18794
20806
|
registerEnvVar({
|
|
18795
20807
|
name: "OTUI_DUMP_CAPTURES",
|
|
18796
20808
|
description: "Dump captured stdout and console caches when the renderer exit handler runs.",
|
|
@@ -18828,6 +20840,9 @@ registerEnvVar({
|
|
|
18828
20840
|
default: false
|
|
18829
20841
|
});
|
|
18830
20842
|
var DEFAULT_FOOTER_HEIGHT = 12;
|
|
20843
|
+
var MAX_SCROLLBACK_SURFACE_HEIGHT_PASSES = 4;
|
|
20844
|
+
var TRANSPARENT_RGBA = RGBA.fromValues(0, 0, 0, 0);
|
|
20845
|
+
var scrollbackSurfaceCounter = 0;
|
|
18831
20846
|
function normalizeFooterHeight(footerHeight) {
|
|
18832
20847
|
if (footerHeight === undefined) {
|
|
18833
20848
|
return DEFAULT_FOOTER_HEIGHT;
|
|
@@ -18860,6 +20875,101 @@ function resolveModes(config) {
|
|
|
18860
20875
|
externalOutputMode
|
|
18861
20876
|
};
|
|
18862
20877
|
}
|
|
20878
|
+
|
|
20879
|
+
class ExternalOutputQueue {
|
|
20880
|
+
commits = [];
|
|
20881
|
+
get size() {
|
|
20882
|
+
return this.commits.length;
|
|
20883
|
+
}
|
|
20884
|
+
writeSnapshot(commit) {
|
|
20885
|
+
this.commits.push(commit);
|
|
20886
|
+
}
|
|
20887
|
+
claim(limit = Number.POSITIVE_INFINITY) {
|
|
20888
|
+
if (this.commits.length === 0) {
|
|
20889
|
+
return [];
|
|
20890
|
+
}
|
|
20891
|
+
const clampedLimit = Number.isFinite(limit) ? Math.max(1, Math.trunc(limit)) : this.commits.length;
|
|
20892
|
+
if (clampedLimit >= this.commits.length) {
|
|
20893
|
+
const output2 = this.commits;
|
|
20894
|
+
this.commits = [];
|
|
20895
|
+
return output2;
|
|
20896
|
+
}
|
|
20897
|
+
const output = this.commits.slice(0, clampedLimit);
|
|
20898
|
+
this.commits = this.commits.slice(clampedLimit);
|
|
20899
|
+
return output;
|
|
20900
|
+
}
|
|
20901
|
+
clear() {
|
|
20902
|
+
for (const commit of this.commits) {
|
|
20903
|
+
commit.snapshot.destroy();
|
|
20904
|
+
}
|
|
20905
|
+
this.commits = [];
|
|
20906
|
+
}
|
|
20907
|
+
}
|
|
20908
|
+
var CHAR_FLAG_CONTINUATION = 3221225472 >>> 0;
|
|
20909
|
+
var CHAR_FLAG_MASK = 3221225472 >>> 0;
|
|
20910
|
+
|
|
20911
|
+
class ScrollbackSnapshotRenderContext extends EventEmitter9 {
|
|
20912
|
+
width;
|
|
20913
|
+
height;
|
|
20914
|
+
frameId = 0;
|
|
20915
|
+
widthMethod;
|
|
20916
|
+
capabilities = null;
|
|
20917
|
+
hasSelection = false;
|
|
20918
|
+
currentFocusedRenderable = null;
|
|
20919
|
+
keyInput;
|
|
20920
|
+
_internalKeyInput;
|
|
20921
|
+
lifecyclePasses = new Set;
|
|
20922
|
+
constructor(width, height, widthMethod) {
|
|
20923
|
+
super();
|
|
20924
|
+
this.width = width;
|
|
20925
|
+
this.height = height;
|
|
20926
|
+
this.widthMethod = widthMethod;
|
|
20927
|
+
this.keyInput = new KeyHandler;
|
|
20928
|
+
this._internalKeyInput = new InternalKeyHandler;
|
|
20929
|
+
}
|
|
20930
|
+
addToHitGrid(_x, _y, _width, _height, _id) {}
|
|
20931
|
+
pushHitGridScissorRect(_x, _y, _width, _height) {}
|
|
20932
|
+
popHitGridScissorRect() {}
|
|
20933
|
+
clearHitGridScissorRects() {}
|
|
20934
|
+
requestRender() {}
|
|
20935
|
+
setCursorPosition(_x, _y, _visible) {}
|
|
20936
|
+
setCursorStyle(_options) {}
|
|
20937
|
+
setCursorColor(_color) {}
|
|
20938
|
+
setMousePointer(_shape) {}
|
|
20939
|
+
requestLive() {}
|
|
20940
|
+
dropLive() {}
|
|
20941
|
+
getSelection() {
|
|
20942
|
+
return null;
|
|
20943
|
+
}
|
|
20944
|
+
get currentFocusedEditor() {
|
|
20945
|
+
if (!this.currentFocusedRenderable)
|
|
20946
|
+
return null;
|
|
20947
|
+
if (!isEditBufferRenderable(this.currentFocusedRenderable))
|
|
20948
|
+
return null;
|
|
20949
|
+
return this.currentFocusedRenderable;
|
|
20950
|
+
}
|
|
20951
|
+
requestSelectionUpdate() {}
|
|
20952
|
+
focusRenderable(renderable) {
|
|
20953
|
+
this.currentFocusedRenderable = renderable;
|
|
20954
|
+
}
|
|
20955
|
+
blurRenderable(renderable) {
|
|
20956
|
+
if (this.currentFocusedRenderable === renderable) {
|
|
20957
|
+
this.currentFocusedRenderable = null;
|
|
20958
|
+
}
|
|
20959
|
+
}
|
|
20960
|
+
registerLifecyclePass(renderable) {
|
|
20961
|
+
this.lifecyclePasses.add(renderable);
|
|
20962
|
+
}
|
|
20963
|
+
unregisterLifecyclePass(renderable) {
|
|
20964
|
+
this.lifecyclePasses.delete(renderable);
|
|
20965
|
+
}
|
|
20966
|
+
getLifecyclePasses() {
|
|
20967
|
+
return this.lifecyclePasses;
|
|
20968
|
+
}
|
|
20969
|
+
clearSelection() {}
|
|
20970
|
+
startSelection(_renderable, _x, _y) {}
|
|
20971
|
+
updateSelection(_currentRenderable, _x, _y, _options) {}
|
|
20972
|
+
}
|
|
18863
20973
|
var DEFAULT_FORWARDED_ENV_KEYS = [
|
|
18864
20974
|
"TMUX",
|
|
18865
20975
|
"TERM",
|
|
@@ -18980,9 +21090,9 @@ async function createCliRenderer(config = {}) {
|
|
|
18980
21090
|
const { screenMode, footerHeight } = resolveModes(config);
|
|
18981
21091
|
const width = stdout.columns || 80;
|
|
18982
21092
|
const height = stdout.rows || 24;
|
|
18983
|
-
const
|
|
21093
|
+
const geometry = calculateRenderGeometry(screenMode, width, height, footerHeight);
|
|
18984
21094
|
const ziglib = resolveRenderLib();
|
|
18985
|
-
const rendererPtr = ziglib.createRenderer(
|
|
21095
|
+
const rendererPtr = ziglib.createRenderer(geometry.renderWidth, geometry.renderHeight, {
|
|
18986
21096
|
remote: config.remote ?? false,
|
|
18987
21097
|
testing: config.testing ?? false
|
|
18988
21098
|
});
|
|
@@ -19099,6 +21209,8 @@ class CliRenderer extends EventEmitter9 {
|
|
|
19099
21209
|
animationRequest = new Map;
|
|
19100
21210
|
resizeTimeoutId = null;
|
|
19101
21211
|
capabilityTimeoutId = null;
|
|
21212
|
+
splitStartupSeedTimeoutId = null;
|
|
21213
|
+
pendingSplitStartupCursorSeed = false;
|
|
19102
21214
|
resizeDebounceDelay = 100;
|
|
19103
21215
|
enableMouseMovement = false;
|
|
19104
21216
|
_useMouse = true;
|
|
@@ -19106,6 +21218,7 @@ class CliRenderer extends EventEmitter9 {
|
|
|
19106
21218
|
_screenMode = "alternate-screen";
|
|
19107
21219
|
_footerHeight = DEFAULT_FOOTER_HEIGHT;
|
|
19108
21220
|
_externalOutputMode = "passthrough";
|
|
21221
|
+
clearOnShutdown = true;
|
|
19109
21222
|
_suspendedMouseEnabled = false;
|
|
19110
21223
|
_previousControlState = "idle" /* IDLE */;
|
|
19111
21224
|
capturedRenderable;
|
|
@@ -19116,15 +21229,15 @@ class CliRenderer extends EventEmitter9 {
|
|
|
19116
21229
|
clipboard;
|
|
19117
21230
|
_splitHeight = 0;
|
|
19118
21231
|
renderOffset = 0;
|
|
21232
|
+
splitTailColumn = 0;
|
|
21233
|
+
pendingSplitFooterTransition = null;
|
|
21234
|
+
forceFullRepaintRequested = false;
|
|
21235
|
+
maxSplitCommitsPerFrame = 8;
|
|
19119
21236
|
_terminalWidth = 0;
|
|
19120
21237
|
_terminalHeight = 0;
|
|
19121
21238
|
_terminalIsSetup = false;
|
|
21239
|
+
externalOutputQueue = new ExternalOutputQueue;
|
|
19122
21240
|
realStdoutWrite;
|
|
19123
|
-
captureCallback = () => {
|
|
19124
|
-
if (this._splitHeight > 0) {
|
|
19125
|
-
this.requestRender();
|
|
19126
|
-
}
|
|
19127
|
-
};
|
|
19128
21241
|
_useConsole = true;
|
|
19129
21242
|
sigwinchHandler = (() => {
|
|
19130
21243
|
const width = this.stdout.columns || 80;
|
|
@@ -19144,18 +21257,20 @@ class CliRenderer extends EventEmitter9 {
|
|
|
19144
21257
|
lifecyclePasses = new Set;
|
|
19145
21258
|
_openConsoleOnError = true;
|
|
19146
21259
|
_paletteDetector = null;
|
|
21260
|
+
_paletteCache = new Map;
|
|
19147
21261
|
_cachedPalette = null;
|
|
19148
21262
|
_paletteDetectionPromise = null;
|
|
21263
|
+
_paletteDetectionSize = 0;
|
|
21264
|
+
_paletteEpoch = 0;
|
|
21265
|
+
_publishedPaletteSignature = null;
|
|
21266
|
+
_palettePublishGeneration = 0;
|
|
19149
21267
|
_onDestroy;
|
|
19150
|
-
|
|
19151
|
-
_themeModeSource = "none";
|
|
19152
|
-
_themeFallbackPending = true;
|
|
19153
|
-
_themeOscForeground = null;
|
|
19154
|
-
_themeOscBackground = null;
|
|
21268
|
+
themeModeState;
|
|
19155
21269
|
_terminalFocusState = null;
|
|
19156
21270
|
sequenceHandlers = [];
|
|
19157
21271
|
prependedInputHandlers = [];
|
|
19158
21272
|
shouldRestoreModesOnNextFocus = false;
|
|
21273
|
+
themeModeHandler;
|
|
19159
21274
|
idleResolvers = [];
|
|
19160
21275
|
_debugInputs = [];
|
|
19161
21276
|
_debugModeEnabled = env.OTUI_DEBUG;
|
|
@@ -19167,8 +21282,15 @@ class CliRenderer extends EventEmitter9 {
|
|
|
19167
21282
|
}).bind(this);
|
|
19168
21283
|
dumpOutputCache(optionalMessage = "") {
|
|
19169
21284
|
const cachedLogs = this.console.getCachedLogs();
|
|
19170
|
-
const
|
|
19171
|
-
|
|
21285
|
+
const capturedConsoleOutput = capture.claimOutput();
|
|
21286
|
+
const capturedExternalOutputCommits = this.externalOutputQueue.claim();
|
|
21287
|
+
let capturedExternalOutput = "";
|
|
21288
|
+
for (const commit of capturedExternalOutputCommits) {
|
|
21289
|
+
capturedExternalOutput += `[snapshot ${commit.snapshot.width}x${commit.snapshot.height}]
|
|
21290
|
+
`;
|
|
21291
|
+
commit.snapshot.destroy();
|
|
21292
|
+
}
|
|
21293
|
+
if (capturedConsoleOutput.length > 0 || capturedExternalOutput.length > 0 || cachedLogs.length > 0) {
|
|
19172
21294
|
this.realStdoutWrite.call(this.stdout, optionalMessage);
|
|
19173
21295
|
}
|
|
19174
21296
|
if (cachedLogs.length > 0) {
|
|
@@ -19176,11 +21298,18 @@ class CliRenderer extends EventEmitter9 {
|
|
|
19176
21298
|
`);
|
|
19177
21299
|
this.realStdoutWrite.call(this.stdout, cachedLogs);
|
|
19178
21300
|
}
|
|
19179
|
-
if (
|
|
21301
|
+
if (capturedConsoleOutput.length > 0) {
|
|
21302
|
+
this.realStdoutWrite.call(this.stdout, `
|
|
21303
|
+
Captured console output:
|
|
21304
|
+
`);
|
|
21305
|
+
this.realStdoutWrite.call(this.stdout, capturedConsoleOutput + `
|
|
21306
|
+
`);
|
|
21307
|
+
}
|
|
21308
|
+
if (capturedExternalOutput.length > 0) {
|
|
19180
21309
|
this.realStdoutWrite.call(this.stdout, `
|
|
19181
|
-
Captured output:
|
|
21310
|
+
Captured external output:
|
|
19182
21311
|
`);
|
|
19183
|
-
this.realStdoutWrite.call(this.stdout,
|
|
21312
|
+
this.realStdoutWrite.call(this.stdout, capturedExternalOutput + `
|
|
19184
21313
|
`);
|
|
19185
21314
|
}
|
|
19186
21315
|
this.realStdoutWrite.call(this.stdout, ANSI.reset);
|
|
@@ -19209,14 +21338,19 @@ Captured output:
|
|
|
19209
21338
|
this.lib = lib;
|
|
19210
21339
|
this._terminalWidth = stdout.columns ?? width;
|
|
19211
21340
|
this._terminalHeight = stdout.rows ?? height;
|
|
19212
|
-
this.width = width;
|
|
19213
|
-
this.height = height;
|
|
19214
21341
|
this._useThread = config.useThread === undefined ? false : config.useThread;
|
|
19215
21342
|
const { screenMode, footerHeight, externalOutputMode } = resolveModes(config);
|
|
21343
|
+
this._externalOutputMode = externalOutputMode;
|
|
21344
|
+
const initialGeometry = calculateRenderGeometry(screenMode, this._terminalWidth, this._terminalHeight, footerHeight);
|
|
21345
|
+
this.width = initialGeometry.renderWidth;
|
|
21346
|
+
this.height = initialGeometry.renderHeight;
|
|
21347
|
+
this._splitHeight = initialGeometry.effectiveFooterHeight;
|
|
21348
|
+
this.renderOffset = screenMode === "split-footer" ? 0 : initialGeometry.renderOffset;
|
|
19216
21349
|
this._footerHeight = footerHeight;
|
|
19217
|
-
this._screenMode = screenMode;
|
|
19218
21350
|
this.rendererPtr = rendererPtr;
|
|
19219
|
-
|
|
21351
|
+
this.clearOnShutdown = config.clearOnShutdown ?? true;
|
|
21352
|
+
this.lib.setClearOnShutdown(this.rendererPtr, this.clearOnShutdown);
|
|
21353
|
+
const forwardEnvKeys = config.forwardEnvKeys ?? (config.remote ? [] : [...DEFAULT_FORWARDED_ENV_KEYS]);
|
|
19220
21354
|
for (const key of forwardEnvKeys) {
|
|
19221
21355
|
const value = process.env[key];
|
|
19222
21356
|
if (value === undefined)
|
|
@@ -19239,6 +21373,18 @@ Captured output:
|
|
|
19239
21373
|
this.targetFps = config.targetFps || 30;
|
|
19240
21374
|
this.maxFps = config.maxFps || 60;
|
|
19241
21375
|
this.clock = config.clock ?? new SystemClock;
|
|
21376
|
+
this.themeModeState = new RendererThemeMode({
|
|
21377
|
+
queryThemeColors: () => {
|
|
21378
|
+
this.lib.queryThemeColors(this.rendererPtr);
|
|
21379
|
+
}
|
|
21380
|
+
}, this.clock);
|
|
21381
|
+
this.themeModeHandler = (sequence) => {
|
|
21382
|
+
const result = this.themeModeState.handleSequence(sequence);
|
|
21383
|
+
if (result.changedMode) {
|
|
21384
|
+
this.emit("theme_mode" /* THEME_MODE */, result.changedMode);
|
|
21385
|
+
}
|
|
21386
|
+
return result.handled;
|
|
21387
|
+
};
|
|
19242
21388
|
this.memorySnapshotInterval = config.memorySnapshotInterval ?? 0;
|
|
19243
21389
|
this.gatherStats = config.gatherStats || false;
|
|
19244
21390
|
this.maxStatSamples = config.maxStatSamples || 300;
|
|
@@ -19283,7 +21429,8 @@ Captured output:
|
|
|
19283
21429
|
kittyKeyboardEnabled: useKittyForParsing,
|
|
19284
21430
|
privateCapabilityRepliesActive: false,
|
|
19285
21431
|
pixelResolutionQueryActive: false,
|
|
19286
|
-
explicitWidthCprActive: false
|
|
21432
|
+
explicitWidthCprActive: false,
|
|
21433
|
+
startupCursorCprActive: false
|
|
19287
21434
|
},
|
|
19288
21435
|
clock: this.clock
|
|
19289
21436
|
});
|
|
@@ -19293,7 +21440,7 @@ Captured output:
|
|
|
19293
21440
|
});
|
|
19294
21441
|
this.consoleMode = config.consoleMode ?? "console-overlay";
|
|
19295
21442
|
this.applyScreenMode(screenMode, false, false);
|
|
19296
|
-
this.
|
|
21443
|
+
this.stdout.write = externalOutputMode === "capture-stdout" ? this.interceptStdoutWrite : this.realStdoutWrite;
|
|
19297
21444
|
this._openConsoleOnError = config.openConsoleOnError ?? true;
|
|
19298
21445
|
this._onDestroy = config.onDestroy;
|
|
19299
21446
|
global.requestAnimationFrame = (callback) => {
|
|
@@ -19520,127 +21667,701 @@ Captured output:
|
|
|
19520
21667
|
this._targetFps = targetFps;
|
|
19521
21668
|
this.targetFrameTime = 1000 / this._targetFps;
|
|
19522
21669
|
}
|
|
19523
|
-
get maxFps() {
|
|
19524
|
-
return this._maxFps;
|
|
21670
|
+
get maxFps() {
|
|
21671
|
+
return this._maxFps;
|
|
21672
|
+
}
|
|
21673
|
+
set maxFps(maxFps) {
|
|
21674
|
+
this._maxFps = maxFps;
|
|
21675
|
+
this.minTargetFrameTime = 1000 / this._maxFps;
|
|
21676
|
+
}
|
|
21677
|
+
get useMouse() {
|
|
21678
|
+
return this._useMouse;
|
|
21679
|
+
}
|
|
21680
|
+
set useMouse(useMouse) {
|
|
21681
|
+
if (this._useMouse === useMouse)
|
|
21682
|
+
return;
|
|
21683
|
+
this._useMouse = useMouse;
|
|
21684
|
+
if (useMouse) {
|
|
21685
|
+
this.enableMouse();
|
|
21686
|
+
} else {
|
|
21687
|
+
this.disableMouse();
|
|
21688
|
+
}
|
|
21689
|
+
}
|
|
21690
|
+
get screenMode() {
|
|
21691
|
+
return this._screenMode;
|
|
21692
|
+
}
|
|
21693
|
+
set screenMode(mode) {
|
|
21694
|
+
if (this.externalOutputMode === "capture-stdout" && mode !== "split-footer") {
|
|
21695
|
+
throw new Error('externalOutputMode "capture-stdout" requires screenMode "split-footer"');
|
|
21696
|
+
}
|
|
21697
|
+
this.applyScreenMode(mode);
|
|
21698
|
+
}
|
|
21699
|
+
get footerHeight() {
|
|
21700
|
+
return this._footerHeight;
|
|
21701
|
+
}
|
|
21702
|
+
set footerHeight(footerHeight) {
|
|
21703
|
+
const normalizedFooterHeight = normalizeFooterHeight(footerHeight);
|
|
21704
|
+
if (normalizedFooterHeight === this._footerHeight) {
|
|
21705
|
+
return;
|
|
21706
|
+
}
|
|
21707
|
+
this._footerHeight = normalizedFooterHeight;
|
|
21708
|
+
if (this.screenMode === "split-footer") {
|
|
21709
|
+
this.applyScreenMode("split-footer");
|
|
21710
|
+
}
|
|
21711
|
+
}
|
|
21712
|
+
get externalOutputMode() {
|
|
21713
|
+
return this._externalOutputMode;
|
|
21714
|
+
}
|
|
21715
|
+
set externalOutputMode(mode) {
|
|
21716
|
+
if (mode === "capture-stdout" && this.screenMode !== "split-footer") {
|
|
21717
|
+
throw new Error('externalOutputMode "capture-stdout" requires screenMode "split-footer"');
|
|
21718
|
+
}
|
|
21719
|
+
const previousMode = this._externalOutputMode;
|
|
21720
|
+
if (previousMode === mode) {
|
|
21721
|
+
return;
|
|
21722
|
+
}
|
|
21723
|
+
if (previousMode === "capture-stdout" && mode === "passthrough" && this._splitHeight > 0) {
|
|
21724
|
+
this.flushPendingSplitOutputBeforeTransition();
|
|
21725
|
+
}
|
|
21726
|
+
this._externalOutputMode = mode;
|
|
21727
|
+
this.stdout.write = mode === "capture-stdout" ? this.interceptStdoutWrite : this.realStdoutWrite;
|
|
21728
|
+
if (this._screenMode === "split-footer" && this._splitHeight > 0 && mode === "capture-stdout") {
|
|
21729
|
+
this.clearPendingSplitFooterTransition();
|
|
21730
|
+
this.resetSplitScrollback(this.getSplitCursorSeedRows());
|
|
21731
|
+
return;
|
|
21732
|
+
}
|
|
21733
|
+
if (this._screenMode === "split-footer" && this._splitHeight > 0 && previousMode === "capture-stdout" && mode === "passthrough") {
|
|
21734
|
+
this.clearPendingSplitFooterTransition();
|
|
21735
|
+
return;
|
|
21736
|
+
}
|
|
21737
|
+
this.syncSplitFooterState();
|
|
21738
|
+
}
|
|
21739
|
+
get liveRequestCount() {
|
|
21740
|
+
return this.liveRequestCounter;
|
|
21741
|
+
}
|
|
21742
|
+
get currentControlState() {
|
|
21743
|
+
return this._controlState;
|
|
21744
|
+
}
|
|
21745
|
+
get capabilities() {
|
|
21746
|
+
return this._capabilities;
|
|
21747
|
+
}
|
|
21748
|
+
get themeMode() {
|
|
21749
|
+
return this.themeModeState.themeMode;
|
|
21750
|
+
}
|
|
21751
|
+
waitForThemeMode(timeoutMs = 1000) {
|
|
21752
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
|
|
21753
|
+
throw new Error("timeoutMs must be a non-negative finite number");
|
|
21754
|
+
}
|
|
21755
|
+
return this.themeModeState.waitForThemeMode(timeoutMs, this._isDestroyed);
|
|
21756
|
+
}
|
|
21757
|
+
getDebugInputs() {
|
|
21758
|
+
return [...this._debugInputs];
|
|
21759
|
+
}
|
|
21760
|
+
get useKittyKeyboard() {
|
|
21761
|
+
return this.lib.getKittyKeyboardFlags(this.rendererPtr) > 0;
|
|
21762
|
+
}
|
|
21763
|
+
set useKittyKeyboard(use) {
|
|
21764
|
+
const flags = use ? KITTY_FLAG_DISAMBIGUATE | KITTY_FLAG_ALTERNATE_KEYS : 0;
|
|
21765
|
+
this.lib.setKittyKeyboardFlags(this.rendererPtr, flags);
|
|
21766
|
+
}
|
|
21767
|
+
createScrollbackSurface(options = {}) {
|
|
21768
|
+
if (this._screenMode !== "split-footer" || this._externalOutputMode !== "capture-stdout") {
|
|
21769
|
+
throw new Error('createScrollbackSurface requires screenMode "split-footer" and externalOutputMode "capture-stdout"');
|
|
21770
|
+
}
|
|
21771
|
+
const renderer = this;
|
|
21772
|
+
const surfaceId = scrollbackSurfaceCounter++;
|
|
21773
|
+
const startOnNewLine = options.startOnNewLine ?? true;
|
|
21774
|
+
const firstLineOffset = !startOnNewLine && renderer.splitTailColumn > 0 && renderer.splitTailColumn < renderer.width ? renderer.splitTailColumn : 0;
|
|
21775
|
+
const snapshotContext = new ScrollbackSnapshotRenderContext(renderer.width, 1, renderer.widthMethod);
|
|
21776
|
+
let firstLineOffsetOwner = null;
|
|
21777
|
+
const renderContext = Object.create(snapshotContext);
|
|
21778
|
+
Object.defineProperty(renderContext, "claimFirstLineOffset", {
|
|
21779
|
+
value: (renderable) => {
|
|
21780
|
+
if (firstLineOffsetOwner?.isDestroyed) {
|
|
21781
|
+
firstLineOffsetOwner = null;
|
|
21782
|
+
}
|
|
21783
|
+
if (firstLineOffsetOwner) {
|
|
21784
|
+
return 0;
|
|
21785
|
+
}
|
|
21786
|
+
firstLineOffsetOwner = renderable ?? null;
|
|
21787
|
+
return firstLineOffset;
|
|
21788
|
+
},
|
|
21789
|
+
enumerable: true,
|
|
21790
|
+
configurable: true
|
|
21791
|
+
});
|
|
21792
|
+
const internalRoot = new RootRenderable(renderContext);
|
|
21793
|
+
const publicRoot = new BoxRenderable(renderContext, {
|
|
21794
|
+
id: `scrollback-surface-root-${surfaceId}`,
|
|
21795
|
+
position: "absolute",
|
|
21796
|
+
left: 0,
|
|
21797
|
+
top: 0,
|
|
21798
|
+
width: renderer.width,
|
|
21799
|
+
height: "auto",
|
|
21800
|
+
border: false,
|
|
21801
|
+
backgroundColor: "transparent",
|
|
21802
|
+
shouldFill: false,
|
|
21803
|
+
flexDirection: "column"
|
|
21804
|
+
});
|
|
21805
|
+
internalRoot.add(publicRoot);
|
|
21806
|
+
let surfaceWidth = renderer.width;
|
|
21807
|
+
let surfaceHeight = 1;
|
|
21808
|
+
let surfaceWidthMethod = renderer.widthMethod;
|
|
21809
|
+
let surfaceDestroyed = false;
|
|
21810
|
+
let hasRendered = false;
|
|
21811
|
+
let nextCommitStartOnNewLine = startOnNewLine;
|
|
21812
|
+
let backingBuffer = OptimizedBuffer.create(surfaceWidth, surfaceHeight, surfaceWidthMethod, {
|
|
21813
|
+
id: `scrollback-surface-buffer-${surfaceId}`
|
|
21814
|
+
});
|
|
21815
|
+
const destroyListener = () => {
|
|
21816
|
+
destroySurface();
|
|
21817
|
+
};
|
|
21818
|
+
const assertNotDestroyed = () => {
|
|
21819
|
+
if (surfaceDestroyed) {
|
|
21820
|
+
throw new Error("ScrollbackSurface is destroyed");
|
|
21821
|
+
}
|
|
21822
|
+
};
|
|
21823
|
+
const assertRendered = () => {
|
|
21824
|
+
if (!hasRendered) {
|
|
21825
|
+
throw new Error("ScrollbackSurface.commitRows requires render() before commitRows()");
|
|
21826
|
+
}
|
|
21827
|
+
};
|
|
21828
|
+
const assertGeometryStillCurrent = () => {
|
|
21829
|
+
if (renderer.width !== surfaceWidth || renderer.widthMethod !== surfaceWidthMethod) {
|
|
21830
|
+
throw new Error("ScrollbackSurface.commitRows requires render() after renderer geometry changes");
|
|
21831
|
+
}
|
|
21832
|
+
};
|
|
21833
|
+
const assertRowRange = (startRow, endRowExclusive) => {
|
|
21834
|
+
if (!Number.isInteger(startRow) || !Number.isInteger(endRowExclusive)) {
|
|
21835
|
+
throw new Error("ScrollbackSurface.commitRows requires finite integer row bounds");
|
|
21836
|
+
}
|
|
21837
|
+
if (startRow < 0) {
|
|
21838
|
+
throw new Error("ScrollbackSurface.commitRows requires startRow >= 0");
|
|
21839
|
+
}
|
|
21840
|
+
if (endRowExclusive < startRow) {
|
|
21841
|
+
throw new Error("ScrollbackSurface.commitRows requires endRowExclusive >= startRow");
|
|
21842
|
+
}
|
|
21843
|
+
if (endRowExclusive > surfaceHeight) {
|
|
21844
|
+
throw new Error("ScrollbackSurface.commitRows row range exceeds rendered surface height");
|
|
21845
|
+
}
|
|
21846
|
+
};
|
|
21847
|
+
const collectPendingCodeRenderables = (node) => {
|
|
21848
|
+
const pending = [];
|
|
21849
|
+
if (node instanceof CodeRenderable && node.isHighlighting) {
|
|
21850
|
+
pending.push(node);
|
|
21851
|
+
}
|
|
21852
|
+
for (const child of node.getChildren()) {
|
|
21853
|
+
pending.push(...collectPendingCodeRenderables(child));
|
|
21854
|
+
}
|
|
21855
|
+
return pending;
|
|
21856
|
+
};
|
|
21857
|
+
const waitForPendingHighlights = async (pending, timeoutMs) => {
|
|
21858
|
+
await new Promise((resolve4, reject) => {
|
|
21859
|
+
let settled = false;
|
|
21860
|
+
const timeoutHandle = renderer.clock.setTimeout(() => {
|
|
21861
|
+
if (settled) {
|
|
21862
|
+
return;
|
|
21863
|
+
}
|
|
21864
|
+
settled = true;
|
|
21865
|
+
reject(new Error("ScrollbackSurface.settle timed out waiting for CodeRenderable highlighting"));
|
|
21866
|
+
}, timeoutMs);
|
|
21867
|
+
Promise.all(pending.map((renderable) => renderable.highlightingDone)).then(() => {
|
|
21868
|
+
if (settled) {
|
|
21869
|
+
return;
|
|
21870
|
+
}
|
|
21871
|
+
settled = true;
|
|
21872
|
+
renderer.clock.clearTimeout(timeoutHandle);
|
|
21873
|
+
resolve4();
|
|
21874
|
+
}, (error) => {
|
|
21875
|
+
if (settled) {
|
|
21876
|
+
return;
|
|
21877
|
+
}
|
|
21878
|
+
settled = true;
|
|
21879
|
+
renderer.clock.clearTimeout(timeoutHandle);
|
|
21880
|
+
reject(error);
|
|
21881
|
+
});
|
|
21882
|
+
});
|
|
21883
|
+
};
|
|
21884
|
+
const renderSurface = () => {
|
|
21885
|
+
assertNotDestroyed();
|
|
21886
|
+
const width = renderer.width;
|
|
21887
|
+
const widthMethod = renderer.widthMethod;
|
|
21888
|
+
snapshotContext.width = width;
|
|
21889
|
+
snapshotContext.widthMethod = widthMethod;
|
|
21890
|
+
publicRoot.width = width;
|
|
21891
|
+
const renderPass = (height) => {
|
|
21892
|
+
snapshotContext.height = height;
|
|
21893
|
+
internalRoot.resize(width, height);
|
|
21894
|
+
backingBuffer.resize(width, height);
|
|
21895
|
+
backingBuffer.clear(TRANSPARENT_RGBA);
|
|
21896
|
+
snapshotContext.frameId += 1;
|
|
21897
|
+
internalRoot.render(backingBuffer, 0);
|
|
21898
|
+
};
|
|
21899
|
+
let targetHeight = Math.max(1, surfaceHeight);
|
|
21900
|
+
if (surfaceWidthMethod !== widthMethod) {
|
|
21901
|
+
backingBuffer.destroy();
|
|
21902
|
+
backingBuffer = OptimizedBuffer.create(width, targetHeight, widthMethod, {
|
|
21903
|
+
id: `scrollback-surface-buffer-${surfaceId}`
|
|
21904
|
+
});
|
|
21905
|
+
} else {
|
|
21906
|
+
backingBuffer.resize(width, targetHeight);
|
|
21907
|
+
}
|
|
21908
|
+
for (let pass = 0;pass < MAX_SCROLLBACK_SURFACE_HEIGHT_PASSES; pass += 1) {
|
|
21909
|
+
renderPass(targetHeight);
|
|
21910
|
+
const measuredHeight = Math.max(1, publicRoot.height);
|
|
21911
|
+
if (measuredHeight === targetHeight) {
|
|
21912
|
+
surfaceWidth = width;
|
|
21913
|
+
surfaceHeight = measuredHeight;
|
|
21914
|
+
surfaceWidthMethod = widthMethod;
|
|
21915
|
+
hasRendered = true;
|
|
21916
|
+
return;
|
|
21917
|
+
}
|
|
21918
|
+
targetHeight = measuredHeight;
|
|
21919
|
+
}
|
|
21920
|
+
renderPass(targetHeight);
|
|
21921
|
+
surfaceWidth = width;
|
|
21922
|
+
surfaceHeight = targetHeight;
|
|
21923
|
+
surfaceWidthMethod = widthMethod;
|
|
21924
|
+
hasRendered = true;
|
|
21925
|
+
};
|
|
21926
|
+
const settleSurface = async (timeoutMs = 2000) => {
|
|
21927
|
+
assertNotDestroyed();
|
|
21928
|
+
const startedAt = renderer.clock.now();
|
|
21929
|
+
renderSurface();
|
|
21930
|
+
while (true) {
|
|
21931
|
+
assertNotDestroyed();
|
|
21932
|
+
const pending = collectPendingCodeRenderables(publicRoot);
|
|
21933
|
+
if (pending.length === 0) {
|
|
21934
|
+
return;
|
|
21935
|
+
}
|
|
21936
|
+
const remainingMs = timeoutMs - (renderer.clock.now() - startedAt);
|
|
21937
|
+
if (remainingMs <= 0) {
|
|
21938
|
+
throw new Error("ScrollbackSurface.settle timed out waiting for CodeRenderable highlighting");
|
|
21939
|
+
}
|
|
21940
|
+
await waitForPendingHighlights(pending, remainingMs);
|
|
21941
|
+
assertNotDestroyed();
|
|
21942
|
+
renderSurface();
|
|
21943
|
+
}
|
|
21944
|
+
};
|
|
21945
|
+
const commitRows = (startRow, endRowExclusive, commitOptions = {}) => {
|
|
21946
|
+
assertNotDestroyed();
|
|
21947
|
+
assertRendered();
|
|
21948
|
+
assertGeometryStillCurrent();
|
|
21949
|
+
assertRowRange(startRow, endRowExclusive);
|
|
21950
|
+
if (startRow === endRowExclusive) {
|
|
21951
|
+
return;
|
|
21952
|
+
}
|
|
21953
|
+
const rowCount = endRowExclusive - startRow;
|
|
21954
|
+
const commitBuffer = OptimizedBuffer.create(surfaceWidth, rowCount, surfaceWidthMethod, {
|
|
21955
|
+
id: `scrollback-surface-commit-${surfaceId}`
|
|
21956
|
+
});
|
|
21957
|
+
try {
|
|
21958
|
+
commitBuffer.drawFrameBuffer(0, 0, backingBuffer, 0, startRow, surfaceWidth, rowCount);
|
|
21959
|
+
renderer.enqueueRenderedScrollbackCommit({
|
|
21960
|
+
snapshot: commitBuffer,
|
|
21961
|
+
rowColumns: commitOptions.rowColumns,
|
|
21962
|
+
startOnNewLine: nextCommitStartOnNewLine,
|
|
21963
|
+
trailingNewline: commitOptions.trailingNewline ?? false
|
|
21964
|
+
});
|
|
21965
|
+
nextCommitStartOnNewLine = false;
|
|
21966
|
+
} catch (error) {
|
|
21967
|
+
commitBuffer.destroy();
|
|
21968
|
+
throw error;
|
|
21969
|
+
}
|
|
21970
|
+
};
|
|
21971
|
+
const destroySurface = () => {
|
|
21972
|
+
if (surfaceDestroyed) {
|
|
21973
|
+
return;
|
|
21974
|
+
}
|
|
21975
|
+
surfaceDestroyed = true;
|
|
21976
|
+
renderer.off("destroy" /* DESTROY */, destroyListener);
|
|
21977
|
+
let destroyError = null;
|
|
21978
|
+
try {
|
|
21979
|
+
internalRoot.destroyRecursively();
|
|
21980
|
+
} catch (error) {
|
|
21981
|
+
destroyError = error;
|
|
21982
|
+
}
|
|
21983
|
+
try {
|
|
21984
|
+
backingBuffer.destroy();
|
|
21985
|
+
} catch (error) {
|
|
21986
|
+
if (destroyError === null) {
|
|
21987
|
+
destroyError = error;
|
|
21988
|
+
}
|
|
21989
|
+
}
|
|
21990
|
+
renderContext.removeAllListeners();
|
|
21991
|
+
snapshotContext.removeAllListeners();
|
|
21992
|
+
if (destroyError !== null) {
|
|
21993
|
+
throw destroyError;
|
|
21994
|
+
}
|
|
21995
|
+
};
|
|
21996
|
+
renderer.on("destroy" /* DESTROY */, destroyListener);
|
|
21997
|
+
return {
|
|
21998
|
+
get renderContext() {
|
|
21999
|
+
return renderContext;
|
|
22000
|
+
},
|
|
22001
|
+
get root() {
|
|
22002
|
+
return publicRoot;
|
|
22003
|
+
},
|
|
22004
|
+
get width() {
|
|
22005
|
+
return surfaceWidth;
|
|
22006
|
+
},
|
|
22007
|
+
get height() {
|
|
22008
|
+
return surfaceHeight;
|
|
22009
|
+
},
|
|
22010
|
+
get isDestroyed() {
|
|
22011
|
+
return surfaceDestroyed;
|
|
22012
|
+
},
|
|
22013
|
+
render: renderSurface,
|
|
22014
|
+
settle: settleSurface,
|
|
22015
|
+
commitRows,
|
|
22016
|
+
destroy: destroySurface
|
|
22017
|
+
};
|
|
22018
|
+
}
|
|
22019
|
+
writeToScrollback(write) {
|
|
22020
|
+
if (this._screenMode !== "split-footer" || this._externalOutputMode !== "capture-stdout") {
|
|
22021
|
+
throw new Error('writeToScrollback requires screenMode "split-footer" and externalOutputMode "capture-stdout"');
|
|
22022
|
+
}
|
|
22023
|
+
const snapshotContext = new ScrollbackSnapshotRenderContext(this.width, this.height, this.widthMethod);
|
|
22024
|
+
const snapshot = write({
|
|
22025
|
+
width: this.width,
|
|
22026
|
+
widthMethod: this.widthMethod,
|
|
22027
|
+
tailColumn: this.splitTailColumn,
|
|
22028
|
+
renderContext: snapshotContext
|
|
22029
|
+
});
|
|
22030
|
+
if (!snapshot || !snapshot.root) {
|
|
22031
|
+
throw new Error("writeToScrollback must return a snapshot root renderable");
|
|
22032
|
+
}
|
|
22033
|
+
let renderFailed = false;
|
|
22034
|
+
let snapshotRoot = null;
|
|
22035
|
+
let snapshotBuffer = null;
|
|
22036
|
+
try {
|
|
22037
|
+
const rootRenderable = snapshot.root;
|
|
22038
|
+
const snapshotWidth = this.getSnapshotWidth(snapshot.width, rootRenderable.width);
|
|
22039
|
+
const snapshotHeight = this.getSnapshotHeight(snapshot.height, rootRenderable.height);
|
|
22040
|
+
snapshotContext.width = snapshotWidth;
|
|
22041
|
+
snapshotContext.height = snapshotHeight;
|
|
22042
|
+
snapshotContext.widthMethod = this.widthMethod;
|
|
22043
|
+
snapshotRoot = new RootRenderable(snapshotContext);
|
|
22044
|
+
snapshotBuffer = OptimizedBuffer.create(snapshotWidth, snapshotHeight, this.widthMethod, {
|
|
22045
|
+
id: "scrollback-snapshot-commit"
|
|
22046
|
+
});
|
|
22047
|
+
snapshotRoot.add(rootRenderable);
|
|
22048
|
+
snapshotRoot.render(snapshotBuffer, 0);
|
|
22049
|
+
this.enqueueRenderedScrollbackCommit({
|
|
22050
|
+
snapshot: snapshotBuffer,
|
|
22051
|
+
rowColumns: snapshot.rowColumns,
|
|
22052
|
+
startOnNewLine: snapshot.startOnNewLine,
|
|
22053
|
+
trailingNewline: snapshot.trailingNewline
|
|
22054
|
+
});
|
|
22055
|
+
} catch (error) {
|
|
22056
|
+
renderFailed = true;
|
|
22057
|
+
snapshotBuffer?.destroy();
|
|
22058
|
+
throw error;
|
|
22059
|
+
} finally {
|
|
22060
|
+
let cleanupError = null;
|
|
22061
|
+
try {
|
|
22062
|
+
if (snapshotRoot) {
|
|
22063
|
+
snapshotRoot.destroyRecursively();
|
|
22064
|
+
} else {
|
|
22065
|
+
snapshot.root.destroyRecursively();
|
|
22066
|
+
}
|
|
22067
|
+
} catch (error) {
|
|
22068
|
+
cleanupError = error;
|
|
22069
|
+
}
|
|
22070
|
+
try {
|
|
22071
|
+
snapshot.teardown?.();
|
|
22072
|
+
} catch (error) {
|
|
22073
|
+
if (cleanupError === null) {
|
|
22074
|
+
cleanupError = error;
|
|
22075
|
+
}
|
|
22076
|
+
}
|
|
22077
|
+
if (!renderFailed && cleanupError) {
|
|
22078
|
+
throw cleanupError;
|
|
22079
|
+
}
|
|
22080
|
+
}
|
|
22081
|
+
}
|
|
22082
|
+
getSnapshotWidth(value, fallback) {
|
|
22083
|
+
const rawValue = value ?? fallback;
|
|
22084
|
+
if (!Number.isFinite(rawValue)) {
|
|
22085
|
+
throw new Error("writeToScrollback produced a non-finite width");
|
|
22086
|
+
}
|
|
22087
|
+
return Math.min(Math.max(Math.trunc(rawValue), 1), Math.max(this.width, 1));
|
|
19525
22088
|
}
|
|
19526
|
-
|
|
19527
|
-
|
|
19528
|
-
|
|
22089
|
+
getSnapshotHeight(value, fallback) {
|
|
22090
|
+
const rawValue = value ?? fallback;
|
|
22091
|
+
if (!Number.isFinite(rawValue)) {
|
|
22092
|
+
throw new Error("writeToScrollback produced a non-finite height");
|
|
22093
|
+
}
|
|
22094
|
+
return Math.max(Math.trunc(rawValue), 1);
|
|
19529
22095
|
}
|
|
19530
|
-
|
|
19531
|
-
|
|
22096
|
+
getSnapshotRowWidths(snapshot, rowColumns) {
|
|
22097
|
+
const widths = [];
|
|
22098
|
+
const limit = Math.min(Math.max(Math.trunc(rowColumns), 0), snapshot.width);
|
|
22099
|
+
const chars = snapshot.buffers.char;
|
|
22100
|
+
for (let y = 0;y < snapshot.height; y += 1) {
|
|
22101
|
+
let x = limit;
|
|
22102
|
+
while (x > 0) {
|
|
22103
|
+
const cp = chars[y * snapshot.width + x - 1];
|
|
22104
|
+
if (cp === 0 || (cp & CHAR_FLAG_MASK) === CHAR_FLAG_CONTINUATION) {
|
|
22105
|
+
x -= 1;
|
|
22106
|
+
continue;
|
|
22107
|
+
}
|
|
22108
|
+
break;
|
|
22109
|
+
}
|
|
22110
|
+
widths.push(x);
|
|
22111
|
+
}
|
|
22112
|
+
return widths;
|
|
19532
22113
|
}
|
|
19533
|
-
|
|
19534
|
-
if (
|
|
22114
|
+
publishSplitTailColumns(columns) {
|
|
22115
|
+
if (columns <= 0) {
|
|
19535
22116
|
return;
|
|
19536
|
-
this._useMouse = useMouse;
|
|
19537
|
-
if (useMouse) {
|
|
19538
|
-
this.enableMouse();
|
|
19539
|
-
} else {
|
|
19540
|
-
this.disableMouse();
|
|
19541
22117
|
}
|
|
22118
|
+
const width = Math.max(this.width, 1);
|
|
22119
|
+
let tail = this.splitTailColumn;
|
|
22120
|
+
let remaining = columns;
|
|
22121
|
+
while (remaining > 0) {
|
|
22122
|
+
if (tail >= width) {
|
|
22123
|
+
tail = 0;
|
|
22124
|
+
}
|
|
22125
|
+
const step = Math.min(remaining, width - tail);
|
|
22126
|
+
tail += step;
|
|
22127
|
+
remaining -= step;
|
|
22128
|
+
if (remaining > 0 && tail >= width) {
|
|
22129
|
+
tail = 0;
|
|
22130
|
+
}
|
|
22131
|
+
}
|
|
22132
|
+
this.splitTailColumn = tail;
|
|
19542
22133
|
}
|
|
19543
|
-
|
|
19544
|
-
|
|
22134
|
+
recordSplitCommit(commit) {
|
|
22135
|
+
if (commit.startOnNewLine && this.splitTailColumn > 0) {
|
|
22136
|
+
this.splitTailColumn = 0;
|
|
22137
|
+
}
|
|
22138
|
+
const rowWidths = this.getSnapshotRowWidths(commit.snapshot, commit.rowColumns);
|
|
22139
|
+
for (const [index, rowWidth] of rowWidths.entries()) {
|
|
22140
|
+
this.publishSplitTailColumns(rowWidth);
|
|
22141
|
+
if (index < rowWidths.length - 1 || commit.trailingNewline) {
|
|
22142
|
+
this.splitTailColumn = 0;
|
|
22143
|
+
}
|
|
22144
|
+
}
|
|
19545
22145
|
}
|
|
19546
|
-
|
|
19547
|
-
if (this.
|
|
19548
|
-
throw new Error('
|
|
22146
|
+
enqueueRenderedScrollbackCommit(options) {
|
|
22147
|
+
if (this._screenMode !== "split-footer" || this._externalOutputMode !== "capture-stdout") {
|
|
22148
|
+
throw new Error('scrollback commit requires screenMode "split-footer" and externalOutputMode "capture-stdout"');
|
|
19549
22149
|
}
|
|
19550
|
-
|
|
22150
|
+
const rowColumns = Math.min(Math.max(Math.trunc(options.rowColumns ?? options.snapshot.width), 0), options.snapshot.width);
|
|
22151
|
+
this.enqueueSplitCommit({
|
|
22152
|
+
snapshot: options.snapshot,
|
|
22153
|
+
rowColumns,
|
|
22154
|
+
startOnNewLine: options.startOnNewLine ?? true,
|
|
22155
|
+
trailingNewline: options.trailingNewline ?? true
|
|
22156
|
+
});
|
|
22157
|
+
this.requestRender();
|
|
19551
22158
|
}
|
|
19552
|
-
|
|
19553
|
-
|
|
22159
|
+
enqueueSplitCommit(commit) {
|
|
22160
|
+
this.recordSplitCommit(commit);
|
|
22161
|
+
this.externalOutputQueue.writeSnapshot(commit);
|
|
22162
|
+
}
|
|
22163
|
+
createStdoutSnapshotCommit(line, trailingNewline) {
|
|
22164
|
+
const snapshotContext = new ScrollbackSnapshotRenderContext(this.width, 1, this.widthMethod);
|
|
22165
|
+
const maxWidth = Math.max(1, this.width);
|
|
22166
|
+
const lineCells = [...line];
|
|
22167
|
+
const rowColumns = Math.min(lineCells.length, maxWidth);
|
|
22168
|
+
const renderedLine = lineCells.slice(0, maxWidth).join("");
|
|
22169
|
+
const snapshotRoot = new RootRenderable(snapshotContext);
|
|
22170
|
+
const snapshotRenderable = new TextRenderable(snapshotContext, {
|
|
22171
|
+
id: "captured-stdout-snapshot",
|
|
22172
|
+
position: "absolute",
|
|
22173
|
+
left: 0,
|
|
22174
|
+
top: 0,
|
|
22175
|
+
width: Math.max(1, rowColumns),
|
|
22176
|
+
height: 1,
|
|
22177
|
+
content: renderedLine
|
|
22178
|
+
});
|
|
22179
|
+
const snapshotBuffer = OptimizedBuffer.create(Math.max(1, rowColumns), 1, this.widthMethod, {
|
|
22180
|
+
id: "captured-stdout-snapshot"
|
|
22181
|
+
});
|
|
22182
|
+
try {
|
|
22183
|
+
snapshotRoot.add(snapshotRenderable);
|
|
22184
|
+
snapshotRoot.render(snapshotBuffer, 0);
|
|
22185
|
+
return {
|
|
22186
|
+
snapshot: snapshotBuffer,
|
|
22187
|
+
rowColumns,
|
|
22188
|
+
startOnNewLine: false,
|
|
22189
|
+
trailingNewline
|
|
22190
|
+
};
|
|
22191
|
+
} catch (error) {
|
|
22192
|
+
snapshotBuffer.destroy();
|
|
22193
|
+
throw error;
|
|
22194
|
+
} finally {
|
|
22195
|
+
snapshotRoot.destroyRecursively();
|
|
22196
|
+
}
|
|
19554
22197
|
}
|
|
19555
|
-
|
|
19556
|
-
const
|
|
19557
|
-
|
|
19558
|
-
|
|
22198
|
+
splitStdoutRows(text) {
|
|
22199
|
+
const rows = [];
|
|
22200
|
+
let current = "";
|
|
22201
|
+
for (const char of text) {
|
|
22202
|
+
if (char === "\r") {
|
|
22203
|
+
current = "";
|
|
22204
|
+
continue;
|
|
22205
|
+
}
|
|
22206
|
+
if (char === `
|
|
22207
|
+
`) {
|
|
22208
|
+
rows.push({ line: current, trailingNewline: true });
|
|
22209
|
+
current = "";
|
|
22210
|
+
continue;
|
|
22211
|
+
}
|
|
22212
|
+
current += char;
|
|
19559
22213
|
}
|
|
19560
|
-
|
|
19561
|
-
|
|
19562
|
-
this.applyScreenMode("split-footer");
|
|
22214
|
+
if (current.length > 0) {
|
|
22215
|
+
rows.push({ line: current, trailingNewline: false });
|
|
19563
22216
|
}
|
|
22217
|
+
return rows;
|
|
19564
22218
|
}
|
|
19565
|
-
|
|
19566
|
-
|
|
19567
|
-
|
|
19568
|
-
set externalOutputMode(mode) {
|
|
19569
|
-
if (mode === "capture-stdout" && this.screenMode !== "split-footer") {
|
|
19570
|
-
throw new Error('externalOutputMode "capture-stdout" requires screenMode "split-footer"');
|
|
22219
|
+
createStdoutSnapshotCommits(text) {
|
|
22220
|
+
if (text.length === 0) {
|
|
22221
|
+
return [];
|
|
19571
22222
|
}
|
|
19572
|
-
|
|
19573
|
-
|
|
19574
|
-
|
|
19575
|
-
|
|
19576
|
-
|
|
22223
|
+
const commits = [];
|
|
22224
|
+
const chunkWidth = Math.max(1, this.width);
|
|
22225
|
+
for (const row of this.splitStdoutRows(text)) {
|
|
22226
|
+
const rowCells = [...row.line];
|
|
22227
|
+
if (rowCells.length === 0) {
|
|
22228
|
+
commits.push(this.createStdoutSnapshotCommit("", row.trailingNewline));
|
|
22229
|
+
continue;
|
|
22230
|
+
}
|
|
22231
|
+
let offset = 0;
|
|
22232
|
+
while (offset < rowCells.length) {
|
|
22233
|
+
const chunk = rowCells.slice(offset, offset + chunkWidth).join("");
|
|
22234
|
+
offset += chunkWidth;
|
|
22235
|
+
const isLastChunk = offset >= rowCells.length;
|
|
22236
|
+
commits.push(this.createStdoutSnapshotCommit(chunk, isLastChunk ? row.trailingNewline : false));
|
|
22237
|
+
}
|
|
22238
|
+
}
|
|
22239
|
+
return commits;
|
|
19577
22240
|
}
|
|
19578
|
-
|
|
19579
|
-
|
|
22241
|
+
flushPendingSplitCommits(forceFooterRepaint = false) {
|
|
22242
|
+
const commits = this.externalOutputQueue.claim(this.maxSplitCommitsPerFrame);
|
|
22243
|
+
let hasCommittedOutput = false;
|
|
22244
|
+
const lastCommitIndex = commits.length - 1;
|
|
22245
|
+
for (const [index, commit] of commits.entries()) {
|
|
22246
|
+
const forceCommit = forceFooterRepaint && index === lastCommitIndex;
|
|
22247
|
+
const beginFrame = index === 0;
|
|
22248
|
+
const finalizeFrame = index === lastCommitIndex;
|
|
22249
|
+
try {
|
|
22250
|
+
this.renderOffset = this.lib.commitSplitFooterSnapshot(this.rendererPtr, commit.snapshot, commit.rowColumns, commit.startOnNewLine, commit.trailingNewline, this.getSplitPinnedRenderOffset(), forceCommit, beginFrame, finalizeFrame);
|
|
22251
|
+
hasCommittedOutput = true;
|
|
22252
|
+
} finally {
|
|
22253
|
+
commit.snapshot.destroy();
|
|
22254
|
+
}
|
|
22255
|
+
}
|
|
22256
|
+
if (!hasCommittedOutput) {
|
|
22257
|
+
this.renderOffset = this.lib.repaintSplitFooter(this.rendererPtr, this.getSplitPinnedRenderOffset(), forceFooterRepaint);
|
|
22258
|
+
}
|
|
22259
|
+
this.pendingSplitFooterTransition = null;
|
|
22260
|
+
if (this.externalOutputQueue.size > 0) {
|
|
22261
|
+
this.requestRender();
|
|
22262
|
+
}
|
|
19580
22263
|
}
|
|
19581
|
-
|
|
19582
|
-
|
|
22264
|
+
interceptStdoutWrite = (chunk, encoding, callback) => {
|
|
22265
|
+
const resolvedCallback = typeof encoding === "function" ? encoding : callback;
|
|
22266
|
+
const resolvedEncoding = typeof encoding === "string" ? encoding : undefined;
|
|
22267
|
+
const text = typeof chunk === "string" ? chunk : chunk?.toString(resolvedEncoding) ?? "";
|
|
22268
|
+
if (this._externalOutputMode === "capture-stdout" && this._screenMode === "split-footer" && this._splitHeight > 0) {
|
|
22269
|
+
const commits = this.createStdoutSnapshotCommits(text);
|
|
22270
|
+
for (const commit of commits) {
|
|
22271
|
+
this.enqueueSplitCommit(commit);
|
|
22272
|
+
}
|
|
22273
|
+
if (commits.length > 0) {
|
|
22274
|
+
this.requestRender();
|
|
22275
|
+
}
|
|
22276
|
+
}
|
|
22277
|
+
if (typeof resolvedCallback === "function") {
|
|
22278
|
+
process.nextTick(resolvedCallback);
|
|
22279
|
+
}
|
|
22280
|
+
return true;
|
|
22281
|
+
};
|
|
22282
|
+
getSplitPinnedRenderOffset() {
|
|
22283
|
+
return this._screenMode === "split-footer" ? Math.max(this._terminalHeight - this._splitHeight, 0) : 0;
|
|
19583
22284
|
}
|
|
19584
|
-
|
|
19585
|
-
|
|
22285
|
+
getSplitCursorSeedRows() {
|
|
22286
|
+
const cursorState = this.lib.getCursorState(this.rendererPtr);
|
|
22287
|
+
const cursorRow = Number.isFinite(cursorState.y) ? Math.max(Math.trunc(cursorState.y), 1) : 1;
|
|
22288
|
+
return Math.min(cursorRow, Math.max(this._terminalHeight, 1));
|
|
19586
22289
|
}
|
|
19587
|
-
|
|
19588
|
-
if (
|
|
19589
|
-
|
|
22290
|
+
flushPendingSplitOutputBeforeTransition(forceFooterRepaint = false) {
|
|
22291
|
+
if (this._screenMode !== "split-footer" || this._splitHeight <= 0 || this._externalOutputMode !== "capture-stdout") {
|
|
22292
|
+
return;
|
|
19590
22293
|
}
|
|
19591
|
-
if (this.
|
|
19592
|
-
return
|
|
22294
|
+
if (this.externalOutputQueue.size === 0 && !forceFooterRepaint) {
|
|
22295
|
+
return;
|
|
19593
22296
|
}
|
|
19594
|
-
|
|
19595
|
-
let timeoutHandle = null;
|
|
19596
|
-
const cleanup = () => {
|
|
19597
|
-
if (timeoutHandle !== null) {
|
|
19598
|
-
this.clock.clearTimeout(timeoutHandle);
|
|
19599
|
-
timeoutHandle = null;
|
|
19600
|
-
}
|
|
19601
|
-
this.off("theme_mode" /* THEME_MODE */, handleThemeMode);
|
|
19602
|
-
this.off("destroy" /* DESTROY */, handleDestroy);
|
|
19603
|
-
};
|
|
19604
|
-
const finish = () => {
|
|
19605
|
-
cleanup();
|
|
19606
|
-
resolve4(this._themeMode);
|
|
19607
|
-
};
|
|
19608
|
-
const handleThemeMode = () => {
|
|
19609
|
-
finish();
|
|
19610
|
-
};
|
|
19611
|
-
const handleDestroy = () => {
|
|
19612
|
-
finish();
|
|
19613
|
-
};
|
|
19614
|
-
this.on("theme_mode" /* THEME_MODE */, handleThemeMode);
|
|
19615
|
-
this.on("destroy" /* DESTROY */, handleDestroy);
|
|
19616
|
-
timeoutHandle = this.clock.setTimeout(finish, timeoutMs);
|
|
19617
|
-
});
|
|
22297
|
+
this.flushPendingSplitCommits(forceFooterRepaint);
|
|
19618
22298
|
}
|
|
19619
|
-
|
|
19620
|
-
|
|
22299
|
+
resetSplitScrollback(seedRows = 0) {
|
|
22300
|
+
this.splitTailColumn = 0;
|
|
22301
|
+
this.renderOffset = this.lib.resetSplitScrollback(this.rendererPtr, seedRows, this.getSplitPinnedRenderOffset());
|
|
19621
22302
|
}
|
|
19622
|
-
|
|
19623
|
-
|
|
22303
|
+
syncSplitScrollback() {
|
|
22304
|
+
this.renderOffset = this.lib.syncSplitScrollback(this.rendererPtr, this.getSplitPinnedRenderOffset());
|
|
19624
22305
|
}
|
|
19625
|
-
|
|
19626
|
-
|
|
19627
|
-
|
|
22306
|
+
clearPendingSplitFooterTransition() {
|
|
22307
|
+
if (this.pendingSplitFooterTransition === null) {
|
|
22308
|
+
return;
|
|
22309
|
+
}
|
|
22310
|
+
this.pendingSplitFooterTransition = null;
|
|
22311
|
+
this.lib.clearPendingSplitFooterTransition(this.rendererPtr);
|
|
19628
22312
|
}
|
|
19629
|
-
|
|
19630
|
-
|
|
19631
|
-
|
|
19632
|
-
|
|
19633
|
-
|
|
22313
|
+
setPendingSplitFooterTransition(transition) {
|
|
22314
|
+
this.pendingSplitFooterTransition = transition;
|
|
22315
|
+
this.lib.setPendingSplitFooterTransition(this.rendererPtr, transition.mode === "viewport-scroll" ? 1 : 2, transition.sourceTopLine, transition.sourceHeight, transition.targetTopLine, transition.targetHeight);
|
|
22316
|
+
}
|
|
22317
|
+
syncSplitFooterState() {
|
|
22318
|
+
const splitActive = this._screenMode === "split-footer" && this._splitHeight > 0;
|
|
22319
|
+
if (!splitActive) {
|
|
22320
|
+
this.clearPendingSplitFooterTransition();
|
|
22321
|
+
this.splitTailColumn = 0;
|
|
22322
|
+
this.lib.resetSplitScrollback(this.rendererPtr, 0, 0);
|
|
22323
|
+
this.renderOffset = 0;
|
|
22324
|
+
this.lib.setRenderOffset(this.rendererPtr, this.renderOffset);
|
|
22325
|
+
return;
|
|
19634
22326
|
}
|
|
19635
|
-
if (
|
|
19636
|
-
|
|
22327
|
+
if (this._externalOutputMode === "capture-stdout") {
|
|
22328
|
+
this.syncSplitScrollback();
|
|
22329
|
+
} else {
|
|
22330
|
+
this.clearPendingSplitFooterTransition();
|
|
22331
|
+
this.splitTailColumn = 0;
|
|
22332
|
+
this.lib.resetSplitScrollback(this.rendererPtr, 0, 0);
|
|
22333
|
+
this.renderOffset = this.getSplitPinnedRenderOffset();
|
|
22334
|
+
this.lib.setRenderOffset(this.rendererPtr, this.renderOffset);
|
|
19637
22335
|
}
|
|
19638
|
-
|
|
19639
|
-
|
|
22336
|
+
}
|
|
22337
|
+
clearStaleSplitSurfaceRows(previousTopLine, previousHeight, nextTopLine, nextHeight) {
|
|
22338
|
+
if (!this._terminalIsSetup || previousHeight <= 0 || this._terminalHeight <= 0) {
|
|
22339
|
+
return;
|
|
22340
|
+
}
|
|
22341
|
+
const terminalBottom = this._terminalHeight;
|
|
22342
|
+
const previousStart = Math.max(1, previousTopLine);
|
|
22343
|
+
const previousEnd = Math.min(terminalBottom, previousTopLine + previousHeight - 1);
|
|
22344
|
+
if (previousEnd < previousStart) {
|
|
22345
|
+
return;
|
|
22346
|
+
}
|
|
22347
|
+
const nextStart = Math.max(1, nextTopLine);
|
|
22348
|
+
const nextEnd = Math.min(terminalBottom, nextTopLine + Math.max(nextHeight, 0) - 1);
|
|
22349
|
+
let clear = "";
|
|
22350
|
+
for (let line = previousStart;line <= previousEnd; line += 1) {
|
|
22351
|
+
if (line >= nextStart && line <= nextEnd) {
|
|
22352
|
+
continue;
|
|
22353
|
+
}
|
|
22354
|
+
clear += `${ANSI.moveCursor(line, 1)}\x1B[2K`;
|
|
22355
|
+
}
|
|
22356
|
+
if (clear.length > 0) {
|
|
22357
|
+
this.writeOut(clear);
|
|
22358
|
+
}
|
|
22359
|
+
}
|
|
19640
22360
|
applyScreenMode(screenMode, emitResize = true, requestRender = true) {
|
|
19641
22361
|
const prevScreenMode = this._screenMode;
|
|
19642
22362
|
const prevSplitHeight = this._splitHeight;
|
|
19643
|
-
const
|
|
22363
|
+
const nextGeometry = calculateRenderGeometry(screenMode, this._terminalWidth, this._terminalHeight, this._footerHeight);
|
|
22364
|
+
const nextSplitHeight = nextGeometry.effectiveFooterHeight;
|
|
19644
22365
|
if (prevScreenMode === screenMode && prevSplitHeight === nextSplitHeight) {
|
|
19645
22366
|
return;
|
|
19646
22367
|
}
|
|
@@ -19648,10 +22369,24 @@ Captured output:
|
|
|
19648
22369
|
const nextUseAlternateScreen = screenMode === "alternate-screen";
|
|
19649
22370
|
const terminalScreenModeChanged = this._terminalIsSetup && prevUseAlternateScreen !== nextUseAlternateScreen;
|
|
19650
22371
|
const leavingSplitFooter = prevSplitHeight > 0 && nextSplitHeight === 0;
|
|
22372
|
+
if (this._terminalIsSetup && prevSplitHeight > 0) {
|
|
22373
|
+
this.flushPendingSplitOutputBeforeTransition();
|
|
22374
|
+
}
|
|
22375
|
+
const previousSurfaceTopLine = this.renderOffset + 1;
|
|
22376
|
+
const previousPinnedRenderOffset = Math.max(this._terminalHeight - prevSplitHeight, 0);
|
|
22377
|
+
const splitWasSettled = prevSplitHeight === 0 || this.renderOffset >= previousPinnedRenderOffset;
|
|
22378
|
+
const shouldUseViewportScrollTransitions = this._externalOutputMode !== "capture-stdout" || splitWasSettled;
|
|
22379
|
+
const shouldDeferSplitFooterResizeTransition = this._terminalIsSetup && prevScreenMode === "split-footer" && screenMode === "split-footer" && this._externalOutputMode === "capture-stdout" && prevSplitHeight > 0 && nextSplitHeight > 0 && !terminalScreenModeChanged;
|
|
22380
|
+
const splitStartupSeedBlocksFirstNativeFrame = this.pendingSplitStartupCursorSeed && this.splitStartupSeedTimeoutId !== null;
|
|
22381
|
+
const splitTransitionSourceTopLine = this.pendingSplitFooterTransition?.sourceTopLine ?? previousSurfaceTopLine;
|
|
22382
|
+
const splitTransitionSourceHeight = this.pendingSplitFooterTransition?.sourceHeight ?? prevSplitHeight;
|
|
22383
|
+
const splitTransitionMode = this.pendingSplitFooterTransition?.mode ?? (splitWasSettled ? "viewport-scroll" : "clear-stale-rows");
|
|
19651
22384
|
if (this._terminalIsSetup && leavingSplitFooter) {
|
|
19652
|
-
this.
|
|
22385
|
+
this.clearPendingSplitFooterTransition();
|
|
22386
|
+
this.renderOffset = 0;
|
|
22387
|
+
this.lib.setRenderOffset(this.rendererPtr, 0);
|
|
19653
22388
|
}
|
|
19654
|
-
if (this._terminalIsSetup && !terminalScreenModeChanged) {
|
|
22389
|
+
if (this._terminalIsSetup && !terminalScreenModeChanged && shouldUseViewportScrollTransitions && !shouldDeferSplitFooterResizeTransition) {
|
|
19655
22390
|
if (prevSplitHeight === 0 && nextSplitHeight > 0) {
|
|
19656
22391
|
const freedLines = this._terminalHeight - nextSplitHeight;
|
|
19657
22392
|
const scrollDown = ANSI.scrollDown(freedLines);
|
|
@@ -19666,18 +22401,39 @@ Captured output:
|
|
|
19666
22401
|
this.writeOut(scrollUp);
|
|
19667
22402
|
}
|
|
19668
22403
|
}
|
|
19669
|
-
if (prevSplitHeight === 0 && nextSplitHeight > 0) {
|
|
19670
|
-
capture.on("write", this.captureCallback);
|
|
19671
|
-
} else if (prevSplitHeight > 0 && nextSplitHeight === 0) {
|
|
19672
|
-
capture.off("write", this.captureCallback);
|
|
19673
|
-
}
|
|
19674
22404
|
this._screenMode = screenMode;
|
|
19675
22405
|
this._splitHeight = nextSplitHeight;
|
|
19676
|
-
this.
|
|
19677
|
-
this.
|
|
19678
|
-
this.height = nextSplitHeight > 0 ? nextSplitHeight : this._terminalHeight;
|
|
19679
|
-
this.lib.setRenderOffset(this.rendererPtr, this.renderOffset);
|
|
22406
|
+
this.width = nextGeometry.renderWidth;
|
|
22407
|
+
this.height = nextGeometry.renderHeight;
|
|
19680
22408
|
this.lib.resizeRenderer(this.rendererPtr, this.width, this.height);
|
|
22409
|
+
if (this._screenMode === "split-footer" && this._externalOutputMode === "capture-stdout") {
|
|
22410
|
+
if (prevScreenMode !== "split-footer") {
|
|
22411
|
+
this.resetSplitScrollback(this.getSplitCursorSeedRows());
|
|
22412
|
+
} else {
|
|
22413
|
+
this.syncSplitScrollback();
|
|
22414
|
+
}
|
|
22415
|
+
if (shouldDeferSplitFooterResizeTransition) {
|
|
22416
|
+
if (splitStartupSeedBlocksFirstNativeFrame) {
|
|
22417
|
+
this.clearPendingSplitFooterTransition();
|
|
22418
|
+
} else {
|
|
22419
|
+
this.setPendingSplitFooterTransition({
|
|
22420
|
+
mode: splitTransitionMode,
|
|
22421
|
+
sourceTopLine: splitTransitionSourceTopLine,
|
|
22422
|
+
sourceHeight: splitTransitionSourceHeight,
|
|
22423
|
+
targetTopLine: this.renderOffset + 1,
|
|
22424
|
+
targetHeight: nextSplitHeight
|
|
22425
|
+
});
|
|
22426
|
+
}
|
|
22427
|
+
this.forceFullRepaintRequested = true;
|
|
22428
|
+
} else if (!shouldUseViewportScrollTransitions && prevSplitHeight > 0 && nextSplitHeight > 0) {
|
|
22429
|
+
this.clearPendingSplitFooterTransition();
|
|
22430
|
+
this.clearStaleSplitSurfaceRows(previousSurfaceTopLine, prevSplitHeight, this.renderOffset + 1, nextSplitHeight);
|
|
22431
|
+
} else {
|
|
22432
|
+
this.clearPendingSplitFooterTransition();
|
|
22433
|
+
}
|
|
22434
|
+
} else {
|
|
22435
|
+
this.syncSplitFooterState();
|
|
22436
|
+
}
|
|
19681
22437
|
this.nextRenderBuffer = this.lib.getNextBuffer(this.rendererPtr);
|
|
19682
22438
|
this.currentRenderBuffer = this.lib.getCurrentBuffer(this.rendererPtr);
|
|
19683
22439
|
this._console.resize(this.width, this.height);
|
|
@@ -19697,12 +22453,18 @@ Captured output:
|
|
|
19697
22453
|
}
|
|
19698
22454
|
}
|
|
19699
22455
|
flushStdoutCache(space, force = false) {
|
|
19700
|
-
if (
|
|
22456
|
+
if (this.externalOutputQueue.size === 0 && !force)
|
|
19701
22457
|
return false;
|
|
19702
|
-
const
|
|
19703
|
-
|
|
22458
|
+
const outputCommits = this.externalOutputQueue.claim();
|
|
22459
|
+
let output = "";
|
|
22460
|
+
for (const commit of outputCommits) {
|
|
22461
|
+
output += `[snapshot ${commit.snapshot.width}x${commit.snapshot.height}]
|
|
22462
|
+
`;
|
|
22463
|
+
commit.snapshot.destroy();
|
|
22464
|
+
}
|
|
22465
|
+
const rendererStartLine = this.renderOffset + 1;
|
|
19704
22466
|
const flush = ANSI.moveCursorAndClear(rendererStartLine, 1);
|
|
19705
|
-
const outputLine = this.
|
|
22467
|
+
const outputLine = this.renderOffset + 1;
|
|
19706
22468
|
const move = ANSI.moveCursor(outputLine, 1);
|
|
19707
22469
|
let clear = "";
|
|
19708
22470
|
if (space > 0) {
|
|
@@ -19744,9 +22506,11 @@ Captured output:
|
|
|
19744
22506
|
if (this._terminalIsSetup)
|
|
19745
22507
|
return;
|
|
19746
22508
|
this._terminalIsSetup = true;
|
|
22509
|
+
const startupCursorCprActive = this._screenMode === "split-footer" && this._externalOutputMode === "capture-stdout";
|
|
19747
22510
|
this.updateStdinParserProtocolContext({
|
|
19748
22511
|
privateCapabilityRepliesActive: true,
|
|
19749
|
-
explicitWidthCprActive: true
|
|
22512
|
+
explicitWidthCprActive: true,
|
|
22513
|
+
startupCursorCprActive
|
|
19750
22514
|
});
|
|
19751
22515
|
this.lib.setupTerminal(this.rendererPtr, this._screenMode === "alternate-screen");
|
|
19752
22516
|
this._capabilities = this.lib.getTerminalCapabilities(this.rendererPtr);
|
|
@@ -19760,16 +22524,42 @@ Captured output:
|
|
|
19760
22524
|
}
|
|
19761
22525
|
this.capabilityTimeoutId = this.clock.setTimeout(() => {
|
|
19762
22526
|
this.capabilityTimeoutId = null;
|
|
22527
|
+
this.pendingSplitStartupCursorSeed = false;
|
|
22528
|
+
if (this.splitStartupSeedTimeoutId !== null) {
|
|
22529
|
+
this.clock.clearTimeout(this.splitStartupSeedTimeoutId);
|
|
22530
|
+
this.splitStartupSeedTimeoutId = null;
|
|
22531
|
+
}
|
|
22532
|
+
if (this._screenMode === "split-footer" && this._externalOutputMode === "capture-stdout") {
|
|
22533
|
+
this.requestRender();
|
|
22534
|
+
}
|
|
19763
22535
|
this.removeInputHandler(this.capabilityHandler);
|
|
19764
22536
|
this.updateStdinParserProtocolContext({
|
|
19765
22537
|
privateCapabilityRepliesActive: false,
|
|
19766
|
-
explicitWidthCprActive: false
|
|
22538
|
+
explicitWidthCprActive: false,
|
|
22539
|
+
startupCursorCprActive: false
|
|
19767
22540
|
}, true);
|
|
19768
22541
|
}, 5000);
|
|
19769
22542
|
if (this._useMouse) {
|
|
19770
22543
|
this.enableMouse();
|
|
19771
22544
|
}
|
|
22545
|
+
if (this._screenMode === "split-footer" && this._externalOutputMode === "capture-stdout") {
|
|
22546
|
+
this.pendingSplitStartupCursorSeed = true;
|
|
22547
|
+
if (this.splitStartupSeedTimeoutId !== null) {
|
|
22548
|
+
this.clock.clearTimeout(this.splitStartupSeedTimeoutId);
|
|
22549
|
+
}
|
|
22550
|
+
this.splitStartupSeedTimeoutId = this.clock.setTimeout(() => {
|
|
22551
|
+
this.splitStartupSeedTimeoutId = null;
|
|
22552
|
+
if (!this.pendingSplitStartupCursorSeed) {
|
|
22553
|
+
return;
|
|
22554
|
+
}
|
|
22555
|
+
this.updateStdinParserProtocolContext({ startupCursorCprActive: false });
|
|
22556
|
+
if (this._screenMode === "split-footer" && this._externalOutputMode === "capture-stdout") {
|
|
22557
|
+
this.requestRender();
|
|
22558
|
+
}
|
|
22559
|
+
}, 120);
|
|
22560
|
+
}
|
|
19772
22561
|
this.queryPixelResolution();
|
|
22562
|
+
this.ensureNativePaletteState();
|
|
19773
22563
|
}
|
|
19774
22564
|
stdinListener = ((chunk) => {
|
|
19775
22565
|
const data = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
@@ -19804,14 +22594,36 @@ Captured output:
|
|
|
19804
22594
|
this.oscSubscribers.delete(handler);
|
|
19805
22595
|
};
|
|
19806
22596
|
}
|
|
19807
|
-
|
|
19808
|
-
|
|
19809
|
-
|
|
19810
|
-
|
|
19811
|
-
|
|
19812
|
-
return true;
|
|
22597
|
+
processCapabilitySequence(sequence, hasCursorReport) {
|
|
22598
|
+
const hasStandardCapabilitySignature = isCapabilityResponse(sequence);
|
|
22599
|
+
const shouldProcessAsCapability = hasStandardCapabilitySignature || hasCursorReport && this.capabilityTimeoutId !== null;
|
|
22600
|
+
if (!shouldProcessAsCapability) {
|
|
22601
|
+
return false;
|
|
19813
22602
|
}
|
|
19814
|
-
|
|
22603
|
+
this.lib.processCapabilityResponse(this.rendererPtr, sequence);
|
|
22604
|
+
this._capabilities = this.lib.getTerminalCapabilities(this.rendererPtr);
|
|
22605
|
+
if (hasStandardCapabilitySignature) {
|
|
22606
|
+
this.forceFullRepaintRequested = true;
|
|
22607
|
+
this.requestRender();
|
|
22608
|
+
}
|
|
22609
|
+
this.emit("capabilities" /* CAPABILITIES */, this._capabilities);
|
|
22610
|
+
const hadPendingSplitStartupCursorSeed = this.pendingSplitStartupCursorSeed;
|
|
22611
|
+
if (hadPendingSplitStartupCursorSeed && hasCursorReport && this._screenMode === "split-footer" && this._externalOutputMode === "capture-stdout") {
|
|
22612
|
+
this.resetSplitScrollback(this.getSplitCursorSeedRows());
|
|
22613
|
+
this.clearPendingSplitFooterTransition();
|
|
22614
|
+
this.pendingSplitStartupCursorSeed = false;
|
|
22615
|
+
this.updateStdinParserProtocolContext({ startupCursorCprActive: false });
|
|
22616
|
+
if (this.splitStartupSeedTimeoutId !== null) {
|
|
22617
|
+
this.clock.clearTimeout(this.splitStartupSeedTimeoutId);
|
|
22618
|
+
this.splitStartupSeedTimeoutId = null;
|
|
22619
|
+
}
|
|
22620
|
+
this.requestRender();
|
|
22621
|
+
}
|
|
22622
|
+
const consumeStartupCursorReport = hadPendingSplitStartupCursorSeed && hasCursorReport && this.splitStartupSeedTimeoutId !== null;
|
|
22623
|
+
return hasStandardCapabilitySignature || consumeStartupCursorReport;
|
|
22624
|
+
}
|
|
22625
|
+
capabilityHandler = ((sequence) => {
|
|
22626
|
+
return this.processCapabilitySequence(sequence, false);
|
|
19815
22627
|
}).bind(this);
|
|
19816
22628
|
focusHandler = ((sequence) => {
|
|
19817
22629
|
if (sequence === "\x1B[I") {
|
|
@@ -19835,52 +22647,6 @@ Captured output:
|
|
|
19835
22647
|
}
|
|
19836
22648
|
return false;
|
|
19837
22649
|
}).bind(this);
|
|
19838
|
-
themeModeHandler = ((sequence) => {
|
|
19839
|
-
if (sequence === "\x1B[?997;1n") {
|
|
19840
|
-
this.applyThemeMode("dark", "csi");
|
|
19841
|
-
this._themeFallbackPending = false;
|
|
19842
|
-
return true;
|
|
19843
|
-
}
|
|
19844
|
-
if (sequence === "\x1B[?997;2n") {
|
|
19845
|
-
this.applyThemeMode("light", "csi");
|
|
19846
|
-
this._themeFallbackPending = false;
|
|
19847
|
-
return true;
|
|
19848
|
-
}
|
|
19849
|
-
let handledOscThemeResponse = false;
|
|
19850
|
-
let match;
|
|
19851
|
-
OSC_THEME_RESPONSE.lastIndex = 0;
|
|
19852
|
-
while (match = OSC_THEME_RESPONSE.exec(sequence)) {
|
|
19853
|
-
handledOscThemeResponse = true;
|
|
19854
|
-
const color = oscThemeColorToHex(match[2], match[3], match[4], match[5]);
|
|
19855
|
-
if (match[1] === "10") {
|
|
19856
|
-
this._themeOscForeground = color;
|
|
19857
|
-
} else {
|
|
19858
|
-
this._themeOscBackground = color;
|
|
19859
|
-
}
|
|
19860
|
-
}
|
|
19861
|
-
if (!handledOscThemeResponse) {
|
|
19862
|
-
return false;
|
|
19863
|
-
}
|
|
19864
|
-
if (!this._themeFallbackPending) {
|
|
19865
|
-
return true;
|
|
19866
|
-
}
|
|
19867
|
-
if (this._themeOscForeground && this._themeOscBackground) {
|
|
19868
|
-
this.applyThemeMode(inferThemeModeFromBackgroundColor(this._themeOscBackground), "osc");
|
|
19869
|
-
this._themeFallbackPending = false;
|
|
19870
|
-
}
|
|
19871
|
-
return true;
|
|
19872
|
-
}).bind(this);
|
|
19873
|
-
applyThemeMode(mode, source) {
|
|
19874
|
-
if (source === "osc" && this._themeModeSource === "csi") {
|
|
19875
|
-
return;
|
|
19876
|
-
}
|
|
19877
|
-
const changed = this._themeMode !== mode;
|
|
19878
|
-
this._themeMode = mode;
|
|
19879
|
-
this._themeModeSource = source;
|
|
19880
|
-
if (changed) {
|
|
19881
|
-
this.emit("theme_mode" /* THEME_MODE */, mode);
|
|
19882
|
-
}
|
|
19883
|
-
}
|
|
19884
22650
|
dispatchSequenceHandlers(sequence) {
|
|
19885
22651
|
if (this._debugModeEnabled) {
|
|
19886
22652
|
this._debugInputs.push({
|
|
@@ -19925,6 +22691,9 @@ Captured output:
|
|
|
19925
22691
|
subscriber(event.sequence);
|
|
19926
22692
|
}
|
|
19927
22693
|
}
|
|
22694
|
+
if (event.protocol === "cpr" && this.processCapabilitySequence(event.sequence, true)) {
|
|
22695
|
+
return;
|
|
22696
|
+
}
|
|
19928
22697
|
this.dispatchSequenceHandlers(event.sequence);
|
|
19929
22698
|
return;
|
|
19930
22699
|
}
|
|
@@ -20211,28 +22980,45 @@ Captured output:
|
|
|
20211
22980
|
processResize(width, height) {
|
|
20212
22981
|
if (width === this._terminalWidth && height === this._terminalHeight)
|
|
20213
22982
|
return;
|
|
22983
|
+
if (this._terminalIsSetup && this._controlState !== "explicit_suspended" /* EXPLICIT_SUSPENDED */) {
|
|
22984
|
+
this.flushPendingSplitOutputBeforeTransition();
|
|
22985
|
+
}
|
|
22986
|
+
const pendingSplitFooterTransition = this.pendingSplitFooterTransition;
|
|
22987
|
+
const previousGeometry = calculateRenderGeometry(this._screenMode, this._terminalWidth, this._terminalHeight, this._footerHeight);
|
|
20214
22988
|
const prevWidth = this._terminalWidth;
|
|
22989
|
+
const previousTerminalHeight = this._terminalHeight;
|
|
22990
|
+
const visiblePreviousSplitHeight = pendingSplitFooterTransition?.sourceHeight ?? previousGeometry.effectiveFooterHeight;
|
|
20215
22991
|
this._terminalWidth = width;
|
|
20216
22992
|
this._terminalHeight = height;
|
|
20217
22993
|
this.queryPixelResolution();
|
|
20218
22994
|
this.setCapturedRenderable(undefined);
|
|
20219
22995
|
this.stdinParser?.resetMouseState();
|
|
20220
|
-
|
|
20221
|
-
|
|
20222
|
-
|
|
20223
|
-
|
|
22996
|
+
const nextGeometry = calculateRenderGeometry(this._screenMode, this._terminalWidth, this._terminalHeight, this._footerHeight);
|
|
22997
|
+
const splitFooterActive = this._screenMode === "split-footer";
|
|
22998
|
+
if (splitFooterActive) {
|
|
22999
|
+
let clearStart = null;
|
|
23000
|
+
if (width < prevWidth && visiblePreviousSplitHeight > 0) {
|
|
23001
|
+
clearStart = Math.max(previousTerminalHeight - visiblePreviousSplitHeight * 2, 1);
|
|
23002
|
+
}
|
|
23003
|
+
if (pendingSplitFooterTransition !== null) {
|
|
23004
|
+
clearStart = clearStart === null ? pendingSplitFooterTransition.sourceTopLine : Math.min(clearStart, pendingSplitFooterTransition.sourceTopLine);
|
|
23005
|
+
}
|
|
23006
|
+
if (clearStart !== null) {
|
|
23007
|
+
const flush = ANSI.moveCursorAndClear(clearStart, 1);
|
|
20224
23008
|
this.writeOut(flush);
|
|
20225
23009
|
}
|
|
20226
|
-
this.renderOffset = height - this._splitHeight;
|
|
20227
|
-
this.width = width;
|
|
20228
|
-
this.height = this._splitHeight;
|
|
20229
23010
|
this.currentRenderBuffer.clear(this.backgroundColor);
|
|
20230
|
-
this.lib.setRenderOffset(this.rendererPtr, this.renderOffset);
|
|
20231
|
-
} else {
|
|
20232
|
-
this.width = width;
|
|
20233
|
-
this.height = height;
|
|
20234
23011
|
}
|
|
23012
|
+
this.clearPendingSplitFooterTransition();
|
|
23013
|
+
this._splitHeight = nextGeometry.effectiveFooterHeight;
|
|
23014
|
+
this.width = nextGeometry.renderWidth;
|
|
23015
|
+
this.height = nextGeometry.renderHeight;
|
|
20235
23016
|
this.lib.resizeRenderer(this.rendererPtr, this.width, this.height);
|
|
23017
|
+
if (this._screenMode === "split-footer" && this._externalOutputMode === "capture-stdout") {
|
|
23018
|
+
this.syncSplitScrollback();
|
|
23019
|
+
} else {
|
|
23020
|
+
this.syncSplitFooterState();
|
|
23021
|
+
}
|
|
20236
23022
|
this.nextRenderBuffer = this.lib.getNextBuffer(this.rendererPtr);
|
|
20237
23023
|
this.currentRenderBuffer = this.lib.getCurrentBuffer(this.rendererPtr);
|
|
20238
23024
|
this._console.resize(this.width, this.height);
|
|
@@ -20380,6 +23166,9 @@ Captured output:
|
|
|
20380
23166
|
this._previousControlState = this._controlState;
|
|
20381
23167
|
this._controlState = "explicit_suspended" /* EXPLICIT_SUSPENDED */;
|
|
20382
23168
|
this.internalPause();
|
|
23169
|
+
if (this._terminalIsSetup) {
|
|
23170
|
+
this.flushPendingSplitOutputBeforeTransition(true);
|
|
23171
|
+
}
|
|
20383
23172
|
this._suspendedMouseEnabled = this._useMouse;
|
|
20384
23173
|
this.disableMouse();
|
|
20385
23174
|
this.removeExitListeners();
|
|
@@ -20387,10 +23176,12 @@ Captured output:
|
|
|
20387
23176
|
this.updateStdinParserProtocolContext({
|
|
20388
23177
|
privateCapabilityRepliesActive: false,
|
|
20389
23178
|
pixelResolutionQueryActive: false,
|
|
20390
|
-
explicitWidthCprActive: false
|
|
23179
|
+
explicitWidthCprActive: false,
|
|
23180
|
+
startupCursorCprActive: false
|
|
20391
23181
|
});
|
|
20392
23182
|
this.stdinParser?.reset();
|
|
20393
23183
|
this.stdin.removeListener("data", this.stdinListener);
|
|
23184
|
+
this.themeModeState.cancelRefresh();
|
|
20394
23185
|
this.lib.suspendRenderer(this.rendererPtr);
|
|
20395
23186
|
if (this.stdin.setRawMode) {
|
|
20396
23187
|
this.stdin.setRawMode(false);
|
|
@@ -20406,6 +23197,9 @@ Captured output:
|
|
|
20406
23197
|
this.stdin.resume();
|
|
20407
23198
|
this.addExitListeners();
|
|
20408
23199
|
this.lib.resumeRenderer(this.rendererPtr);
|
|
23200
|
+
if (this._screenMode === "split-footer" && this._splitHeight > 0) {
|
|
23201
|
+
this.syncSplitFooterState();
|
|
23202
|
+
}
|
|
20409
23203
|
if (this._suspendedMouseEnabled) {
|
|
20410
23204
|
this.enableMouse();
|
|
20411
23205
|
}
|
|
@@ -20467,7 +23261,6 @@ Captured output:
|
|
|
20467
23261
|
process.removeListener("unhandledRejection", this.handleError);
|
|
20468
23262
|
process.removeListener("warning", this.warningHandler);
|
|
20469
23263
|
process.removeListener("beforeExit", this.exitHandler);
|
|
20470
|
-
capture.removeListener("write", this.captureCallback);
|
|
20471
23264
|
this.removeExitListeners();
|
|
20472
23265
|
if (this.resizeTimeoutId !== null) {
|
|
20473
23266
|
this.clock.clearTimeout(this.resizeTimeoutId);
|
|
@@ -20477,6 +23270,10 @@ Captured output:
|
|
|
20477
23270
|
this.clock.clearTimeout(this.capabilityTimeoutId);
|
|
20478
23271
|
this.capabilityTimeoutId = null;
|
|
20479
23272
|
}
|
|
23273
|
+
if (this.splitStartupSeedTimeoutId !== null) {
|
|
23274
|
+
this.clock.clearTimeout(this.splitStartupSeedTimeoutId);
|
|
23275
|
+
this.splitStartupSeedTimeoutId = null;
|
|
23276
|
+
}
|
|
20480
23277
|
if (this.memorySnapshotTimer) {
|
|
20481
23278
|
this.clock.clearInterval(this.memorySnapshotTimer);
|
|
20482
23279
|
this.memorySnapshotTimer = null;
|
|
@@ -20485,12 +23282,14 @@ Captured output:
|
|
|
20485
23282
|
this.clock.clearTimeout(this.renderTimeout);
|
|
20486
23283
|
this.renderTimeout = null;
|
|
20487
23284
|
}
|
|
23285
|
+
this.themeModeState.cancelRefresh();
|
|
20488
23286
|
this._isRunning = false;
|
|
20489
23287
|
this.waitingForPixelResolution = false;
|
|
20490
23288
|
this.updateStdinParserProtocolContext({
|
|
20491
23289
|
privateCapabilityRepliesActive: false,
|
|
20492
23290
|
pixelResolutionQueryActive: false,
|
|
20493
|
-
explicitWidthCprActive: false
|
|
23291
|
+
explicitWidthCprActive: false,
|
|
23292
|
+
startupCursorCprActive: false
|
|
20494
23293
|
}, true);
|
|
20495
23294
|
this._useMouse = false;
|
|
20496
23295
|
this.setCapturedRenderable(undefined);
|
|
@@ -20517,8 +23316,14 @@ Captured output:
|
|
|
20517
23316
|
this._paletteDetector.cleanup();
|
|
20518
23317
|
this._paletteDetector = null;
|
|
20519
23318
|
}
|
|
23319
|
+
this._paletteCache.clear();
|
|
20520
23320
|
this._paletteDetectionPromise = null;
|
|
23321
|
+
this._paletteDetectionSize = 0;
|
|
20521
23322
|
this._cachedPalette = null;
|
|
23323
|
+
this._publishedPaletteSignature = null;
|
|
23324
|
+
this._paletteEpoch = 0;
|
|
23325
|
+
this._palettePublishGeneration = 0;
|
|
23326
|
+
this.themeModeState.dispose();
|
|
20522
23327
|
this.emit("destroy" /* DESTROY */);
|
|
20523
23328
|
try {
|
|
20524
23329
|
this.root.destroyRecursively();
|
|
@@ -20529,6 +23334,16 @@ Captured output:
|
|
|
20529
23334
|
this.stdinParser = null;
|
|
20530
23335
|
this.oscSubscribers.clear();
|
|
20531
23336
|
this._console.destroy();
|
|
23337
|
+
if (this._splitHeight > 0 && this._terminalIsSetup && this._controlState !== "explicit_suspended" /* EXPLICIT_SUSPENDED */) {
|
|
23338
|
+
this.flushPendingSplitOutputBeforeTransition(true);
|
|
23339
|
+
this.renderOffset = 0;
|
|
23340
|
+
if (this.clearOnShutdown) {
|
|
23341
|
+
this.lib.setRenderOffset(this.rendererPtr, 0);
|
|
23342
|
+
}
|
|
23343
|
+
}
|
|
23344
|
+
this._externalOutputMode = "passthrough";
|
|
23345
|
+
this.stdout.write = this.realStdoutWrite;
|
|
23346
|
+
this.externalOutputQueue.clear();
|
|
20532
23347
|
this.lib.destroyRenderer(this.rendererPtr);
|
|
20533
23348
|
rendererTracker.removeRenderer(this);
|
|
20534
23349
|
if (this._onDestroy) {
|
|
@@ -20637,12 +23452,22 @@ Captured output:
|
|
|
20637
23452
|
console.error("Rendering called concurrently");
|
|
20638
23453
|
throw new Error("Rendering called concurrently");
|
|
20639
23454
|
}
|
|
20640
|
-
let force = false;
|
|
20641
|
-
if (this._splitHeight > 0) {
|
|
20642
|
-
force = this.flushStdoutCache(this._splitHeight);
|
|
20643
|
-
}
|
|
20644
23455
|
this.renderingNative = true;
|
|
20645
|
-
this.
|
|
23456
|
+
if (this.pendingSplitStartupCursorSeed && this.splitStartupSeedTimeoutId !== null && this._splitHeight > 0 && this._externalOutputMode === "capture-stdout") {
|
|
23457
|
+
this.renderingNative = false;
|
|
23458
|
+
return;
|
|
23459
|
+
}
|
|
23460
|
+
if (this._splitHeight > 0 && this._externalOutputMode === "capture-stdout") {
|
|
23461
|
+
const forceSplitRepaint = this.forceFullRepaintRequested;
|
|
23462
|
+
this.forceFullRepaintRequested = false;
|
|
23463
|
+
this.flushPendingSplitCommits(forceSplitRepaint);
|
|
23464
|
+
this.pendingSplitFooterTransition = null;
|
|
23465
|
+
} else {
|
|
23466
|
+
const force = this.forceFullRepaintRequested;
|
|
23467
|
+
this.forceFullRepaintRequested = false;
|
|
23468
|
+
this.pendingSplitFooterTransition = null;
|
|
23469
|
+
this.lib.render(this.rendererPtr, force);
|
|
23470
|
+
}
|
|
20646
23471
|
this.renderingNative = false;
|
|
20647
23472
|
}
|
|
20648
23473
|
collectStatSample(frameTime) {
|
|
@@ -20786,13 +23611,63 @@ Captured output:
|
|
|
20786
23611
|
}
|
|
20787
23612
|
}
|
|
20788
23613
|
get paletteDetectionStatus() {
|
|
20789
|
-
if (this._cachedPalette)
|
|
20790
|
-
return "cached";
|
|
20791
23614
|
if (this._paletteDetectionPromise)
|
|
20792
23615
|
return "detecting";
|
|
23616
|
+
if (this._paletteCache.size > 0)
|
|
23617
|
+
return "cached";
|
|
20793
23618
|
return "idle";
|
|
20794
23619
|
}
|
|
23620
|
+
getCachedPaletteBySize(size) {
|
|
23621
|
+
const exactMatch = this._paletteCache.get(size);
|
|
23622
|
+
if (exactMatch) {
|
|
23623
|
+
return exactMatch;
|
|
23624
|
+
}
|
|
23625
|
+
const largerSize = [...this._paletteCache.keys()].sort((a, b) => a - b).find((candidate) => candidate >= size);
|
|
23626
|
+
if (largerSize === undefined) {
|
|
23627
|
+
return null;
|
|
23628
|
+
}
|
|
23629
|
+
const source = this._paletteCache.get(largerSize);
|
|
23630
|
+
if (!source) {
|
|
23631
|
+
return null;
|
|
23632
|
+
}
|
|
23633
|
+
const projected = {
|
|
23634
|
+
...source,
|
|
23635
|
+
palette: source.palette.slice(0, size)
|
|
23636
|
+
};
|
|
23637
|
+
this._paletteCache.set(size, projected);
|
|
23638
|
+
return projected;
|
|
23639
|
+
}
|
|
23640
|
+
ensurePaletteDetector() {
|
|
23641
|
+
if (!this._paletteDetector) {
|
|
23642
|
+
const isLegacyTmux = this.capabilities?.terminal?.name?.toLowerCase()?.includes("tmux") && this.capabilities?.terminal?.version?.localeCompare("3.6") < 0;
|
|
23643
|
+
this._paletteDetector = createTerminalPalette(this.stdin, this.stdout, this.writeOut.bind(this), isLegacyTmux, {
|
|
23644
|
+
subscribeOsc: this.subscribeOsc.bind(this)
|
|
23645
|
+
}, this.clock);
|
|
23646
|
+
}
|
|
23647
|
+
return this._paletteDetector;
|
|
23648
|
+
}
|
|
23649
|
+
syncNativePaletteState(colors) {
|
|
23650
|
+
const signature = buildTerminalPaletteSignature(colors);
|
|
23651
|
+
if (this._publishedPaletteSignature !== null && this._publishedPaletteSignature !== signature) {
|
|
23652
|
+
this._paletteEpoch = this._paletteEpoch + 1 >>> 0;
|
|
23653
|
+
}
|
|
23654
|
+
this._publishedPaletteSignature = signature;
|
|
23655
|
+
const normalized = normalizeTerminalPalette(colors);
|
|
23656
|
+
this.lib.rendererSetPaletteState(this.rendererPtr, normalized.palette, normalized.defaultForeground, normalized.defaultBackground, this._paletteEpoch);
|
|
23657
|
+
}
|
|
23658
|
+
ensureNativePaletteState() {
|
|
23659
|
+
if (!this._terminalIsSetup || this._isDestroyed)
|
|
23660
|
+
return;
|
|
23661
|
+
const publishGeneration = this._palettePublishGeneration;
|
|
23662
|
+
this.getPalette({ size: 256 }).then((colors) => {
|
|
23663
|
+
if (this._palettePublishGeneration === publishGeneration) {
|
|
23664
|
+
this.syncNativePaletteState(colors);
|
|
23665
|
+
}
|
|
23666
|
+
this.requestRender();
|
|
23667
|
+
}).catch(() => {});
|
|
23668
|
+
}
|
|
20795
23669
|
clearPaletteCache() {
|
|
23670
|
+
this._paletteCache.clear();
|
|
20796
23671
|
this._cachedPalette = null;
|
|
20797
23672
|
}
|
|
20798
23673
|
async getPalette(options) {
|
|
@@ -20800,31 +23675,65 @@ Captured output:
|
|
|
20800
23675
|
throw new Error("Cannot detect palette while renderer is suspended");
|
|
20801
23676
|
}
|
|
20802
23677
|
const requestedSize = options?.size ?? 16;
|
|
20803
|
-
|
|
20804
|
-
|
|
20805
|
-
|
|
20806
|
-
|
|
20807
|
-
return
|
|
23678
|
+
const detectionTimeout = options?.timeout;
|
|
23679
|
+
const cachedPalette = this.getCachedPaletteBySize(requestedSize);
|
|
23680
|
+
if (cachedPalette) {
|
|
23681
|
+
this._cachedPalette = cachedPalette;
|
|
23682
|
+
return cachedPalette;
|
|
20808
23683
|
}
|
|
20809
23684
|
if (this._paletteDetectionPromise) {
|
|
20810
|
-
|
|
20811
|
-
|
|
20812
|
-
|
|
20813
|
-
|
|
20814
|
-
|
|
20815
|
-
|
|
20816
|
-
|
|
23685
|
+
if (this._paletteDetectionSize >= requestedSize) {
|
|
23686
|
+
return this._paletteDetectionPromise.then((palette) => {
|
|
23687
|
+
const cached = this.getCachedPaletteBySize(requestedSize);
|
|
23688
|
+
if (cached) {
|
|
23689
|
+
this._cachedPalette = cached;
|
|
23690
|
+
return cached;
|
|
23691
|
+
}
|
|
23692
|
+
const projected = {
|
|
23693
|
+
...palette,
|
|
23694
|
+
palette: palette.palette.slice(0, requestedSize)
|
|
23695
|
+
};
|
|
23696
|
+
this._paletteCache.set(requestedSize, projected);
|
|
23697
|
+
this._cachedPalette = projected;
|
|
23698
|
+
return projected;
|
|
23699
|
+
});
|
|
23700
|
+
}
|
|
23701
|
+
await this._paletteDetectionPromise;
|
|
23702
|
+
const afterWait = this.getCachedPaletteBySize(requestedSize);
|
|
23703
|
+
if (afterWait) {
|
|
23704
|
+
this._cachedPalette = afterWait;
|
|
23705
|
+
return afterWait;
|
|
23706
|
+
}
|
|
20817
23707
|
}
|
|
20818
|
-
|
|
23708
|
+
const detector = this.ensurePaletteDetector();
|
|
23709
|
+
const publishGeneration = this._palettePublishGeneration;
|
|
23710
|
+
this._paletteDetectionSize = requestedSize;
|
|
23711
|
+
this._paletteDetectionPromise = detector.detect({ ...options, timeout: detectionTimeout }).then((result) => {
|
|
23712
|
+
this._paletteCache.set(result.palette.length, result);
|
|
20819
23713
|
this._cachedPalette = result;
|
|
20820
23714
|
this._paletteDetectionPromise = null;
|
|
23715
|
+
this._paletteDetectionSize = 0;
|
|
23716
|
+
if (this._palettePublishGeneration === publishGeneration) {
|
|
23717
|
+
if (result.palette.length >= 256) {
|
|
23718
|
+
this.syncNativePaletteState(result);
|
|
23719
|
+
} else if (this._terminalIsSetup && !this._paletteCache.has(256)) {
|
|
23720
|
+
this.ensureNativePaletteState();
|
|
23721
|
+
}
|
|
23722
|
+
}
|
|
20821
23723
|
return result;
|
|
23724
|
+
}).catch((error) => {
|
|
23725
|
+
this._paletteDetectionPromise = null;
|
|
23726
|
+
this._paletteDetectionSize = 0;
|
|
23727
|
+
throw error;
|
|
20822
23728
|
});
|
|
20823
|
-
|
|
23729
|
+
const detected = await this._paletteDetectionPromise;
|
|
23730
|
+
const finalPalette = this.getCachedPaletteBySize(requestedSize) ?? detected;
|
|
23731
|
+
this._cachedPalette = finalPalette;
|
|
23732
|
+
return finalPalette;
|
|
20824
23733
|
}
|
|
20825
23734
|
}
|
|
20826
23735
|
|
|
20827
|
-
export { __toESM, __commonJS, __export, __require,
|
|
23736
|
+
export { __toESM, __commonJS, __export, __require, MeasureMode, exports_src, isValidBorderStyle, parseBorderStyle, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, KeyEvent, PasteEvent, KeyHandler, InternalKeyHandler, COLOR_TAG_RGB, COLOR_TAG_DEFAULT, DEFAULT_FOREGROUND_RGB, DEFAULT_BACKGROUND_RGB, normalizeIndexedColorIndex, ansi256IndexToRgb, decodeColorTag, RGBA, normalizeColorValue, 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, normalizeTerminalPalette, buildTerminalPaletteSignature, 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 };
|
|
20828
23737
|
|
|
20829
|
-
//# debugId=
|
|
20830
|
-
//# sourceMappingURL=index-
|
|
23738
|
+
//# debugId=B1BCF94D9F983F0164756E2164756E21
|
|
23739
|
+
//# sourceMappingURL=index-4pvh4sbk.js.map
|