@opentui/core 0.1.25 → 0.1.27
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 +140 -140
- package/3d.js.map +2 -2
- package/README.md +5 -1
- package/Renderable.d.ts +8 -7
- package/animation/Timeline.d.ts +2 -1
- package/assets/javascript/highlights.scm +205 -0
- package/assets/javascript/tree-sitter-javascript.wasm +0 -0
- package/assets/typescript/highlights.scm +604 -0
- package/assets/typescript/tree-sitter-typescript.wasm +0 -0
- package/{index-6kvgbzah.js → index-zx1dwm33.js} +1498 -133
- package/index-zx1dwm33.js.map +52 -0
- package/index.js +2371 -2179
- package/index.js.map +16 -14
- package/lib/KeyHandler.d.ts +54 -12
- package/lib/data-paths.d.ts +26 -0
- package/lib/debounce.d.ts +42 -0
- package/lib/env.d.ts +2 -1
- package/lib/hast-styled-text.d.ts +3 -23
- package/lib/index.d.ts +5 -0
- package/lib/parse.keypress.d.ts +2 -2
- package/lib/queue.d.ts +15 -0
- package/lib/scroll-acceleration.d.ts +43 -0
- package/lib/singleton.d.ts +2 -0
- package/lib/styled-text.d.ts +0 -15
- package/lib/syntax-style.d.ts +36 -0
- package/lib/tree-sitter/assets/update.d.ts +11 -0
- package/lib/tree-sitter/client.d.ts +46 -0
- package/lib/tree-sitter/default-parsers.d.ts +2 -0
- package/lib/tree-sitter/download-utils.d.ts +21 -0
- package/lib/tree-sitter/index.d.ts +10 -0
- package/lib/tree-sitter/parser.worker.d.ts +1 -0
- package/lib/tree-sitter/resolve-ft.d.ts +2 -0
- package/lib/tree-sitter/types.d.ts +64 -0
- package/lib/tree-sitter-styled-text.d.ts +7 -0
- package/lib/validate-dir-name.d.ts +1 -0
- package/package.json +22 -8
- package/parser.worker.js +640 -0
- package/parser.worker.js.map +11 -0
- package/renderables/Code.d.ts +31 -0
- package/renderables/Input.d.ts +2 -2
- package/renderables/ScrollBar.d.ts +2 -2
- package/renderables/ScrollBox.d.ts +9 -3
- package/renderables/Select.d.ts +2 -2
- package/renderables/TabSelect.d.ts +2 -2
- package/renderables/Text.d.ts +10 -67
- package/renderables/TextBufferRenderable.d.ts +81 -0
- package/renderables/TextNode.d.ts +3 -1
- package/renderables/index.d.ts +11 -8
- package/renderer.d.ts +18 -3
- package/testing/spy.d.ts +7 -0
- package/testing.d.ts +1 -0
- package/testing.js +17 -2
- package/testing.js.map +5 -4
- package/types.d.ts +2 -1
- package/index-6kvgbzah.js.map +0 -39
|
@@ -27,7 +27,7 @@ var __export = (target, all) => {
|
|
|
27
27
|
};
|
|
28
28
|
var __require = import.meta.require;
|
|
29
29
|
|
|
30
|
-
// ../../node_modules/yoga-layout/dist/src/index.js
|
|
30
|
+
// ../../node_modules/.bun/yoga-layout@3.2.1/node_modules/yoga-layout/dist/src/index.js
|
|
31
31
|
var exports_src = {};
|
|
32
32
|
__export(exports_src, {
|
|
33
33
|
default: () => src_default,
|
|
@@ -51,7 +51,7 @@ __export(exports_src, {
|
|
|
51
51
|
Align: () => Align
|
|
52
52
|
});
|
|
53
53
|
|
|
54
|
-
// ../../node_modules/yoga-layout/dist/binaries/yoga-wasm-base64-esm.js
|
|
54
|
+
// ../../node_modules/.bun/yoga-layout@3.2.1/node_modules/yoga-layout/dist/binaries/yoga-wasm-base64-esm.js
|
|
55
55
|
var loadYoga = (() => {
|
|
56
56
|
var _scriptDir = import.meta.url;
|
|
57
57
|
return function(loadYoga2) {
|
|
@@ -1356,7 +1356,7 @@ var loadYoga = (() => {
|
|
|
1356
1356
|
})();
|
|
1357
1357
|
var yoga_wasm_base64_esm_default = loadYoga;
|
|
1358
1358
|
|
|
1359
|
-
// ../../node_modules/yoga-layout/dist/src/generated/YGEnums.js
|
|
1359
|
+
// ../../node_modules/.bun/yoga-layout@3.2.1/node_modules/yoga-layout/dist/src/generated/YGEnums.js
|
|
1360
1360
|
var Align = /* @__PURE__ */ function(Align2) {
|
|
1361
1361
|
Align2[Align2["Auto"] = 0] = "Auto";
|
|
1362
1362
|
Align2[Align2["FlexStart"] = 1] = "FlexStart";
|
|
@@ -1559,7 +1559,7 @@ var constants = {
|
|
|
1559
1559
|
};
|
|
1560
1560
|
var YGEnums_default = constants;
|
|
1561
1561
|
|
|
1562
|
-
// ../../node_modules/yoga-layout/dist/src/wrapAssembly.js
|
|
1562
|
+
// ../../node_modules/.bun/yoga-layout@3.2.1/node_modules/yoga-layout/dist/src/wrapAssembly.js
|
|
1563
1563
|
function wrapAssembly(lib) {
|
|
1564
1564
|
function patch(prototype, name, fn) {
|
|
1565
1565
|
const original = prototype[name];
|
|
@@ -1661,7 +1661,7 @@ function wrapAssembly(lib) {
|
|
|
1661
1661
|
};
|
|
1662
1662
|
}
|
|
1663
1663
|
|
|
1664
|
-
// ../../node_modules/yoga-layout/dist/src/index.js
|
|
1664
|
+
// ../../node_modules/.bun/yoga-layout@3.2.1/node_modules/yoga-layout/dist/src/index.js
|
|
1665
1665
|
var Yoga = wrapAssembly(await yoga_wasm_base64_esm_default());
|
|
1666
1666
|
var src_default = Yoga;
|
|
1667
1667
|
|
|
@@ -1763,7 +1763,7 @@ var BorderCharArrays = {
|
|
|
1763
1763
|
};
|
|
1764
1764
|
|
|
1765
1765
|
// src/lib/parse.keypress.ts
|
|
1766
|
-
import { Buffer } from "buffer";
|
|
1766
|
+
import { Buffer as Buffer2 } from "buffer";
|
|
1767
1767
|
|
|
1768
1768
|
// src/lib/parse.keypress-kitty.ts
|
|
1769
1769
|
var kittyKeyMap = {
|
|
@@ -2080,7 +2080,7 @@ var isCtrlKey = (code) => {
|
|
|
2080
2080
|
};
|
|
2081
2081
|
var parseKeypress = (s = "", options = {}) => {
|
|
2082
2082
|
let parts;
|
|
2083
|
-
if (
|
|
2083
|
+
if (Buffer2.isBuffer(s)) {
|
|
2084
2084
|
if (s[0] > 127 && s[1] === undefined) {
|
|
2085
2085
|
s[0] -= 128;
|
|
2086
2086
|
s = "\x1B" + String(s);
|
|
@@ -2143,6 +2143,10 @@ var parseKeypress = (s = "", options = {}) => {
|
|
|
2143
2143
|
key.meta = true;
|
|
2144
2144
|
key.shift = /^[A-Z]$/.test(parts[1]);
|
|
2145
2145
|
key.name = parts[1];
|
|
2146
|
+
} else if (s.length === 2 && s[0] === "\x1B" && s[1] <= "\x1A") {
|
|
2147
|
+
key.meta = true;
|
|
2148
|
+
key.ctrl = true;
|
|
2149
|
+
key.name = String.fromCharCode(s.charCodeAt(1) + 97 - 1);
|
|
2146
2150
|
} else if (parts = fnKeyRe.exec(s)) {
|
|
2147
2151
|
const segs = [...s];
|
|
2148
2152
|
if (segs[0] === "\x1B" && segs[1] === "\x1B") {
|
|
@@ -2191,12 +2195,69 @@ var ANSI = {
|
|
|
2191
2195
|
};
|
|
2192
2196
|
|
|
2193
2197
|
// src/lib/KeyHandler.ts
|
|
2198
|
+
class KeyEvent {
|
|
2199
|
+
name;
|
|
2200
|
+
ctrl;
|
|
2201
|
+
meta;
|
|
2202
|
+
shift;
|
|
2203
|
+
option;
|
|
2204
|
+
sequence;
|
|
2205
|
+
number;
|
|
2206
|
+
raw;
|
|
2207
|
+
eventType;
|
|
2208
|
+
code;
|
|
2209
|
+
super;
|
|
2210
|
+
hyper;
|
|
2211
|
+
capsLock;
|
|
2212
|
+
numLock;
|
|
2213
|
+
baseCode;
|
|
2214
|
+
_defaultPrevented = false;
|
|
2215
|
+
constructor(key) {
|
|
2216
|
+
this.name = key.name;
|
|
2217
|
+
this.ctrl = key.ctrl;
|
|
2218
|
+
this.meta = key.meta;
|
|
2219
|
+
this.shift = key.shift;
|
|
2220
|
+
this.option = key.option;
|
|
2221
|
+
this.sequence = key.sequence;
|
|
2222
|
+
this.number = key.number;
|
|
2223
|
+
this.raw = key.raw;
|
|
2224
|
+
this.eventType = key.eventType;
|
|
2225
|
+
this.code = key.code;
|
|
2226
|
+
this.super = key.super;
|
|
2227
|
+
this.hyper = key.hyper;
|
|
2228
|
+
this.capsLock = key.capsLock;
|
|
2229
|
+
this.numLock = key.numLock;
|
|
2230
|
+
this.baseCode = key.baseCode;
|
|
2231
|
+
}
|
|
2232
|
+
get defaultPrevented() {
|
|
2233
|
+
return this._defaultPrevented;
|
|
2234
|
+
}
|
|
2235
|
+
preventDefault() {
|
|
2236
|
+
this._defaultPrevented = true;
|
|
2237
|
+
}
|
|
2238
|
+
}
|
|
2239
|
+
|
|
2240
|
+
class PasteEvent {
|
|
2241
|
+
text;
|
|
2242
|
+
_defaultPrevented = false;
|
|
2243
|
+
constructor(text) {
|
|
2244
|
+
this.text = text;
|
|
2245
|
+
}
|
|
2246
|
+
get defaultPrevented() {
|
|
2247
|
+
return this._defaultPrevented;
|
|
2248
|
+
}
|
|
2249
|
+
preventDefault() {
|
|
2250
|
+
this._defaultPrevented = true;
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
|
|
2194
2254
|
class KeyHandler extends EventEmitter {
|
|
2195
2255
|
stdin;
|
|
2196
2256
|
useKittyKeyboard;
|
|
2197
2257
|
listener;
|
|
2198
2258
|
pasteMode = false;
|
|
2199
2259
|
pasteBuffer = [];
|
|
2260
|
+
suspended = false;
|
|
2200
2261
|
constructor(stdin, useKittyKeyboard = false) {
|
|
2201
2262
|
super();
|
|
2202
2263
|
this.stdin = stdin || process.stdin;
|
|
@@ -2210,7 +2271,7 @@ class KeyHandler extends EventEmitter {
|
|
|
2210
2271
|
this.pasteBuffer.push(Bun.stripANSI(data));
|
|
2211
2272
|
if (data.endsWith(ANSI.bracketedPasteEnd)) {
|
|
2212
2273
|
this.pasteMode = false;
|
|
2213
|
-
this.emit("paste", this.pasteBuffer.join(""));
|
|
2274
|
+
this.emit("paste", new PasteEvent(this.pasteBuffer.join("")));
|
|
2214
2275
|
this.pasteBuffer = [];
|
|
2215
2276
|
}
|
|
2216
2277
|
return;
|
|
@@ -2218,16 +2279,16 @@ class KeyHandler extends EventEmitter {
|
|
|
2218
2279
|
const parsedKey = parseKeypress(key, { useKittyKeyboard: this.useKittyKeyboard });
|
|
2219
2280
|
switch (parsedKey.eventType) {
|
|
2220
2281
|
case "press":
|
|
2221
|
-
this.emit("keypress", parsedKey);
|
|
2282
|
+
this.emit("keypress", new KeyEvent(parsedKey));
|
|
2222
2283
|
break;
|
|
2223
2284
|
case "repeat":
|
|
2224
|
-
this.emit("keyrepeat", parsedKey);
|
|
2285
|
+
this.emit("keyrepeat", new KeyEvent(parsedKey));
|
|
2225
2286
|
break;
|
|
2226
2287
|
case "release":
|
|
2227
|
-
this.emit("keyrelease", parsedKey);
|
|
2288
|
+
this.emit("keyrelease", new KeyEvent(parsedKey));
|
|
2228
2289
|
break;
|
|
2229
2290
|
default:
|
|
2230
|
-
this.emit("keypress", parsedKey);
|
|
2291
|
+
this.emit("keypress", new KeyEvent(parsedKey));
|
|
2231
2292
|
break;
|
|
2232
2293
|
}
|
|
2233
2294
|
};
|
|
@@ -2236,6 +2297,57 @@ class KeyHandler extends EventEmitter {
|
|
|
2236
2297
|
destroy() {
|
|
2237
2298
|
this.stdin.removeListener("data", this.listener);
|
|
2238
2299
|
}
|
|
2300
|
+
suspend() {
|
|
2301
|
+
if (!this.suspended) {
|
|
2302
|
+
this.suspended = true;
|
|
2303
|
+
this.stdin.removeListener("data", this.listener);
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
2306
|
+
resume() {
|
|
2307
|
+
if (this.suspended) {
|
|
2308
|
+
this.suspended = false;
|
|
2309
|
+
this.stdin.on("data", this.listener);
|
|
2310
|
+
}
|
|
2311
|
+
}
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2314
|
+
class InternalKeyHandler extends KeyHandler {
|
|
2315
|
+
renderableHandlers = new Map;
|
|
2316
|
+
constructor(stdin, useKittyKeyboard = false) {
|
|
2317
|
+
super(stdin, useKittyKeyboard);
|
|
2318
|
+
}
|
|
2319
|
+
emit(event, ...args) {
|
|
2320
|
+
return this.emitWithPriority(event, ...args);
|
|
2321
|
+
}
|
|
2322
|
+
emitWithPriority(event, ...args) {
|
|
2323
|
+
const hasGlobalListeners = super.emit(event, ...args);
|
|
2324
|
+
const renderableSet = this.renderableHandlers.get(event);
|
|
2325
|
+
let hasRenderableListeners = false;
|
|
2326
|
+
if (renderableSet && renderableSet.size > 0) {
|
|
2327
|
+
hasRenderableListeners = true;
|
|
2328
|
+
if (event === "keypress" || event === "keyrepeat" || event === "keyrelease" || event === "paste") {
|
|
2329
|
+
const keyEvent = args[0];
|
|
2330
|
+
if (keyEvent.defaultPrevented)
|
|
2331
|
+
return hasGlobalListeners || hasRenderableListeners;
|
|
2332
|
+
}
|
|
2333
|
+
for (const handler of renderableSet) {
|
|
2334
|
+
handler(...args);
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
return hasGlobalListeners || hasRenderableListeners;
|
|
2338
|
+
}
|
|
2339
|
+
onInternal(event, handler) {
|
|
2340
|
+
if (!this.renderableHandlers.has(event)) {
|
|
2341
|
+
this.renderableHandlers.set(event, new Set);
|
|
2342
|
+
}
|
|
2343
|
+
this.renderableHandlers.get(event).add(handler);
|
|
2344
|
+
}
|
|
2345
|
+
offInternal(event, handler) {
|
|
2346
|
+
const handlers = this.renderableHandlers.get(event);
|
|
2347
|
+
if (handlers) {
|
|
2348
|
+
handlers.delete(handler);
|
|
2349
|
+
}
|
|
2350
|
+
}
|
|
2239
2351
|
}
|
|
2240
2352
|
|
|
2241
2353
|
// src/lib/RGBA.ts
|
|
@@ -4089,60 +4201,9 @@ function isStyledText(obj) {
|
|
|
4089
4201
|
class StyledText {
|
|
4090
4202
|
[BrandedStyledText] = true;
|
|
4091
4203
|
chunks;
|
|
4092
|
-
textRenderable;
|
|
4093
4204
|
constructor(chunks) {
|
|
4094
4205
|
this.chunks = chunks;
|
|
4095
4206
|
}
|
|
4096
|
-
mount(textRenderable) {
|
|
4097
|
-
this.textRenderable = textRenderable;
|
|
4098
|
-
}
|
|
4099
|
-
insert(chunk, index) {
|
|
4100
|
-
const originalLength = this.chunks.length;
|
|
4101
|
-
if (this.textRenderable) {
|
|
4102
|
-
this.textRenderable.insertChunk(chunk, index ?? originalLength);
|
|
4103
|
-
let newChunks;
|
|
4104
|
-
if (index === undefined || index === originalLength) {
|
|
4105
|
-
newChunks = [...this.chunks, chunk];
|
|
4106
|
-
} else {
|
|
4107
|
-
newChunks = [...this.chunks.slice(0, index), chunk, ...this.chunks.slice(index)];
|
|
4108
|
-
}
|
|
4109
|
-
this.chunks = newChunks;
|
|
4110
|
-
}
|
|
4111
|
-
return this;
|
|
4112
|
-
}
|
|
4113
|
-
remove(chunk) {
|
|
4114
|
-
if (this.textRenderable) {
|
|
4115
|
-
this.textRenderable.removeChunk(chunk);
|
|
4116
|
-
const originalLength = this.chunks.length;
|
|
4117
|
-
const index = this.chunks.indexOf(chunk);
|
|
4118
|
-
if (index === -1)
|
|
4119
|
-
return this;
|
|
4120
|
-
let newChunks;
|
|
4121
|
-
if (index === originalLength - 1) {
|
|
4122
|
-
newChunks = this.chunks.slice(0, -1);
|
|
4123
|
-
} else {
|
|
4124
|
-
newChunks = [...this.chunks.slice(0, index), ...this.chunks.slice(index + 1)];
|
|
4125
|
-
}
|
|
4126
|
-
this.chunks = newChunks;
|
|
4127
|
-
}
|
|
4128
|
-
return this;
|
|
4129
|
-
}
|
|
4130
|
-
replace(chunk, oldChunk) {
|
|
4131
|
-
if (this.textRenderable) {
|
|
4132
|
-
this.textRenderable.replaceChunk(chunk, oldChunk);
|
|
4133
|
-
const index = this.chunks.indexOf(oldChunk);
|
|
4134
|
-
if (index === -1)
|
|
4135
|
-
return this;
|
|
4136
|
-
let newChunks;
|
|
4137
|
-
if (index === this.chunks.length - 1) {
|
|
4138
|
-
newChunks = [...this.chunks.slice(0, -1), chunk];
|
|
4139
|
-
} else {
|
|
4140
|
-
newChunks = [...this.chunks.slice(0, index), chunk, ...this.chunks.slice(index + 1)];
|
|
4141
|
-
}
|
|
4142
|
-
this.chunks = newChunks;
|
|
4143
|
-
}
|
|
4144
|
-
return this;
|
|
4145
|
-
}
|
|
4146
4207
|
}
|
|
4147
4208
|
function stringToStyledText(content) {
|
|
4148
4209
|
const chunk = {
|
|
@@ -4238,7 +4299,36 @@ function t(strings, ...values) {
|
|
|
4238
4299
|
return new StyledText(chunks);
|
|
4239
4300
|
}
|
|
4240
4301
|
|
|
4241
|
-
// src/lib/
|
|
4302
|
+
// src/lib/syntax-style.ts
|
|
4303
|
+
function convertThemeToStyles(theme) {
|
|
4304
|
+
const flatStyles = {};
|
|
4305
|
+
for (const tokenStyle of theme) {
|
|
4306
|
+
const styleDefinition = {};
|
|
4307
|
+
if (tokenStyle.style.foreground) {
|
|
4308
|
+
styleDefinition.fg = parseColor(tokenStyle.style.foreground);
|
|
4309
|
+
}
|
|
4310
|
+
if (tokenStyle.style.background) {
|
|
4311
|
+
styleDefinition.bg = parseColor(tokenStyle.style.background);
|
|
4312
|
+
}
|
|
4313
|
+
if (tokenStyle.style.bold !== undefined) {
|
|
4314
|
+
styleDefinition.bold = tokenStyle.style.bold;
|
|
4315
|
+
}
|
|
4316
|
+
if (tokenStyle.style.italic !== undefined) {
|
|
4317
|
+
styleDefinition.italic = tokenStyle.style.italic;
|
|
4318
|
+
}
|
|
4319
|
+
if (tokenStyle.style.underline !== undefined) {
|
|
4320
|
+
styleDefinition.underline = tokenStyle.style.underline;
|
|
4321
|
+
}
|
|
4322
|
+
if (tokenStyle.style.dim !== undefined) {
|
|
4323
|
+
styleDefinition.dim = tokenStyle.style.dim;
|
|
4324
|
+
}
|
|
4325
|
+
for (const scope of tokenStyle.scope) {
|
|
4326
|
+
flatStyles[scope] = styleDefinition;
|
|
4327
|
+
}
|
|
4328
|
+
}
|
|
4329
|
+
return flatStyles;
|
|
4330
|
+
}
|
|
4331
|
+
|
|
4242
4332
|
class SyntaxStyle {
|
|
4243
4333
|
styles;
|
|
4244
4334
|
mergedStyleCache;
|
|
@@ -4246,6 +4336,10 @@ class SyntaxStyle {
|
|
|
4246
4336
|
this.styles = styles;
|
|
4247
4337
|
this.mergedStyleCache = new Map;
|
|
4248
4338
|
}
|
|
4339
|
+
static fromTheme(theme) {
|
|
4340
|
+
const flatStyles = convertThemeToStyles(theme);
|
|
4341
|
+
return new SyntaxStyle(flatStyles);
|
|
4342
|
+
}
|
|
4249
4343
|
mergeStyles(...styleNames) {
|
|
4250
4344
|
const cacheKey = styleNames.join(":");
|
|
4251
4345
|
const cached = this.mergedStyleCache.get(cacheKey);
|
|
@@ -4253,7 +4347,7 @@ class SyntaxStyle {
|
|
|
4253
4347
|
return cached;
|
|
4254
4348
|
const styleDefinition = {};
|
|
4255
4349
|
for (const name of styleNames) {
|
|
4256
|
-
const style = this.
|
|
4350
|
+
const style = this.getStyle(name);
|
|
4257
4351
|
if (!style)
|
|
4258
4352
|
continue;
|
|
4259
4353
|
if (style.fg)
|
|
@@ -4283,6 +4377,18 @@ class SyntaxStyle {
|
|
|
4283
4377
|
this.mergedStyleCache.set(cacheKey, merged);
|
|
4284
4378
|
return merged;
|
|
4285
4379
|
}
|
|
4380
|
+
getStyle(name) {
|
|
4381
|
+
if (Object.prototype.hasOwnProperty.call(this.styles, name)) {
|
|
4382
|
+
return this.styles[name];
|
|
4383
|
+
}
|
|
4384
|
+
if (name.includes(".")) {
|
|
4385
|
+
const baseName = name.split(".")[0];
|
|
4386
|
+
if (Object.prototype.hasOwnProperty.call(this.styles, baseName)) {
|
|
4387
|
+
return this.styles[baseName];
|
|
4388
|
+
}
|
|
4389
|
+
}
|
|
4390
|
+
return;
|
|
4391
|
+
}
|
|
4286
4392
|
clearCache() {
|
|
4287
4393
|
this.mergedStyleCache.clear();
|
|
4288
4394
|
}
|
|
@@ -4290,6 +4396,8 @@ class SyntaxStyle {
|
|
|
4290
4396
|
return this.mergedStyleCache.size;
|
|
4291
4397
|
}
|
|
4292
4398
|
}
|
|
4399
|
+
|
|
4400
|
+
// src/lib/hast-styled-text.ts
|
|
4293
4401
|
function hastToTextChunks(node, syntaxStyle, parentStyles = []) {
|
|
4294
4402
|
const chunks = [];
|
|
4295
4403
|
if (node.type === "text") {
|
|
@@ -4321,6 +4429,55 @@ function hastToStyledText(hast, syntaxStyle) {
|
|
|
4321
4429
|
return new StyledText(chunks);
|
|
4322
4430
|
}
|
|
4323
4431
|
|
|
4432
|
+
// src/lib/scroll-acceleration.ts
|
|
4433
|
+
class LinearScrollAccel {
|
|
4434
|
+
tick(_now) {
|
|
4435
|
+
return 1;
|
|
4436
|
+
}
|
|
4437
|
+
reset() {}
|
|
4438
|
+
}
|
|
4439
|
+
|
|
4440
|
+
class MacOSScrollAccel {
|
|
4441
|
+
opts;
|
|
4442
|
+
lastTickTime = 0;
|
|
4443
|
+
velocityHistory = [];
|
|
4444
|
+
historySize = 3;
|
|
4445
|
+
streakTimeout = 150;
|
|
4446
|
+
minTickInterval = 6;
|
|
4447
|
+
constructor(opts = {}) {
|
|
4448
|
+
this.opts = opts;
|
|
4449
|
+
}
|
|
4450
|
+
tick(now = Date.now()) {
|
|
4451
|
+
const A = this.opts.A ?? 0.8;
|
|
4452
|
+
const tau = this.opts.tau ?? 3;
|
|
4453
|
+
const maxMultiplier = this.opts.maxMultiplier ?? 6;
|
|
4454
|
+
const dt = this.lastTickTime ? now - this.lastTickTime : Infinity;
|
|
4455
|
+
if (dt === Infinity || dt > this.streakTimeout) {
|
|
4456
|
+
this.lastTickTime = now;
|
|
4457
|
+
this.velocityHistory = [];
|
|
4458
|
+
return 1;
|
|
4459
|
+
}
|
|
4460
|
+
if (dt < this.minTickInterval) {
|
|
4461
|
+
return 1;
|
|
4462
|
+
}
|
|
4463
|
+
this.lastTickTime = now;
|
|
4464
|
+
this.velocityHistory.push(dt);
|
|
4465
|
+
if (this.velocityHistory.length > this.historySize) {
|
|
4466
|
+
this.velocityHistory.shift();
|
|
4467
|
+
}
|
|
4468
|
+
const avgInterval = this.velocityHistory.reduce((a, b) => a + b, 0) / this.velocityHistory.length;
|
|
4469
|
+
const referenceInterval = 100;
|
|
4470
|
+
const velocity = referenceInterval / avgInterval;
|
|
4471
|
+
const x = velocity / tau;
|
|
4472
|
+
const multiplier = 1 + A * (Math.exp(x) - 1);
|
|
4473
|
+
return Math.min(multiplier, maxMultiplier);
|
|
4474
|
+
}
|
|
4475
|
+
reset() {
|
|
4476
|
+
this.lastTickTime = 0;
|
|
4477
|
+
this.velocityHistory = [];
|
|
4478
|
+
}
|
|
4479
|
+
}
|
|
4480
|
+
|
|
4324
4481
|
// src/lib/yoga.options.ts
|
|
4325
4482
|
function parseAlign(value) {
|
|
4326
4483
|
switch (value.toLowerCase()) {
|
|
@@ -4824,9 +4981,19 @@ function singleton(key, factory) {
|
|
|
4824
4981
|
}
|
|
4825
4982
|
return bag[key];
|
|
4826
4983
|
}
|
|
4984
|
+
function destroySingleton(key) {
|
|
4985
|
+
const bag = globalThis[singletonCacheSymbol];
|
|
4986
|
+
if (bag && key in bag) {
|
|
4987
|
+
delete bag[key];
|
|
4988
|
+
}
|
|
4989
|
+
}
|
|
4990
|
+
function hasSingleton(key) {
|
|
4991
|
+
const bag = globalThis[singletonCacheSymbol];
|
|
4992
|
+
return bag && key in bag;
|
|
4993
|
+
}
|
|
4827
4994
|
|
|
4828
4995
|
// src/lib/env.ts
|
|
4829
|
-
var envRegistry = {};
|
|
4996
|
+
var envRegistry = singleton("env-registry", () => ({}));
|
|
4830
4997
|
function registerEnvVar(config) {
|
|
4831
4998
|
const existing = envRegistry[config.name];
|
|
4832
4999
|
if (existing) {
|
|
@@ -4884,8 +5051,14 @@ class EnvStore {
|
|
|
4884
5051
|
has(key) {
|
|
4885
5052
|
return key in envRegistry;
|
|
4886
5053
|
}
|
|
5054
|
+
clearCache() {
|
|
5055
|
+
this.parsedValues.clear();
|
|
5056
|
+
}
|
|
4887
5057
|
}
|
|
4888
5058
|
var envStore = singleton("env-store", () => new EnvStore);
|
|
5059
|
+
function clearEnvCache() {
|
|
5060
|
+
envStore.clearCache();
|
|
5061
|
+
}
|
|
4889
5062
|
function generateEnvMarkdown() {
|
|
4890
5063
|
const configs = Object.values(envRegistry);
|
|
4891
5064
|
if (configs.length === 0) {
|
|
@@ -4974,9 +5147,1115 @@ var env = new Proxy({}, {
|
|
|
4974
5147
|
return;
|
|
4975
5148
|
}
|
|
4976
5149
|
});
|
|
5150
|
+
|
|
5151
|
+
// src/lib/tree-sitter-styled-text.ts
|
|
5152
|
+
function treeSitterToTextChunks(content, highlights, syntaxStyle) {
|
|
5153
|
+
const chunks = [];
|
|
5154
|
+
const defaultStyle = syntaxStyle.getStyle("default");
|
|
5155
|
+
let currentIndex = 0;
|
|
5156
|
+
for (let i = 0;i < highlights.length; i++) {
|
|
5157
|
+
const [startIndex, endIndex, group] = highlights[i];
|
|
5158
|
+
if (startIndex < currentIndex)
|
|
5159
|
+
continue;
|
|
5160
|
+
if (currentIndex < startIndex) {
|
|
5161
|
+
const text2 = content.slice(currentIndex, startIndex);
|
|
5162
|
+
chunks.push({
|
|
5163
|
+
__isChunk: true,
|
|
5164
|
+
text: text2,
|
|
5165
|
+
fg: defaultStyle?.fg,
|
|
5166
|
+
bg: defaultStyle?.bg,
|
|
5167
|
+
attributes: defaultStyle ? createTextAttributes({
|
|
5168
|
+
bold: defaultStyle.bold,
|
|
5169
|
+
italic: defaultStyle.italic,
|
|
5170
|
+
underline: defaultStyle.underline,
|
|
5171
|
+
dim: defaultStyle.dim
|
|
5172
|
+
}) : 0
|
|
5173
|
+
});
|
|
5174
|
+
currentIndex = startIndex;
|
|
5175
|
+
}
|
|
5176
|
+
let resolvedStyle = syntaxStyle.getStyle(group);
|
|
5177
|
+
let j = i + 1;
|
|
5178
|
+
while (j < highlights.length && highlights[j][0] === startIndex) {
|
|
5179
|
+
const [, , nextGroup] = highlights[j];
|
|
5180
|
+
const nextStyle = syntaxStyle.getStyle(nextGroup);
|
|
5181
|
+
if (nextStyle) {
|
|
5182
|
+
resolvedStyle = nextStyle;
|
|
5183
|
+
}
|
|
5184
|
+
j++;
|
|
5185
|
+
}
|
|
5186
|
+
i = j - 1;
|
|
5187
|
+
const text = content.slice(startIndex, endIndex);
|
|
5188
|
+
const styleToUse = resolvedStyle || defaultStyle;
|
|
5189
|
+
chunks.push({
|
|
5190
|
+
__isChunk: true,
|
|
5191
|
+
text,
|
|
5192
|
+
fg: styleToUse?.fg,
|
|
5193
|
+
bg: styleToUse?.bg,
|
|
5194
|
+
attributes: styleToUse ? createTextAttributes({
|
|
5195
|
+
bold: styleToUse.bold,
|
|
5196
|
+
italic: styleToUse.italic,
|
|
5197
|
+
underline: styleToUse.underline,
|
|
5198
|
+
dim: styleToUse.dim
|
|
5199
|
+
}) : 0
|
|
5200
|
+
});
|
|
5201
|
+
currentIndex = endIndex;
|
|
5202
|
+
}
|
|
5203
|
+
if (currentIndex < content.length) {
|
|
5204
|
+
const text = content.slice(currentIndex);
|
|
5205
|
+
chunks.push({
|
|
5206
|
+
__isChunk: true,
|
|
5207
|
+
text,
|
|
5208
|
+
fg: defaultStyle?.fg,
|
|
5209
|
+
bg: defaultStyle?.bg,
|
|
5210
|
+
attributes: defaultStyle ? createTextAttributes({
|
|
5211
|
+
bold: defaultStyle.bold,
|
|
5212
|
+
italic: defaultStyle.italic,
|
|
5213
|
+
underline: defaultStyle.underline,
|
|
5214
|
+
dim: defaultStyle.dim
|
|
5215
|
+
}) : 0
|
|
5216
|
+
});
|
|
5217
|
+
}
|
|
5218
|
+
return chunks;
|
|
5219
|
+
}
|
|
5220
|
+
async function treeSitterToStyledText(content, filetype, syntaxStyle, client) {
|
|
5221
|
+
const result = await client.highlightOnce(content, filetype);
|
|
5222
|
+
if (result.highlights && result.highlights.length > 0) {
|
|
5223
|
+
const chunks = treeSitterToTextChunks(content, result.highlights, syntaxStyle);
|
|
5224
|
+
return new StyledText(chunks);
|
|
5225
|
+
} else {
|
|
5226
|
+
const defaultStyle = syntaxStyle.mergeStyles("default");
|
|
5227
|
+
const chunks = [
|
|
5228
|
+
{
|
|
5229
|
+
__isChunk: true,
|
|
5230
|
+
text: content,
|
|
5231
|
+
fg: defaultStyle.fg,
|
|
5232
|
+
bg: defaultStyle.bg,
|
|
5233
|
+
attributes: defaultStyle.attributes
|
|
5234
|
+
}
|
|
5235
|
+
];
|
|
5236
|
+
return new StyledText(chunks);
|
|
5237
|
+
}
|
|
5238
|
+
}
|
|
5239
|
+
|
|
5240
|
+
// src/lib/tree-sitter/client.ts
|
|
5241
|
+
import { EventEmitter as EventEmitter2 } from "events";
|
|
5242
|
+
|
|
5243
|
+
// src/lib/debounce.ts
|
|
5244
|
+
var TIMERS_MAP = new Map;
|
|
5245
|
+
|
|
5246
|
+
class DebounceController {
|
|
5247
|
+
scopeId;
|
|
5248
|
+
constructor(scopeId) {
|
|
5249
|
+
this.scopeId = scopeId;
|
|
5250
|
+
if (!TIMERS_MAP.has(this.scopeId)) {
|
|
5251
|
+
TIMERS_MAP.set(this.scopeId, new Map);
|
|
5252
|
+
}
|
|
5253
|
+
}
|
|
5254
|
+
debounce(id, ms, fn) {
|
|
5255
|
+
const scopeMap = TIMERS_MAP.get(this.scopeId);
|
|
5256
|
+
return new Promise((resolve, reject) => {
|
|
5257
|
+
if (scopeMap.has(id)) {
|
|
5258
|
+
clearTimeout(scopeMap.get(id));
|
|
5259
|
+
}
|
|
5260
|
+
const timerId = setTimeout(() => {
|
|
5261
|
+
try {
|
|
5262
|
+
resolve(fn());
|
|
5263
|
+
} catch (error) {
|
|
5264
|
+
reject(error);
|
|
5265
|
+
}
|
|
5266
|
+
scopeMap.delete(id);
|
|
5267
|
+
}, ms);
|
|
5268
|
+
scopeMap.set(id, timerId);
|
|
5269
|
+
});
|
|
5270
|
+
}
|
|
5271
|
+
clearDebounce(id) {
|
|
5272
|
+
const scopeMap = TIMERS_MAP.get(this.scopeId);
|
|
5273
|
+
if (scopeMap && scopeMap.has(id)) {
|
|
5274
|
+
clearTimeout(scopeMap.get(id));
|
|
5275
|
+
scopeMap.delete(id);
|
|
5276
|
+
}
|
|
5277
|
+
}
|
|
5278
|
+
clear() {
|
|
5279
|
+
const scopeMap = TIMERS_MAP.get(this.scopeId);
|
|
5280
|
+
if (scopeMap) {
|
|
5281
|
+
scopeMap.forEach((timerId) => clearTimeout(timerId));
|
|
5282
|
+
scopeMap.clear();
|
|
5283
|
+
}
|
|
5284
|
+
}
|
|
5285
|
+
}
|
|
5286
|
+
function createDebounce(scopeId) {
|
|
5287
|
+
return new DebounceController(scopeId);
|
|
5288
|
+
}
|
|
5289
|
+
function clearDebounceScope(scopeId) {
|
|
5290
|
+
const scopeMap = TIMERS_MAP.get(scopeId);
|
|
5291
|
+
if (scopeMap) {
|
|
5292
|
+
scopeMap.forEach((timerId) => clearTimeout(timerId));
|
|
5293
|
+
scopeMap.clear();
|
|
5294
|
+
}
|
|
5295
|
+
}
|
|
5296
|
+
|
|
5297
|
+
// src/lib/queue.ts
|
|
5298
|
+
class ProcessQueue {
|
|
5299
|
+
processor;
|
|
5300
|
+
queue = [];
|
|
5301
|
+
processing = false;
|
|
5302
|
+
autoProcess = true;
|
|
5303
|
+
constructor(processor, autoProcess = true) {
|
|
5304
|
+
this.processor = processor;
|
|
5305
|
+
this.autoProcess = autoProcess;
|
|
5306
|
+
}
|
|
5307
|
+
enqueue(item) {
|
|
5308
|
+
this.queue.push(item);
|
|
5309
|
+
if (!this.processing && this.autoProcess) {
|
|
5310
|
+
this.processQueue();
|
|
5311
|
+
}
|
|
5312
|
+
}
|
|
5313
|
+
processQueue() {
|
|
5314
|
+
if (this.queue.length === 0) {
|
|
5315
|
+
return;
|
|
5316
|
+
}
|
|
5317
|
+
this.processing = true;
|
|
5318
|
+
queueMicrotask(async () => {
|
|
5319
|
+
if (this.queue.length === 0) {
|
|
5320
|
+
this.processing = false;
|
|
5321
|
+
return;
|
|
5322
|
+
}
|
|
5323
|
+
const item = this.queue.shift();
|
|
5324
|
+
try {
|
|
5325
|
+
await this.processor(item);
|
|
5326
|
+
} catch (error) {
|
|
5327
|
+
console.error("Error processing queue item:", error);
|
|
5328
|
+
}
|
|
5329
|
+
if (this.queue.length > 0) {
|
|
5330
|
+
this.processQueue();
|
|
5331
|
+
} else {
|
|
5332
|
+
this.processing = false;
|
|
5333
|
+
}
|
|
5334
|
+
});
|
|
5335
|
+
}
|
|
5336
|
+
clear() {
|
|
5337
|
+
this.queue = [];
|
|
5338
|
+
}
|
|
5339
|
+
isProcessing() {
|
|
5340
|
+
return this.processing;
|
|
5341
|
+
}
|
|
5342
|
+
size() {
|
|
5343
|
+
return this.queue.length;
|
|
5344
|
+
}
|
|
5345
|
+
}
|
|
5346
|
+
|
|
5347
|
+
// src/lib/tree-sitter/default-parsers.ts
|
|
5348
|
+
import { resolve, dirname } from "path";
|
|
5349
|
+
import { fileURLToPath } from "url";
|
|
5350
|
+
import javascript_highlights from "./assets/javascript/highlights.scm" with { type: "file" };
|
|
5351
|
+
import javascript_language from "./assets/javascript/tree-sitter-javascript.wasm" with { type: "file" };
|
|
5352
|
+
import typescript_highlights from "./assets/typescript/highlights.scm" with { type: "file" };
|
|
5353
|
+
import typescript_language from "./assets/typescript/tree-sitter-typescript.wasm" with { type: "file" };
|
|
5354
|
+
var _cachedParsers;
|
|
5355
|
+
function getParsers() {
|
|
5356
|
+
if (!_cachedParsers) {
|
|
5357
|
+
_cachedParsers = [
|
|
5358
|
+
{
|
|
5359
|
+
filetype: "javascript",
|
|
5360
|
+
queries: {
|
|
5361
|
+
highlights: [resolve(dirname(fileURLToPath(import.meta.url)), javascript_highlights)]
|
|
5362
|
+
},
|
|
5363
|
+
wasm: resolve(dirname(fileURLToPath(import.meta.url)), javascript_language)
|
|
5364
|
+
},
|
|
5365
|
+
{
|
|
5366
|
+
filetype: "typescript",
|
|
5367
|
+
queries: {
|
|
5368
|
+
highlights: [resolve(dirname(fileURLToPath(import.meta.url)), typescript_highlights)]
|
|
5369
|
+
},
|
|
5370
|
+
wasm: resolve(dirname(fileURLToPath(import.meta.url)), typescript_language)
|
|
5371
|
+
}
|
|
5372
|
+
];
|
|
5373
|
+
}
|
|
5374
|
+
return _cachedParsers;
|
|
5375
|
+
}
|
|
5376
|
+
|
|
5377
|
+
// src/lib/tree-sitter/client.ts
|
|
5378
|
+
import { resolve as resolve2, isAbsolute } from "path";
|
|
5379
|
+
import { existsSync } from "fs";
|
|
5380
|
+
import { parse } from "path";
|
|
5381
|
+
registerEnvVar({
|
|
5382
|
+
name: "OTUI_TREE_SITTER_WORKER_PATH",
|
|
5383
|
+
description: "Path to the TreeSitter worker",
|
|
5384
|
+
type: "string",
|
|
5385
|
+
default: ""
|
|
5386
|
+
});
|
|
5387
|
+
var DEFAULT_PARSERS = getParsers();
|
|
5388
|
+
function addDefaultParsers(parsers) {
|
|
5389
|
+
for (const parser of parsers) {
|
|
5390
|
+
const existingIndex = DEFAULT_PARSERS.findIndex((p) => p.filetype === parser.filetype);
|
|
5391
|
+
if (existingIndex >= 0) {
|
|
5392
|
+
DEFAULT_PARSERS[existingIndex] = parser;
|
|
5393
|
+
} else {
|
|
5394
|
+
DEFAULT_PARSERS.push(parser);
|
|
5395
|
+
}
|
|
5396
|
+
}
|
|
5397
|
+
}
|
|
5398
|
+
var isUrl = (path) => path.startsWith("http://") || path.startsWith("https://");
|
|
5399
|
+
|
|
5400
|
+
class TreeSitterClient extends EventEmitter2 {
|
|
5401
|
+
initialized = false;
|
|
5402
|
+
worker;
|
|
5403
|
+
buffers = new Map;
|
|
5404
|
+
initializePromise;
|
|
5405
|
+
initializeResolvers;
|
|
5406
|
+
messageCallbacks = new Map;
|
|
5407
|
+
messageIdCounter = 0;
|
|
5408
|
+
editQueues = new Map;
|
|
5409
|
+
debouncer;
|
|
5410
|
+
options;
|
|
5411
|
+
constructor(options) {
|
|
5412
|
+
super();
|
|
5413
|
+
this.options = options;
|
|
5414
|
+
this.debouncer = createDebounce("tree-sitter-client");
|
|
5415
|
+
this.startWorker();
|
|
5416
|
+
}
|
|
5417
|
+
emitError(error, bufferId) {
|
|
5418
|
+
if (this.listenerCount("error") > 0) {
|
|
5419
|
+
this.emit("error", error, bufferId);
|
|
5420
|
+
}
|
|
5421
|
+
}
|
|
5422
|
+
emitWarning(warning, bufferId) {
|
|
5423
|
+
if (this.listenerCount("warning") > 0) {
|
|
5424
|
+
this.emit("warning", warning, bufferId);
|
|
5425
|
+
}
|
|
5426
|
+
}
|
|
5427
|
+
startWorker() {
|
|
5428
|
+
if (this.worker) {
|
|
5429
|
+
return;
|
|
5430
|
+
}
|
|
5431
|
+
let worker_path;
|
|
5432
|
+
if (env.OTUI_TREE_SITTER_WORKER_PATH) {
|
|
5433
|
+
worker_path = env.OTUI_TREE_SITTER_WORKER_PATH;
|
|
5434
|
+
} else if (typeof OTUI_TREE_SITTER_WORKER_PATH !== "undefined") {
|
|
5435
|
+
worker_path = OTUI_TREE_SITTER_WORKER_PATH;
|
|
5436
|
+
} else if (this.options.workerPath) {
|
|
5437
|
+
worker_path = this.options.workerPath;
|
|
5438
|
+
} else {
|
|
5439
|
+
worker_path = new URL("./parser.worker.js", import.meta.url).href;
|
|
5440
|
+
if (!existsSync(resolve2(import.meta.dirname, "parser.worker.js"))) {
|
|
5441
|
+
worker_path = new URL("./parser.worker.ts", import.meta.url).href;
|
|
5442
|
+
}
|
|
5443
|
+
}
|
|
5444
|
+
this.worker = new Worker(worker_path);
|
|
5445
|
+
this.worker.onmessage = this.handleWorkerMessage.bind(this);
|
|
5446
|
+
this.worker.onerror = (error) => {
|
|
5447
|
+
console.error("TreeSitter worker error:", error.message);
|
|
5448
|
+
if (this.initializeResolvers) {
|
|
5449
|
+
clearTimeout(this.initializeResolvers.timeoutId);
|
|
5450
|
+
this.initializeResolvers.reject(new Error(`Worker error: ${error.message}`));
|
|
5451
|
+
this.initializeResolvers = undefined;
|
|
5452
|
+
}
|
|
5453
|
+
this.emitError(`Worker error: ${error.message}`);
|
|
5454
|
+
};
|
|
5455
|
+
}
|
|
5456
|
+
stopWorker() {
|
|
5457
|
+
if (!this.worker) {
|
|
5458
|
+
return;
|
|
5459
|
+
}
|
|
5460
|
+
this.worker.terminate();
|
|
5461
|
+
this.worker = undefined;
|
|
5462
|
+
}
|
|
5463
|
+
handleReset() {
|
|
5464
|
+
this.buffers.clear();
|
|
5465
|
+
this.stopWorker();
|
|
5466
|
+
this.startWorker();
|
|
5467
|
+
this.initializePromise = undefined;
|
|
5468
|
+
this.initializeResolvers = undefined;
|
|
5469
|
+
return this.initialize();
|
|
5470
|
+
}
|
|
5471
|
+
async initialize() {
|
|
5472
|
+
if (this.initializePromise) {
|
|
5473
|
+
return this.initializePromise;
|
|
5474
|
+
}
|
|
5475
|
+
this.initializePromise = new Promise((resolve3, reject) => {
|
|
5476
|
+
const timeoutMs = this.options.initTimeout ?? 1e4;
|
|
5477
|
+
const timeoutId = setTimeout(() => {
|
|
5478
|
+
const error = new Error("Worker initialization timed out");
|
|
5479
|
+
console.error("TreeSitter client:", error.message);
|
|
5480
|
+
this.initializeResolvers = undefined;
|
|
5481
|
+
reject(error);
|
|
5482
|
+
}, timeoutMs);
|
|
5483
|
+
this.initializeResolvers = { resolve: resolve3, reject, timeoutId };
|
|
5484
|
+
this.worker?.postMessage({
|
|
5485
|
+
type: "INIT",
|
|
5486
|
+
dataPath: this.options.dataPath
|
|
5487
|
+
});
|
|
5488
|
+
});
|
|
5489
|
+
await this.initializePromise;
|
|
5490
|
+
await this.registerDefaultParsers();
|
|
5491
|
+
return this.initializePromise;
|
|
5492
|
+
}
|
|
5493
|
+
async registerDefaultParsers() {
|
|
5494
|
+
for (const parser of DEFAULT_PARSERS) {
|
|
5495
|
+
this.addFiletypeParser(parser);
|
|
5496
|
+
}
|
|
5497
|
+
}
|
|
5498
|
+
resolvePath(path) {
|
|
5499
|
+
if (isUrl(path)) {
|
|
5500
|
+
return path;
|
|
5501
|
+
}
|
|
5502
|
+
if (/\$bunfs/.test(path)) {
|
|
5503
|
+
return "/$bunfs/root/" + parse(path).base;
|
|
5504
|
+
}
|
|
5505
|
+
if (!isAbsolute(path)) {
|
|
5506
|
+
return resolve2(path);
|
|
5507
|
+
}
|
|
5508
|
+
return path;
|
|
5509
|
+
}
|
|
5510
|
+
addFiletypeParser(filetypeParser) {
|
|
5511
|
+
const resolvedParser = {
|
|
5512
|
+
...filetypeParser,
|
|
5513
|
+
wasm: this.resolvePath(filetypeParser.wasm),
|
|
5514
|
+
queries: {
|
|
5515
|
+
highlights: filetypeParser.queries.highlights.map((path) => this.resolvePath(path))
|
|
5516
|
+
}
|
|
5517
|
+
};
|
|
5518
|
+
this.worker?.postMessage({ type: "ADD_FILETYPE_PARSER", filetypeParser: resolvedParser });
|
|
5519
|
+
}
|
|
5520
|
+
async getPerformance() {
|
|
5521
|
+
const messageId = `performance_${this.messageIdCounter++}`;
|
|
5522
|
+
return new Promise((resolve3) => {
|
|
5523
|
+
this.messageCallbacks.set(messageId, resolve3);
|
|
5524
|
+
this.worker?.postMessage({ type: "GET_PERFORMANCE", messageId });
|
|
5525
|
+
});
|
|
5526
|
+
}
|
|
5527
|
+
async highlightOnce(content, filetype) {
|
|
5528
|
+
if (!this.initialized) {
|
|
5529
|
+
try {
|
|
5530
|
+
await this.initialize();
|
|
5531
|
+
} catch (error) {
|
|
5532
|
+
return { error: "Could not highlight because of initialization error" };
|
|
5533
|
+
}
|
|
5534
|
+
}
|
|
5535
|
+
const messageId = `oneshot_${this.messageIdCounter++}`;
|
|
5536
|
+
return new Promise((resolve3) => {
|
|
5537
|
+
this.messageCallbacks.set(messageId, resolve3);
|
|
5538
|
+
this.worker?.postMessage({
|
|
5539
|
+
type: "ONESHOT_HIGHLIGHT",
|
|
5540
|
+
content,
|
|
5541
|
+
filetype,
|
|
5542
|
+
messageId
|
|
5543
|
+
});
|
|
5544
|
+
});
|
|
5545
|
+
}
|
|
5546
|
+
handleWorkerMessage(event) {
|
|
5547
|
+
const { type, bufferId, error, highlights, warning, messageId, hasParser, performance: performance2, version } = event.data;
|
|
5548
|
+
if (type === "HIGHLIGHT_RESPONSE") {
|
|
5549
|
+
const buffer = this.buffers.get(bufferId);
|
|
5550
|
+
if (!buffer || !buffer.hasParser)
|
|
5551
|
+
return;
|
|
5552
|
+
if (buffer.version !== version) {
|
|
5553
|
+
this.resetBuffer(bufferId, buffer.version, buffer.content);
|
|
5554
|
+
return;
|
|
5555
|
+
}
|
|
5556
|
+
this.emit("highlights:response", bufferId, version, highlights);
|
|
5557
|
+
}
|
|
5558
|
+
if (type === "INIT_RESPONSE") {
|
|
5559
|
+
if (this.initializeResolvers) {
|
|
5560
|
+
clearTimeout(this.initializeResolvers.timeoutId);
|
|
5561
|
+
if (error) {
|
|
5562
|
+
console.error("TreeSitter client initialization failed:", error);
|
|
5563
|
+
this.initializeResolvers.reject(new Error(error));
|
|
5564
|
+
} else {
|
|
5565
|
+
this.initialized = true;
|
|
5566
|
+
this.initializeResolvers.resolve();
|
|
5567
|
+
}
|
|
5568
|
+
this.initializeResolvers = undefined;
|
|
5569
|
+
return;
|
|
5570
|
+
}
|
|
5571
|
+
}
|
|
5572
|
+
if (type === "PARSER_INIT_RESPONSE") {
|
|
5573
|
+
const callback = this.messageCallbacks.get(messageId);
|
|
5574
|
+
if (callback) {
|
|
5575
|
+
this.messageCallbacks.delete(messageId);
|
|
5576
|
+
callback({ hasParser, warning, error });
|
|
5577
|
+
}
|
|
5578
|
+
return;
|
|
5579
|
+
}
|
|
5580
|
+
if (type === "PRELOAD_PARSER_RESPONSE") {
|
|
5581
|
+
const callback = this.messageCallbacks.get(messageId);
|
|
5582
|
+
if (callback) {
|
|
5583
|
+
this.messageCallbacks.delete(messageId);
|
|
5584
|
+
callback({ hasParser });
|
|
5585
|
+
}
|
|
5586
|
+
return;
|
|
5587
|
+
}
|
|
5588
|
+
if (type === "BUFFER_DISPOSED") {
|
|
5589
|
+
const callback = this.messageCallbacks.get(`dispose_${bufferId}`);
|
|
5590
|
+
if (callback) {
|
|
5591
|
+
this.messageCallbacks.delete(`dispose_${bufferId}`);
|
|
5592
|
+
callback(true);
|
|
5593
|
+
}
|
|
5594
|
+
this.emit("buffer:disposed", bufferId);
|
|
5595
|
+
return;
|
|
5596
|
+
}
|
|
5597
|
+
if (type === "PERFORMANCE_RESPONSE") {
|
|
5598
|
+
const callback = this.messageCallbacks.get(messageId);
|
|
5599
|
+
if (callback) {
|
|
5600
|
+
this.messageCallbacks.delete(messageId);
|
|
5601
|
+
callback(performance2);
|
|
5602
|
+
}
|
|
5603
|
+
return;
|
|
5604
|
+
}
|
|
5605
|
+
if (type === "ONESHOT_HIGHLIGHT_RESPONSE") {
|
|
5606
|
+
const callback = this.messageCallbacks.get(messageId);
|
|
5607
|
+
if (callback) {
|
|
5608
|
+
this.messageCallbacks.delete(messageId);
|
|
5609
|
+
callback({ highlights, warning, error });
|
|
5610
|
+
}
|
|
5611
|
+
return;
|
|
5612
|
+
}
|
|
5613
|
+
if (type === "UPDATE_DATA_PATH_RESPONSE") {
|
|
5614
|
+
const callback = this.messageCallbacks.get(messageId);
|
|
5615
|
+
if (callback) {
|
|
5616
|
+
this.messageCallbacks.delete(messageId);
|
|
5617
|
+
callback({ error });
|
|
5618
|
+
}
|
|
5619
|
+
return;
|
|
5620
|
+
}
|
|
5621
|
+
if (warning) {
|
|
5622
|
+
this.emitWarning(warning, bufferId);
|
|
5623
|
+
return;
|
|
5624
|
+
}
|
|
5625
|
+
if (error) {
|
|
5626
|
+
this.emitError(error, bufferId);
|
|
5627
|
+
return;
|
|
5628
|
+
}
|
|
5629
|
+
if (type === "WORKER_LOG") {
|
|
5630
|
+
const { logType, data } = event.data;
|
|
5631
|
+
const message = data.join(" ");
|
|
5632
|
+
this.emit("worker:log", logType, message);
|
|
5633
|
+
if (logType === "log") {
|
|
5634
|
+
console.log("Worker stdout:", ...data);
|
|
5635
|
+
} else if (logType === "error") {
|
|
5636
|
+
console.error("Worker stderr:", ...data);
|
|
5637
|
+
}
|
|
5638
|
+
return;
|
|
5639
|
+
}
|
|
5640
|
+
}
|
|
5641
|
+
async preloadParser(filetype) {
|
|
5642
|
+
const messageId = `has_parser_${this.messageIdCounter++}`;
|
|
5643
|
+
const response = await new Promise((resolve3) => {
|
|
5644
|
+
this.messageCallbacks.set(messageId, resolve3);
|
|
5645
|
+
this.worker?.postMessage({
|
|
5646
|
+
type: "PRELOAD_PARSER",
|
|
5647
|
+
filetype,
|
|
5648
|
+
messageId
|
|
5649
|
+
});
|
|
5650
|
+
});
|
|
5651
|
+
return response.hasParser;
|
|
5652
|
+
}
|
|
5653
|
+
async createBuffer(id, content, filetype, version = 1, autoInitialize = true) {
|
|
5654
|
+
if (!this.initialized) {
|
|
5655
|
+
if (!autoInitialize) {
|
|
5656
|
+
this.emitError("Could not create buffer because client is not initialized");
|
|
5657
|
+
return false;
|
|
5658
|
+
}
|
|
5659
|
+
try {
|
|
5660
|
+
await this.initialize();
|
|
5661
|
+
} catch (error) {
|
|
5662
|
+
this.emitError("Could not create buffer because of initialization error");
|
|
5663
|
+
return false;
|
|
5664
|
+
}
|
|
5665
|
+
}
|
|
5666
|
+
if (this.buffers.has(id)) {
|
|
5667
|
+
throw new Error(`Buffer with id ${id} already exists`);
|
|
5668
|
+
}
|
|
5669
|
+
this.buffers.set(id, { id, content, filetype, version, hasParser: false });
|
|
5670
|
+
const messageId = `init_${this.messageIdCounter++}`;
|
|
5671
|
+
const response = await new Promise((resolve3) => {
|
|
5672
|
+
this.messageCallbacks.set(messageId, resolve3);
|
|
5673
|
+
this.worker?.postMessage({
|
|
5674
|
+
type: "INITIALIZE_PARSER",
|
|
5675
|
+
bufferId: id,
|
|
5676
|
+
version,
|
|
5677
|
+
content,
|
|
5678
|
+
filetype,
|
|
5679
|
+
messageId
|
|
5680
|
+
});
|
|
5681
|
+
});
|
|
5682
|
+
if (!response.hasParser) {
|
|
5683
|
+
this.emit("buffer:initialized", id, false);
|
|
5684
|
+
if (filetype !== "plaintext") {
|
|
5685
|
+
this.emitWarning(response.warning || response.error || "Buffer has no parser", id);
|
|
5686
|
+
}
|
|
5687
|
+
return false;
|
|
5688
|
+
}
|
|
5689
|
+
const bufferState = { id, content, filetype, version, hasParser: true };
|
|
5690
|
+
this.buffers.set(id, bufferState);
|
|
5691
|
+
this.emit("buffer:initialized", id, true);
|
|
5692
|
+
return true;
|
|
5693
|
+
}
|
|
5694
|
+
async updateBuffer(id, edits, newContent, version) {
|
|
5695
|
+
if (!this.initialized) {
|
|
5696
|
+
return;
|
|
5697
|
+
}
|
|
5698
|
+
const buffer = this.buffers.get(id);
|
|
5699
|
+
if (!buffer || !buffer.hasParser) {
|
|
5700
|
+
return;
|
|
5701
|
+
}
|
|
5702
|
+
this.buffers.set(id, { ...buffer, content: newContent, version });
|
|
5703
|
+
if (!this.editQueues.has(id)) {
|
|
5704
|
+
this.editQueues.set(id, new ProcessQueue((item) => this.processEdit(id, item.edits, item.newContent, item.version, item.isReset)));
|
|
5705
|
+
}
|
|
5706
|
+
const bufferQueue = this.editQueues.get(id);
|
|
5707
|
+
bufferQueue.enqueue({ edits, newContent, version });
|
|
5708
|
+
}
|
|
5709
|
+
async processEdit(bufferId, edits, newContent, version, isReset = false) {
|
|
5710
|
+
this.worker?.postMessage({
|
|
5711
|
+
type: isReset ? "RESET_BUFFER" : "HANDLE_EDITS",
|
|
5712
|
+
bufferId,
|
|
5713
|
+
version,
|
|
5714
|
+
content: newContent,
|
|
5715
|
+
edits
|
|
5716
|
+
});
|
|
5717
|
+
}
|
|
5718
|
+
async removeBuffer(bufferId) {
|
|
5719
|
+
if (!this.initialized) {
|
|
5720
|
+
return;
|
|
5721
|
+
}
|
|
5722
|
+
this.buffers.delete(bufferId);
|
|
5723
|
+
if (this.editQueues.has(bufferId)) {
|
|
5724
|
+
this.editQueues.get(bufferId)?.clear();
|
|
5725
|
+
this.editQueues.delete(bufferId);
|
|
5726
|
+
}
|
|
5727
|
+
if (this.worker) {
|
|
5728
|
+
await new Promise((resolve3) => {
|
|
5729
|
+
const messageId = `dispose_${bufferId}`;
|
|
5730
|
+
this.messageCallbacks.set(messageId, resolve3);
|
|
5731
|
+
try {
|
|
5732
|
+
this.worker.postMessage({
|
|
5733
|
+
type: "DISPOSE_BUFFER",
|
|
5734
|
+
bufferId
|
|
5735
|
+
});
|
|
5736
|
+
} catch (error) {
|
|
5737
|
+
console.error("Error disposing buffer", error);
|
|
5738
|
+
resolve3(false);
|
|
5739
|
+
}
|
|
5740
|
+
setTimeout(() => {
|
|
5741
|
+
if (this.messageCallbacks.has(messageId)) {
|
|
5742
|
+
this.messageCallbacks.delete(messageId);
|
|
5743
|
+
console.warn({ bufferId }, "Timed out waiting for buffer to be disposed");
|
|
5744
|
+
resolve3(false);
|
|
5745
|
+
}
|
|
5746
|
+
}, 3000);
|
|
5747
|
+
});
|
|
5748
|
+
}
|
|
5749
|
+
this.debouncer.clearDebounce(`reset-${bufferId}`);
|
|
5750
|
+
}
|
|
5751
|
+
async destroy() {
|
|
5752
|
+
if (this.initializeResolvers) {
|
|
5753
|
+
clearTimeout(this.initializeResolvers.timeoutId);
|
|
5754
|
+
this.initializeResolvers = undefined;
|
|
5755
|
+
}
|
|
5756
|
+
for (const [messageId, callback] of this.messageCallbacks.entries()) {
|
|
5757
|
+
if (typeof callback === "function") {
|
|
5758
|
+
try {
|
|
5759
|
+
callback({ error: "Client destroyed" });
|
|
5760
|
+
} catch (e) {}
|
|
5761
|
+
}
|
|
5762
|
+
}
|
|
5763
|
+
this.messageCallbacks.clear();
|
|
5764
|
+
clearDebounceScope("tree-sitter-client");
|
|
5765
|
+
this.debouncer.clear();
|
|
5766
|
+
this.editQueues.clear();
|
|
5767
|
+
this.buffers.clear();
|
|
5768
|
+
this.stopWorker();
|
|
5769
|
+
this.initialized = false;
|
|
5770
|
+
this.initializePromise = undefined;
|
|
5771
|
+
}
|
|
5772
|
+
async resetBuffer(bufferId, version, content) {
|
|
5773
|
+
if (!this.initialized) {
|
|
5774
|
+
return;
|
|
5775
|
+
}
|
|
5776
|
+
const buffer = this.buffers.get(bufferId);
|
|
5777
|
+
if (!buffer || !buffer.hasParser) {
|
|
5778
|
+
this.emitError("Cannot reset buffer with no parser", bufferId);
|
|
5779
|
+
return;
|
|
5780
|
+
}
|
|
5781
|
+
this.buffers.set(bufferId, { ...buffer, content, version });
|
|
5782
|
+
this.debouncer.debounce(`reset-${bufferId}`, 10, () => this.processEdit(bufferId, [], content, version, true));
|
|
5783
|
+
}
|
|
5784
|
+
getBuffer(bufferId) {
|
|
5785
|
+
return this.buffers.get(bufferId);
|
|
5786
|
+
}
|
|
5787
|
+
getAllBuffers() {
|
|
5788
|
+
return Array.from(this.buffers.values());
|
|
5789
|
+
}
|
|
5790
|
+
isInitialized() {
|
|
5791
|
+
return this.initialized;
|
|
5792
|
+
}
|
|
5793
|
+
async setDataPath(dataPath) {
|
|
5794
|
+
if (this.options.dataPath === dataPath) {
|
|
5795
|
+
return;
|
|
5796
|
+
}
|
|
5797
|
+
this.options.dataPath = dataPath;
|
|
5798
|
+
if (this.initialized && this.worker) {
|
|
5799
|
+
const messageId = `update_datapath_${this.messageIdCounter++}`;
|
|
5800
|
+
return new Promise((resolve3, reject) => {
|
|
5801
|
+
this.messageCallbacks.set(messageId, (response) => {
|
|
5802
|
+
if (response.error) {
|
|
5803
|
+
reject(new Error(response.error));
|
|
5804
|
+
} else {
|
|
5805
|
+
resolve3();
|
|
5806
|
+
}
|
|
5807
|
+
});
|
|
5808
|
+
this.worker.postMessage({
|
|
5809
|
+
type: "UPDATE_DATA_PATH",
|
|
5810
|
+
dataPath,
|
|
5811
|
+
messageId
|
|
5812
|
+
});
|
|
5813
|
+
});
|
|
5814
|
+
}
|
|
5815
|
+
}
|
|
5816
|
+
}
|
|
5817
|
+
|
|
5818
|
+
// src/lib/data-paths.ts
|
|
5819
|
+
import os from "os";
|
|
5820
|
+
import path from "path";
|
|
5821
|
+
import { EventEmitter as EventEmitter3 } from "events";
|
|
5822
|
+
|
|
5823
|
+
// src/lib/validate-dir-name.ts
|
|
5824
|
+
function isValidDirectoryName(name) {
|
|
5825
|
+
if (!name || typeof name !== "string") {
|
|
5826
|
+
return false;
|
|
5827
|
+
}
|
|
5828
|
+
if (name.trim().length === 0) {
|
|
5829
|
+
return false;
|
|
5830
|
+
}
|
|
5831
|
+
const reservedNames = [
|
|
5832
|
+
"CON",
|
|
5833
|
+
"PRN",
|
|
5834
|
+
"AUX",
|
|
5835
|
+
"NUL",
|
|
5836
|
+
"COM1",
|
|
5837
|
+
"COM2",
|
|
5838
|
+
"COM3",
|
|
5839
|
+
"COM4",
|
|
5840
|
+
"COM5",
|
|
5841
|
+
"COM6",
|
|
5842
|
+
"COM7",
|
|
5843
|
+
"COM8",
|
|
5844
|
+
"COM9",
|
|
5845
|
+
"LPT1",
|
|
5846
|
+
"LPT2",
|
|
5847
|
+
"LPT3",
|
|
5848
|
+
"LPT4",
|
|
5849
|
+
"LPT5",
|
|
5850
|
+
"LPT6",
|
|
5851
|
+
"LPT7",
|
|
5852
|
+
"LPT8",
|
|
5853
|
+
"LPT9"
|
|
5854
|
+
];
|
|
5855
|
+
if (reservedNames.includes(name.toUpperCase())) {
|
|
5856
|
+
return false;
|
|
5857
|
+
}
|
|
5858
|
+
const invalidChars = /[<>:"|?*\/\\\x00-\x1f]/;
|
|
5859
|
+
if (invalidChars.test(name)) {
|
|
5860
|
+
return false;
|
|
5861
|
+
}
|
|
5862
|
+
if (name.endsWith(".") || name.endsWith(" ")) {
|
|
5863
|
+
return false;
|
|
5864
|
+
}
|
|
5865
|
+
if (name === "." || name === "..") {
|
|
5866
|
+
return false;
|
|
5867
|
+
}
|
|
5868
|
+
return true;
|
|
5869
|
+
}
|
|
5870
|
+
|
|
5871
|
+
// src/lib/data-paths.ts
|
|
5872
|
+
registerEnvVar({
|
|
5873
|
+
name: "XDG_CONFIG_HOME",
|
|
5874
|
+
description: "Base directory for user-specific configuration files",
|
|
5875
|
+
type: "string",
|
|
5876
|
+
default: ""
|
|
5877
|
+
});
|
|
5878
|
+
registerEnvVar({
|
|
5879
|
+
name: "XDG_DATA_HOME",
|
|
5880
|
+
description: "Base directory for user-specific data files",
|
|
5881
|
+
type: "string",
|
|
5882
|
+
default: ""
|
|
5883
|
+
});
|
|
5884
|
+
|
|
5885
|
+
class DataPathsManager extends EventEmitter3 {
|
|
5886
|
+
_appName;
|
|
5887
|
+
_globalConfigPath;
|
|
5888
|
+
_globalConfigFile;
|
|
5889
|
+
_localConfigFile;
|
|
5890
|
+
_globalDataPath;
|
|
5891
|
+
constructor() {
|
|
5892
|
+
super();
|
|
5893
|
+
this._appName = "opentui";
|
|
5894
|
+
}
|
|
5895
|
+
get appName() {
|
|
5896
|
+
return this._appName;
|
|
5897
|
+
}
|
|
5898
|
+
set appName(value) {
|
|
5899
|
+
if (!isValidDirectoryName(value)) {
|
|
5900
|
+
throw new Error(`Invalid app name "${value}": must be a valid directory name`);
|
|
5901
|
+
}
|
|
5902
|
+
if (this._appName !== value) {
|
|
5903
|
+
this._appName = value;
|
|
5904
|
+
this._globalConfigPath = undefined;
|
|
5905
|
+
this._globalConfigFile = undefined;
|
|
5906
|
+
this._localConfigFile = undefined;
|
|
5907
|
+
this._globalDataPath = undefined;
|
|
5908
|
+
this.emit("paths:changed", this.toObject());
|
|
5909
|
+
}
|
|
5910
|
+
}
|
|
5911
|
+
get globalConfigPath() {
|
|
5912
|
+
if (this._globalConfigPath === undefined) {
|
|
5913
|
+
const homeDir = os.homedir();
|
|
5914
|
+
const xdgConfigHome = env.XDG_CONFIG_HOME;
|
|
5915
|
+
const baseConfigDir = xdgConfigHome || path.join(homeDir, ".config");
|
|
5916
|
+
this._globalConfigPath = path.join(baseConfigDir, this._appName);
|
|
5917
|
+
}
|
|
5918
|
+
return this._globalConfigPath;
|
|
5919
|
+
}
|
|
5920
|
+
get globalConfigFile() {
|
|
5921
|
+
if (this._globalConfigFile === undefined) {
|
|
5922
|
+
this._globalConfigFile = path.join(this.globalConfigPath, "init.ts");
|
|
5923
|
+
}
|
|
5924
|
+
return this._globalConfigFile;
|
|
5925
|
+
}
|
|
5926
|
+
get localConfigFile() {
|
|
5927
|
+
if (this._localConfigFile === undefined) {
|
|
5928
|
+
this._localConfigFile = path.join(process.cwd(), `.${this._appName}.ts`);
|
|
5929
|
+
}
|
|
5930
|
+
return this._localConfigFile;
|
|
5931
|
+
}
|
|
5932
|
+
get globalDataPath() {
|
|
5933
|
+
if (this._globalDataPath === undefined) {
|
|
5934
|
+
const homeDir = os.homedir();
|
|
5935
|
+
const xdgDataHome = env.XDG_DATA_HOME;
|
|
5936
|
+
const baseDataDir = xdgDataHome || path.join(homeDir, ".local/share");
|
|
5937
|
+
this._globalDataPath = path.join(baseDataDir, this._appName);
|
|
5938
|
+
}
|
|
5939
|
+
return this._globalDataPath;
|
|
5940
|
+
}
|
|
5941
|
+
toObject() {
|
|
5942
|
+
return {
|
|
5943
|
+
globalConfigPath: this.globalConfigPath,
|
|
5944
|
+
globalConfigFile: this.globalConfigFile,
|
|
5945
|
+
localConfigFile: this.localConfigFile,
|
|
5946
|
+
globalDataPath: this.globalDataPath
|
|
5947
|
+
};
|
|
5948
|
+
}
|
|
5949
|
+
}
|
|
5950
|
+
function getDataPaths() {
|
|
5951
|
+
return singleton("data-paths-opentui", () => new DataPathsManager);
|
|
5952
|
+
}
|
|
5953
|
+
|
|
5954
|
+
// src/lib/tree-sitter/resolve-ft.ts
|
|
5955
|
+
function extToFiletype(extension) {
|
|
5956
|
+
const extensionToFiletype = new Map([
|
|
5957
|
+
["js", "javascript"],
|
|
5958
|
+
["jsx", "javascriptreact"],
|
|
5959
|
+
["ts", "typescript"],
|
|
5960
|
+
["tsx", "typescriptreact"],
|
|
5961
|
+
["md", "markdown"],
|
|
5962
|
+
["json", "json"],
|
|
5963
|
+
["py", "python"],
|
|
5964
|
+
["rb", "ruby"],
|
|
5965
|
+
["go", "go"],
|
|
5966
|
+
["rs", "rust"],
|
|
5967
|
+
["c", "c"],
|
|
5968
|
+
["cpp", "cpp"],
|
|
5969
|
+
["h", "c"],
|
|
5970
|
+
["hpp", "cpp"],
|
|
5971
|
+
["html", "html"],
|
|
5972
|
+
["css", "css"],
|
|
5973
|
+
["scss", "scss"],
|
|
5974
|
+
["less", "less"],
|
|
5975
|
+
["sh", "shell"],
|
|
5976
|
+
["bash", "shell"],
|
|
5977
|
+
["zsh", "shell"],
|
|
5978
|
+
["vim", "vim"],
|
|
5979
|
+
["yaml", "yaml"],
|
|
5980
|
+
["yml", "yaml"],
|
|
5981
|
+
["toml", "toml"],
|
|
5982
|
+
["xml", "xml"],
|
|
5983
|
+
["zig", "zig"]
|
|
5984
|
+
]);
|
|
5985
|
+
return extensionToFiletype.get(extension);
|
|
5986
|
+
}
|
|
5987
|
+
function pathToFiletype(path2) {
|
|
5988
|
+
if (typeof path2 !== "string")
|
|
5989
|
+
return;
|
|
5990
|
+
const lastDot = path2.lastIndexOf(".");
|
|
5991
|
+
if (lastDot === -1 || lastDot === path2.length - 1) {
|
|
5992
|
+
return;
|
|
5993
|
+
}
|
|
5994
|
+
const extension = path2.substring(lastDot + 1);
|
|
5995
|
+
return extToFiletype(extension);
|
|
5996
|
+
}
|
|
5997
|
+
|
|
5998
|
+
// src/lib/tree-sitter/assets/update.ts
|
|
5999
|
+
import { readFile, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
6000
|
+
import * as path3 from "path";
|
|
6001
|
+
|
|
6002
|
+
// src/lib/tree-sitter/download-utils.ts
|
|
6003
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
6004
|
+
import * as path2 from "path";
|
|
6005
|
+
|
|
6006
|
+
class DownloadUtils {
|
|
6007
|
+
static hashUrl(url) {
|
|
6008
|
+
let hash = 0;
|
|
6009
|
+
for (let i = 0;i < url.length; i++) {
|
|
6010
|
+
const char = url.charCodeAt(i);
|
|
6011
|
+
hash = (hash << 5) - hash + char;
|
|
6012
|
+
hash = hash & hash;
|
|
6013
|
+
}
|
|
6014
|
+
return Math.abs(hash).toString(16);
|
|
6015
|
+
}
|
|
6016
|
+
static async downloadOrLoad(source, cacheDir, cacheSubdir, fileExtension, useHashForCache = true, filetype) {
|
|
6017
|
+
const isUrl2 = source.startsWith("http://") || source.startsWith("https://");
|
|
6018
|
+
if (isUrl2) {
|
|
6019
|
+
let cacheFileName;
|
|
6020
|
+
if (useHashForCache) {
|
|
6021
|
+
const hash = this.hashUrl(source);
|
|
6022
|
+
cacheFileName = filetype ? `${filetype}-${hash}${fileExtension}` : `${hash}${fileExtension}`;
|
|
6023
|
+
} else {
|
|
6024
|
+
cacheFileName = path2.basename(source);
|
|
6025
|
+
}
|
|
6026
|
+
const cacheFile = path2.join(cacheDir, cacheSubdir, cacheFileName);
|
|
6027
|
+
await mkdir(path2.dirname(cacheFile), { recursive: true });
|
|
6028
|
+
try {
|
|
6029
|
+
const cachedContent = await Bun.file(cacheFile).arrayBuffer();
|
|
6030
|
+
if (cachedContent.byteLength > 0) {
|
|
6031
|
+
console.log(`Loaded from cache: ${cacheFile} (${source})`);
|
|
6032
|
+
return { content: cachedContent, filePath: cacheFile };
|
|
6033
|
+
}
|
|
6034
|
+
} catch (error) {}
|
|
6035
|
+
try {
|
|
6036
|
+
console.log(`Downloading from URL: ${source}`);
|
|
6037
|
+
const response = await fetch(source);
|
|
6038
|
+
if (!response.ok) {
|
|
6039
|
+
return { error: `Failed to fetch from ${source}: ${response.statusText}` };
|
|
6040
|
+
}
|
|
6041
|
+
const content = await response.arrayBuffer();
|
|
6042
|
+
try {
|
|
6043
|
+
await writeFile(cacheFile, Buffer.from(content));
|
|
6044
|
+
console.log(`Cached: ${source}`);
|
|
6045
|
+
} catch (cacheError) {
|
|
6046
|
+
console.warn(`Failed to cache: ${cacheError}`);
|
|
6047
|
+
}
|
|
6048
|
+
return { content, filePath: cacheFile };
|
|
6049
|
+
} catch (error) {
|
|
6050
|
+
return { error: `Error downloading from ${source}: ${error}` };
|
|
6051
|
+
}
|
|
6052
|
+
} else {
|
|
6053
|
+
try {
|
|
6054
|
+
console.log(`Loading from local path: ${source}`);
|
|
6055
|
+
const content = await Bun.file(source).arrayBuffer();
|
|
6056
|
+
return { content, filePath: source };
|
|
6057
|
+
} catch (error) {
|
|
6058
|
+
return { error: `Error loading from local path ${source}: ${error}` };
|
|
6059
|
+
}
|
|
6060
|
+
}
|
|
6061
|
+
}
|
|
6062
|
+
static async downloadToPath(source, targetPath) {
|
|
6063
|
+
const isUrl2 = source.startsWith("http://") || source.startsWith("https://");
|
|
6064
|
+
await mkdir(path2.dirname(targetPath), { recursive: true });
|
|
6065
|
+
if (isUrl2) {
|
|
6066
|
+
try {
|
|
6067
|
+
console.log(`Downloading from URL: ${source}`);
|
|
6068
|
+
const response = await fetch(source);
|
|
6069
|
+
if (!response.ok) {
|
|
6070
|
+
return { error: `Failed to fetch from ${source}: ${response.statusText}` };
|
|
6071
|
+
}
|
|
6072
|
+
const content = await response.arrayBuffer();
|
|
6073
|
+
await writeFile(targetPath, Buffer.from(content));
|
|
6074
|
+
console.log(`Downloaded: ${source} -> ${targetPath}`);
|
|
6075
|
+
return { content, filePath: targetPath };
|
|
6076
|
+
} catch (error) {
|
|
6077
|
+
return { error: `Error downloading from ${source}: ${error}` };
|
|
6078
|
+
}
|
|
6079
|
+
} else {
|
|
6080
|
+
try {
|
|
6081
|
+
console.log(`Copying from local path: ${source}`);
|
|
6082
|
+
const content = await Bun.file(source).arrayBuffer();
|
|
6083
|
+
await writeFile(targetPath, Buffer.from(content));
|
|
6084
|
+
return { content, filePath: targetPath };
|
|
6085
|
+
} catch (error) {
|
|
6086
|
+
return { error: `Error copying from local path ${source}: ${error}` };
|
|
6087
|
+
}
|
|
6088
|
+
}
|
|
6089
|
+
}
|
|
6090
|
+
static async fetchHighlightQueries(sources, cacheDir, filetype) {
|
|
6091
|
+
const queryPromises = sources.map((source) => this.fetchHighlightQuery(source, cacheDir, filetype));
|
|
6092
|
+
const queryResults = await Promise.all(queryPromises);
|
|
6093
|
+
const validQueries = queryResults.filter((query) => query.trim().length > 0);
|
|
6094
|
+
return validQueries.join(`
|
|
6095
|
+
`);
|
|
6096
|
+
}
|
|
6097
|
+
static async fetchHighlightQuery(source, cacheDir, filetype) {
|
|
6098
|
+
const result = await this.downloadOrLoad(source, cacheDir, "queries", ".scm", true, filetype);
|
|
6099
|
+
if (result.error) {
|
|
6100
|
+
console.error(`Error fetching highlight query from ${source}:`, result.error);
|
|
6101
|
+
return "";
|
|
6102
|
+
}
|
|
6103
|
+
if (result.content) {
|
|
6104
|
+
return new TextDecoder().decode(result.content);
|
|
6105
|
+
}
|
|
6106
|
+
return "";
|
|
6107
|
+
}
|
|
6108
|
+
}
|
|
6109
|
+
|
|
6110
|
+
// src/lib/tree-sitter/assets/update.ts
|
|
6111
|
+
var __dirname = "/Users/runner/work/opentui/opentui/packages/core/src/lib/tree-sitter/assets";
|
|
6112
|
+
function getDefaultOptions() {
|
|
6113
|
+
return {
|
|
6114
|
+
configPath: path3.resolve(__dirname, "../parsers-config.json"),
|
|
6115
|
+
assetsDir: path3.resolve(__dirname),
|
|
6116
|
+
outputPath: path3.resolve(__dirname, "../default-parsers.ts")
|
|
6117
|
+
};
|
|
6118
|
+
}
|
|
6119
|
+
async function loadConfig(configPath) {
|
|
6120
|
+
const configContent = await readFile(configPath, "utf-8");
|
|
6121
|
+
return JSON.parse(configContent);
|
|
6122
|
+
}
|
|
6123
|
+
async function downloadLanguage(filetype, languageUrl, assetsDir, outputPath) {
|
|
6124
|
+
const languageDir = path3.join(assetsDir, filetype);
|
|
6125
|
+
const languageFilename = path3.basename(languageUrl);
|
|
6126
|
+
const languagePath = path3.join(languageDir, languageFilename);
|
|
6127
|
+
const result = await DownloadUtils.downloadToPath(languageUrl, languagePath);
|
|
6128
|
+
if (result.error) {
|
|
6129
|
+
throw new Error(`Failed to download language for ${filetype}: ${result.error}`);
|
|
6130
|
+
}
|
|
6131
|
+
return "./" + path3.relative(path3.dirname(outputPath), languagePath);
|
|
6132
|
+
}
|
|
6133
|
+
async function downloadAndCombineQueries(filetype, queryUrls, assetsDir, outputPath) {
|
|
6134
|
+
const queriesDir = path3.join(assetsDir, filetype);
|
|
6135
|
+
const highlightsPath = path3.join(queriesDir, "highlights.scm");
|
|
6136
|
+
const queryContents = [];
|
|
6137
|
+
for (let i = 0;i < queryUrls.length; i++) {
|
|
6138
|
+
const queryUrl = queryUrls[i];
|
|
6139
|
+
console.log(` Downloading query ${i + 1}/${queryUrls.length}: ${queryUrl}`);
|
|
6140
|
+
try {
|
|
6141
|
+
const response = await fetch(queryUrl);
|
|
6142
|
+
if (!response.ok) {
|
|
6143
|
+
console.warn(`Failed to download query from ${queryUrl}: ${response.statusText}`);
|
|
6144
|
+
continue;
|
|
6145
|
+
}
|
|
6146
|
+
const content = await response.text();
|
|
6147
|
+
if (content.trim()) {
|
|
6148
|
+
queryContents.push(`; Query from: ${queryUrl}
|
|
6149
|
+
${content}`);
|
|
6150
|
+
console.log(` \u2713 Downloaded ${content.split(`
|
|
6151
|
+
`).length} lines`);
|
|
6152
|
+
}
|
|
6153
|
+
} catch (error) {
|
|
6154
|
+
console.warn(`Failed to download query from ${queryUrl}: ${error}`);
|
|
6155
|
+
continue;
|
|
6156
|
+
}
|
|
6157
|
+
}
|
|
6158
|
+
const combinedContent = queryContents.join(`
|
|
6159
|
+
|
|
6160
|
+
`);
|
|
6161
|
+
await writeFile2(highlightsPath, combinedContent, "utf-8");
|
|
6162
|
+
console.log(` Combined ${queryContents.length} queries into ${highlightsPath}`);
|
|
6163
|
+
return "./" + path3.relative(path3.dirname(outputPath), highlightsPath);
|
|
6164
|
+
}
|
|
6165
|
+
async function generateDefaultParsersFile(parsers, outputPath) {
|
|
6166
|
+
const imports = parsers.map((parser) => {
|
|
6167
|
+
const safeFiletype = parser.filetype.replace(/[^a-zA-Z0-9]/g, "_");
|
|
6168
|
+
return `import ${safeFiletype}_highlights from "${parser.highlightsPath}" with { type: "file" }
|
|
6169
|
+
import ${safeFiletype}_language from "${parser.languagePath}" with { type: "file" }`;
|
|
6170
|
+
}).join(`
|
|
6171
|
+
`);
|
|
6172
|
+
const parserDefinitions = parsers.map((parser) => {
|
|
6173
|
+
const safeFiletype = parser.filetype.replace(/[^a-zA-Z0-9]/g, "_");
|
|
6174
|
+
return ` {
|
|
6175
|
+
filetype: "${parser.filetype}",
|
|
6176
|
+
queries: {
|
|
6177
|
+
highlights: [resolve(dirname(fileURLToPath(import.meta.url)), ${safeFiletype}_highlights)],
|
|
6178
|
+
},
|
|
6179
|
+
wasm: resolve(dirname(fileURLToPath(import.meta.url)), ${safeFiletype}_language),
|
|
6180
|
+
}`;
|
|
6181
|
+
}).join(`,
|
|
6182
|
+
`);
|
|
6183
|
+
const fileContent = `// This file is generated by assets/update.ts - DO NOT EDIT MANUALLY
|
|
6184
|
+
// Run 'bun assets/update.ts' to regenerate this file
|
|
6185
|
+
// Last generated: ${new Date().toISOString()}
|
|
6186
|
+
|
|
6187
|
+
import type { FiletypeParserOptions } from "./types"
|
|
6188
|
+
import { resolve, dirname } from "path"
|
|
6189
|
+
import { fileURLToPath } from "url"
|
|
6190
|
+
|
|
6191
|
+
${imports}
|
|
6192
|
+
|
|
6193
|
+
// Cached parsers to avoid re-resolving paths on every call
|
|
6194
|
+
let _cachedParsers: FiletypeParserOptions[] | undefined
|
|
6195
|
+
|
|
6196
|
+
export function getParsers(): FiletypeParserOptions[] {
|
|
6197
|
+
if (!_cachedParsers) {
|
|
6198
|
+
_cachedParsers = [
|
|
6199
|
+
${parserDefinitions},
|
|
6200
|
+
]
|
|
6201
|
+
}
|
|
6202
|
+
return _cachedParsers
|
|
6203
|
+
}
|
|
6204
|
+
`;
|
|
6205
|
+
await mkdir2(path3.dirname(outputPath), { recursive: true });
|
|
6206
|
+
await writeFile2(outputPath, fileContent, "utf-8");
|
|
6207
|
+
console.log(`Generated ${path3.basename(outputPath)} with ${parsers.length} parsers`);
|
|
6208
|
+
}
|
|
6209
|
+
async function main(options) {
|
|
6210
|
+
const opts = { ...getDefaultOptions(), ...options };
|
|
6211
|
+
try {
|
|
6212
|
+
console.log("Loading parsers configuration...");
|
|
6213
|
+
console.log(` Config: ${opts.configPath}`);
|
|
6214
|
+
console.log(` Assets Dir: ${opts.assetsDir}`);
|
|
6215
|
+
console.log(` Output: ${opts.outputPath}`);
|
|
6216
|
+
const config = await loadConfig(opts.configPath);
|
|
6217
|
+
console.log(`Found ${config.parsers.length} parsers to process`);
|
|
6218
|
+
const generatedParsers = [];
|
|
6219
|
+
for (const parser of config.parsers) {
|
|
6220
|
+
console.log(`Processing ${parser.filetype}...`);
|
|
6221
|
+
console.log(` Downloading language...`);
|
|
6222
|
+
const languagePath = await downloadLanguage(parser.filetype, parser.wasm, opts.assetsDir, opts.outputPath);
|
|
6223
|
+
console.log(` Downloading ${parser.queries.highlights.length} highlight queries...`);
|
|
6224
|
+
const highlightsPath = await downloadAndCombineQueries(parser.filetype, parser.queries.highlights, opts.assetsDir, opts.outputPath);
|
|
6225
|
+
generatedParsers.push({
|
|
6226
|
+
filetype: parser.filetype,
|
|
6227
|
+
languagePath,
|
|
6228
|
+
highlightsPath
|
|
6229
|
+
});
|
|
6230
|
+
console.log(` \u2713 Completed ${parser.filetype}`);
|
|
6231
|
+
}
|
|
6232
|
+
console.log("Generating output file...");
|
|
6233
|
+
await generateDefaultParsersFile(generatedParsers, opts.outputPath);
|
|
6234
|
+
console.log("\u2705 Update completed successfully!");
|
|
6235
|
+
} catch (error) {
|
|
6236
|
+
console.error("\u274C Update failed:", error);
|
|
6237
|
+
process.exit(1);
|
|
6238
|
+
}
|
|
6239
|
+
}
|
|
6240
|
+
if (false) {}
|
|
6241
|
+
|
|
6242
|
+
// src/lib/tree-sitter/index.ts
|
|
6243
|
+
function getTreeSitterClient() {
|
|
6244
|
+
const dataPathsManager = getDataPaths();
|
|
6245
|
+
const defaultOptions = {
|
|
6246
|
+
dataPath: dataPathsManager.globalDataPath
|
|
6247
|
+
};
|
|
6248
|
+
return singleton("tree-sitter-client", () => {
|
|
6249
|
+
const client2 = new TreeSitterClient(defaultOptions);
|
|
6250
|
+
dataPathsManager.on("paths:changed", (paths) => {
|
|
6251
|
+
client2.setDataPath(paths.globalDataPath);
|
|
6252
|
+
});
|
|
6253
|
+
return client2;
|
|
6254
|
+
});
|
|
6255
|
+
}
|
|
4977
6256
|
// src/zig.ts
|
|
4978
6257
|
import { dlopen, toArrayBuffer as toArrayBuffer2, JSCallback, ptr } from "bun:ffi";
|
|
4979
|
-
import { existsSync } from "fs";
|
|
6258
|
+
import { existsSync as existsSync2 } from "fs";
|
|
4980
6259
|
|
|
4981
6260
|
// src/buffer.ts
|
|
4982
6261
|
import { toArrayBuffer } from "bun:ffi";
|
|
@@ -5177,7 +6456,10 @@ class OptimizedBuffer {
|
|
|
5177
6456
|
// src/zig.ts
|
|
5178
6457
|
var module = await import(`@opentui/core-${process.platform}-${process.arch}/index.ts`);
|
|
5179
6458
|
var targetLibPath = module.default;
|
|
5180
|
-
if (
|
|
6459
|
+
if (/\$bunfs/.test(targetLibPath)) {
|
|
6460
|
+
targetLibPath = targetLibPath.replace("../", "");
|
|
6461
|
+
}
|
|
6462
|
+
if (!existsSync2(targetLibPath)) {
|
|
5181
6463
|
throw new Error(`opentui is not supported on the current platform: ${process.platform}-${process.arch}`);
|
|
5182
6464
|
}
|
|
5183
6465
|
registerEnvVar({
|
|
@@ -6281,7 +7563,7 @@ class TextBuffer {
|
|
|
6281
7563
|
}
|
|
6282
7564
|
|
|
6283
7565
|
// src/Renderable.ts
|
|
6284
|
-
import { EventEmitter as
|
|
7566
|
+
import { EventEmitter as EventEmitter4 } from "events";
|
|
6285
7567
|
|
|
6286
7568
|
// src/lib/renderable.validations.ts
|
|
6287
7569
|
function validateOptions(id, options) {
|
|
@@ -6374,7 +7656,7 @@ function isRenderable(obj) {
|
|
|
6374
7656
|
return !!obj?.[BrandedRenderable];
|
|
6375
7657
|
}
|
|
6376
7658
|
|
|
6377
|
-
class BaseRenderable extends
|
|
7659
|
+
class BaseRenderable extends EventEmitter4 {
|
|
6378
7660
|
[BrandedRenderable] = true;
|
|
6379
7661
|
static renderableNumber = 1;
|
|
6380
7662
|
_id;
|
|
@@ -6546,18 +7828,18 @@ class Renderable extends BaseRenderable {
|
|
|
6546
7828
|
this.requestRender();
|
|
6547
7829
|
this.keypressHandler = (key) => {
|
|
6548
7830
|
this._keyListeners["down"]?.(key);
|
|
6549
|
-
if (this.handleKeyPress) {
|
|
7831
|
+
if (!key.defaultPrevented && this.handleKeyPress) {
|
|
6550
7832
|
this.handleKeyPress(key);
|
|
6551
7833
|
}
|
|
6552
7834
|
};
|
|
6553
|
-
this.pasteHandler = (
|
|
6554
|
-
this._pasteListener?.call(this, text);
|
|
6555
|
-
if (this.handlePaste) {
|
|
6556
|
-
this.handlePaste(text);
|
|
7835
|
+
this.pasteHandler = (event) => {
|
|
7836
|
+
this._pasteListener?.call(this, event.text);
|
|
7837
|
+
if (!event.defaultPrevented && this.handlePaste) {
|
|
7838
|
+
this.handlePaste(event.text);
|
|
6557
7839
|
}
|
|
6558
7840
|
};
|
|
6559
|
-
this.ctx.
|
|
6560
|
-
this.ctx.
|
|
7841
|
+
this.ctx._internalKeyInput.onInternal("keypress", this.keypressHandler);
|
|
7842
|
+
this.ctx._internalKeyInput.onInternal("paste", this.pasteHandler);
|
|
6561
7843
|
this.emit("focused" /* FOCUSED */);
|
|
6562
7844
|
}
|
|
6563
7845
|
blur() {
|
|
@@ -6566,11 +7848,11 @@ class Renderable extends BaseRenderable {
|
|
|
6566
7848
|
this._focused = false;
|
|
6567
7849
|
this.requestRender();
|
|
6568
7850
|
if (this.keypressHandler) {
|
|
6569
|
-
this.ctx.
|
|
7851
|
+
this.ctx._internalKeyInput.offInternal("keypress", this.keypressHandler);
|
|
6570
7852
|
this.keypressHandler = null;
|
|
6571
7853
|
}
|
|
6572
7854
|
if (this.pasteHandler) {
|
|
6573
|
-
this.ctx.
|
|
7855
|
+
this.ctx._internalKeyInput.offInternal("paste", this.pasteHandler);
|
|
6574
7856
|
this.pasteHandler = null;
|
|
6575
7857
|
}
|
|
6576
7858
|
this.emit("blurred" /* BLURRED */);
|
|
@@ -7171,10 +8453,11 @@ class Renderable extends BaseRenderable {
|
|
|
7171
8453
|
if (renderable.parent === this) {
|
|
7172
8454
|
this.yogaNode.removeChild(renderable.getLayoutNode());
|
|
7173
8455
|
this._childrenInLayoutOrder.splice(this._childrenInLayoutOrder.indexOf(renderable), 1);
|
|
7174
|
-
} else
|
|
8456
|
+
} else {
|
|
7175
8457
|
this.replaceParent(renderable);
|
|
7176
8458
|
this.needsZIndexSort = true;
|
|
7177
8459
|
this.renderableMapById.set(renderable.id, renderable);
|
|
8460
|
+
this._childrenInZIndexOrder.push(renderable);
|
|
7178
8461
|
if (typeof renderable.onLifecyclePass === "function") {
|
|
7179
8462
|
this._ctx.registerLifecyclePass(renderable);
|
|
7180
8463
|
}
|
|
@@ -7219,6 +8502,16 @@ class Renderable extends BaseRenderable {
|
|
|
7219
8502
|
if (zIndexIndex !== -1) {
|
|
7220
8503
|
this._childrenInZIndexOrder.splice(zIndexIndex, 1);
|
|
7221
8504
|
}
|
|
8505
|
+
if (this._forceLayoutUpdateFor) {
|
|
8506
|
+
const forceIndex = this._forceLayoutUpdateFor.findIndex((obj2) => obj2.id === id);
|
|
8507
|
+
if (forceIndex !== -1) {
|
|
8508
|
+
this._forceLayoutUpdateFor?.splice(forceIndex, 1);
|
|
8509
|
+
}
|
|
8510
|
+
}
|
|
8511
|
+
const newChildIndex = this._newChildren.findIndex((obj2) => obj2.id === id);
|
|
8512
|
+
if (newChildIndex !== -1) {
|
|
8513
|
+
this._newChildren?.splice(newChildIndex, 1);
|
|
8514
|
+
}
|
|
7222
8515
|
this.childrenPrimarySortDirty = true;
|
|
7223
8516
|
}
|
|
7224
8517
|
}
|
|
@@ -7327,7 +8620,8 @@ class Renderable extends BaseRenderable {
|
|
|
7327
8620
|
} catch (e) {}
|
|
7328
8621
|
}
|
|
7329
8622
|
destroyRecursively() {
|
|
7330
|
-
|
|
8623
|
+
const children = [...this._childrenInLayoutOrder];
|
|
8624
|
+
for (const child of children) {
|
|
7331
8625
|
child.destroyRecursively();
|
|
7332
8626
|
}
|
|
7333
8627
|
this.destroy();
|
|
@@ -7666,17 +8960,17 @@ function delegate(mapping, vnode) {
|
|
|
7666
8960
|
}
|
|
7667
8961
|
|
|
7668
8962
|
// src/console.ts
|
|
7669
|
-
import { EventEmitter as
|
|
8963
|
+
import { EventEmitter as EventEmitter6 } from "events";
|
|
7670
8964
|
import { Console } from "console";
|
|
7671
8965
|
import fs from "fs";
|
|
7672
|
-
import
|
|
8966
|
+
import path4 from "path";
|
|
7673
8967
|
import util2 from "util";
|
|
7674
8968
|
|
|
7675
8969
|
// src/lib/output.capture.ts
|
|
7676
8970
|
import { Writable } from "stream";
|
|
7677
|
-
import { EventEmitter as
|
|
8971
|
+
import { EventEmitter as EventEmitter5 } from "events";
|
|
7678
8972
|
|
|
7679
|
-
class Capture extends
|
|
8973
|
+
class Capture extends EventEmitter5 {
|
|
7680
8974
|
output = [];
|
|
7681
8975
|
constructor() {
|
|
7682
8976
|
super();
|
|
@@ -7752,7 +9046,7 @@ registerEnvVar({
|
|
|
7752
9046
|
default: false
|
|
7753
9047
|
});
|
|
7754
9048
|
|
|
7755
|
-
class TerminalConsoleCache extends
|
|
9049
|
+
class TerminalConsoleCache extends EventEmitter6 {
|
|
7756
9050
|
_cachedLogs = [];
|
|
7757
9051
|
MAX_CACHE_SIZE = 1000;
|
|
7758
9052
|
_collectCallerInfo = false;
|
|
@@ -7873,7 +9167,7 @@ var DEFAULT_CONSOLE_OPTIONS = {
|
|
|
7873
9167
|
};
|
|
7874
9168
|
var INDENT_WIDTH = 2;
|
|
7875
9169
|
|
|
7876
|
-
class TerminalConsole extends
|
|
9170
|
+
class TerminalConsole extends EventEmitter6 {
|
|
7877
9171
|
isVisible = false;
|
|
7878
9172
|
isFocused = false;
|
|
7879
9173
|
renderer;
|
|
@@ -8312,7 +9606,7 @@ class TerminalConsole extends EventEmitter4 {
|
|
|
8312
9606
|
try {
|
|
8313
9607
|
const timestamp = Date.now();
|
|
8314
9608
|
const filename = `_console_${timestamp}.log`;
|
|
8315
|
-
const filepath =
|
|
9609
|
+
const filepath = path4.join(process.cwd(), filename);
|
|
8316
9610
|
const allLogEntries = [...this._allLogEntries, ...terminalConsoleCache.cachedLogs];
|
|
8317
9611
|
const logLines = [];
|
|
8318
9612
|
for (const [date, level, args, callerInfo] of allLogEntries) {
|
|
@@ -8333,7 +9627,7 @@ class TerminalConsole extends EventEmitter4 {
|
|
|
8333
9627
|
}
|
|
8334
9628
|
|
|
8335
9629
|
// src/renderer.ts
|
|
8336
|
-
import { EventEmitter as
|
|
9630
|
+
import { EventEmitter as EventEmitter7 } from "events";
|
|
8337
9631
|
|
|
8338
9632
|
// src/lib/objects-in-viewport.ts
|
|
8339
9633
|
function getObjectsInViewport(viewport, objects, direction = "column", padding = 10, minTriggerSize = 16) {
|
|
@@ -8423,6 +9717,18 @@ registerEnvVar({
|
|
|
8423
9717
|
type: "boolean",
|
|
8424
9718
|
default: false
|
|
8425
9719
|
});
|
|
9720
|
+
registerEnvVar({
|
|
9721
|
+
name: "OTUI_USE_ALTERNATE_SCREEN",
|
|
9722
|
+
description: "Whether to use the console. Will not capture console output if set to false.",
|
|
9723
|
+
type: "boolean",
|
|
9724
|
+
default: true
|
|
9725
|
+
});
|
|
9726
|
+
registerEnvVar({
|
|
9727
|
+
name: "OTUI_OVERRIDE_STDOUT",
|
|
9728
|
+
description: "Override the stdout stream. This is useful for debugging.",
|
|
9729
|
+
type: "boolean",
|
|
9730
|
+
default: true
|
|
9731
|
+
});
|
|
8426
9732
|
|
|
8427
9733
|
class MouseEvent {
|
|
8428
9734
|
type;
|
|
@@ -8485,13 +9791,17 @@ var rendererTracker = singleton("RendererTracker", () => {
|
|
|
8485
9791
|
renderers.delete(renderer);
|
|
8486
9792
|
if (renderers.size === 0) {
|
|
8487
9793
|
process.stdin.pause();
|
|
9794
|
+
if (hasSingleton("tree-sitter-client")) {
|
|
9795
|
+
getTreeSitterClient().destroy();
|
|
9796
|
+
destroySingleton("tree-sitter-client");
|
|
9797
|
+
}
|
|
8488
9798
|
}
|
|
8489
9799
|
}
|
|
8490
9800
|
};
|
|
8491
9801
|
});
|
|
8492
9802
|
async function createCliRenderer(config = {}) {
|
|
8493
9803
|
if (process.argv.includes("--delay-start")) {
|
|
8494
|
-
await new Promise((
|
|
9804
|
+
await new Promise((resolve4) => setTimeout(resolve4, 5000));
|
|
8495
9805
|
}
|
|
8496
9806
|
const stdin = config.stdin || process.stdin;
|
|
8497
9807
|
const stdout = config.stdout || process.stdout;
|
|
@@ -8518,14 +9828,24 @@ var CliRenderEvents;
|
|
|
8518
9828
|
((CliRenderEvents2) => {
|
|
8519
9829
|
CliRenderEvents2["DEBUG_OVERLAY_TOGGLE"] = "debugOverlay:toggle";
|
|
8520
9830
|
})(CliRenderEvents ||= {});
|
|
8521
|
-
|
|
9831
|
+
var RendererControlState;
|
|
9832
|
+
((RendererControlState2) => {
|
|
9833
|
+
RendererControlState2["IDLE"] = "idle";
|
|
9834
|
+
RendererControlState2["AUTO_STARTED"] = "auto_started";
|
|
9835
|
+
RendererControlState2["EXPLICIT_STARTED"] = "explicit_started";
|
|
9836
|
+
RendererControlState2["EXPLICIT_PAUSED"] = "explicit_paused";
|
|
9837
|
+
RendererControlState2["EXPLICIT_SUSPENDED"] = "explicit_suspended";
|
|
9838
|
+
RendererControlState2["EXPLICIT_STOPPED"] = "explicit_stopped";
|
|
9839
|
+
})(RendererControlState ||= {});
|
|
9840
|
+
|
|
9841
|
+
class CliRenderer extends EventEmitter7 {
|
|
8522
9842
|
static animationFrameId = 0;
|
|
8523
9843
|
lib;
|
|
8524
9844
|
rendererPtr;
|
|
8525
9845
|
stdin;
|
|
8526
9846
|
stdout;
|
|
8527
9847
|
exitOnCtrlC;
|
|
8528
|
-
|
|
9848
|
+
_isDestroyed = false;
|
|
8529
9849
|
nextRenderBuffer;
|
|
8530
9850
|
currentRenderBuffer;
|
|
8531
9851
|
_isRunning = false;
|
|
@@ -8559,7 +9879,7 @@ class CliRenderer extends EventEmitter5 {
|
|
|
8559
9879
|
immediateRerenderRequested = false;
|
|
8560
9880
|
updateScheduled = false;
|
|
8561
9881
|
liveRequestCounter = 0;
|
|
8562
|
-
|
|
9882
|
+
_controlState = "idle" /* IDLE */;
|
|
8563
9883
|
frameCallbacks = [];
|
|
8564
9884
|
renderStats = {
|
|
8565
9885
|
frameCount: 0,
|
|
@@ -8579,7 +9899,9 @@ class CliRenderer extends EventEmitter5 {
|
|
|
8579
9899
|
resizeDebounceDelay = 100;
|
|
8580
9900
|
enableMouseMovement = false;
|
|
8581
9901
|
_useMouse = true;
|
|
8582
|
-
_useAlternateScreen =
|
|
9902
|
+
_useAlternateScreen = env.OTUI_USE_ALTERNATE_SCREEN;
|
|
9903
|
+
_suspendedMouseEnabled = false;
|
|
9904
|
+
_previousControlState = "idle" /* IDLE */;
|
|
8583
9905
|
capturedRenderable;
|
|
8584
9906
|
lastOverRenderableNum = 0;
|
|
8585
9907
|
lastOverRenderable;
|
|
@@ -8610,9 +9932,9 @@ class CliRenderer extends EventEmitter5 {
|
|
|
8610
9932
|
handleError = ((error) => {
|
|
8611
9933
|
this.stop();
|
|
8612
9934
|
this.destroy();
|
|
8613
|
-
new Promise((
|
|
9935
|
+
new Promise((resolve4) => {
|
|
8614
9936
|
setTimeout(() => {
|
|
8615
|
-
|
|
9937
|
+
resolve4(true);
|
|
8616
9938
|
}, 100);
|
|
8617
9939
|
}).then(() => {
|
|
8618
9940
|
this.realStdoutWrite.call(this.stdout, `
|
|
@@ -8663,6 +9985,9 @@ Captured output:
|
|
|
8663
9985
|
warningHandler = ((warning) => {
|
|
8664
9986
|
console.warn(JSON.stringify(warning.message, null, 2));
|
|
8665
9987
|
}).bind(this);
|
|
9988
|
+
get controlState() {
|
|
9989
|
+
return this._controlState;
|
|
9990
|
+
}
|
|
8666
9991
|
constructor(lib, rendererPtr, stdin, stdout, width, height, config = {}) {
|
|
8667
9992
|
super();
|
|
8668
9993
|
rendererTracker.addRenderer(this);
|
|
@@ -8691,7 +10016,7 @@ Captured output:
|
|
|
8691
10016
|
this.maxStatSamples = config.maxStatSamples || 300;
|
|
8692
10017
|
this.enableMouseMovement = config.enableMouseMovement || true;
|
|
8693
10018
|
this._useMouse = config.useMouse ?? true;
|
|
8694
|
-
this._useAlternateScreen = config.useAlternateScreen ??
|
|
10019
|
+
this._useAlternateScreen = config.useAlternateScreen ?? env.OTUI_USE_ALTERNATE_SCREEN;
|
|
8695
10020
|
this.nextRenderBuffer = this.lib.getNextBuffer(this.rendererPtr);
|
|
8696
10021
|
this.currentRenderBuffer = this.lib.getCurrentBuffer(this.rendererPtr);
|
|
8697
10022
|
this.postProcessFns = config.postProcessFns || [];
|
|
@@ -8699,7 +10024,9 @@ Captured output:
|
|
|
8699
10024
|
if (this.memorySnapshotInterval > 0) {
|
|
8700
10025
|
this.startMemorySnapshotTimer();
|
|
8701
10026
|
}
|
|
8702
|
-
|
|
10027
|
+
if (env.OTUI_OVERRIDE_STDOUT) {
|
|
10028
|
+
this.stdout.write = this.interceptStdoutWrite.bind(this);
|
|
10029
|
+
}
|
|
8703
10030
|
process.on("SIGWINCH", this.sigwinchHandler);
|
|
8704
10031
|
process.on("warning", this.warningHandler);
|
|
8705
10032
|
process.on("uncaughtException", this.handleError);
|
|
@@ -8707,7 +10034,7 @@ Captured output:
|
|
|
8707
10034
|
process.on("exit", this.exitHandler);
|
|
8708
10035
|
this._console = new TerminalConsole(this, config.consoleOptions);
|
|
8709
10036
|
this.useConsole = config.useConsole ?? true;
|
|
8710
|
-
this._keyHandler = new
|
|
10037
|
+
this._keyHandler = new InternalKeyHandler(this.stdin, config.useKittyKeyboard ?? false);
|
|
8711
10038
|
global.requestAnimationFrame = (callback) => {
|
|
8712
10039
|
const id = CliRenderer.animationFrameId++;
|
|
8713
10040
|
this.animationRequest.set(id, callback);
|
|
@@ -8731,6 +10058,9 @@ Captured output:
|
|
|
8731
10058
|
}
|
|
8732
10059
|
this.setupInput();
|
|
8733
10060
|
}
|
|
10061
|
+
get isDestroyed() {
|
|
10062
|
+
return this._isDestroyed;
|
|
10063
|
+
}
|
|
8734
10064
|
registerLifecyclePass(renderable) {
|
|
8735
10065
|
this.lifecyclePasses.add(renderable);
|
|
8736
10066
|
}
|
|
@@ -8764,7 +10094,7 @@ Captured output:
|
|
|
8764
10094
|
return this.realStdoutWrite.call(this.stdout, chunk, encoding, callback);
|
|
8765
10095
|
}
|
|
8766
10096
|
requestRender() {
|
|
8767
|
-
if (!this.rendering && !this.updateScheduled && !this._isRunning) {
|
|
10097
|
+
if (!this.rendering && !this.updateScheduled && !this._isRunning && this._controlState !== "explicit_suspended" /* EXPLICIT_SUSPENDED */) {
|
|
8768
10098
|
this.updateScheduled = true;
|
|
8769
10099
|
process.nextTick(() => {
|
|
8770
10100
|
this.loop();
|
|
@@ -8795,6 +10125,9 @@ Captured output:
|
|
|
8795
10125
|
get keyInput() {
|
|
8796
10126
|
return this._keyHandler;
|
|
8797
10127
|
}
|
|
10128
|
+
get _internalKeyInput() {
|
|
10129
|
+
return this._keyHandler;
|
|
10130
|
+
}
|
|
8798
10131
|
get terminalWidth() {
|
|
8799
10132
|
return this._terminalWidth;
|
|
8800
10133
|
}
|
|
@@ -8824,7 +10157,7 @@ Captured output:
|
|
|
8824
10157
|
return this.liveRequestCounter;
|
|
8825
10158
|
}
|
|
8826
10159
|
get currentControlState() {
|
|
8827
|
-
return this.
|
|
10160
|
+
return this._controlState;
|
|
8828
10161
|
}
|
|
8829
10162
|
get capabilities() {
|
|
8830
10163
|
return this._capabilities;
|
|
@@ -8904,9 +10237,11 @@ Captured output:
|
|
|
8904
10237
|
return true;
|
|
8905
10238
|
}
|
|
8906
10239
|
enableMouse() {
|
|
10240
|
+
this._useMouse = true;
|
|
8907
10241
|
this.lib.enableMouse(this.rendererPtr, this.enableMouseMovement);
|
|
8908
10242
|
}
|
|
8909
10243
|
disableMouse() {
|
|
10244
|
+
this._useMouse = false;
|
|
8910
10245
|
this.capturedRenderable = undefined;
|
|
8911
10246
|
this.mouseParser.reset();
|
|
8912
10247
|
this.lib.disableMouse(this.rendererPtr);
|
|
@@ -8925,16 +10260,16 @@ Captured output:
|
|
|
8925
10260
|
if (this._terminalIsSetup)
|
|
8926
10261
|
return;
|
|
8927
10262
|
this._terminalIsSetup = true;
|
|
8928
|
-
await new Promise((
|
|
10263
|
+
await new Promise((resolve4) => {
|
|
8929
10264
|
const timeout = setTimeout(() => {
|
|
8930
10265
|
this.stdin.off("data", capListener);
|
|
8931
|
-
|
|
10266
|
+
resolve4(true);
|
|
8932
10267
|
}, 100);
|
|
8933
10268
|
const capListener = (str) => {
|
|
8934
10269
|
clearTimeout(timeout);
|
|
8935
10270
|
this.lib.processCapabilityResponse(this.rendererPtr, str);
|
|
8936
10271
|
this.stdin.off("data", capListener);
|
|
8937
|
-
|
|
10272
|
+
resolve4(true);
|
|
8938
10273
|
};
|
|
8939
10274
|
this.stdin.on("data", capListener);
|
|
8940
10275
|
this.lib.setupTerminal(this.rendererPtr, this._useAlternateScreen);
|
|
@@ -9091,7 +10426,7 @@ Captured output:
|
|
|
9091
10426
|
return false;
|
|
9092
10427
|
}
|
|
9093
10428
|
takeMemorySnapshot() {
|
|
9094
|
-
if (this.
|
|
10429
|
+
if (this._isDestroyed)
|
|
9095
10430
|
return;
|
|
9096
10431
|
const memoryUsage = process.memoryUsage();
|
|
9097
10432
|
this.lastMemorySnapshot = {
|
|
@@ -9124,7 +10459,7 @@ Captured output:
|
|
|
9124
10459
|
}
|
|
9125
10460
|
}
|
|
9126
10461
|
handleResize(width, height) {
|
|
9127
|
-
if (this.
|
|
10462
|
+
if (this._isDestroyed)
|
|
9128
10463
|
return;
|
|
9129
10464
|
if (this._splitHeight > 0) {
|
|
9130
10465
|
this.processResize(width, height);
|
|
@@ -9263,27 +10598,27 @@ Captured output:
|
|
|
9263
10598
|
}
|
|
9264
10599
|
requestLive() {
|
|
9265
10600
|
this.liveRequestCounter++;
|
|
9266
|
-
if (this.
|
|
9267
|
-
this.
|
|
10601
|
+
if (this._controlState === "idle" /* IDLE */ && this.liveRequestCounter > 0) {
|
|
10602
|
+
this._controlState = "auto_started" /* AUTO_STARTED */;
|
|
9268
10603
|
this.internalStart();
|
|
9269
10604
|
}
|
|
9270
10605
|
}
|
|
9271
10606
|
dropLive() {
|
|
9272
10607
|
this.liveRequestCounter = Math.max(0, this.liveRequestCounter - 1);
|
|
9273
|
-
if (this.
|
|
9274
|
-
this.
|
|
10608
|
+
if (this._controlState === "auto_started" /* AUTO_STARTED */ && this.liveRequestCounter === 0) {
|
|
10609
|
+
this._controlState = "idle" /* IDLE */;
|
|
9275
10610
|
this.internalPause();
|
|
9276
10611
|
}
|
|
9277
10612
|
}
|
|
9278
10613
|
start() {
|
|
9279
|
-
this.
|
|
10614
|
+
this._controlState = "explicit_started" /* EXPLICIT_STARTED */;
|
|
9280
10615
|
this.internalStart();
|
|
9281
10616
|
}
|
|
9282
10617
|
auto() {
|
|
9283
|
-
this.
|
|
10618
|
+
this._controlState = this._isRunning ? "auto_started" /* AUTO_STARTED */ : "idle" /* IDLE */;
|
|
9284
10619
|
}
|
|
9285
10620
|
internalStart() {
|
|
9286
|
-
if (!this._isRunning && !this.
|
|
10621
|
+
if (!this._isRunning && !this._isDestroyed) {
|
|
9287
10622
|
this._isRunning = true;
|
|
9288
10623
|
if (this.memorySnapshotInterval > 0) {
|
|
9289
10624
|
this.startMemorySnapshotTimer();
|
|
@@ -9292,18 +10627,44 @@ Captured output:
|
|
|
9292
10627
|
}
|
|
9293
10628
|
}
|
|
9294
10629
|
pause() {
|
|
9295
|
-
this.
|
|
10630
|
+
this._controlState = "explicit_paused" /* EXPLICIT_PAUSED */;
|
|
9296
10631
|
this.internalPause();
|
|
9297
10632
|
}
|
|
10633
|
+
suspend() {
|
|
10634
|
+
this._previousControlState = this._controlState;
|
|
10635
|
+
this._controlState = "explicit_suspended" /* EXPLICIT_SUSPENDED */;
|
|
10636
|
+
this.internalPause();
|
|
10637
|
+
this._suspendedMouseEnabled = this._useMouse;
|
|
10638
|
+
this.disableMouse();
|
|
10639
|
+
this._keyHandler.suspend();
|
|
10640
|
+
if (this.stdin.setRawMode) {
|
|
10641
|
+
this.stdin.setRawMode(false);
|
|
10642
|
+
}
|
|
10643
|
+
this.stdin.pause();
|
|
10644
|
+
}
|
|
10645
|
+
resume() {
|
|
10646
|
+
if (this.stdin.setRawMode) {
|
|
10647
|
+
this.stdin.setRawMode(true);
|
|
10648
|
+
}
|
|
10649
|
+
this.stdin.resume();
|
|
10650
|
+
this._keyHandler.resume();
|
|
10651
|
+
if (this._suspendedMouseEnabled) {
|
|
10652
|
+
this.enableMouse();
|
|
10653
|
+
}
|
|
10654
|
+
this._controlState = this._previousControlState;
|
|
10655
|
+
if (this._previousControlState === "auto_started" /* AUTO_STARTED */ || this._previousControlState === "explicit_started" /* EXPLICIT_STARTED */) {
|
|
10656
|
+
this.internalStart();
|
|
10657
|
+
}
|
|
10658
|
+
}
|
|
9298
10659
|
internalPause() {
|
|
9299
10660
|
this._isRunning = false;
|
|
9300
10661
|
}
|
|
9301
10662
|
stop() {
|
|
9302
|
-
this.
|
|
10663
|
+
this._controlState = "explicit_stopped" /* EXPLICIT_STOPPED */;
|
|
9303
10664
|
this.internalStop();
|
|
9304
10665
|
}
|
|
9305
10666
|
internalStop() {
|
|
9306
|
-
if (this.isRunning && !this.
|
|
10667
|
+
if (this.isRunning && !this._isDestroyed) {
|
|
9307
10668
|
this._isRunning = false;
|
|
9308
10669
|
if (this.memorySnapshotTimer) {
|
|
9309
10670
|
clearInterval(this.memorySnapshotTimer);
|
|
@@ -9324,9 +10685,9 @@ Captured output:
|
|
|
9324
10685
|
if (this.memorySnapshotTimer) {
|
|
9325
10686
|
clearInterval(this.memorySnapshotTimer);
|
|
9326
10687
|
}
|
|
9327
|
-
if (this.
|
|
10688
|
+
if (this._isDestroyed)
|
|
9328
10689
|
return;
|
|
9329
|
-
this.
|
|
10690
|
+
this._isDestroyed = true;
|
|
9330
10691
|
if (this.renderTimeout) {
|
|
9331
10692
|
clearTimeout(this.renderTimeout);
|
|
9332
10693
|
this.renderTimeout = null;
|
|
@@ -9334,7 +10695,11 @@ Captured output:
|
|
|
9334
10695
|
this._isRunning = false;
|
|
9335
10696
|
this.waitingForPixelResolution = false;
|
|
9336
10697
|
this.capturedRenderable = undefined;
|
|
9337
|
-
|
|
10698
|
+
try {
|
|
10699
|
+
this.root.destroyRecursively();
|
|
10700
|
+
} catch (e) {
|
|
10701
|
+
console.error("Error destroying root renderable:", e instanceof Error ? e.stack : String(e));
|
|
10702
|
+
}
|
|
9338
10703
|
this._keyHandler.destroy();
|
|
9339
10704
|
this._console.deactivate();
|
|
9340
10705
|
this.disableStdoutInterception();
|
|
@@ -9359,7 +10724,7 @@ Captured output:
|
|
|
9359
10724
|
this.loop();
|
|
9360
10725
|
}
|
|
9361
10726
|
async loop() {
|
|
9362
|
-
if (this.rendering || this.
|
|
10727
|
+
if (this.rendering || this._isDestroyed)
|
|
9363
10728
|
return;
|
|
9364
10729
|
this.rendering = true;
|
|
9365
10730
|
if (this.renderTimeout) {
|
|
@@ -9403,17 +10768,17 @@ Captured output:
|
|
|
9403
10768
|
postProcessFn(this.nextRenderBuffer, deltaTime);
|
|
9404
10769
|
}
|
|
9405
10770
|
this._console.renderToBuffer(this.nextRenderBuffer);
|
|
9406
|
-
if (!this.
|
|
10771
|
+
if (!this._isDestroyed) {
|
|
9407
10772
|
this.renderNative();
|
|
9408
|
-
|
|
9409
|
-
|
|
9410
|
-
|
|
9411
|
-
|
|
9412
|
-
|
|
9413
|
-
|
|
9414
|
-
|
|
9415
|
-
|
|
9416
|
-
|
|
10773
|
+
const overallFrameTime = performance.now() - overallStart;
|
|
10774
|
+
this.lib.updateStats(this.rendererPtr, overallFrameTime, this.renderStats.fps, this.renderStats.frameCallbackTime);
|
|
10775
|
+
if (this.gatherStats) {
|
|
10776
|
+
this.collectStatSample(overallFrameTime);
|
|
10777
|
+
}
|
|
10778
|
+
if (this._isRunning) {
|
|
10779
|
+
const delay = Math.max(1, this.targetFrameTime - Math.floor(overallFrameTime));
|
|
10780
|
+
this.renderTimeout = setTimeout(() => this.loop(), delay);
|
|
10781
|
+
}
|
|
9417
10782
|
}
|
|
9418
10783
|
this.rendering = false;
|
|
9419
10784
|
if (this.immediateRerenderRequested) {
|
|
@@ -9572,7 +10937,7 @@ Captured output:
|
|
|
9572
10937
|
}
|
|
9573
10938
|
}
|
|
9574
10939
|
|
|
9575
|
-
export { __toESM, __commonJS, __export, __require, Edge, Gutter, exports_src, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, nonAlphanumericKeys, parseKeypress, ANSI, KeyHandler, RGBA, hexToRgb, rgbToHex, hsvToRgb, parseColor, fonts, measureText, getCharacterPositions, coordinateToCharacterIndex, renderFontToFrameBuffer, TextAttributes, DebugOverlayCorner, createTextAttributes, 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, t, SyntaxStyle, hastToStyledText, parseAlign, parseBoxSizing, parseDimension, parseDirection, parseDisplay, parseEdge, parseFlexDirection, parseGutter, parseJustify, parseLogLevel, parseMeasureMode, parseOverflow, parsePositionType, parseUnit, parseWrap, MouseParser, Selection, convertGlobalToLocalSelection, ASCIIFontSelectionHelper, envRegistry, registerEnvVar, generateEnvMarkdown, generateEnvColored, env, TextBuffer, LogLevel2 as LogLevel, setRenderLibPath, resolveRenderLib, OptimizedBuffer, h, isVNode, maybeMakeRenderable, wrapWithDelegates, instantiate, delegate, isValidPercentage, LayoutEvents, RenderableEvents, isRenderable, BaseRenderable, Renderable, RootRenderable, capture, ConsolePosition, TerminalConsole, getObjectsInViewport, MouseEvent, MouseButton, createCliRenderer, CliRenderEvents, CliRenderer };
|
|
10940
|
+
export { __toESM, __commonJS, __export, __require, Edge, Gutter, exports_src, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, nonAlphanumericKeys, parseKeypress, ANSI, KeyEvent, PasteEvent, KeyHandler, InternalKeyHandler, RGBA, hexToRgb, rgbToHex, hsvToRgb, parseColor, fonts, measureText, getCharacterPositions, coordinateToCharacterIndex, renderFontToFrameBuffer, TextAttributes, DebugOverlayCorner, createTextAttributes, 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, t, convertThemeToStyles, SyntaxStyle, hastToStyledText, LinearScrollAccel, MacOSScrollAccel, parseAlign, parseBoxSizing, parseDimension, parseDirection, parseDisplay, parseEdge, parseFlexDirection, parseGutter, parseJustify, parseLogLevel, parseMeasureMode, parseOverflow, parsePositionType, parseUnit, parseWrap, MouseParser, Selection, convertGlobalToLocalSelection, ASCIIFontSelectionHelper, envRegistry, registerEnvVar, clearEnvCache, generateEnvMarkdown, generateEnvColored, env, treeSitterToTextChunks, treeSitterToStyledText, addDefaultParsers, TreeSitterClient, DataPathsManager, getDataPaths, extToFiletype, pathToFiletype, main, getTreeSitterClient, TextBuffer, LogLevel2 as LogLevel, setRenderLibPath, resolveRenderLib, OptimizedBuffer, h, isVNode, maybeMakeRenderable, wrapWithDelegates, instantiate, delegate, isValidPercentage, LayoutEvents, RenderableEvents, isRenderable, BaseRenderable, Renderable, RootRenderable, capture, ConsolePosition, TerminalConsole, getObjectsInViewport, MouseEvent, MouseButton, createCliRenderer, CliRenderEvents, RendererControlState, CliRenderer };
|
|
9576
10941
|
|
|
9577
|
-
//# debugId=
|
|
9578
|
-
//# sourceMappingURL=index-
|
|
10942
|
+
//# debugId=4CAC9B07B4894E3E64756E2164756E21
|
|
10943
|
+
//# sourceMappingURL=index-zx1dwm33.js.map
|