@opentui/core 0.0.0-20250930-6541ec7f → 0.0.0-20250930-a8fe63ce
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/README.md +5 -1
- package/highlights-eq9cgrbb.scm +604 -0
- package/highlights-ghv9g403.scm +205 -0
- package/{index-kvwmgj67.js → index-h87jjatk.js} +1121 -77
- package/{index-kvwmgj67.js.map → index-h87jjatk.js.map} +20 -8
- package/index.js +393 -240
- package/index.js.map +6 -4
- 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 +4 -0
- package/lib/queue.d.ts +15 -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 +40 -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 +55 -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 +7 -7
- package/renderables/Code.d.ts +31 -0
- package/renderables/Text.d.ts +10 -67
- package/renderables/TextBufferRenderable.d.ts +81 -0
- package/renderables/index.d.ts +2 -0
- package/testing.js +1 -1
- package/tree-sitter-javascript-nd0q4pe9.wasm +0 -0
- package/tree-sitter-typescript-zxjzwt75.wasm +0 -0
|
@@ -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);
|
|
@@ -4188,60 +4188,9 @@ function isStyledText(obj) {
|
|
|
4188
4188
|
class StyledText {
|
|
4189
4189
|
[BrandedStyledText] = true;
|
|
4190
4190
|
chunks;
|
|
4191
|
-
textRenderable;
|
|
4192
4191
|
constructor(chunks) {
|
|
4193
4192
|
this.chunks = chunks;
|
|
4194
4193
|
}
|
|
4195
|
-
mount(textRenderable) {
|
|
4196
|
-
this.textRenderable = textRenderable;
|
|
4197
|
-
}
|
|
4198
|
-
insert(chunk, index) {
|
|
4199
|
-
const originalLength = this.chunks.length;
|
|
4200
|
-
if (this.textRenderable) {
|
|
4201
|
-
this.textRenderable.insertChunk(chunk, index ?? originalLength);
|
|
4202
|
-
let newChunks;
|
|
4203
|
-
if (index === undefined || index === originalLength) {
|
|
4204
|
-
newChunks = [...this.chunks, chunk];
|
|
4205
|
-
} else {
|
|
4206
|
-
newChunks = [...this.chunks.slice(0, index), chunk, ...this.chunks.slice(index)];
|
|
4207
|
-
}
|
|
4208
|
-
this.chunks = newChunks;
|
|
4209
|
-
}
|
|
4210
|
-
return this;
|
|
4211
|
-
}
|
|
4212
|
-
remove(chunk) {
|
|
4213
|
-
if (this.textRenderable) {
|
|
4214
|
-
this.textRenderable.removeChunk(chunk);
|
|
4215
|
-
const originalLength = this.chunks.length;
|
|
4216
|
-
const index = this.chunks.indexOf(chunk);
|
|
4217
|
-
if (index === -1)
|
|
4218
|
-
return this;
|
|
4219
|
-
let newChunks;
|
|
4220
|
-
if (index === originalLength - 1) {
|
|
4221
|
-
newChunks = this.chunks.slice(0, -1);
|
|
4222
|
-
} else {
|
|
4223
|
-
newChunks = [...this.chunks.slice(0, index), ...this.chunks.slice(index + 1)];
|
|
4224
|
-
}
|
|
4225
|
-
this.chunks = newChunks;
|
|
4226
|
-
}
|
|
4227
|
-
return this;
|
|
4228
|
-
}
|
|
4229
|
-
replace(chunk, oldChunk) {
|
|
4230
|
-
if (this.textRenderable) {
|
|
4231
|
-
this.textRenderable.replaceChunk(chunk, oldChunk);
|
|
4232
|
-
const index = this.chunks.indexOf(oldChunk);
|
|
4233
|
-
if (index === -1)
|
|
4234
|
-
return this;
|
|
4235
|
-
let newChunks;
|
|
4236
|
-
if (index === this.chunks.length - 1) {
|
|
4237
|
-
newChunks = [...this.chunks.slice(0, -1), chunk];
|
|
4238
|
-
} else {
|
|
4239
|
-
newChunks = [...this.chunks.slice(0, index), chunk, ...this.chunks.slice(index + 1)];
|
|
4240
|
-
}
|
|
4241
|
-
this.chunks = newChunks;
|
|
4242
|
-
}
|
|
4243
|
-
return this;
|
|
4244
|
-
}
|
|
4245
4194
|
}
|
|
4246
4195
|
function stringToStyledText(content) {
|
|
4247
4196
|
const chunk = {
|
|
@@ -4337,7 +4286,36 @@ function t(strings, ...values) {
|
|
|
4337
4286
|
return new StyledText(chunks);
|
|
4338
4287
|
}
|
|
4339
4288
|
|
|
4340
|
-
// src/lib/
|
|
4289
|
+
// src/lib/syntax-style.ts
|
|
4290
|
+
function convertThemeToStyles(theme) {
|
|
4291
|
+
const flatStyles = {};
|
|
4292
|
+
for (const tokenStyle of theme) {
|
|
4293
|
+
const styleDefinition = {};
|
|
4294
|
+
if (tokenStyle.style.foreground) {
|
|
4295
|
+
styleDefinition.fg = parseColor(tokenStyle.style.foreground);
|
|
4296
|
+
}
|
|
4297
|
+
if (tokenStyle.style.background) {
|
|
4298
|
+
styleDefinition.bg = parseColor(tokenStyle.style.background);
|
|
4299
|
+
}
|
|
4300
|
+
if (tokenStyle.style.bold !== undefined) {
|
|
4301
|
+
styleDefinition.bold = tokenStyle.style.bold;
|
|
4302
|
+
}
|
|
4303
|
+
if (tokenStyle.style.italic !== undefined) {
|
|
4304
|
+
styleDefinition.italic = tokenStyle.style.italic;
|
|
4305
|
+
}
|
|
4306
|
+
if (tokenStyle.style.underline !== undefined) {
|
|
4307
|
+
styleDefinition.underline = tokenStyle.style.underline;
|
|
4308
|
+
}
|
|
4309
|
+
if (tokenStyle.style.dim !== undefined) {
|
|
4310
|
+
styleDefinition.dim = tokenStyle.style.dim;
|
|
4311
|
+
}
|
|
4312
|
+
for (const scope of tokenStyle.scope) {
|
|
4313
|
+
flatStyles[scope] = styleDefinition;
|
|
4314
|
+
}
|
|
4315
|
+
}
|
|
4316
|
+
return flatStyles;
|
|
4317
|
+
}
|
|
4318
|
+
|
|
4341
4319
|
class SyntaxStyle {
|
|
4342
4320
|
styles;
|
|
4343
4321
|
mergedStyleCache;
|
|
@@ -4345,6 +4323,10 @@ class SyntaxStyle {
|
|
|
4345
4323
|
this.styles = styles;
|
|
4346
4324
|
this.mergedStyleCache = new Map;
|
|
4347
4325
|
}
|
|
4326
|
+
static fromTheme(theme) {
|
|
4327
|
+
const flatStyles = convertThemeToStyles(theme);
|
|
4328
|
+
return new SyntaxStyle(flatStyles);
|
|
4329
|
+
}
|
|
4348
4330
|
mergeStyles(...styleNames) {
|
|
4349
4331
|
const cacheKey = styleNames.join(":");
|
|
4350
4332
|
const cached = this.mergedStyleCache.get(cacheKey);
|
|
@@ -4352,7 +4334,7 @@ class SyntaxStyle {
|
|
|
4352
4334
|
return cached;
|
|
4353
4335
|
const styleDefinition = {};
|
|
4354
4336
|
for (const name of styleNames) {
|
|
4355
|
-
const style = this.
|
|
4337
|
+
const style = this.getStyle(name);
|
|
4356
4338
|
if (!style)
|
|
4357
4339
|
continue;
|
|
4358
4340
|
if (style.fg)
|
|
@@ -4382,6 +4364,18 @@ class SyntaxStyle {
|
|
|
4382
4364
|
this.mergedStyleCache.set(cacheKey, merged);
|
|
4383
4365
|
return merged;
|
|
4384
4366
|
}
|
|
4367
|
+
getStyle(name) {
|
|
4368
|
+
if (Object.prototype.hasOwnProperty.call(this.styles, name)) {
|
|
4369
|
+
return this.styles[name];
|
|
4370
|
+
}
|
|
4371
|
+
if (name.includes(".")) {
|
|
4372
|
+
const baseName = name.split(".")[0];
|
|
4373
|
+
if (Object.prototype.hasOwnProperty.call(this.styles, baseName)) {
|
|
4374
|
+
return this.styles[baseName];
|
|
4375
|
+
}
|
|
4376
|
+
}
|
|
4377
|
+
return;
|
|
4378
|
+
}
|
|
4385
4379
|
clearCache() {
|
|
4386
4380
|
this.mergedStyleCache.clear();
|
|
4387
4381
|
}
|
|
@@ -4389,6 +4383,8 @@ class SyntaxStyle {
|
|
|
4389
4383
|
return this.mergedStyleCache.size;
|
|
4390
4384
|
}
|
|
4391
4385
|
}
|
|
4386
|
+
|
|
4387
|
+
// src/lib/hast-styled-text.ts
|
|
4392
4388
|
function hastToTextChunks(node, syntaxStyle, parentStyles = []) {
|
|
4393
4389
|
const chunks = [];
|
|
4394
4390
|
if (node.type === "text") {
|
|
@@ -4923,9 +4919,19 @@ function singleton(key, factory) {
|
|
|
4923
4919
|
}
|
|
4924
4920
|
return bag[key];
|
|
4925
4921
|
}
|
|
4922
|
+
function destroySingleton(key) {
|
|
4923
|
+
const bag = globalThis[singletonCacheSymbol];
|
|
4924
|
+
if (bag && key in bag) {
|
|
4925
|
+
delete bag[key];
|
|
4926
|
+
}
|
|
4927
|
+
}
|
|
4928
|
+
function hasSingleton(key) {
|
|
4929
|
+
const bag = globalThis[singletonCacheSymbol];
|
|
4930
|
+
return bag && key in bag;
|
|
4931
|
+
}
|
|
4926
4932
|
|
|
4927
4933
|
// src/lib/env.ts
|
|
4928
|
-
var envRegistry = {};
|
|
4934
|
+
var envRegistry = singleton("env-registry", () => ({}));
|
|
4929
4935
|
function registerEnvVar(config) {
|
|
4930
4936
|
const existing = envRegistry[config.name];
|
|
4931
4937
|
if (existing) {
|
|
@@ -4983,8 +4989,14 @@ class EnvStore {
|
|
|
4983
4989
|
has(key) {
|
|
4984
4990
|
return key in envRegistry;
|
|
4985
4991
|
}
|
|
4992
|
+
clearCache() {
|
|
4993
|
+
this.parsedValues.clear();
|
|
4994
|
+
}
|
|
4986
4995
|
}
|
|
4987
4996
|
var envStore = singleton("env-store", () => new EnvStore);
|
|
4997
|
+
function clearEnvCache() {
|
|
4998
|
+
envStore.clearCache();
|
|
4999
|
+
}
|
|
4988
5000
|
function generateEnvMarkdown() {
|
|
4989
5001
|
const configs = Object.values(envRegistry);
|
|
4990
5002
|
if (configs.length === 0) {
|
|
@@ -5073,6 +5085,1030 @@ var env = new Proxy({}, {
|
|
|
5073
5085
|
return;
|
|
5074
5086
|
}
|
|
5075
5087
|
});
|
|
5088
|
+
|
|
5089
|
+
// src/lib/tree-sitter-styled-text.ts
|
|
5090
|
+
function treeSitterToTextChunks(content, highlights, syntaxStyle) {
|
|
5091
|
+
const chunks = [];
|
|
5092
|
+
const defaultStyle = syntaxStyle.getStyle("default");
|
|
5093
|
+
let currentIndex = 0;
|
|
5094
|
+
for (let i = 0;i < highlights.length; i++) {
|
|
5095
|
+
const [startIndex, endIndex, group] = highlights[i];
|
|
5096
|
+
if (startIndex < currentIndex)
|
|
5097
|
+
continue;
|
|
5098
|
+
if (currentIndex < startIndex) {
|
|
5099
|
+
const text2 = content.slice(currentIndex, startIndex);
|
|
5100
|
+
chunks.push({
|
|
5101
|
+
__isChunk: true,
|
|
5102
|
+
text: text2,
|
|
5103
|
+
fg: defaultStyle?.fg,
|
|
5104
|
+
bg: defaultStyle?.bg,
|
|
5105
|
+
attributes: defaultStyle ? createTextAttributes({
|
|
5106
|
+
bold: defaultStyle.bold,
|
|
5107
|
+
italic: defaultStyle.italic,
|
|
5108
|
+
underline: defaultStyle.underline,
|
|
5109
|
+
dim: defaultStyle.dim
|
|
5110
|
+
}) : 0
|
|
5111
|
+
});
|
|
5112
|
+
currentIndex = startIndex;
|
|
5113
|
+
}
|
|
5114
|
+
let resolvedStyle = syntaxStyle.getStyle(group);
|
|
5115
|
+
let j = i + 1;
|
|
5116
|
+
while (j < highlights.length && highlights[j][0] === startIndex) {
|
|
5117
|
+
const [, , nextGroup] = highlights[j];
|
|
5118
|
+
const nextStyle = syntaxStyle.getStyle(nextGroup);
|
|
5119
|
+
if (nextStyle) {
|
|
5120
|
+
resolvedStyle = nextStyle;
|
|
5121
|
+
}
|
|
5122
|
+
j++;
|
|
5123
|
+
}
|
|
5124
|
+
i = j - 1;
|
|
5125
|
+
const text = content.slice(startIndex, endIndex);
|
|
5126
|
+
const styleToUse = resolvedStyle || defaultStyle;
|
|
5127
|
+
chunks.push({
|
|
5128
|
+
__isChunk: true,
|
|
5129
|
+
text,
|
|
5130
|
+
fg: styleToUse?.fg,
|
|
5131
|
+
bg: styleToUse?.bg,
|
|
5132
|
+
attributes: styleToUse ? createTextAttributes({
|
|
5133
|
+
bold: styleToUse.bold,
|
|
5134
|
+
italic: styleToUse.italic,
|
|
5135
|
+
underline: styleToUse.underline,
|
|
5136
|
+
dim: styleToUse.dim
|
|
5137
|
+
}) : 0
|
|
5138
|
+
});
|
|
5139
|
+
currentIndex = endIndex;
|
|
5140
|
+
}
|
|
5141
|
+
if (currentIndex < content.length) {
|
|
5142
|
+
const text = content.slice(currentIndex);
|
|
5143
|
+
chunks.push({
|
|
5144
|
+
__isChunk: true,
|
|
5145
|
+
text,
|
|
5146
|
+
fg: defaultStyle?.fg,
|
|
5147
|
+
bg: defaultStyle?.bg,
|
|
5148
|
+
attributes: defaultStyle ? createTextAttributes({
|
|
5149
|
+
bold: defaultStyle.bold,
|
|
5150
|
+
italic: defaultStyle.italic,
|
|
5151
|
+
underline: defaultStyle.underline,
|
|
5152
|
+
dim: defaultStyle.dim
|
|
5153
|
+
}) : 0
|
|
5154
|
+
});
|
|
5155
|
+
}
|
|
5156
|
+
return chunks;
|
|
5157
|
+
}
|
|
5158
|
+
async function treeSitterToStyledText(content, filetype, syntaxStyle, client) {
|
|
5159
|
+
const result = await client.highlightOnce(content, filetype);
|
|
5160
|
+
if (result.highlights && result.highlights.length > 0) {
|
|
5161
|
+
const chunks = treeSitterToTextChunks(content, result.highlights, syntaxStyle);
|
|
5162
|
+
return new StyledText(chunks);
|
|
5163
|
+
} else {
|
|
5164
|
+
const defaultStyle = syntaxStyle.mergeStyles("default");
|
|
5165
|
+
const chunks = [
|
|
5166
|
+
{
|
|
5167
|
+
__isChunk: true,
|
|
5168
|
+
text: content,
|
|
5169
|
+
fg: defaultStyle.fg,
|
|
5170
|
+
bg: defaultStyle.bg,
|
|
5171
|
+
attributes: defaultStyle.attributes
|
|
5172
|
+
}
|
|
5173
|
+
];
|
|
5174
|
+
return new StyledText(chunks);
|
|
5175
|
+
}
|
|
5176
|
+
}
|
|
5177
|
+
|
|
5178
|
+
// src/lib/tree-sitter/client.ts
|
|
5179
|
+
import { EventEmitter as EventEmitter2 } from "events";
|
|
5180
|
+
|
|
5181
|
+
// src/lib/debounce.ts
|
|
5182
|
+
var TIMERS_MAP = new Map;
|
|
5183
|
+
|
|
5184
|
+
class DebounceController {
|
|
5185
|
+
scopeId;
|
|
5186
|
+
constructor(scopeId) {
|
|
5187
|
+
this.scopeId = scopeId;
|
|
5188
|
+
if (!TIMERS_MAP.has(this.scopeId)) {
|
|
5189
|
+
TIMERS_MAP.set(this.scopeId, new Map);
|
|
5190
|
+
}
|
|
5191
|
+
}
|
|
5192
|
+
debounce(id, ms, fn) {
|
|
5193
|
+
const scopeMap = TIMERS_MAP.get(this.scopeId);
|
|
5194
|
+
return new Promise((resolve, reject) => {
|
|
5195
|
+
if (scopeMap.has(id)) {
|
|
5196
|
+
clearTimeout(scopeMap.get(id));
|
|
5197
|
+
}
|
|
5198
|
+
const timerId = setTimeout(() => {
|
|
5199
|
+
try {
|
|
5200
|
+
resolve(fn());
|
|
5201
|
+
} catch (error) {
|
|
5202
|
+
reject(error);
|
|
5203
|
+
}
|
|
5204
|
+
scopeMap.delete(id);
|
|
5205
|
+
}, ms);
|
|
5206
|
+
scopeMap.set(id, timerId);
|
|
5207
|
+
});
|
|
5208
|
+
}
|
|
5209
|
+
clearDebounce(id) {
|
|
5210
|
+
const scopeMap = TIMERS_MAP.get(this.scopeId);
|
|
5211
|
+
if (scopeMap && scopeMap.has(id)) {
|
|
5212
|
+
clearTimeout(scopeMap.get(id));
|
|
5213
|
+
scopeMap.delete(id);
|
|
5214
|
+
}
|
|
5215
|
+
}
|
|
5216
|
+
clear() {
|
|
5217
|
+
const scopeMap = TIMERS_MAP.get(this.scopeId);
|
|
5218
|
+
if (scopeMap) {
|
|
5219
|
+
scopeMap.forEach((timerId) => clearTimeout(timerId));
|
|
5220
|
+
scopeMap.clear();
|
|
5221
|
+
}
|
|
5222
|
+
}
|
|
5223
|
+
}
|
|
5224
|
+
function createDebounce(scopeId) {
|
|
5225
|
+
return new DebounceController(scopeId);
|
|
5226
|
+
}
|
|
5227
|
+
function clearDebounceScope(scopeId) {
|
|
5228
|
+
const scopeMap = TIMERS_MAP.get(scopeId);
|
|
5229
|
+
if (scopeMap) {
|
|
5230
|
+
scopeMap.forEach((timerId) => clearTimeout(timerId));
|
|
5231
|
+
scopeMap.clear();
|
|
5232
|
+
}
|
|
5233
|
+
}
|
|
5234
|
+
|
|
5235
|
+
// src/lib/queue.ts
|
|
5236
|
+
class ProcessQueue {
|
|
5237
|
+
processor;
|
|
5238
|
+
queue = [];
|
|
5239
|
+
processing = false;
|
|
5240
|
+
autoProcess = true;
|
|
5241
|
+
constructor(processor, autoProcess = true) {
|
|
5242
|
+
this.processor = processor;
|
|
5243
|
+
this.autoProcess = autoProcess;
|
|
5244
|
+
}
|
|
5245
|
+
enqueue(item) {
|
|
5246
|
+
this.queue.push(item);
|
|
5247
|
+
if (!this.processing && this.autoProcess) {
|
|
5248
|
+
this.processQueue();
|
|
5249
|
+
}
|
|
5250
|
+
}
|
|
5251
|
+
processQueue() {
|
|
5252
|
+
if (this.queue.length === 0) {
|
|
5253
|
+
return;
|
|
5254
|
+
}
|
|
5255
|
+
this.processing = true;
|
|
5256
|
+
queueMicrotask(async () => {
|
|
5257
|
+
if (this.queue.length === 0) {
|
|
5258
|
+
this.processing = false;
|
|
5259
|
+
return;
|
|
5260
|
+
}
|
|
5261
|
+
const item = this.queue.shift();
|
|
5262
|
+
try {
|
|
5263
|
+
await this.processor(item);
|
|
5264
|
+
} catch (error) {
|
|
5265
|
+
console.error("Error processing queue item:", error);
|
|
5266
|
+
}
|
|
5267
|
+
if (this.queue.length > 0) {
|
|
5268
|
+
this.processQueue();
|
|
5269
|
+
} else {
|
|
5270
|
+
this.processing = false;
|
|
5271
|
+
}
|
|
5272
|
+
});
|
|
5273
|
+
}
|
|
5274
|
+
clear() {
|
|
5275
|
+
this.queue = [];
|
|
5276
|
+
}
|
|
5277
|
+
isProcessing() {
|
|
5278
|
+
return this.processing;
|
|
5279
|
+
}
|
|
5280
|
+
size() {
|
|
5281
|
+
return this.queue.length;
|
|
5282
|
+
}
|
|
5283
|
+
}
|
|
5284
|
+
|
|
5285
|
+
// src/lib/tree-sitter/assets/javascript/highlights.scm
|
|
5286
|
+
var highlights_default = "./highlights-ghv9g403.scm";
|
|
5287
|
+
|
|
5288
|
+
// src/lib/tree-sitter/assets/javascript/tree-sitter-javascript.wasm
|
|
5289
|
+
var tree_sitter_javascript_default = "./tree-sitter-javascript-nd0q4pe9.wasm";
|
|
5290
|
+
|
|
5291
|
+
// src/lib/tree-sitter/assets/typescript/highlights.scm
|
|
5292
|
+
var highlights_default2 = "./highlights-eq9cgrbb.scm";
|
|
5293
|
+
|
|
5294
|
+
// src/lib/tree-sitter/assets/typescript/tree-sitter-typescript.wasm
|
|
5295
|
+
var tree_sitter_typescript_default = "./tree-sitter-typescript-zxjzwt75.wasm";
|
|
5296
|
+
|
|
5297
|
+
// src/lib/tree-sitter/default-parsers.ts
|
|
5298
|
+
var DEFAULT_PARSERS = [
|
|
5299
|
+
{
|
|
5300
|
+
filetype: "javascript",
|
|
5301
|
+
queries: {
|
|
5302
|
+
highlights: [highlights_default]
|
|
5303
|
+
},
|
|
5304
|
+
wasm: tree_sitter_javascript_default
|
|
5305
|
+
},
|
|
5306
|
+
{
|
|
5307
|
+
filetype: "typescript",
|
|
5308
|
+
queries: {
|
|
5309
|
+
highlights: [highlights_default2]
|
|
5310
|
+
},
|
|
5311
|
+
wasm: tree_sitter_typescript_default
|
|
5312
|
+
}
|
|
5313
|
+
];
|
|
5314
|
+
|
|
5315
|
+
// src/lib/tree-sitter/client.ts
|
|
5316
|
+
var DEFAULT_PARSERS2 = DEFAULT_PARSERS;
|
|
5317
|
+
function addDefaultParsers(parsers) {
|
|
5318
|
+
for (const parser of parsers) {
|
|
5319
|
+
const existingIndex = DEFAULT_PARSERS2.findIndex((p) => p.filetype === parser.filetype);
|
|
5320
|
+
if (existingIndex >= 0) {
|
|
5321
|
+
DEFAULT_PARSERS2[existingIndex] = parser;
|
|
5322
|
+
} else {
|
|
5323
|
+
DEFAULT_PARSERS2.push(parser);
|
|
5324
|
+
}
|
|
5325
|
+
}
|
|
5326
|
+
}
|
|
5327
|
+
|
|
5328
|
+
class TreeSitterClient extends EventEmitter2 {
|
|
5329
|
+
initialized = false;
|
|
5330
|
+
worker;
|
|
5331
|
+
buffers = new Map;
|
|
5332
|
+
initializePromise;
|
|
5333
|
+
initializeResolvers;
|
|
5334
|
+
messageCallbacks = new Map;
|
|
5335
|
+
messageIdCounter = 0;
|
|
5336
|
+
editQueues = new Map;
|
|
5337
|
+
debouncer;
|
|
5338
|
+
options;
|
|
5339
|
+
constructor(options) {
|
|
5340
|
+
super();
|
|
5341
|
+
this.options = options;
|
|
5342
|
+
this.debouncer = createDebounce("tree-sitter-client");
|
|
5343
|
+
this.startWorker();
|
|
5344
|
+
}
|
|
5345
|
+
startWorker() {
|
|
5346
|
+
if (this.worker) {
|
|
5347
|
+
return;
|
|
5348
|
+
}
|
|
5349
|
+
const workerPath = this.options.workerPath || new URL("./parser.worker.ts", import.meta.url);
|
|
5350
|
+
this.worker = new Worker(workerPath);
|
|
5351
|
+
this.worker.onmessage = this.handleWorkerMessage.bind(this);
|
|
5352
|
+
}
|
|
5353
|
+
stopWorker() {
|
|
5354
|
+
if (!this.worker) {
|
|
5355
|
+
return;
|
|
5356
|
+
}
|
|
5357
|
+
this.worker.terminate();
|
|
5358
|
+
this.worker = undefined;
|
|
5359
|
+
}
|
|
5360
|
+
handleReset() {
|
|
5361
|
+
this.buffers.clear();
|
|
5362
|
+
this.stopWorker();
|
|
5363
|
+
this.startWorker();
|
|
5364
|
+
this.initializePromise = undefined;
|
|
5365
|
+
this.initializeResolvers = undefined;
|
|
5366
|
+
return this.initialize();
|
|
5367
|
+
}
|
|
5368
|
+
async initialize() {
|
|
5369
|
+
if (this.initializePromise) {
|
|
5370
|
+
return this.initializePromise;
|
|
5371
|
+
}
|
|
5372
|
+
this.initializePromise = new Promise((resolve, reject) => {
|
|
5373
|
+
const timeoutMs = this.options.initTimeout ?? 1e4;
|
|
5374
|
+
const timeoutId = setTimeout(() => {
|
|
5375
|
+
this.initializeResolvers = undefined;
|
|
5376
|
+
reject(new Error("Worker initialization timed out"));
|
|
5377
|
+
}, timeoutMs);
|
|
5378
|
+
this.initializeResolvers = { resolve, reject, timeoutId };
|
|
5379
|
+
this.worker?.postMessage({
|
|
5380
|
+
type: "INIT",
|
|
5381
|
+
dataPath: this.options.dataPath
|
|
5382
|
+
});
|
|
5383
|
+
});
|
|
5384
|
+
await this.initializePromise;
|
|
5385
|
+
await this.registerDefaultParsers();
|
|
5386
|
+
return this.initializePromise;
|
|
5387
|
+
}
|
|
5388
|
+
async registerDefaultParsers() {
|
|
5389
|
+
for (const parser of DEFAULT_PARSERS2) {
|
|
5390
|
+
this.addFiletypeParser(parser);
|
|
5391
|
+
}
|
|
5392
|
+
}
|
|
5393
|
+
addFiletypeParser(filetypeParser) {
|
|
5394
|
+
this.worker?.postMessage({ type: "ADD_FILETYPE_PARSER", filetypeParser });
|
|
5395
|
+
}
|
|
5396
|
+
async getPerformance() {
|
|
5397
|
+
const messageId = `performance_${this.messageIdCounter++}`;
|
|
5398
|
+
return new Promise((resolve) => {
|
|
5399
|
+
this.messageCallbacks.set(messageId, resolve);
|
|
5400
|
+
this.worker?.postMessage({ type: "GET_PERFORMANCE", messageId });
|
|
5401
|
+
});
|
|
5402
|
+
}
|
|
5403
|
+
async highlightOnce(content, filetype) {
|
|
5404
|
+
if (!this.initialized) {
|
|
5405
|
+
try {
|
|
5406
|
+
await this.initialize();
|
|
5407
|
+
} catch (error) {
|
|
5408
|
+
return { error: "Could not highlight because of initialization error" };
|
|
5409
|
+
}
|
|
5410
|
+
}
|
|
5411
|
+
const messageId = `oneshot_${this.messageIdCounter++}`;
|
|
5412
|
+
return new Promise((resolve) => {
|
|
5413
|
+
this.messageCallbacks.set(messageId, resolve);
|
|
5414
|
+
this.worker?.postMessage({
|
|
5415
|
+
type: "ONESHOT_HIGHLIGHT",
|
|
5416
|
+
content,
|
|
5417
|
+
filetype,
|
|
5418
|
+
messageId
|
|
5419
|
+
});
|
|
5420
|
+
});
|
|
5421
|
+
}
|
|
5422
|
+
handleWorkerMessage(event) {
|
|
5423
|
+
const { type, bufferId, error, highlights, warning, messageId, hasParser, performance: performance2, version } = event.data;
|
|
5424
|
+
if (type === "HIGHLIGHT_RESPONSE") {
|
|
5425
|
+
const buffer = this.buffers.get(bufferId);
|
|
5426
|
+
if (!buffer || !buffer.hasParser)
|
|
5427
|
+
return;
|
|
5428
|
+
if (buffer.version !== version) {
|
|
5429
|
+
this.resetBuffer(bufferId, buffer.version, buffer.content);
|
|
5430
|
+
return;
|
|
5431
|
+
}
|
|
5432
|
+
this.emit("highlights:response", bufferId, version, highlights);
|
|
5433
|
+
}
|
|
5434
|
+
if (type === "INIT_RESPONSE") {
|
|
5435
|
+
if (this.initializeResolvers) {
|
|
5436
|
+
clearTimeout(this.initializeResolvers.timeoutId);
|
|
5437
|
+
if (error) {
|
|
5438
|
+
this.initializeResolvers.reject(new Error(error));
|
|
5439
|
+
} else {
|
|
5440
|
+
this.initialized = true;
|
|
5441
|
+
this.initializeResolvers.resolve();
|
|
5442
|
+
}
|
|
5443
|
+
this.initializeResolvers = undefined;
|
|
5444
|
+
return;
|
|
5445
|
+
}
|
|
5446
|
+
}
|
|
5447
|
+
if (type === "PARSER_INIT_RESPONSE") {
|
|
5448
|
+
const callback = this.messageCallbacks.get(messageId);
|
|
5449
|
+
if (callback) {
|
|
5450
|
+
this.messageCallbacks.delete(messageId);
|
|
5451
|
+
callback({ hasParser, warning, error });
|
|
5452
|
+
}
|
|
5453
|
+
return;
|
|
5454
|
+
}
|
|
5455
|
+
if (type === "PRELOAD_PARSER_RESPONSE") {
|
|
5456
|
+
const callback = this.messageCallbacks.get(messageId);
|
|
5457
|
+
if (callback) {
|
|
5458
|
+
this.messageCallbacks.delete(messageId);
|
|
5459
|
+
callback({ hasParser });
|
|
5460
|
+
}
|
|
5461
|
+
return;
|
|
5462
|
+
}
|
|
5463
|
+
if (type === "BUFFER_DISPOSED") {
|
|
5464
|
+
const callback = this.messageCallbacks.get(`dispose_${bufferId}`);
|
|
5465
|
+
if (callback) {
|
|
5466
|
+
this.messageCallbacks.delete(`dispose_${bufferId}`);
|
|
5467
|
+
callback(true);
|
|
5468
|
+
}
|
|
5469
|
+
this.emit("buffer:disposed", bufferId);
|
|
5470
|
+
return;
|
|
5471
|
+
}
|
|
5472
|
+
if (type === "PERFORMANCE_RESPONSE") {
|
|
5473
|
+
const callback = this.messageCallbacks.get(messageId);
|
|
5474
|
+
if (callback) {
|
|
5475
|
+
this.messageCallbacks.delete(messageId);
|
|
5476
|
+
callback(performance2);
|
|
5477
|
+
}
|
|
5478
|
+
return;
|
|
5479
|
+
}
|
|
5480
|
+
if (type === "ONESHOT_HIGHLIGHT_RESPONSE") {
|
|
5481
|
+
const callback = this.messageCallbacks.get(messageId);
|
|
5482
|
+
if (callback) {
|
|
5483
|
+
this.messageCallbacks.delete(messageId);
|
|
5484
|
+
callback({ highlights, warning, error });
|
|
5485
|
+
}
|
|
5486
|
+
return;
|
|
5487
|
+
}
|
|
5488
|
+
if (type === "UPDATE_DATA_PATH_RESPONSE") {
|
|
5489
|
+
const callback = this.messageCallbacks.get(messageId);
|
|
5490
|
+
if (callback) {
|
|
5491
|
+
this.messageCallbacks.delete(messageId);
|
|
5492
|
+
callback({ error });
|
|
5493
|
+
}
|
|
5494
|
+
return;
|
|
5495
|
+
}
|
|
5496
|
+
if (warning) {
|
|
5497
|
+
this.emit("warning", warning, bufferId);
|
|
5498
|
+
return;
|
|
5499
|
+
}
|
|
5500
|
+
if (error) {
|
|
5501
|
+
this.emit("error", error, bufferId);
|
|
5502
|
+
return;
|
|
5503
|
+
}
|
|
5504
|
+
if (type === "WORKER_LOG") {
|
|
5505
|
+
const { logType, data } = event.data;
|
|
5506
|
+
const message = data.join(" ");
|
|
5507
|
+
this.emit("worker:log", logType, message);
|
|
5508
|
+
if (logType === "log") {
|
|
5509
|
+
console.log("Worker stdout:", ...data);
|
|
5510
|
+
} else if (logType === "error") {
|
|
5511
|
+
console.error("Worker stderr:", ...data);
|
|
5512
|
+
}
|
|
5513
|
+
return;
|
|
5514
|
+
}
|
|
5515
|
+
}
|
|
5516
|
+
async preloadParser(filetype) {
|
|
5517
|
+
const messageId = `has_parser_${this.messageIdCounter++}`;
|
|
5518
|
+
const response = await new Promise((resolve) => {
|
|
5519
|
+
this.messageCallbacks.set(messageId, resolve);
|
|
5520
|
+
this.worker?.postMessage({
|
|
5521
|
+
type: "PRELOAD_PARSER",
|
|
5522
|
+
filetype,
|
|
5523
|
+
messageId
|
|
5524
|
+
});
|
|
5525
|
+
});
|
|
5526
|
+
return response.hasParser;
|
|
5527
|
+
}
|
|
5528
|
+
async createBuffer(id, content, filetype, version = 1, autoInitialize = true) {
|
|
5529
|
+
if (!this.initialized) {
|
|
5530
|
+
if (!autoInitialize) {
|
|
5531
|
+
this.emit("error", "Could not create buffer because client is not initialized");
|
|
5532
|
+
return false;
|
|
5533
|
+
}
|
|
5534
|
+
try {
|
|
5535
|
+
await this.initialize();
|
|
5536
|
+
} catch (error) {
|
|
5537
|
+
this.emit("error", "Could not create buffer because of initialization error");
|
|
5538
|
+
return false;
|
|
5539
|
+
}
|
|
5540
|
+
}
|
|
5541
|
+
if (this.buffers.has(id)) {
|
|
5542
|
+
throw new Error(`Buffer with id ${id} already exists`);
|
|
5543
|
+
}
|
|
5544
|
+
this.buffers.set(id, { id, content, filetype, version, hasParser: false });
|
|
5545
|
+
const messageId = `init_${this.messageIdCounter++}`;
|
|
5546
|
+
const response = await new Promise((resolve) => {
|
|
5547
|
+
this.messageCallbacks.set(messageId, resolve);
|
|
5548
|
+
this.worker?.postMessage({
|
|
5549
|
+
type: "INITIALIZE_PARSER",
|
|
5550
|
+
bufferId: id,
|
|
5551
|
+
version,
|
|
5552
|
+
content,
|
|
5553
|
+
filetype,
|
|
5554
|
+
messageId
|
|
5555
|
+
});
|
|
5556
|
+
});
|
|
5557
|
+
if (!response.hasParser) {
|
|
5558
|
+
this.emit("buffer:initialized", id, false);
|
|
5559
|
+
if (filetype !== "plaintext") {
|
|
5560
|
+
this.emit("warning", response.warning || response.error || "Buffer has no parser", id);
|
|
5561
|
+
}
|
|
5562
|
+
return false;
|
|
5563
|
+
}
|
|
5564
|
+
const bufferState = { id, content, filetype, version, hasParser: true };
|
|
5565
|
+
this.buffers.set(id, bufferState);
|
|
5566
|
+
this.emit("buffer:initialized", id, true);
|
|
5567
|
+
return true;
|
|
5568
|
+
}
|
|
5569
|
+
async updateBuffer(id, edits, newContent, version) {
|
|
5570
|
+
if (!this.initialized) {
|
|
5571
|
+
return;
|
|
5572
|
+
}
|
|
5573
|
+
const buffer = this.buffers.get(id);
|
|
5574
|
+
if (!buffer || !buffer.hasParser) {
|
|
5575
|
+
return;
|
|
5576
|
+
}
|
|
5577
|
+
this.buffers.set(id, { ...buffer, content: newContent, version });
|
|
5578
|
+
if (!this.editQueues.has(id)) {
|
|
5579
|
+
this.editQueues.set(id, new ProcessQueue((item) => this.processEdit(id, item.edits, item.newContent, item.version, item.isReset)));
|
|
5580
|
+
}
|
|
5581
|
+
const bufferQueue = this.editQueues.get(id);
|
|
5582
|
+
bufferQueue.enqueue({ edits, newContent, version });
|
|
5583
|
+
}
|
|
5584
|
+
async processEdit(bufferId, edits, newContent, version, isReset = false) {
|
|
5585
|
+
this.worker?.postMessage({
|
|
5586
|
+
type: isReset ? "RESET_BUFFER" : "HANDLE_EDITS",
|
|
5587
|
+
bufferId,
|
|
5588
|
+
version,
|
|
5589
|
+
content: newContent,
|
|
5590
|
+
edits
|
|
5591
|
+
});
|
|
5592
|
+
}
|
|
5593
|
+
async removeBuffer(bufferId) {
|
|
5594
|
+
if (!this.initialized) {
|
|
5595
|
+
return;
|
|
5596
|
+
}
|
|
5597
|
+
this.buffers.delete(bufferId);
|
|
5598
|
+
if (this.editQueues.has(bufferId)) {
|
|
5599
|
+
this.editQueues.get(bufferId)?.clear();
|
|
5600
|
+
this.editQueues.delete(bufferId);
|
|
5601
|
+
}
|
|
5602
|
+
if (this.worker) {
|
|
5603
|
+
await new Promise((resolve) => {
|
|
5604
|
+
const messageId = `dispose_${bufferId}`;
|
|
5605
|
+
this.messageCallbacks.set(messageId, resolve);
|
|
5606
|
+
try {
|
|
5607
|
+
this.worker.postMessage({
|
|
5608
|
+
type: "DISPOSE_BUFFER",
|
|
5609
|
+
bufferId
|
|
5610
|
+
});
|
|
5611
|
+
} catch (error) {
|
|
5612
|
+
console.error("Error disposing buffer", error);
|
|
5613
|
+
resolve(false);
|
|
5614
|
+
}
|
|
5615
|
+
setTimeout(() => {
|
|
5616
|
+
if (this.messageCallbacks.has(messageId)) {
|
|
5617
|
+
this.messageCallbacks.delete(messageId);
|
|
5618
|
+
console.warn({ bufferId }, "Timed out waiting for buffer to be disposed");
|
|
5619
|
+
resolve(false);
|
|
5620
|
+
}
|
|
5621
|
+
}, 3000);
|
|
5622
|
+
});
|
|
5623
|
+
}
|
|
5624
|
+
this.debouncer.clearDebounce(`reset-${bufferId}`);
|
|
5625
|
+
}
|
|
5626
|
+
async destroy() {
|
|
5627
|
+
if (this.initializeResolvers) {
|
|
5628
|
+
clearTimeout(this.initializeResolvers.timeoutId);
|
|
5629
|
+
this.initializeResolvers = undefined;
|
|
5630
|
+
}
|
|
5631
|
+
clearDebounceScope("tree-sitter-client");
|
|
5632
|
+
this.stopWorker();
|
|
5633
|
+
this.buffers.clear();
|
|
5634
|
+
this.editQueues.clear();
|
|
5635
|
+
this.initialized = false;
|
|
5636
|
+
this.initializePromise = undefined;
|
|
5637
|
+
}
|
|
5638
|
+
async resetBuffer(bufferId, version, content) {
|
|
5639
|
+
if (!this.initialized) {
|
|
5640
|
+
return;
|
|
5641
|
+
}
|
|
5642
|
+
const buffer = this.buffers.get(bufferId);
|
|
5643
|
+
if (!buffer || !buffer.hasParser) {
|
|
5644
|
+
this.emit("error", "Cannot reset buffer with no parser", bufferId);
|
|
5645
|
+
return;
|
|
5646
|
+
}
|
|
5647
|
+
this.buffers.set(bufferId, { ...buffer, content, version });
|
|
5648
|
+
this.debouncer.debounce(`reset-${bufferId}`, 10, () => this.processEdit(bufferId, [], content, version, true));
|
|
5649
|
+
}
|
|
5650
|
+
getBuffer(bufferId) {
|
|
5651
|
+
return this.buffers.get(bufferId);
|
|
5652
|
+
}
|
|
5653
|
+
getAllBuffers() {
|
|
5654
|
+
return Array.from(this.buffers.values());
|
|
5655
|
+
}
|
|
5656
|
+
isInitialized() {
|
|
5657
|
+
return this.initialized;
|
|
5658
|
+
}
|
|
5659
|
+
async setDataPath(dataPath) {
|
|
5660
|
+
if (this.options.dataPath === dataPath) {
|
|
5661
|
+
return;
|
|
5662
|
+
}
|
|
5663
|
+
this.options.dataPath = dataPath;
|
|
5664
|
+
if (this.initialized && this.worker) {
|
|
5665
|
+
const messageId = `update_datapath_${this.messageIdCounter++}`;
|
|
5666
|
+
return new Promise((resolve, reject) => {
|
|
5667
|
+
this.messageCallbacks.set(messageId, (response) => {
|
|
5668
|
+
if (response.error) {
|
|
5669
|
+
reject(new Error(response.error));
|
|
5670
|
+
} else {
|
|
5671
|
+
resolve();
|
|
5672
|
+
}
|
|
5673
|
+
});
|
|
5674
|
+
this.worker.postMessage({
|
|
5675
|
+
type: "UPDATE_DATA_PATH",
|
|
5676
|
+
dataPath,
|
|
5677
|
+
messageId
|
|
5678
|
+
});
|
|
5679
|
+
});
|
|
5680
|
+
}
|
|
5681
|
+
}
|
|
5682
|
+
}
|
|
5683
|
+
|
|
5684
|
+
// src/lib/data-paths.ts
|
|
5685
|
+
import os from "os";
|
|
5686
|
+
import path from "path";
|
|
5687
|
+
import { EventEmitter as EventEmitter3 } from "events";
|
|
5688
|
+
|
|
5689
|
+
// src/lib/validate-dir-name.ts
|
|
5690
|
+
function isValidDirectoryName(name) {
|
|
5691
|
+
if (!name || typeof name !== "string") {
|
|
5692
|
+
return false;
|
|
5693
|
+
}
|
|
5694
|
+
if (name.trim().length === 0) {
|
|
5695
|
+
return false;
|
|
5696
|
+
}
|
|
5697
|
+
const reservedNames = [
|
|
5698
|
+
"CON",
|
|
5699
|
+
"PRN",
|
|
5700
|
+
"AUX",
|
|
5701
|
+
"NUL",
|
|
5702
|
+
"COM1",
|
|
5703
|
+
"COM2",
|
|
5704
|
+
"COM3",
|
|
5705
|
+
"COM4",
|
|
5706
|
+
"COM5",
|
|
5707
|
+
"COM6",
|
|
5708
|
+
"COM7",
|
|
5709
|
+
"COM8",
|
|
5710
|
+
"COM9",
|
|
5711
|
+
"LPT1",
|
|
5712
|
+
"LPT2",
|
|
5713
|
+
"LPT3",
|
|
5714
|
+
"LPT4",
|
|
5715
|
+
"LPT5",
|
|
5716
|
+
"LPT6",
|
|
5717
|
+
"LPT7",
|
|
5718
|
+
"LPT8",
|
|
5719
|
+
"LPT9"
|
|
5720
|
+
];
|
|
5721
|
+
if (reservedNames.includes(name.toUpperCase())) {
|
|
5722
|
+
return false;
|
|
5723
|
+
}
|
|
5724
|
+
const invalidChars = /[<>:"|?*\/\\\x00-\x1f]/;
|
|
5725
|
+
if (invalidChars.test(name)) {
|
|
5726
|
+
return false;
|
|
5727
|
+
}
|
|
5728
|
+
if (name.endsWith(".") || name.endsWith(" ")) {
|
|
5729
|
+
return false;
|
|
5730
|
+
}
|
|
5731
|
+
if (name === "." || name === "..") {
|
|
5732
|
+
return false;
|
|
5733
|
+
}
|
|
5734
|
+
return true;
|
|
5735
|
+
}
|
|
5736
|
+
|
|
5737
|
+
// src/lib/data-paths.ts
|
|
5738
|
+
registerEnvVar({
|
|
5739
|
+
name: "XDG_CONFIG_HOME",
|
|
5740
|
+
description: "Base directory for user-specific configuration files",
|
|
5741
|
+
type: "string",
|
|
5742
|
+
default: ""
|
|
5743
|
+
});
|
|
5744
|
+
registerEnvVar({
|
|
5745
|
+
name: "XDG_DATA_HOME",
|
|
5746
|
+
description: "Base directory for user-specific data files",
|
|
5747
|
+
type: "string",
|
|
5748
|
+
default: ""
|
|
5749
|
+
});
|
|
5750
|
+
|
|
5751
|
+
class DataPathsManager extends EventEmitter3 {
|
|
5752
|
+
_appName;
|
|
5753
|
+
_globalConfigPath;
|
|
5754
|
+
_globalConfigFile;
|
|
5755
|
+
_localConfigFile;
|
|
5756
|
+
_globalDataPath;
|
|
5757
|
+
constructor() {
|
|
5758
|
+
super();
|
|
5759
|
+
this._appName = "opentui";
|
|
5760
|
+
}
|
|
5761
|
+
get appName() {
|
|
5762
|
+
return this._appName;
|
|
5763
|
+
}
|
|
5764
|
+
set appName(value) {
|
|
5765
|
+
if (!isValidDirectoryName(value)) {
|
|
5766
|
+
throw new Error(`Invalid app name "${value}": must be a valid directory name`);
|
|
5767
|
+
}
|
|
5768
|
+
if (this._appName !== value) {
|
|
5769
|
+
this._appName = value;
|
|
5770
|
+
this._globalConfigPath = undefined;
|
|
5771
|
+
this._globalConfigFile = undefined;
|
|
5772
|
+
this._localConfigFile = undefined;
|
|
5773
|
+
this._globalDataPath = undefined;
|
|
5774
|
+
this.emit("paths:changed", this.toObject());
|
|
5775
|
+
}
|
|
5776
|
+
}
|
|
5777
|
+
get globalConfigPath() {
|
|
5778
|
+
if (this._globalConfigPath === undefined) {
|
|
5779
|
+
const homeDir = os.homedir();
|
|
5780
|
+
const xdgConfigHome = env.XDG_CONFIG_HOME;
|
|
5781
|
+
const baseConfigDir = xdgConfigHome || path.join(homeDir, ".config");
|
|
5782
|
+
this._globalConfigPath = path.join(baseConfigDir, this._appName);
|
|
5783
|
+
}
|
|
5784
|
+
return this._globalConfigPath;
|
|
5785
|
+
}
|
|
5786
|
+
get globalConfigFile() {
|
|
5787
|
+
if (this._globalConfigFile === undefined) {
|
|
5788
|
+
this._globalConfigFile = path.join(this.globalConfigPath, "init.ts");
|
|
5789
|
+
}
|
|
5790
|
+
return this._globalConfigFile;
|
|
5791
|
+
}
|
|
5792
|
+
get localConfigFile() {
|
|
5793
|
+
if (this._localConfigFile === undefined) {
|
|
5794
|
+
this._localConfigFile = path.join(process.cwd(), `.${this._appName}.ts`);
|
|
5795
|
+
}
|
|
5796
|
+
return this._localConfigFile;
|
|
5797
|
+
}
|
|
5798
|
+
get globalDataPath() {
|
|
5799
|
+
if (this._globalDataPath === undefined) {
|
|
5800
|
+
const homeDir = os.homedir();
|
|
5801
|
+
const xdgDataHome = env.XDG_DATA_HOME;
|
|
5802
|
+
const baseDataDir = xdgDataHome || path.join(homeDir, ".local/share");
|
|
5803
|
+
this._globalDataPath = path.join(baseDataDir, this._appName);
|
|
5804
|
+
}
|
|
5805
|
+
return this._globalDataPath;
|
|
5806
|
+
}
|
|
5807
|
+
toObject() {
|
|
5808
|
+
return {
|
|
5809
|
+
globalConfigPath: this.globalConfigPath,
|
|
5810
|
+
globalConfigFile: this.globalConfigFile,
|
|
5811
|
+
localConfigFile: this.localConfigFile,
|
|
5812
|
+
globalDataPath: this.globalDataPath
|
|
5813
|
+
};
|
|
5814
|
+
}
|
|
5815
|
+
}
|
|
5816
|
+
function getDataPaths() {
|
|
5817
|
+
return singleton("data-paths-opentui", () => new DataPathsManager);
|
|
5818
|
+
}
|
|
5819
|
+
|
|
5820
|
+
// src/lib/tree-sitter/resolve-ft.ts
|
|
5821
|
+
function extToFiletype(extension) {
|
|
5822
|
+
const extensionToFiletype = new Map([
|
|
5823
|
+
["js", "javascript"],
|
|
5824
|
+
["jsx", "javascriptreact"],
|
|
5825
|
+
["ts", "typescript"],
|
|
5826
|
+
["tsx", "typescriptreact"],
|
|
5827
|
+
["md", "markdown"],
|
|
5828
|
+
["json", "json"],
|
|
5829
|
+
["py", "python"],
|
|
5830
|
+
["rb", "ruby"],
|
|
5831
|
+
["go", "go"],
|
|
5832
|
+
["rs", "rust"],
|
|
5833
|
+
["c", "c"],
|
|
5834
|
+
["cpp", "cpp"],
|
|
5835
|
+
["h", "c"],
|
|
5836
|
+
["hpp", "cpp"],
|
|
5837
|
+
["html", "html"],
|
|
5838
|
+
["css", "css"],
|
|
5839
|
+
["scss", "scss"],
|
|
5840
|
+
["less", "less"],
|
|
5841
|
+
["sh", "shell"],
|
|
5842
|
+
["bash", "shell"],
|
|
5843
|
+
["zsh", "shell"],
|
|
5844
|
+
["vim", "vim"],
|
|
5845
|
+
["yaml", "yaml"],
|
|
5846
|
+
["yml", "yaml"],
|
|
5847
|
+
["toml", "toml"],
|
|
5848
|
+
["xml", "xml"],
|
|
5849
|
+
["zig", "zig"]
|
|
5850
|
+
]);
|
|
5851
|
+
return extensionToFiletype.get(extension);
|
|
5852
|
+
}
|
|
5853
|
+
function pathToFiletype(path2) {
|
|
5854
|
+
if (typeof path2 !== "string")
|
|
5855
|
+
return;
|
|
5856
|
+
const lastDot = path2.lastIndexOf(".");
|
|
5857
|
+
if (lastDot === -1 || lastDot === path2.length - 1) {
|
|
5858
|
+
return;
|
|
5859
|
+
}
|
|
5860
|
+
const extension = path2.substring(lastDot + 1);
|
|
5861
|
+
return extToFiletype(extension);
|
|
5862
|
+
}
|
|
5863
|
+
|
|
5864
|
+
// src/lib/tree-sitter/assets/update.ts
|
|
5865
|
+
import { readFile, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
5866
|
+
import * as path3 from "path";
|
|
5867
|
+
|
|
5868
|
+
// src/lib/tree-sitter/download-utils.ts
|
|
5869
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
5870
|
+
import * as path2 from "path";
|
|
5871
|
+
|
|
5872
|
+
class DownloadUtils {
|
|
5873
|
+
static hashUrl(url) {
|
|
5874
|
+
let hash = 0;
|
|
5875
|
+
for (let i = 0;i < url.length; i++) {
|
|
5876
|
+
const char = url.charCodeAt(i);
|
|
5877
|
+
hash = (hash << 5) - hash + char;
|
|
5878
|
+
hash = hash & hash;
|
|
5879
|
+
}
|
|
5880
|
+
return Math.abs(hash).toString(16);
|
|
5881
|
+
}
|
|
5882
|
+
static async downloadOrLoad(source, cacheDir, cacheSubdir, fileExtension, useHashForCache = true, filetype) {
|
|
5883
|
+
const isUrl = source.startsWith("http://") || source.startsWith("https://");
|
|
5884
|
+
if (isUrl) {
|
|
5885
|
+
let cacheFileName;
|
|
5886
|
+
if (useHashForCache) {
|
|
5887
|
+
const hash = this.hashUrl(source);
|
|
5888
|
+
cacheFileName = filetype ? `${filetype}-${hash}${fileExtension}` : `${hash}${fileExtension}`;
|
|
5889
|
+
} else {
|
|
5890
|
+
cacheFileName = path2.basename(source);
|
|
5891
|
+
}
|
|
5892
|
+
const cacheFile = path2.join(cacheDir, cacheSubdir, cacheFileName);
|
|
5893
|
+
await mkdir(path2.dirname(cacheFile), { recursive: true });
|
|
5894
|
+
try {
|
|
5895
|
+
const cachedContent = await Bun.file(cacheFile).arrayBuffer();
|
|
5896
|
+
if (cachedContent.byteLength > 0) {
|
|
5897
|
+
console.log(`Loaded from cache: ${cacheFile} (${source})`);
|
|
5898
|
+
return { content: cachedContent, filePath: cacheFile };
|
|
5899
|
+
}
|
|
5900
|
+
} catch (error) {}
|
|
5901
|
+
try {
|
|
5902
|
+
console.log(`Downloading from URL: ${source}`);
|
|
5903
|
+
const response = await fetch(source);
|
|
5904
|
+
if (!response.ok) {
|
|
5905
|
+
return { error: `Failed to fetch from ${source}: ${response.statusText}` };
|
|
5906
|
+
}
|
|
5907
|
+
const content = await response.arrayBuffer();
|
|
5908
|
+
try {
|
|
5909
|
+
await writeFile(cacheFile, Buffer.from(content));
|
|
5910
|
+
console.log(`Cached: ${source}`);
|
|
5911
|
+
} catch (cacheError) {
|
|
5912
|
+
console.warn(`Failed to cache: ${cacheError}`);
|
|
5913
|
+
}
|
|
5914
|
+
return { content, filePath: cacheFile };
|
|
5915
|
+
} catch (error) {
|
|
5916
|
+
return { error: `Error downloading from ${source}: ${error}` };
|
|
5917
|
+
}
|
|
5918
|
+
} else {
|
|
5919
|
+
try {
|
|
5920
|
+
console.log(`Loading from local path: ${source}`);
|
|
5921
|
+
const content = await Bun.file(source).arrayBuffer();
|
|
5922
|
+
return { content, filePath: source };
|
|
5923
|
+
} catch (error) {
|
|
5924
|
+
return { error: `Error loading from local path ${source}: ${error}` };
|
|
5925
|
+
}
|
|
5926
|
+
}
|
|
5927
|
+
}
|
|
5928
|
+
static async downloadToPath(source, targetPath) {
|
|
5929
|
+
const isUrl = source.startsWith("http://") || source.startsWith("https://");
|
|
5930
|
+
await mkdir(path2.dirname(targetPath), { recursive: true });
|
|
5931
|
+
if (isUrl) {
|
|
5932
|
+
try {
|
|
5933
|
+
console.log(`Downloading from URL: ${source}`);
|
|
5934
|
+
const response = await fetch(source);
|
|
5935
|
+
if (!response.ok) {
|
|
5936
|
+
return { error: `Failed to fetch from ${source}: ${response.statusText}` };
|
|
5937
|
+
}
|
|
5938
|
+
const content = await response.arrayBuffer();
|
|
5939
|
+
await writeFile(targetPath, Buffer.from(content));
|
|
5940
|
+
console.log(`Downloaded: ${source} -> ${targetPath}`);
|
|
5941
|
+
return { content, filePath: targetPath };
|
|
5942
|
+
} catch (error) {
|
|
5943
|
+
return { error: `Error downloading from ${source}: ${error}` };
|
|
5944
|
+
}
|
|
5945
|
+
} else {
|
|
5946
|
+
try {
|
|
5947
|
+
console.log(`Copying from local path: ${source}`);
|
|
5948
|
+
const content = await Bun.file(source).arrayBuffer();
|
|
5949
|
+
await writeFile(targetPath, Buffer.from(content));
|
|
5950
|
+
return { content, filePath: targetPath };
|
|
5951
|
+
} catch (error) {
|
|
5952
|
+
return { error: `Error copying from local path ${source}: ${error}` };
|
|
5953
|
+
}
|
|
5954
|
+
}
|
|
5955
|
+
}
|
|
5956
|
+
static async fetchHighlightQueries(sources, cacheDir, filetype) {
|
|
5957
|
+
const queryPromises = sources.map((source) => this.fetchHighlightQuery(source, cacheDir, filetype));
|
|
5958
|
+
const queryResults = await Promise.all(queryPromises);
|
|
5959
|
+
const validQueries = queryResults.filter((query) => query.trim().length > 0);
|
|
5960
|
+
return validQueries.join(`
|
|
5961
|
+
`);
|
|
5962
|
+
}
|
|
5963
|
+
static async fetchHighlightQuery(source, cacheDir, filetype) {
|
|
5964
|
+
const result = await this.downloadOrLoad(source, cacheDir, "queries", ".scm", true, filetype);
|
|
5965
|
+
if (result.error) {
|
|
5966
|
+
console.error(`Error fetching highlight query from ${source}:`, result.error);
|
|
5967
|
+
return "";
|
|
5968
|
+
}
|
|
5969
|
+
if (result.content) {
|
|
5970
|
+
return new TextDecoder().decode(result.content);
|
|
5971
|
+
}
|
|
5972
|
+
return "";
|
|
5973
|
+
}
|
|
5974
|
+
}
|
|
5975
|
+
|
|
5976
|
+
// src/lib/tree-sitter/assets/update.ts
|
|
5977
|
+
var __dirname = "/Users/runner/work/opentui/opentui/packages/core/src/lib/tree-sitter/assets";
|
|
5978
|
+
function getDefaultOptions() {
|
|
5979
|
+
return {
|
|
5980
|
+
configPath: path3.resolve(__dirname, "../parsers-config.json"),
|
|
5981
|
+
assetsDir: path3.resolve(__dirname),
|
|
5982
|
+
outputPath: path3.resolve(__dirname, "../default-parsers.ts")
|
|
5983
|
+
};
|
|
5984
|
+
}
|
|
5985
|
+
async function loadConfig(configPath) {
|
|
5986
|
+
const configContent = await readFile(configPath, "utf-8");
|
|
5987
|
+
return JSON.parse(configContent);
|
|
5988
|
+
}
|
|
5989
|
+
async function downloadLanguage(filetype, languageUrl, assetsDir, outputPath) {
|
|
5990
|
+
const languageDir = path3.join(assetsDir, filetype);
|
|
5991
|
+
const languageFilename = path3.basename(languageUrl);
|
|
5992
|
+
const languagePath = path3.join(languageDir, languageFilename);
|
|
5993
|
+
const result = await DownloadUtils.downloadToPath(languageUrl, languagePath);
|
|
5994
|
+
if (result.error) {
|
|
5995
|
+
throw new Error(`Failed to download language for ${filetype}: ${result.error}`);
|
|
5996
|
+
}
|
|
5997
|
+
return "./" + path3.relative(path3.dirname(outputPath), languagePath);
|
|
5998
|
+
}
|
|
5999
|
+
async function downloadAndCombineQueries(filetype, queryUrls, assetsDir, outputPath) {
|
|
6000
|
+
const queriesDir = path3.join(assetsDir, filetype);
|
|
6001
|
+
const highlightsPath = path3.join(queriesDir, "highlights.scm");
|
|
6002
|
+
const queryContents = [];
|
|
6003
|
+
for (let i = 0;i < queryUrls.length; i++) {
|
|
6004
|
+
const queryUrl = queryUrls[i];
|
|
6005
|
+
console.log(` Downloading query ${i + 1}/${queryUrls.length}: ${queryUrl}`);
|
|
6006
|
+
try {
|
|
6007
|
+
const response = await fetch(queryUrl);
|
|
6008
|
+
if (!response.ok) {
|
|
6009
|
+
console.warn(`Failed to download query from ${queryUrl}: ${response.statusText}`);
|
|
6010
|
+
continue;
|
|
6011
|
+
}
|
|
6012
|
+
const content = await response.text();
|
|
6013
|
+
if (content.trim()) {
|
|
6014
|
+
queryContents.push(`; Query from: ${queryUrl}
|
|
6015
|
+
${content}`);
|
|
6016
|
+
console.log(` \u2713 Downloaded ${content.split(`
|
|
6017
|
+
`).length} lines`);
|
|
6018
|
+
}
|
|
6019
|
+
} catch (error) {
|
|
6020
|
+
console.warn(`Failed to download query from ${queryUrl}: ${error}`);
|
|
6021
|
+
continue;
|
|
6022
|
+
}
|
|
6023
|
+
}
|
|
6024
|
+
const combinedContent = queryContents.join(`
|
|
6025
|
+
|
|
6026
|
+
`);
|
|
6027
|
+
await writeFile2(highlightsPath, combinedContent, "utf-8");
|
|
6028
|
+
console.log(` Combined ${queryContents.length} queries into ${highlightsPath}`);
|
|
6029
|
+
return "./" + path3.relative(path3.dirname(outputPath), highlightsPath);
|
|
6030
|
+
}
|
|
6031
|
+
async function generateDefaultParsersFile(parsers, outputPath) {
|
|
6032
|
+
const imports = parsers.map((parser) => {
|
|
6033
|
+
const safeFiletype = parser.filetype.replace(/[^a-zA-Z0-9]/g, "_");
|
|
6034
|
+
return `import ${safeFiletype}_highlights from "${parser.highlightsPath}" with { type: "file" }
|
|
6035
|
+
import ${safeFiletype}_language from "${parser.languagePath}" with { type: "file" }`;
|
|
6036
|
+
}).join(`
|
|
6037
|
+
`);
|
|
6038
|
+
const parserDefinitions = parsers.map((parser) => {
|
|
6039
|
+
const safeFiletype = parser.filetype.replace(/[^a-zA-Z0-9]/g, "_");
|
|
6040
|
+
return ` {
|
|
6041
|
+
filetype: "${parser.filetype}",
|
|
6042
|
+
queries: {
|
|
6043
|
+
highlights: [${safeFiletype}_highlights],
|
|
6044
|
+
},
|
|
6045
|
+
wasm: ${safeFiletype}_language,
|
|
6046
|
+
}`;
|
|
6047
|
+
}).join(`,
|
|
6048
|
+
`);
|
|
6049
|
+
const fileContent = `// This file is generated by assets/update.ts - DO NOT EDIT MANUALLY
|
|
6050
|
+
// Run 'bun assets/update.ts' to regenerate this file
|
|
6051
|
+
// Last generated: ${new Date().toISOString()}
|
|
6052
|
+
|
|
6053
|
+
import type { FiletypeParserOptions } from "./types"
|
|
6054
|
+
|
|
6055
|
+
${imports}
|
|
6056
|
+
|
|
6057
|
+
export const DEFAULT_PARSERS: FiletypeParserOptions[] = [
|
|
6058
|
+
${parserDefinitions},
|
|
6059
|
+
]
|
|
6060
|
+
`;
|
|
6061
|
+
await mkdir2(path3.dirname(outputPath), { recursive: true });
|
|
6062
|
+
await writeFile2(outputPath, fileContent, "utf-8");
|
|
6063
|
+
console.log(`Generated ${path3.basename(outputPath)} with ${parsers.length} parsers`);
|
|
6064
|
+
}
|
|
6065
|
+
async function main(options) {
|
|
6066
|
+
const opts = { ...getDefaultOptions(), ...options };
|
|
6067
|
+
try {
|
|
6068
|
+
console.log("Loading parsers configuration...");
|
|
6069
|
+
console.log(` Config: ${opts.configPath}`);
|
|
6070
|
+
console.log(` Assets Dir: ${opts.assetsDir}`);
|
|
6071
|
+
console.log(` Output: ${opts.outputPath}`);
|
|
6072
|
+
const config = await loadConfig(opts.configPath);
|
|
6073
|
+
console.log(`Found ${config.parsers.length} parsers to process`);
|
|
6074
|
+
const generatedParsers = [];
|
|
6075
|
+
for (const parser of config.parsers) {
|
|
6076
|
+
console.log(`Processing ${parser.filetype}...`);
|
|
6077
|
+
console.log(` Downloading language...`);
|
|
6078
|
+
const languagePath = await downloadLanguage(parser.filetype, parser.wasm, opts.assetsDir, opts.outputPath);
|
|
6079
|
+
console.log(` Downloading ${parser.queries.highlights.length} highlight queries...`);
|
|
6080
|
+
const highlightsPath = await downloadAndCombineQueries(parser.filetype, parser.queries.highlights, opts.assetsDir, opts.outputPath);
|
|
6081
|
+
generatedParsers.push({
|
|
6082
|
+
filetype: parser.filetype,
|
|
6083
|
+
languagePath,
|
|
6084
|
+
highlightsPath
|
|
6085
|
+
});
|
|
6086
|
+
console.log(` \u2713 Completed ${parser.filetype}`);
|
|
6087
|
+
}
|
|
6088
|
+
console.log("Generating output file...");
|
|
6089
|
+
await generateDefaultParsersFile(generatedParsers, opts.outputPath);
|
|
6090
|
+
console.log("\u2705 Update completed successfully!");
|
|
6091
|
+
} catch (error) {
|
|
6092
|
+
console.error("\u274C Update failed:", error);
|
|
6093
|
+
process.exit(1);
|
|
6094
|
+
}
|
|
6095
|
+
}
|
|
6096
|
+
if (false) {}
|
|
6097
|
+
|
|
6098
|
+
// src/lib/tree-sitter/index.ts
|
|
6099
|
+
function getTreeSitterClient() {
|
|
6100
|
+
const dataPathsManager = getDataPaths();
|
|
6101
|
+
const defaultOptions = {
|
|
6102
|
+
dataPath: dataPathsManager.globalDataPath
|
|
6103
|
+
};
|
|
6104
|
+
return singleton("tree-sitter-client", () => {
|
|
6105
|
+
const client2 = new TreeSitterClient(defaultOptions);
|
|
6106
|
+
dataPathsManager.on("paths:changed", (paths) => {
|
|
6107
|
+
client2.setDataPath(paths.globalDataPath);
|
|
6108
|
+
});
|
|
6109
|
+
return client2;
|
|
6110
|
+
});
|
|
6111
|
+
}
|
|
5076
6112
|
// src/zig.ts
|
|
5077
6113
|
import { dlopen, toArrayBuffer as toArrayBuffer2, JSCallback, ptr } from "bun:ffi";
|
|
5078
6114
|
import { existsSync } from "fs";
|
|
@@ -6380,7 +7416,7 @@ class TextBuffer {
|
|
|
6380
7416
|
}
|
|
6381
7417
|
|
|
6382
7418
|
// src/Renderable.ts
|
|
6383
|
-
import { EventEmitter as
|
|
7419
|
+
import { EventEmitter as EventEmitter4 } from "events";
|
|
6384
7420
|
|
|
6385
7421
|
// src/lib/renderable.validations.ts
|
|
6386
7422
|
function validateOptions(id, options) {
|
|
@@ -6473,7 +7509,7 @@ function isRenderable(obj) {
|
|
|
6473
7509
|
return !!obj?.[BrandedRenderable];
|
|
6474
7510
|
}
|
|
6475
7511
|
|
|
6476
|
-
class BaseRenderable extends
|
|
7512
|
+
class BaseRenderable extends EventEmitter4 {
|
|
6477
7513
|
[BrandedRenderable] = true;
|
|
6478
7514
|
static renderableNumber = 1;
|
|
6479
7515
|
_id;
|
|
@@ -7776,17 +8812,17 @@ function delegate(mapping, vnode) {
|
|
|
7776
8812
|
}
|
|
7777
8813
|
|
|
7778
8814
|
// src/console.ts
|
|
7779
|
-
import { EventEmitter as
|
|
8815
|
+
import { EventEmitter as EventEmitter6 } from "events";
|
|
7780
8816
|
import { Console } from "console";
|
|
7781
8817
|
import fs from "fs";
|
|
7782
|
-
import
|
|
8818
|
+
import path4 from "path";
|
|
7783
8819
|
import util2 from "util";
|
|
7784
8820
|
|
|
7785
8821
|
// src/lib/output.capture.ts
|
|
7786
8822
|
import { Writable } from "stream";
|
|
7787
|
-
import { EventEmitter as
|
|
8823
|
+
import { EventEmitter as EventEmitter5 } from "events";
|
|
7788
8824
|
|
|
7789
|
-
class Capture extends
|
|
8825
|
+
class Capture extends EventEmitter5 {
|
|
7790
8826
|
output = [];
|
|
7791
8827
|
constructor() {
|
|
7792
8828
|
super();
|
|
@@ -7862,7 +8898,7 @@ registerEnvVar({
|
|
|
7862
8898
|
default: false
|
|
7863
8899
|
});
|
|
7864
8900
|
|
|
7865
|
-
class TerminalConsoleCache extends
|
|
8901
|
+
class TerminalConsoleCache extends EventEmitter6 {
|
|
7866
8902
|
_cachedLogs = [];
|
|
7867
8903
|
MAX_CACHE_SIZE = 1000;
|
|
7868
8904
|
_collectCallerInfo = false;
|
|
@@ -7983,7 +9019,7 @@ var DEFAULT_CONSOLE_OPTIONS = {
|
|
|
7983
9019
|
};
|
|
7984
9020
|
var INDENT_WIDTH = 2;
|
|
7985
9021
|
|
|
7986
|
-
class TerminalConsole extends
|
|
9022
|
+
class TerminalConsole extends EventEmitter6 {
|
|
7987
9023
|
isVisible = false;
|
|
7988
9024
|
isFocused = false;
|
|
7989
9025
|
renderer;
|
|
@@ -8422,7 +9458,7 @@ class TerminalConsole extends EventEmitter4 {
|
|
|
8422
9458
|
try {
|
|
8423
9459
|
const timestamp = Date.now();
|
|
8424
9460
|
const filename = `_console_${timestamp}.log`;
|
|
8425
|
-
const filepath =
|
|
9461
|
+
const filepath = path4.join(process.cwd(), filename);
|
|
8426
9462
|
const allLogEntries = [...this._allLogEntries, ...terminalConsoleCache.cachedLogs];
|
|
8427
9463
|
const logLines = [];
|
|
8428
9464
|
for (const [date, level, args, callerInfo] of allLogEntries) {
|
|
@@ -8443,7 +9479,7 @@ class TerminalConsole extends EventEmitter4 {
|
|
|
8443
9479
|
}
|
|
8444
9480
|
|
|
8445
9481
|
// src/renderer.ts
|
|
8446
|
-
import { EventEmitter as
|
|
9482
|
+
import { EventEmitter as EventEmitter7 } from "events";
|
|
8447
9483
|
|
|
8448
9484
|
// src/lib/objects-in-viewport.ts
|
|
8449
9485
|
function getObjectsInViewport(viewport, objects, direction = "column", padding = 10, minTriggerSize = 16) {
|
|
@@ -8595,13 +9631,17 @@ var rendererTracker = singleton("RendererTracker", () => {
|
|
|
8595
9631
|
renderers.delete(renderer);
|
|
8596
9632
|
if (renderers.size === 0) {
|
|
8597
9633
|
process.stdin.pause();
|
|
9634
|
+
if (hasSingleton("tree-sitter-client")) {
|
|
9635
|
+
getTreeSitterClient().destroy();
|
|
9636
|
+
destroySingleton("tree-sitter-client");
|
|
9637
|
+
}
|
|
8598
9638
|
}
|
|
8599
9639
|
}
|
|
8600
9640
|
};
|
|
8601
9641
|
});
|
|
8602
9642
|
async function createCliRenderer(config = {}) {
|
|
8603
9643
|
if (process.argv.includes("--delay-start")) {
|
|
8604
|
-
await new Promise((
|
|
9644
|
+
await new Promise((resolve2) => setTimeout(resolve2, 5000));
|
|
8605
9645
|
}
|
|
8606
9646
|
const stdin = config.stdin || process.stdin;
|
|
8607
9647
|
const stdout = config.stdout || process.stdout;
|
|
@@ -8628,7 +9668,7 @@ var CliRenderEvents;
|
|
|
8628
9668
|
((CliRenderEvents2) => {
|
|
8629
9669
|
CliRenderEvents2["DEBUG_OVERLAY_TOGGLE"] = "debugOverlay:toggle";
|
|
8630
9670
|
})(CliRenderEvents ||= {});
|
|
8631
|
-
class CliRenderer extends
|
|
9671
|
+
class CliRenderer extends EventEmitter7 {
|
|
8632
9672
|
static animationFrameId = 0;
|
|
8633
9673
|
lib;
|
|
8634
9674
|
rendererPtr;
|
|
@@ -8720,9 +9760,9 @@ class CliRenderer extends EventEmitter5 {
|
|
|
8720
9760
|
handleError = ((error) => {
|
|
8721
9761
|
this.stop();
|
|
8722
9762
|
this.destroy();
|
|
8723
|
-
new Promise((
|
|
9763
|
+
new Promise((resolve2) => {
|
|
8724
9764
|
setTimeout(() => {
|
|
8725
|
-
|
|
9765
|
+
resolve2(true);
|
|
8726
9766
|
}, 100);
|
|
8727
9767
|
}).then(() => {
|
|
8728
9768
|
this.realStdoutWrite.call(this.stdout, `
|
|
@@ -9041,16 +10081,16 @@ Captured output:
|
|
|
9041
10081
|
if (this._terminalIsSetup)
|
|
9042
10082
|
return;
|
|
9043
10083
|
this._terminalIsSetup = true;
|
|
9044
|
-
await new Promise((
|
|
10084
|
+
await new Promise((resolve2) => {
|
|
9045
10085
|
const timeout = setTimeout(() => {
|
|
9046
10086
|
this.stdin.off("data", capListener);
|
|
9047
|
-
|
|
10087
|
+
resolve2(true);
|
|
9048
10088
|
}, 100);
|
|
9049
10089
|
const capListener = (str) => {
|
|
9050
10090
|
clearTimeout(timeout);
|
|
9051
10091
|
this.lib.processCapabilityResponse(this.rendererPtr, str);
|
|
9052
10092
|
this.stdin.off("data", capListener);
|
|
9053
|
-
|
|
10093
|
+
resolve2(true);
|
|
9054
10094
|
};
|
|
9055
10095
|
this.stdin.on("data", capListener);
|
|
9056
10096
|
this.lib.setupTerminal(this.rendererPtr, this._useAlternateScreen);
|
|
@@ -9450,7 +10490,11 @@ Captured output:
|
|
|
9450
10490
|
this._isRunning = false;
|
|
9451
10491
|
this.waitingForPixelResolution = false;
|
|
9452
10492
|
this.capturedRenderable = undefined;
|
|
9453
|
-
|
|
10493
|
+
try {
|
|
10494
|
+
this.root.destroyRecursively();
|
|
10495
|
+
} catch (e) {
|
|
10496
|
+
console.error("Error destroying root renderable:", e instanceof Error ? e.stack : String(e));
|
|
10497
|
+
}
|
|
9454
10498
|
this._keyHandler.destroy();
|
|
9455
10499
|
this._console.deactivate();
|
|
9456
10500
|
this.disableStdoutInterception();
|
|
@@ -9688,7 +10732,7 @@ Captured output:
|
|
|
9688
10732
|
}
|
|
9689
10733
|
}
|
|
9690
10734
|
|
|
9691
|
-
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, 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 };
|
|
10735
|
+
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, 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, CliRenderer };
|
|
9692
10736
|
|
|
9693
|
-
//# debugId=
|
|
9694
|
-
//# sourceMappingURL=index-
|
|
10737
|
+
//# debugId=259CDC2839F0878D64756E2164756E21
|
|
10738
|
+
//# sourceMappingURL=index-h87jjatk.js.map
|