@opentui/core 0.0.0-20251030-1c570263 → 0.0.0-20251102-23e7b561
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/assets/markdown/highlights.scm +150 -0
- package/assets/markdown/injections.scm +27 -0
- package/assets/markdown/tree-sitter-markdown.wasm +0 -0
- package/assets/markdown_inline/highlights.scm +115 -0
- package/assets/markdown_inline/tree-sitter-markdown_inline.wasm +0 -0
- package/{index-xn9k0wzm.js → index-rzgaxyf4.js} +611 -148
- package/{index-xn9k0wzm.js.map → index-rzgaxyf4.js.map} +16 -15
- package/index.js +82 -17
- package/index.js.map +5 -5
- package/lib/KeyHandler.d.ts +4 -1
- package/lib/index.d.ts +1 -0
- package/lib/parse.keypress.d.ts +1 -0
- package/lib/stdin-buffer.d.ts +42 -0
- package/lib/tree-sitter/client.d.ts +1 -0
- package/lib/tree-sitter/parsers-config.d.ts +38 -0
- package/lib/tree-sitter/types.d.ts +18 -1
- package/lib/tree-sitter-styled-text.d.ts +9 -2
- package/package.json +9 -9
- package/parser.worker.js +250 -27
- package/parser.worker.js.map +3 -3
- package/renderables/Box.d.ts +1 -0
- package/renderables/Code.d.ts +14 -0
- package/syntax-style.d.ts +2 -0
- package/testing.js +1 -1
- package/text-buffer.d.ts +1 -0
- package/zig.d.ts +1 -0
|
@@ -1896,6 +1896,7 @@ function parseKittyKeyboard(sequence) {
|
|
|
1896
1896
|
sequence,
|
|
1897
1897
|
raw: sequence,
|
|
1898
1898
|
eventType: "press",
|
|
1899
|
+
source: "kitty",
|
|
1899
1900
|
super: false,
|
|
1900
1901
|
hyper: false,
|
|
1901
1902
|
capsLock: false,
|
|
@@ -2107,10 +2108,11 @@ var parseKeypress = (s = "", options = {}) => {
|
|
|
2107
2108
|
number: false,
|
|
2108
2109
|
sequence: s,
|
|
2109
2110
|
raw: s,
|
|
2110
|
-
eventType: "press"
|
|
2111
|
+
eventType: "press",
|
|
2112
|
+
source: "raw"
|
|
2111
2113
|
};
|
|
2112
2114
|
key.sequence = key.sequence || s || key.name;
|
|
2113
|
-
if (options.useKittyKeyboard
|
|
2115
|
+
if (options.useKittyKeyboard) {
|
|
2114
2116
|
const kittyResult = parseKittyKeyboard(s);
|
|
2115
2117
|
if (kittyResult) {
|
|
2116
2118
|
return kittyResult;
|
|
@@ -2135,6 +2137,9 @@ var parseKeypress = (s = "", options = {}) => {
|
|
|
2135
2137
|
} else if (s === " " || s === "\x1B ") {
|
|
2136
2138
|
key.name = "space";
|
|
2137
2139
|
key.meta = s.length === 2;
|
|
2140
|
+
} else if (s === "\x00") {
|
|
2141
|
+
key.name = "space";
|
|
2142
|
+
key.ctrl = true;
|
|
2138
2143
|
} else if (s.length === 1 && s <= "\x1A") {
|
|
2139
2144
|
key.name = String.fromCharCode(s.charCodeAt(0) + 97 - 1);
|
|
2140
2145
|
key.ctrl = true;
|
|
@@ -2185,8 +2190,184 @@ var parseKeypress = (s = "", options = {}) => {
|
|
|
2185
2190
|
return key;
|
|
2186
2191
|
};
|
|
2187
2192
|
|
|
2188
|
-
// src/lib/
|
|
2193
|
+
// src/lib/stdin-buffer.ts
|
|
2189
2194
|
import { EventEmitter } from "events";
|
|
2195
|
+
var ESC = "\x1B";
|
|
2196
|
+
function isCompleteSequence(data) {
|
|
2197
|
+
if (!data.startsWith(ESC)) {
|
|
2198
|
+
return "not-escape";
|
|
2199
|
+
}
|
|
2200
|
+
if (data.length === 1) {
|
|
2201
|
+
return "incomplete";
|
|
2202
|
+
}
|
|
2203
|
+
const afterEsc = data.slice(1);
|
|
2204
|
+
if (afterEsc.startsWith("[")) {
|
|
2205
|
+
if (afterEsc.startsWith("[M")) {
|
|
2206
|
+
return data.length >= 6 ? "complete" : "incomplete";
|
|
2207
|
+
}
|
|
2208
|
+
return isCompleteCsiSequence(data);
|
|
2209
|
+
}
|
|
2210
|
+
if (afterEsc.startsWith("]")) {
|
|
2211
|
+
return isCompleteOscSequence(data);
|
|
2212
|
+
}
|
|
2213
|
+
if (afterEsc.startsWith("O")) {
|
|
2214
|
+
return afterEsc.length >= 2 ? "complete" : "incomplete";
|
|
2215
|
+
}
|
|
2216
|
+
if (afterEsc.length === 1) {
|
|
2217
|
+
return "complete";
|
|
2218
|
+
}
|
|
2219
|
+
return "complete";
|
|
2220
|
+
}
|
|
2221
|
+
function isCompleteCsiSequence(data) {
|
|
2222
|
+
if (!data.startsWith(ESC + "[")) {
|
|
2223
|
+
return "complete";
|
|
2224
|
+
}
|
|
2225
|
+
if (data.length < 3) {
|
|
2226
|
+
return "incomplete";
|
|
2227
|
+
}
|
|
2228
|
+
const payload = data.slice(2);
|
|
2229
|
+
const lastChar = payload[payload.length - 1];
|
|
2230
|
+
const lastCharCode = lastChar.charCodeAt(0);
|
|
2231
|
+
if (lastCharCode >= 64 && lastCharCode <= 126) {
|
|
2232
|
+
if (payload.startsWith("<")) {
|
|
2233
|
+
const mouseMatch = /^<\d+;\d+;\d+[Mm]$/.test(payload);
|
|
2234
|
+
if (mouseMatch) {
|
|
2235
|
+
return "complete";
|
|
2236
|
+
}
|
|
2237
|
+
if (lastChar === "M" || lastChar === "m") {
|
|
2238
|
+
const parts = payload.slice(1, -1).split(";");
|
|
2239
|
+
if (parts.length === 3 && parts.every((p) => /^\d+$/.test(p))) {
|
|
2240
|
+
return "complete";
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
return "incomplete";
|
|
2244
|
+
}
|
|
2245
|
+
return "complete";
|
|
2246
|
+
}
|
|
2247
|
+
return "incomplete";
|
|
2248
|
+
}
|
|
2249
|
+
function isCompleteOscSequence(data) {
|
|
2250
|
+
if (!data.startsWith(ESC + "]")) {
|
|
2251
|
+
return "complete";
|
|
2252
|
+
}
|
|
2253
|
+
if (data.endsWith(ESC + "\\") || data.endsWith("\x07")) {
|
|
2254
|
+
return "complete";
|
|
2255
|
+
}
|
|
2256
|
+
return "incomplete";
|
|
2257
|
+
}
|
|
2258
|
+
function extractCompleteSequences(buffer) {
|
|
2259
|
+
const sequences = [];
|
|
2260
|
+
let pos = 0;
|
|
2261
|
+
while (pos < buffer.length) {
|
|
2262
|
+
const remaining = buffer.slice(pos);
|
|
2263
|
+
if (remaining.startsWith(ESC)) {
|
|
2264
|
+
let seqEnd = 1;
|
|
2265
|
+
while (seqEnd <= remaining.length) {
|
|
2266
|
+
const candidate = remaining.slice(0, seqEnd);
|
|
2267
|
+
const status = isCompleteSequence(candidate);
|
|
2268
|
+
if (status === "complete") {
|
|
2269
|
+
sequences.push(candidate);
|
|
2270
|
+
pos += seqEnd;
|
|
2271
|
+
break;
|
|
2272
|
+
} else if (status === "incomplete") {
|
|
2273
|
+
seqEnd++;
|
|
2274
|
+
} else {
|
|
2275
|
+
sequences.push(candidate);
|
|
2276
|
+
pos += seqEnd;
|
|
2277
|
+
break;
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
if (seqEnd > remaining.length) {
|
|
2281
|
+
return { sequences, remainder: remaining };
|
|
2282
|
+
}
|
|
2283
|
+
} else {
|
|
2284
|
+
sequences.push(remaining[0]);
|
|
2285
|
+
pos++;
|
|
2286
|
+
}
|
|
2287
|
+
}
|
|
2288
|
+
return { sequences, remainder: "" };
|
|
2289
|
+
}
|
|
2290
|
+
|
|
2291
|
+
class StdinBuffer extends EventEmitter {
|
|
2292
|
+
buffer = "";
|
|
2293
|
+
timeout = null;
|
|
2294
|
+
timeoutMs;
|
|
2295
|
+
stdin;
|
|
2296
|
+
stdinListener;
|
|
2297
|
+
constructor(stdin, options = {}) {
|
|
2298
|
+
super();
|
|
2299
|
+
this.stdin = stdin;
|
|
2300
|
+
this.timeoutMs = options.timeout ?? 10;
|
|
2301
|
+
this.stdinListener = (data) => {
|
|
2302
|
+
this.handleData(data);
|
|
2303
|
+
};
|
|
2304
|
+
this.stdin.on("data", this.stdinListener);
|
|
2305
|
+
}
|
|
2306
|
+
handleData(data) {
|
|
2307
|
+
if (this.timeout) {
|
|
2308
|
+
clearTimeout(this.timeout);
|
|
2309
|
+
this.timeout = null;
|
|
2310
|
+
}
|
|
2311
|
+
let str;
|
|
2312
|
+
if (Buffer.isBuffer(data)) {
|
|
2313
|
+
if (data.length === 1 && data[0] > 127) {
|
|
2314
|
+
const byte = data[0] - 128;
|
|
2315
|
+
str = "\x1B" + String.fromCharCode(byte);
|
|
2316
|
+
} else {
|
|
2317
|
+
str = data.toString();
|
|
2318
|
+
}
|
|
2319
|
+
} else {
|
|
2320
|
+
str = data;
|
|
2321
|
+
}
|
|
2322
|
+
if (str.length === 0 && this.buffer.length === 0) {
|
|
2323
|
+
this.emit("data", "");
|
|
2324
|
+
return;
|
|
2325
|
+
}
|
|
2326
|
+
this.buffer += str;
|
|
2327
|
+
const result = extractCompleteSequences(this.buffer);
|
|
2328
|
+
this.buffer = result.remainder;
|
|
2329
|
+
for (const sequence of result.sequences) {
|
|
2330
|
+
this.emit("data", sequence);
|
|
2331
|
+
}
|
|
2332
|
+
if (this.buffer.length > 0) {
|
|
2333
|
+
this.timeout = setTimeout(() => {
|
|
2334
|
+
const flushed = this.flush();
|
|
2335
|
+
for (const sequence of flushed) {
|
|
2336
|
+
this.emit("data", sequence);
|
|
2337
|
+
}
|
|
2338
|
+
}, this.timeoutMs);
|
|
2339
|
+
}
|
|
2340
|
+
}
|
|
2341
|
+
flush() {
|
|
2342
|
+
if (this.timeout) {
|
|
2343
|
+
clearTimeout(this.timeout);
|
|
2344
|
+
this.timeout = null;
|
|
2345
|
+
}
|
|
2346
|
+
if (this.buffer.length === 0) {
|
|
2347
|
+
return [];
|
|
2348
|
+
}
|
|
2349
|
+
const sequences = [this.buffer];
|
|
2350
|
+
this.buffer = "";
|
|
2351
|
+
return sequences;
|
|
2352
|
+
}
|
|
2353
|
+
clear() {
|
|
2354
|
+
if (this.timeout) {
|
|
2355
|
+
clearTimeout(this.timeout);
|
|
2356
|
+
this.timeout = null;
|
|
2357
|
+
}
|
|
2358
|
+
this.buffer = "";
|
|
2359
|
+
}
|
|
2360
|
+
getBuffer() {
|
|
2361
|
+
return this.buffer;
|
|
2362
|
+
}
|
|
2363
|
+
destroy() {
|
|
2364
|
+
this.stdin.removeListener("data", this.stdinListener);
|
|
2365
|
+
this.clear();
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2368
|
+
|
|
2369
|
+
// src/lib/KeyHandler.ts
|
|
2370
|
+
import { EventEmitter as EventEmitter2 } from "events";
|
|
2190
2371
|
|
|
2191
2372
|
// src/ansi.ts
|
|
2192
2373
|
var ANSI = {
|
|
@@ -2214,6 +2395,7 @@ class KeyEvent {
|
|
|
2214
2395
|
number;
|
|
2215
2396
|
raw;
|
|
2216
2397
|
eventType;
|
|
2398
|
+
source;
|
|
2217
2399
|
code;
|
|
2218
2400
|
super;
|
|
2219
2401
|
hyper;
|
|
@@ -2231,6 +2413,7 @@ class KeyEvent {
|
|
|
2231
2413
|
this.number = key.number;
|
|
2232
2414
|
this.raw = key.raw;
|
|
2233
2415
|
this.eventType = key.eventType;
|
|
2416
|
+
this.source = key.source;
|
|
2234
2417
|
this.code = key.code;
|
|
2235
2418
|
this.super = key.super;
|
|
2236
2419
|
this.hyper = key.hyper;
|
|
@@ -2260,65 +2443,70 @@ class PasteEvent {
|
|
|
2260
2443
|
}
|
|
2261
2444
|
}
|
|
2262
2445
|
|
|
2263
|
-
class KeyHandler extends
|
|
2446
|
+
class KeyHandler extends EventEmitter2 {
|
|
2264
2447
|
stdin;
|
|
2265
2448
|
useKittyKeyboard;
|
|
2266
|
-
listener;
|
|
2267
2449
|
pasteMode = false;
|
|
2268
2450
|
pasteBuffer = [];
|
|
2269
2451
|
suspended = false;
|
|
2452
|
+
stdinBuffer;
|
|
2453
|
+
dataListener;
|
|
2270
2454
|
constructor(stdin, useKittyKeyboard = false) {
|
|
2271
2455
|
super();
|
|
2272
2456
|
this.stdin = stdin || process.stdin;
|
|
2273
2457
|
this.useKittyKeyboard = useKittyKeyboard;
|
|
2274
|
-
this.
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
this.pasteMode = true;
|
|
2278
|
-
}
|
|
2279
|
-
if (this.pasteMode) {
|
|
2280
|
-
this.pasteBuffer.push(Bun.stripANSI(data));
|
|
2281
|
-
if (data.endsWith(ANSI.bracketedPasteEnd)) {
|
|
2282
|
-
this.pasteMode = false;
|
|
2283
|
-
this.emit("paste", new PasteEvent(this.pasteBuffer.join("")));
|
|
2284
|
-
this.pasteBuffer = [];
|
|
2285
|
-
}
|
|
2286
|
-
return;
|
|
2287
|
-
}
|
|
2288
|
-
const parsedKey = parseKeypress(key, { useKittyKeyboard: this.useKittyKeyboard });
|
|
2289
|
-
if (!parsedKey) {
|
|
2290
|
-
return;
|
|
2291
|
-
}
|
|
2292
|
-
switch (parsedKey.eventType) {
|
|
2293
|
-
case "press":
|
|
2294
|
-
this.emit("keypress", new KeyEvent(parsedKey));
|
|
2295
|
-
break;
|
|
2296
|
-
case "repeat":
|
|
2297
|
-
this.emit("keyrepeat", new KeyEvent(parsedKey));
|
|
2298
|
-
break;
|
|
2299
|
-
case "release":
|
|
2300
|
-
this.emit("keyrelease", new KeyEvent(parsedKey));
|
|
2301
|
-
break;
|
|
2302
|
-
default:
|
|
2303
|
-
this.emit("keypress", new KeyEvent(parsedKey));
|
|
2304
|
-
break;
|
|
2305
|
-
}
|
|
2458
|
+
this.stdinBuffer = new StdinBuffer(this.stdin, { timeout: 5 });
|
|
2459
|
+
this.dataListener = (sequence) => {
|
|
2460
|
+
this.processSequence(sequence);
|
|
2306
2461
|
};
|
|
2307
|
-
this.
|
|
2462
|
+
this.stdinBuffer.on("data", this.dataListener);
|
|
2463
|
+
}
|
|
2464
|
+
processSequence(data) {
|
|
2465
|
+
if (data.startsWith(ANSI.bracketedPasteStart)) {
|
|
2466
|
+
this.pasteMode = true;
|
|
2467
|
+
}
|
|
2468
|
+
if (this.pasteMode) {
|
|
2469
|
+
this.pasteBuffer.push(Bun.stripANSI(data));
|
|
2470
|
+
if (data.endsWith(ANSI.bracketedPasteEnd)) {
|
|
2471
|
+
this.pasteMode = false;
|
|
2472
|
+
this.emit("paste", new PasteEvent(this.pasteBuffer.join("")));
|
|
2473
|
+
this.pasteBuffer = [];
|
|
2474
|
+
}
|
|
2475
|
+
return;
|
|
2476
|
+
}
|
|
2477
|
+
const parsedKey = parseKeypress(data, { useKittyKeyboard: this.useKittyKeyboard });
|
|
2478
|
+
if (!parsedKey) {
|
|
2479
|
+
return;
|
|
2480
|
+
}
|
|
2481
|
+
switch (parsedKey.eventType) {
|
|
2482
|
+
case "press":
|
|
2483
|
+
this.emit("keypress", new KeyEvent(parsedKey));
|
|
2484
|
+
break;
|
|
2485
|
+
case "repeat":
|
|
2486
|
+
this.emit("keyrepeat", new KeyEvent(parsedKey));
|
|
2487
|
+
break;
|
|
2488
|
+
case "release":
|
|
2489
|
+
this.emit("keyrelease", new KeyEvent(parsedKey));
|
|
2490
|
+
break;
|
|
2491
|
+
default:
|
|
2492
|
+
this.emit("keypress", new KeyEvent(parsedKey));
|
|
2493
|
+
break;
|
|
2494
|
+
}
|
|
2308
2495
|
}
|
|
2309
2496
|
destroy() {
|
|
2310
|
-
this.
|
|
2497
|
+
this.stdinBuffer.removeListener("data", this.dataListener);
|
|
2498
|
+
this.stdinBuffer.destroy();
|
|
2311
2499
|
}
|
|
2312
2500
|
suspend() {
|
|
2313
2501
|
if (!this.suspended) {
|
|
2314
2502
|
this.suspended = true;
|
|
2315
|
-
this.
|
|
2503
|
+
this.stdinBuffer.removeListener("data", this.dataListener);
|
|
2316
2504
|
}
|
|
2317
2505
|
}
|
|
2318
2506
|
resume() {
|
|
2319
2507
|
if (this.suspended) {
|
|
2320
2508
|
this.suspended = false;
|
|
2321
|
-
this.
|
|
2509
|
+
this.stdinBuffer.on("data", this.dataListener);
|
|
2322
2510
|
}
|
|
2323
2511
|
}
|
|
2324
2512
|
}
|
|
@@ -5112,19 +5300,141 @@ var env = new Proxy({}, {
|
|
|
5112
5300
|
});
|
|
5113
5301
|
|
|
5114
5302
|
// src/lib/tree-sitter-styled-text.ts
|
|
5115
|
-
|
|
5303
|
+
registerEnvVar({ name: "OTUI_TS_STYLE_WARN", default: false, description: "Enable warnings for missing syntax styles" });
|
|
5304
|
+
function getSpecificity(group) {
|
|
5305
|
+
return group.split(".").length;
|
|
5306
|
+
}
|
|
5307
|
+
function shouldSuppressInInjection(group, meta) {
|
|
5308
|
+
if (meta?.isInjection) {
|
|
5309
|
+
return false;
|
|
5310
|
+
}
|
|
5311
|
+
return group === "markup.raw.block";
|
|
5312
|
+
}
|
|
5313
|
+
function treeSitterToTextChunks(content, highlights, syntaxStyle, options) {
|
|
5116
5314
|
const chunks = [];
|
|
5117
5315
|
const defaultStyle = syntaxStyle.getStyle("default");
|
|
5118
|
-
|
|
5316
|
+
const concealEnabled = options?.enabled ?? true;
|
|
5317
|
+
const injectionContainerRanges = [];
|
|
5318
|
+
const boundaries = [];
|
|
5119
5319
|
for (let i = 0;i < highlights.length; i++) {
|
|
5120
|
-
const [
|
|
5121
|
-
if (
|
|
5320
|
+
const [start, end, , meta] = highlights[i];
|
|
5321
|
+
if (start === end)
|
|
5122
5322
|
continue;
|
|
5123
|
-
if (
|
|
5124
|
-
|
|
5323
|
+
if (meta?.containsInjection) {
|
|
5324
|
+
injectionContainerRanges.push({ start, end });
|
|
5325
|
+
}
|
|
5326
|
+
boundaries.push({ offset: start, type: "start", highlightIndex: i });
|
|
5327
|
+
boundaries.push({ offset: end, type: "end", highlightIndex: i });
|
|
5328
|
+
}
|
|
5329
|
+
boundaries.sort((a, b) => {
|
|
5330
|
+
if (a.offset !== b.offset)
|
|
5331
|
+
return a.offset - b.offset;
|
|
5332
|
+
if (a.type === "end" && b.type === "start")
|
|
5333
|
+
return -1;
|
|
5334
|
+
if (a.type === "start" && b.type === "end")
|
|
5335
|
+
return 1;
|
|
5336
|
+
return 0;
|
|
5337
|
+
});
|
|
5338
|
+
const activeHighlights = new Set;
|
|
5339
|
+
let currentOffset = 0;
|
|
5340
|
+
for (let i = 0;i < boundaries.length; i++) {
|
|
5341
|
+
const boundary = boundaries[i];
|
|
5342
|
+
if (currentOffset < boundary.offset && activeHighlights.size > 0) {
|
|
5343
|
+
const segmentText = content.slice(currentOffset, boundary.offset);
|
|
5344
|
+
const activeGroups = [];
|
|
5345
|
+
for (const idx of activeHighlights) {
|
|
5346
|
+
const [, , group, meta] = highlights[idx];
|
|
5347
|
+
activeGroups.push({ group, meta, index: idx });
|
|
5348
|
+
}
|
|
5349
|
+
const concealHighlight = concealEnabled ? activeGroups.find((h) => h.meta?.conceal !== undefined || h.group === "conceal" || h.group.startsWith("conceal.")) : undefined;
|
|
5350
|
+
if (concealHighlight) {
|
|
5351
|
+
let replacementText = "";
|
|
5352
|
+
if (concealHighlight.meta?.conceal !== undefined) {
|
|
5353
|
+
replacementText = concealHighlight.meta.conceal;
|
|
5354
|
+
} else if (concealHighlight.group === "conceal.with.space") {
|
|
5355
|
+
replacementText = " ";
|
|
5356
|
+
}
|
|
5357
|
+
if (replacementText) {
|
|
5358
|
+
chunks.push({
|
|
5359
|
+
__isChunk: true,
|
|
5360
|
+
text: replacementText,
|
|
5361
|
+
fg: defaultStyle?.fg,
|
|
5362
|
+
bg: defaultStyle?.bg,
|
|
5363
|
+
attributes: defaultStyle ? createTextAttributes({
|
|
5364
|
+
bold: defaultStyle.bold,
|
|
5365
|
+
italic: defaultStyle.italic,
|
|
5366
|
+
underline: defaultStyle.underline,
|
|
5367
|
+
dim: defaultStyle.dim
|
|
5368
|
+
}) : 0
|
|
5369
|
+
});
|
|
5370
|
+
}
|
|
5371
|
+
} else {
|
|
5372
|
+
const insideInjectionContainer = injectionContainerRanges.some((range) => currentOffset >= range.start && currentOffset < range.end);
|
|
5373
|
+
const validGroups = activeGroups.filter((h) => {
|
|
5374
|
+
if (insideInjectionContainer && shouldSuppressInInjection(h.group, h.meta)) {
|
|
5375
|
+
return false;
|
|
5376
|
+
}
|
|
5377
|
+
return true;
|
|
5378
|
+
});
|
|
5379
|
+
const sortedGroups = validGroups.sort((a, b) => {
|
|
5380
|
+
const aSpec = getSpecificity(a.group);
|
|
5381
|
+
const bSpec = getSpecificity(b.group);
|
|
5382
|
+
if (aSpec !== bSpec)
|
|
5383
|
+
return aSpec - bSpec;
|
|
5384
|
+
return a.index - b.index;
|
|
5385
|
+
});
|
|
5386
|
+
const mergedStyle = {};
|
|
5387
|
+
for (const { group } of sortedGroups) {
|
|
5388
|
+
let styleForGroup = syntaxStyle.getStyle(group);
|
|
5389
|
+
if (!styleForGroup && group.includes(".")) {
|
|
5390
|
+
const baseName = group.split(".")[0];
|
|
5391
|
+
styleForGroup = syntaxStyle.getStyle(baseName);
|
|
5392
|
+
}
|
|
5393
|
+
if (styleForGroup) {
|
|
5394
|
+
if (styleForGroup.fg !== undefined)
|
|
5395
|
+
mergedStyle.fg = styleForGroup.fg;
|
|
5396
|
+
if (styleForGroup.bg !== undefined)
|
|
5397
|
+
mergedStyle.bg = styleForGroup.bg;
|
|
5398
|
+
if (styleForGroup.bold !== undefined)
|
|
5399
|
+
mergedStyle.bold = styleForGroup.bold;
|
|
5400
|
+
if (styleForGroup.italic !== undefined)
|
|
5401
|
+
mergedStyle.italic = styleForGroup.italic;
|
|
5402
|
+
if (styleForGroup.underline !== undefined)
|
|
5403
|
+
mergedStyle.underline = styleForGroup.underline;
|
|
5404
|
+
if (styleForGroup.dim !== undefined)
|
|
5405
|
+
mergedStyle.dim = styleForGroup.dim;
|
|
5406
|
+
} else {
|
|
5407
|
+
if (group.includes(".")) {
|
|
5408
|
+
const baseName = group.split(".")[0];
|
|
5409
|
+
if (env.OTUI_TS_STYLE_WARN) {
|
|
5410
|
+
console.warn(`Syntax style not found for group "${group}" or base scope "${baseName}", using default style`);
|
|
5411
|
+
}
|
|
5412
|
+
} else {
|
|
5413
|
+
if (env.OTUI_TS_STYLE_WARN) {
|
|
5414
|
+
console.warn(`Syntax style not found for group "${group}", using default style`);
|
|
5415
|
+
}
|
|
5416
|
+
}
|
|
5417
|
+
}
|
|
5418
|
+
}
|
|
5419
|
+
const finalStyle = Object.keys(mergedStyle).length > 0 ? mergedStyle : defaultStyle;
|
|
5420
|
+
chunks.push({
|
|
5421
|
+
__isChunk: true,
|
|
5422
|
+
text: segmentText,
|
|
5423
|
+
fg: finalStyle?.fg,
|
|
5424
|
+
bg: finalStyle?.bg,
|
|
5425
|
+
attributes: finalStyle ? createTextAttributes({
|
|
5426
|
+
bold: finalStyle.bold,
|
|
5427
|
+
italic: finalStyle.italic,
|
|
5428
|
+
underline: finalStyle.underline,
|
|
5429
|
+
dim: finalStyle.dim
|
|
5430
|
+
}) : 0
|
|
5431
|
+
});
|
|
5432
|
+
}
|
|
5433
|
+
} else if (currentOffset < boundary.offset) {
|
|
5434
|
+
const text = content.slice(currentOffset, boundary.offset);
|
|
5125
5435
|
chunks.push({
|
|
5126
5436
|
__isChunk: true,
|
|
5127
|
-
text
|
|
5437
|
+
text,
|
|
5128
5438
|
fg: defaultStyle?.fg,
|
|
5129
5439
|
bg: defaultStyle?.bg,
|
|
5130
5440
|
attributes: defaultStyle ? createTextAttributes({
|
|
@@ -5134,37 +5444,39 @@ function treeSitterToTextChunks(content, highlights, syntaxStyle) {
|
|
|
5134
5444
|
dim: defaultStyle.dim
|
|
5135
5445
|
}) : 0
|
|
5136
5446
|
});
|
|
5137
|
-
currentIndex = startIndex;
|
|
5138
5447
|
}
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5448
|
+
if (boundary.type === "start") {
|
|
5449
|
+
activeHighlights.add(boundary.highlightIndex);
|
|
5450
|
+
} else {
|
|
5451
|
+
activeHighlights.delete(boundary.highlightIndex);
|
|
5452
|
+
if (concealEnabled) {
|
|
5453
|
+
const [, , group, meta] = highlights[boundary.highlightIndex];
|
|
5454
|
+
if (meta?.concealLines !== undefined) {
|
|
5455
|
+
if (boundary.offset < content.length && content[boundary.offset] === `
|
|
5456
|
+
`) {
|
|
5457
|
+
currentOffset = boundary.offset + 1;
|
|
5458
|
+
continue;
|
|
5459
|
+
}
|
|
5460
|
+
}
|
|
5461
|
+
if (meta?.conceal !== undefined) {
|
|
5462
|
+
if (meta.conceal === " ") {
|
|
5463
|
+
if (boundary.offset < content.length && content[boundary.offset] === " ") {
|
|
5464
|
+
currentOffset = boundary.offset + 1;
|
|
5465
|
+
continue;
|
|
5466
|
+
}
|
|
5467
|
+
} else if (meta.conceal === "" && group === "conceal" && !meta.isInjection) {
|
|
5468
|
+
if (boundary.offset < content.length && content[boundary.offset] === " ") {
|
|
5469
|
+
currentOffset = boundary.offset + 1;
|
|
5470
|
+
continue;
|
|
5471
|
+
}
|
|
5472
|
+
}
|
|
5473
|
+
}
|
|
5146
5474
|
}
|
|
5147
|
-
j++;
|
|
5148
5475
|
}
|
|
5149
|
-
|
|
5150
|
-
const text = content.slice(startIndex, endIndex);
|
|
5151
|
-
const styleToUse = resolvedStyle || defaultStyle;
|
|
5152
|
-
chunks.push({
|
|
5153
|
-
__isChunk: true,
|
|
5154
|
-
text,
|
|
5155
|
-
fg: styleToUse?.fg,
|
|
5156
|
-
bg: styleToUse?.bg,
|
|
5157
|
-
attributes: styleToUse ? createTextAttributes({
|
|
5158
|
-
bold: styleToUse.bold,
|
|
5159
|
-
italic: styleToUse.italic,
|
|
5160
|
-
underline: styleToUse.underline,
|
|
5161
|
-
dim: styleToUse.dim
|
|
5162
|
-
}) : 0
|
|
5163
|
-
});
|
|
5164
|
-
currentIndex = endIndex;
|
|
5476
|
+
currentOffset = boundary.offset;
|
|
5165
5477
|
}
|
|
5166
|
-
if (
|
|
5167
|
-
const text = content.slice(
|
|
5478
|
+
if (currentOffset < content.length) {
|
|
5479
|
+
const text = content.slice(currentOffset);
|
|
5168
5480
|
chunks.push({
|
|
5169
5481
|
__isChunk: true,
|
|
5170
5482
|
text,
|
|
@@ -5180,10 +5492,10 @@ function treeSitterToTextChunks(content, highlights, syntaxStyle) {
|
|
|
5180
5492
|
}
|
|
5181
5493
|
return chunks;
|
|
5182
5494
|
}
|
|
5183
|
-
async function treeSitterToStyledText(content, filetype, syntaxStyle, client) {
|
|
5495
|
+
async function treeSitterToStyledText(content, filetype, syntaxStyle, client, options) {
|
|
5184
5496
|
const result = await client.highlightOnce(content, filetype);
|
|
5185
5497
|
if (result.highlights && result.highlights.length > 0) {
|
|
5186
|
-
const chunks = treeSitterToTextChunks(content, result.highlights, syntaxStyle);
|
|
5498
|
+
const chunks = treeSitterToTextChunks(content, result.highlights, syntaxStyle, options?.conceal);
|
|
5187
5499
|
return new StyledText(chunks);
|
|
5188
5500
|
} else {
|
|
5189
5501
|
const defaultStyle = syntaxStyle.mergeStyles("default");
|
|
@@ -5201,7 +5513,7 @@ async function treeSitterToStyledText(content, filetype, syntaxStyle, client) {
|
|
|
5201
5513
|
}
|
|
5202
5514
|
|
|
5203
5515
|
// src/lib/tree-sitter/client.ts
|
|
5204
|
-
import { EventEmitter as
|
|
5516
|
+
import { EventEmitter as EventEmitter3 } from "events";
|
|
5205
5517
|
|
|
5206
5518
|
// src/lib/debounce.ts
|
|
5207
5519
|
var TIMERS_MAP = new Map;
|
|
@@ -5314,6 +5626,11 @@ import javascript_highlights from "./assets/javascript/highlights.scm" with { ty
|
|
|
5314
5626
|
import javascript_language from "./assets/javascript/tree-sitter-javascript.wasm" with { type: "file" };
|
|
5315
5627
|
import typescript_highlights from "./assets/typescript/highlights.scm" with { type: "file" };
|
|
5316
5628
|
import typescript_language from "./assets/typescript/tree-sitter-typescript.wasm" with { type: "file" };
|
|
5629
|
+
import markdown_highlights from "./assets/markdown/highlights.scm" with { type: "file" };
|
|
5630
|
+
import markdown_language from "./assets/markdown/tree-sitter-markdown.wasm" with { type: "file" };
|
|
5631
|
+
import markdown_injections from "./assets/markdown/injections.scm" with { type: "file" };
|
|
5632
|
+
import markdown_inline_highlights from "./assets/markdown_inline/highlights.scm" with { type: "file" };
|
|
5633
|
+
import markdown_inline_language from "./assets/markdown_inline/tree-sitter-markdown_inline.wasm" with { type: "file" };
|
|
5317
5634
|
var _cachedParsers;
|
|
5318
5635
|
function getParsers() {
|
|
5319
5636
|
if (!_cachedParsers) {
|
|
@@ -5331,6 +5648,35 @@ function getParsers() {
|
|
|
5331
5648
|
highlights: [resolve(dirname(fileURLToPath(import.meta.url)), typescript_highlights)]
|
|
5332
5649
|
},
|
|
5333
5650
|
wasm: resolve(dirname(fileURLToPath(import.meta.url)), typescript_language)
|
|
5651
|
+
},
|
|
5652
|
+
{
|
|
5653
|
+
filetype: "markdown",
|
|
5654
|
+
queries: {
|
|
5655
|
+
highlights: [resolve(dirname(fileURLToPath(import.meta.url)), markdown_highlights)],
|
|
5656
|
+
injections: [resolve(dirname(fileURLToPath(import.meta.url)), markdown_injections)]
|
|
5657
|
+
},
|
|
5658
|
+
wasm: resolve(dirname(fileURLToPath(import.meta.url)), markdown_language),
|
|
5659
|
+
injectionMapping: {
|
|
5660
|
+
nodeTypes: {
|
|
5661
|
+
inline: "markdown_inline",
|
|
5662
|
+
pipe_table_cell: "markdown_inline"
|
|
5663
|
+
},
|
|
5664
|
+
infoStringMap: {
|
|
5665
|
+
javascript: "javascript",
|
|
5666
|
+
js: "javascript",
|
|
5667
|
+
typescript: "typescript",
|
|
5668
|
+
ts: "typescript",
|
|
5669
|
+
markdown: "markdown",
|
|
5670
|
+
md: "markdown"
|
|
5671
|
+
}
|
|
5672
|
+
}
|
|
5673
|
+
},
|
|
5674
|
+
{
|
|
5675
|
+
filetype: "markdown_inline",
|
|
5676
|
+
queries: {
|
|
5677
|
+
highlights: [resolve(dirname(fileURLToPath(import.meta.url)), markdown_inline_highlights)]
|
|
5678
|
+
},
|
|
5679
|
+
wasm: resolve(dirname(fileURLToPath(import.meta.url)), markdown_inline_language)
|
|
5334
5680
|
}
|
|
5335
5681
|
];
|
|
5336
5682
|
}
|
|
@@ -5338,9 +5684,8 @@ function getParsers() {
|
|
|
5338
5684
|
}
|
|
5339
5685
|
|
|
5340
5686
|
// src/lib/tree-sitter/client.ts
|
|
5341
|
-
import { resolve as resolve2, isAbsolute } from "path";
|
|
5687
|
+
import { resolve as resolve2, isAbsolute, parse } from "path";
|
|
5342
5688
|
import { existsSync } from "fs";
|
|
5343
|
-
import { parse } from "path";
|
|
5344
5689
|
registerEnvVar({
|
|
5345
5690
|
name: "OTUI_TREE_SITTER_WORKER_PATH",
|
|
5346
5691
|
description: "Path to the TreeSitter worker",
|
|
@@ -5360,7 +5705,7 @@ function addDefaultParsers(parsers) {
|
|
|
5360
5705
|
}
|
|
5361
5706
|
var isUrl = (path) => path.startsWith("http://") || path.startsWith("https://");
|
|
5362
5707
|
|
|
5363
|
-
class TreeSitterClient extends
|
|
5708
|
+
class TreeSitterClient extends EventEmitter3 {
|
|
5364
5709
|
initialized = false;
|
|
5365
5710
|
worker;
|
|
5366
5711
|
buffers = new Map;
|
|
@@ -5393,9 +5738,9 @@ class TreeSitterClient extends EventEmitter2 {
|
|
|
5393
5738
|
}
|
|
5394
5739
|
let worker_path;
|
|
5395
5740
|
if (env.OTUI_TREE_SITTER_WORKER_PATH) {
|
|
5396
|
-
worker_path = env.OTUI_TREE_SITTER_WORKER_PATH;
|
|
5741
|
+
worker_path = resolve2(env.OTUI_TREE_SITTER_WORKER_PATH);
|
|
5397
5742
|
} else if (typeof OTUI_TREE_SITTER_WORKER_PATH !== "undefined") {
|
|
5398
|
-
worker_path = OTUI_TREE_SITTER_WORKER_PATH;
|
|
5743
|
+
worker_path = resolve2(OTUI_TREE_SITTER_WORKER_PATH);
|
|
5399
5744
|
} else if (this.options.workerPath) {
|
|
5400
5745
|
worker_path = this.options.workerPath;
|
|
5401
5746
|
} else {
|
|
@@ -5475,7 +5820,8 @@ class TreeSitterClient extends EventEmitter2 {
|
|
|
5475
5820
|
...filetypeParser,
|
|
5476
5821
|
wasm: this.resolvePath(filetypeParser.wasm),
|
|
5477
5822
|
queries: {
|
|
5478
|
-
highlights: filetypeParser.queries.highlights.map((path) => this.resolvePath(path))
|
|
5823
|
+
highlights: filetypeParser.queries.highlights.map((path) => this.resolvePath(path)),
|
|
5824
|
+
injections: filetypeParser.queries.injections?.map((path) => this.resolvePath(path))
|
|
5479
5825
|
}
|
|
5480
5826
|
};
|
|
5481
5827
|
this.worker?.postMessage({ type: "ADD_FILETYPE_PARSER", filetypeParser: resolvedParser });
|
|
@@ -5581,6 +5927,14 @@ class TreeSitterClient extends EventEmitter2 {
|
|
|
5581
5927
|
}
|
|
5582
5928
|
return;
|
|
5583
5929
|
}
|
|
5930
|
+
if (type === "CLEAR_CACHE_RESPONSE") {
|
|
5931
|
+
const callback = this.messageCallbacks.get(messageId);
|
|
5932
|
+
if (callback) {
|
|
5933
|
+
this.messageCallbacks.delete(messageId);
|
|
5934
|
+
callback({ error });
|
|
5935
|
+
}
|
|
5936
|
+
return;
|
|
5937
|
+
}
|
|
5584
5938
|
if (warning) {
|
|
5585
5939
|
this.emitWarning(warning, bufferId);
|
|
5586
5940
|
return;
|
|
@@ -5594,9 +5948,11 @@ class TreeSitterClient extends EventEmitter2 {
|
|
|
5594
5948
|
const message = data.join(" ");
|
|
5595
5949
|
this.emit("worker:log", logType, message);
|
|
5596
5950
|
if (logType === "log") {
|
|
5597
|
-
console.log("
|
|
5951
|
+
console.log("TSWorker:", ...data);
|
|
5598
5952
|
} else if (logType === "error") {
|
|
5599
|
-
console.error("
|
|
5953
|
+
console.error("TSWorker:", ...data);
|
|
5954
|
+
} else if (logType === "warn") {
|
|
5955
|
+
console.warn("TSWorker:", ...data);
|
|
5600
5956
|
}
|
|
5601
5957
|
return;
|
|
5602
5958
|
}
|
|
@@ -5776,12 +6132,31 @@ class TreeSitterClient extends EventEmitter2 {
|
|
|
5776
6132
|
});
|
|
5777
6133
|
}
|
|
5778
6134
|
}
|
|
6135
|
+
async clearCache() {
|
|
6136
|
+
if (!this.initialized || !this.worker) {
|
|
6137
|
+
throw new Error("Cannot clear cache: client is not initialized");
|
|
6138
|
+
}
|
|
6139
|
+
const messageId = `clear_cache_${this.messageIdCounter++}`;
|
|
6140
|
+
return new Promise((resolve3, reject) => {
|
|
6141
|
+
this.messageCallbacks.set(messageId, (response) => {
|
|
6142
|
+
if (response.error) {
|
|
6143
|
+
reject(new Error(response.error));
|
|
6144
|
+
} else {
|
|
6145
|
+
resolve3();
|
|
6146
|
+
}
|
|
6147
|
+
});
|
|
6148
|
+
this.worker.postMessage({
|
|
6149
|
+
type: "CLEAR_CACHE",
|
|
6150
|
+
messageId
|
|
6151
|
+
});
|
|
6152
|
+
});
|
|
6153
|
+
}
|
|
5779
6154
|
}
|
|
5780
6155
|
|
|
5781
6156
|
// src/lib/data-paths.ts
|
|
5782
6157
|
import os from "os";
|
|
5783
6158
|
import path from "path";
|
|
5784
|
-
import { EventEmitter as
|
|
6159
|
+
import { EventEmitter as EventEmitter4 } from "events";
|
|
5785
6160
|
|
|
5786
6161
|
// src/lib/validate-dir-name.ts
|
|
5787
6162
|
function isValidDirectoryName(name) {
|
|
@@ -5845,7 +6220,7 @@ registerEnvVar({
|
|
|
5845
6220
|
default: ""
|
|
5846
6221
|
});
|
|
5847
6222
|
|
|
5848
|
-
class DataPathsManager extends
|
|
6223
|
+
class DataPathsManager extends EventEmitter4 {
|
|
5849
6224
|
_appName;
|
|
5850
6225
|
_globalConfigPath;
|
|
5851
6226
|
_globalConfigFile;
|
|
@@ -5929,6 +6304,24 @@ function extToFiletype(extension) {
|
|
|
5929
6304
|
["rs", "rust"],
|
|
5930
6305
|
["c", "c"],
|
|
5931
6306
|
["cpp", "cpp"],
|
|
6307
|
+
["c++", "cpp"],
|
|
6308
|
+
["cs", "csharp"],
|
|
6309
|
+
["java", "java"],
|
|
6310
|
+
["kt", "kotlin"],
|
|
6311
|
+
["swift", "swift"],
|
|
6312
|
+
["php", "php"],
|
|
6313
|
+
["sql", "sql"],
|
|
6314
|
+
["pl", "perl"],
|
|
6315
|
+
["lua", "lua"],
|
|
6316
|
+
["erl", "erlang"],
|
|
6317
|
+
["exs", "elixir"],
|
|
6318
|
+
["ex", "elixir"],
|
|
6319
|
+
["elm", "elm"],
|
|
6320
|
+
["fsharp", "fsharp"],
|
|
6321
|
+
["fs", "fsharp"],
|
|
6322
|
+
["fsx", "fsharp"],
|
|
6323
|
+
["fsscript", "fsharp"],
|
|
6324
|
+
["fsi", "fsharp"],
|
|
5932
6325
|
["h", "c"],
|
|
5933
6326
|
["hpp", "cpp"],
|
|
5934
6327
|
["html", "html"],
|
|
@@ -6071,17 +6464,35 @@ class DownloadUtils {
|
|
|
6071
6464
|
}
|
|
6072
6465
|
|
|
6073
6466
|
// src/lib/tree-sitter/assets/update.ts
|
|
6467
|
+
import { readdir } from "fs/promises";
|
|
6074
6468
|
var __dirname = "/Users/runner/work/opentui/opentui/packages/core/src/lib/tree-sitter/assets";
|
|
6075
6469
|
function getDefaultOptions() {
|
|
6076
6470
|
return {
|
|
6077
|
-
configPath: path3.resolve(__dirname, "../parsers-config
|
|
6471
|
+
configPath: path3.resolve(__dirname, "../parsers-config"),
|
|
6078
6472
|
assetsDir: path3.resolve(__dirname),
|
|
6079
6473
|
outputPath: path3.resolve(__dirname, "../default-parsers.ts")
|
|
6080
6474
|
};
|
|
6081
6475
|
}
|
|
6082
6476
|
async function loadConfig(configPath) {
|
|
6083
|
-
|
|
6084
|
-
|
|
6477
|
+
let ext = path3.extname(configPath);
|
|
6478
|
+
let resolvedConfigPath = configPath;
|
|
6479
|
+
if (ext === "") {
|
|
6480
|
+
const files = await readdir(path3.dirname(configPath));
|
|
6481
|
+
const file = files.find((file2) => file2.startsWith(path3.basename(configPath)) && (file2.endsWith(".json") || file2.endsWith(".ts") || file2.endsWith(".js")));
|
|
6482
|
+
if (!file) {
|
|
6483
|
+
throw new Error(`No config file found for ${configPath}`);
|
|
6484
|
+
}
|
|
6485
|
+
resolvedConfigPath = path3.join(path3.dirname(configPath), file);
|
|
6486
|
+
ext = path3.extname(resolvedConfigPath);
|
|
6487
|
+
}
|
|
6488
|
+
if (ext === ".json") {
|
|
6489
|
+
const configContent = await readFile(resolvedConfigPath, "utf-8");
|
|
6490
|
+
return JSON.parse(configContent);
|
|
6491
|
+
} else if (ext === ".ts" || ext === ".js") {
|
|
6492
|
+
const { default: configContent } = await import(resolvedConfigPath);
|
|
6493
|
+
return configContent;
|
|
6494
|
+
}
|
|
6495
|
+
throw new Error(`Unsupported config file extension: ${ext}`);
|
|
6085
6496
|
}
|
|
6086
6497
|
async function downloadLanguage(filetype, languageUrl, assetsDir, outputPath) {
|
|
6087
6498
|
const languageDir = path3.join(assetsDir, filetype);
|
|
@@ -6093,53 +6504,85 @@ async function downloadLanguage(filetype, languageUrl, assetsDir, outputPath) {
|
|
|
6093
6504
|
}
|
|
6094
6505
|
return "./" + path3.relative(path3.dirname(outputPath), languagePath);
|
|
6095
6506
|
}
|
|
6096
|
-
async function downloadAndCombineQueries(filetype, queryUrls, assetsDir, outputPath) {
|
|
6507
|
+
async function downloadAndCombineQueries(filetype, queryUrls, assetsDir, outputPath, queryType, configPath) {
|
|
6097
6508
|
const queriesDir = path3.join(assetsDir, filetype);
|
|
6098
|
-
const
|
|
6509
|
+
const queryPath = path3.join(queriesDir, `${queryType}.scm`);
|
|
6099
6510
|
const queryContents = [];
|
|
6100
6511
|
for (let i = 0;i < queryUrls.length; i++) {
|
|
6101
6512
|
const queryUrl = queryUrls[i];
|
|
6102
|
-
|
|
6103
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
|
|
6513
|
+
if (queryUrl.startsWith("./")) {
|
|
6514
|
+
console.log(` Using local query ${i + 1}/${queryUrls.length}: ${queryUrl}`);
|
|
6515
|
+
try {
|
|
6516
|
+
const localPath = path3.resolve(path3.dirname(configPath), queryUrl);
|
|
6517
|
+
const content = await readFile(localPath, "utf-8");
|
|
6518
|
+
if (content.trim()) {
|
|
6519
|
+
queryContents.push(content);
|
|
6520
|
+
console.log(` \u2713 Loaded ${content.split(`
|
|
6521
|
+
`).length} lines from local file`);
|
|
6522
|
+
}
|
|
6523
|
+
} catch (error) {
|
|
6524
|
+
console.warn(`Failed to read local query from ${queryUrl}: ${error}`);
|
|
6107
6525
|
continue;
|
|
6108
6526
|
}
|
|
6109
|
-
|
|
6110
|
-
|
|
6111
|
-
|
|
6527
|
+
} else {
|
|
6528
|
+
console.log(` Downloading query ${i + 1}/${queryUrls.length}: ${queryUrl}`);
|
|
6529
|
+
try {
|
|
6530
|
+
const response = await fetch(queryUrl);
|
|
6531
|
+
if (!response.ok) {
|
|
6532
|
+
console.warn(`Failed to download query from ${queryUrl}: ${response.statusText}`);
|
|
6533
|
+
continue;
|
|
6534
|
+
}
|
|
6535
|
+
const content = await response.text();
|
|
6536
|
+
if (content.trim()) {
|
|
6537
|
+
queryContents.push(`; Query from: ${queryUrl}
|
|
6112
6538
|
${content}`);
|
|
6113
|
-
|
|
6539
|
+
console.log(` \u2713 Downloaded ${content.split(`
|
|
6114
6540
|
`).length} lines`);
|
|
6541
|
+
}
|
|
6542
|
+
} catch (error) {
|
|
6543
|
+
console.warn(`Failed to download query from ${queryUrl}: ${error}`);
|
|
6544
|
+
continue;
|
|
6115
6545
|
}
|
|
6116
|
-
} catch (error) {
|
|
6117
|
-
console.warn(`Failed to download query from ${queryUrl}: ${error}`);
|
|
6118
|
-
continue;
|
|
6119
6546
|
}
|
|
6120
6547
|
}
|
|
6121
6548
|
const combinedContent = queryContents.join(`
|
|
6122
6549
|
|
|
6123
6550
|
`);
|
|
6124
|
-
await writeFile2(
|
|
6125
|
-
console.log(` Combined ${queryContents.length} queries into ${
|
|
6126
|
-
return "./" + path3.relative(path3.dirname(outputPath),
|
|
6551
|
+
await writeFile2(queryPath, combinedContent, "utf-8");
|
|
6552
|
+
console.log(` Combined ${queryContents.length} queries into ${queryPath}`);
|
|
6553
|
+
return "./" + path3.relative(path3.dirname(outputPath), queryPath);
|
|
6127
6554
|
}
|
|
6128
6555
|
async function generateDefaultParsersFile(parsers, outputPath) {
|
|
6129
6556
|
const imports = parsers.map((parser) => {
|
|
6130
6557
|
const safeFiletype = parser.filetype.replace(/[^a-zA-Z0-9]/g, "_");
|
|
6131
|
-
|
|
6132
|
-
import ${safeFiletype}
|
|
6558
|
+
const lines = [
|
|
6559
|
+
`import ${safeFiletype}_highlights from "${parser.highlightsPath}" with { type: "file" }`,
|
|
6560
|
+
`import ${safeFiletype}_language from "${parser.languagePath}" with { type: "file" }`
|
|
6561
|
+
];
|
|
6562
|
+
if (parser.injectionsPath) {
|
|
6563
|
+
lines.push(`import ${safeFiletype}_injections from "${parser.injectionsPath}" with { type: "file" }`);
|
|
6564
|
+
}
|
|
6565
|
+
return lines.join(`
|
|
6566
|
+
`);
|
|
6133
6567
|
}).join(`
|
|
6134
6568
|
`);
|
|
6135
6569
|
const parserDefinitions = parsers.map((parser) => {
|
|
6136
6570
|
const safeFiletype = parser.filetype.replace(/[^a-zA-Z0-9]/g, "_");
|
|
6571
|
+
const queriesLines = [
|
|
6572
|
+
` highlights: [resolve(dirname(fileURLToPath(import.meta.url)), ${safeFiletype}_highlights)],`
|
|
6573
|
+
];
|
|
6574
|
+
if (parser.injectionsPath) {
|
|
6575
|
+
queriesLines.push(` injections: [resolve(dirname(fileURLToPath(import.meta.url)), ${safeFiletype}_injections)],`);
|
|
6576
|
+
}
|
|
6577
|
+
const injectionMappingLine = parser.injectionMapping ? ` injectionMapping: ${JSON.stringify(parser.injectionMapping, null, 10)},` : "";
|
|
6137
6578
|
return ` {
|
|
6138
6579
|
filetype: "${parser.filetype}",
|
|
6139
6580
|
queries: {
|
|
6140
|
-
|
|
6581
|
+
${queriesLines.join(`
|
|
6582
|
+
`)}
|
|
6141
6583
|
},
|
|
6142
|
-
wasm: resolve(dirname(fileURLToPath(import.meta.url)), ${safeFiletype}_language)
|
|
6584
|
+
wasm: resolve(dirname(fileURLToPath(import.meta.url)), ${safeFiletype}_language),${injectionMappingLine ? `
|
|
6585
|
+
` + injectionMappingLine : ""}
|
|
6143
6586
|
}`;
|
|
6144
6587
|
}).join(`,
|
|
6145
6588
|
`);
|
|
@@ -6184,11 +6627,18 @@ async function main(options) {
|
|
|
6184
6627
|
console.log(` Downloading language...`);
|
|
6185
6628
|
const languagePath = await downloadLanguage(parser.filetype, parser.wasm, opts.assetsDir, opts.outputPath);
|
|
6186
6629
|
console.log(` Downloading ${parser.queries.highlights.length} highlight queries...`);
|
|
6187
|
-
const highlightsPath = await downloadAndCombineQueries(parser.filetype, parser.queries.highlights, opts.assetsDir, opts.outputPath);
|
|
6630
|
+
const highlightsPath = await downloadAndCombineQueries(parser.filetype, parser.queries.highlights, opts.assetsDir, opts.outputPath, "highlights", opts.configPath);
|
|
6631
|
+
let injectionsPath;
|
|
6632
|
+
if (parser.queries.injections && parser.queries.injections.length > 0) {
|
|
6633
|
+
console.log(` Downloading ${parser.queries.injections.length} injection queries...`);
|
|
6634
|
+
injectionsPath = await downloadAndCombineQueries(parser.filetype, parser.queries.injections, opts.assetsDir, opts.outputPath, "injections", opts.configPath);
|
|
6635
|
+
}
|
|
6188
6636
|
generatedParsers.push({
|
|
6189
6637
|
filetype: parser.filetype,
|
|
6190
6638
|
languagePath,
|
|
6191
|
-
highlightsPath
|
|
6639
|
+
highlightsPath,
|
|
6640
|
+
injectionsPath,
|
|
6641
|
+
injectionMapping: parser.injectionMapping
|
|
6192
6642
|
});
|
|
6193
6643
|
console.log(` \u2713 Completed ${parser.filetype}`);
|
|
6194
6644
|
}
|
|
@@ -6893,7 +7343,7 @@ function createExtmarksController(editBuffer, editorView) {
|
|
|
6893
7343
|
// src/zig.ts
|
|
6894
7344
|
import { dlopen, toArrayBuffer as toArrayBuffer4, JSCallback, ptr as ptr3 } from "bun:ffi";
|
|
6895
7345
|
import { existsSync as existsSync2 } from "fs";
|
|
6896
|
-
import { EventEmitter as
|
|
7346
|
+
import { EventEmitter as EventEmitter5 } from "events";
|
|
6897
7347
|
|
|
6898
7348
|
// src/buffer.ts
|
|
6899
7349
|
import { toArrayBuffer } from "bun:ffi";
|
|
@@ -8073,6 +8523,10 @@ function getOpenTUILib(libPath) {
|
|
|
8073
8523
|
args: ["ptr", "usize"],
|
|
8074
8524
|
returns: "void"
|
|
8075
8525
|
},
|
|
8526
|
+
textBufferGetHighlightCount: {
|
|
8527
|
+
args: ["ptr"],
|
|
8528
|
+
returns: "u32"
|
|
8529
|
+
},
|
|
8076
8530
|
createTextBufferView: {
|
|
8077
8531
|
args: ["ptr"],
|
|
8078
8532
|
returns: "ptr"
|
|
@@ -8570,7 +9024,7 @@ class FFIRenderLib {
|
|
|
8570
9024
|
decoder = new TextDecoder;
|
|
8571
9025
|
logCallbackWrapper;
|
|
8572
9026
|
eventCallbackWrapper;
|
|
8573
|
-
_nativeEvents = new
|
|
9027
|
+
_nativeEvents = new EventEmitter5;
|
|
8574
9028
|
_anyEventHandlers = [];
|
|
8575
9029
|
constructor(libPath) {
|
|
8576
9030
|
this.opentui = getOpenTUILib(libPath);
|
|
@@ -9118,6 +9572,9 @@ class FFIRenderLib {
|
|
|
9118
9572
|
this.opentui.symbols.textBufferFreeLineHighlights(nativePtr, count);
|
|
9119
9573
|
return results;
|
|
9120
9574
|
}
|
|
9575
|
+
textBufferGetHighlightCount(buffer) {
|
|
9576
|
+
return this.opentui.symbols.textBufferGetHighlightCount(buffer);
|
|
9577
|
+
}
|
|
9121
9578
|
getArenaAllocatedBytes() {
|
|
9122
9579
|
const result = this.opentui.symbols.getArenaAllocatedBytes();
|
|
9123
9580
|
return typeof result === "bigint" ? Number(result) : result;
|
|
@@ -9657,6 +10114,10 @@ class TextBuffer {
|
|
|
9657
10114
|
this.guard();
|
|
9658
10115
|
return this.lib.textBufferGetLineHighlights(this.bufferPtr, lineIdx);
|
|
9659
10116
|
}
|
|
10117
|
+
getHighlightCount() {
|
|
10118
|
+
this.guard();
|
|
10119
|
+
return this.lib.textBufferGetHighlightCount(this.bufferPtr);
|
|
10120
|
+
}
|
|
9660
10121
|
setSyntaxStyle(style) {
|
|
9661
10122
|
this.guard();
|
|
9662
10123
|
this._syntaxStyle = style ?? undefined;
|
|
@@ -9700,7 +10161,7 @@ class TextBuffer {
|
|
|
9700
10161
|
}
|
|
9701
10162
|
|
|
9702
10163
|
// src/Renderable.ts
|
|
9703
|
-
import { EventEmitter as
|
|
10164
|
+
import { EventEmitter as EventEmitter6 } from "events";
|
|
9704
10165
|
|
|
9705
10166
|
// src/lib/renderable.validations.ts
|
|
9706
10167
|
function validateOptions(id, options) {
|
|
@@ -9793,7 +10254,7 @@ function isRenderable(obj) {
|
|
|
9793
10254
|
return !!obj?.[BrandedRenderable];
|
|
9794
10255
|
}
|
|
9795
10256
|
|
|
9796
|
-
class BaseRenderable extends
|
|
10257
|
+
class BaseRenderable extends EventEmitter6 {
|
|
9797
10258
|
[BrandedRenderable] = true;
|
|
9798
10259
|
static renderableNumber = 1;
|
|
9799
10260
|
_id;
|
|
@@ -11114,7 +11575,7 @@ function delegate(mapping, vnode) {
|
|
|
11114
11575
|
}
|
|
11115
11576
|
|
|
11116
11577
|
// src/console.ts
|
|
11117
|
-
import { EventEmitter as
|
|
11578
|
+
import { EventEmitter as EventEmitter8 } from "events";
|
|
11118
11579
|
import { Console } from "console";
|
|
11119
11580
|
import fs from "fs";
|
|
11120
11581
|
import path4 from "path";
|
|
@@ -11122,9 +11583,9 @@ import util2 from "util";
|
|
|
11122
11583
|
|
|
11123
11584
|
// src/lib/output.capture.ts
|
|
11124
11585
|
import { Writable } from "stream";
|
|
11125
|
-
import { EventEmitter as
|
|
11586
|
+
import { EventEmitter as EventEmitter7 } from "events";
|
|
11126
11587
|
|
|
11127
|
-
class Capture extends
|
|
11588
|
+
class Capture extends EventEmitter7 {
|
|
11128
11589
|
output = [];
|
|
11129
11590
|
constructor() {
|
|
11130
11591
|
super();
|
|
@@ -11200,7 +11661,7 @@ registerEnvVar({
|
|
|
11200
11661
|
default: false
|
|
11201
11662
|
});
|
|
11202
11663
|
|
|
11203
|
-
class TerminalConsoleCache extends
|
|
11664
|
+
class TerminalConsoleCache extends EventEmitter8 {
|
|
11204
11665
|
_cachedLogs = [];
|
|
11205
11666
|
MAX_CACHE_SIZE = 1000;
|
|
11206
11667
|
_collectCallerInfo = false;
|
|
@@ -11326,7 +11787,7 @@ var DEFAULT_CONSOLE_OPTIONS = {
|
|
|
11326
11787
|
};
|
|
11327
11788
|
var INDENT_WIDTH = 2;
|
|
11328
11789
|
|
|
11329
|
-
class TerminalConsole extends
|
|
11790
|
+
class TerminalConsole extends EventEmitter8 {
|
|
11330
11791
|
isVisible = false;
|
|
11331
11792
|
isFocused = false;
|
|
11332
11793
|
renderer;
|
|
@@ -11415,34 +11876,34 @@ class TerminalConsole extends EventEmitter7 {
|
|
|
11415
11876
|
}
|
|
11416
11877
|
this.markNeedsRerender();
|
|
11417
11878
|
}
|
|
11418
|
-
_updateConsoleDimensions() {
|
|
11419
|
-
const
|
|
11420
|
-
const
|
|
11879
|
+
_updateConsoleDimensions(termWidth, termHeight) {
|
|
11880
|
+
const width = termWidth ?? this.renderer.terminalWidth;
|
|
11881
|
+
const height = termHeight ?? this.renderer.terminalHeight;
|
|
11421
11882
|
const sizePercent = this.options.sizePercent / 100;
|
|
11422
11883
|
switch (this.options.position) {
|
|
11423
11884
|
case "top" /* TOP */:
|
|
11424
11885
|
this.consoleX = 0;
|
|
11425
11886
|
this.consoleY = 0;
|
|
11426
|
-
this.consoleWidth =
|
|
11427
|
-
this.consoleHeight = Math.max(1, Math.floor(
|
|
11887
|
+
this.consoleWidth = width;
|
|
11888
|
+
this.consoleHeight = Math.max(1, Math.floor(height * sizePercent));
|
|
11428
11889
|
break;
|
|
11429
11890
|
case "bottom" /* BOTTOM */:
|
|
11430
|
-
this.consoleHeight = Math.max(1, Math.floor(
|
|
11431
|
-
this.consoleWidth =
|
|
11891
|
+
this.consoleHeight = Math.max(1, Math.floor(height * sizePercent));
|
|
11892
|
+
this.consoleWidth = width;
|
|
11432
11893
|
this.consoleX = 0;
|
|
11433
|
-
this.consoleY =
|
|
11894
|
+
this.consoleY = height - this.consoleHeight;
|
|
11434
11895
|
break;
|
|
11435
11896
|
case "left" /* LEFT */:
|
|
11436
|
-
this.consoleWidth = Math.max(1, Math.floor(
|
|
11437
|
-
this.consoleHeight =
|
|
11897
|
+
this.consoleWidth = Math.max(1, Math.floor(width * sizePercent));
|
|
11898
|
+
this.consoleHeight = height;
|
|
11438
11899
|
this.consoleX = 0;
|
|
11439
11900
|
this.consoleY = 0;
|
|
11440
11901
|
break;
|
|
11441
11902
|
case "right" /* RIGHT */:
|
|
11442
|
-
this.consoleWidth = Math.max(1, Math.floor(
|
|
11443
|
-
this.consoleHeight =
|
|
11903
|
+
this.consoleWidth = Math.max(1, Math.floor(width * sizePercent));
|
|
11904
|
+
this.consoleHeight = height;
|
|
11444
11905
|
this.consoleY = 0;
|
|
11445
|
-
this.consoleX =
|
|
11906
|
+
this.consoleX = width - this.consoleWidth;
|
|
11446
11907
|
break;
|
|
11447
11908
|
}
|
|
11448
11909
|
this.currentLineIndex = Math.max(0, Math.min(this.currentLineIndex, this.consoleHeight - 1));
|
|
@@ -11564,7 +12025,7 @@ class TerminalConsole extends EventEmitter7 {
|
|
|
11564
12025
|
}).join(" ");
|
|
11565
12026
|
}
|
|
11566
12027
|
resize(width, height) {
|
|
11567
|
-
this._updateConsoleDimensions();
|
|
12028
|
+
this._updateConsoleDimensions(width, height);
|
|
11568
12029
|
if (this.frameBuffer) {
|
|
11569
12030
|
this.frameBuffer.resize(this.consoleWidth, this.consoleHeight);
|
|
11570
12031
|
const displayLineCount = this._displayLines.length;
|
|
@@ -11786,7 +12247,7 @@ class TerminalConsole extends EventEmitter7 {
|
|
|
11786
12247
|
}
|
|
11787
12248
|
|
|
11788
12249
|
// src/renderer.ts
|
|
11789
|
-
import { EventEmitter as
|
|
12250
|
+
import { EventEmitter as EventEmitter9 } from "events";
|
|
11790
12251
|
|
|
11791
12252
|
// src/lib/objects-in-viewport.ts
|
|
11792
12253
|
function getObjectsInViewport(viewport, objects, direction = "column", padding = 10, minTriggerSize = 16) {
|
|
@@ -12012,7 +12473,7 @@ var RendererControlState;
|
|
|
12012
12473
|
RendererControlState2["EXPLICIT_STOPPED"] = "explicit_stopped";
|
|
12013
12474
|
})(RendererControlState ||= {});
|
|
12014
12475
|
|
|
12015
|
-
class CliRenderer extends
|
|
12476
|
+
class CliRenderer extends EventEmitter9 {
|
|
12016
12477
|
static animationFrameId = 0;
|
|
12017
12478
|
lib;
|
|
12018
12479
|
rendererPtr;
|
|
@@ -12191,6 +12652,14 @@ Captured output:
|
|
|
12191
12652
|
this._console = new TerminalConsole(this, config.consoleOptions);
|
|
12192
12653
|
this.useConsole = config.useConsole ?? true;
|
|
12193
12654
|
this._keyHandler = new InternalKeyHandler(this.stdin, config.useKittyKeyboard ?? false);
|
|
12655
|
+
this._keyHandler.on("keypress", (event) => {
|
|
12656
|
+
if (this.exitOnCtrlC && event.name === "c" && event.ctrl) {
|
|
12657
|
+
process.nextTick(() => {
|
|
12658
|
+
this.destroy();
|
|
12659
|
+
});
|
|
12660
|
+
return;
|
|
12661
|
+
}
|
|
12662
|
+
});
|
|
12194
12663
|
global.requestAnimationFrame = (callback) => {
|
|
12195
12664
|
const id = CliRenderer.animationFrameId++;
|
|
12196
12665
|
this.animationRequest.set(id, callback);
|
|
@@ -12450,12 +12919,6 @@ Captured output:
|
|
|
12450
12919
|
return;
|
|
12451
12920
|
}
|
|
12452
12921
|
}
|
|
12453
|
-
if (this.exitOnCtrlC && str === "\x03") {
|
|
12454
|
-
process.nextTick(() => {
|
|
12455
|
-
this.destroy();
|
|
12456
|
-
});
|
|
12457
|
-
return;
|
|
12458
|
-
}
|
|
12459
12922
|
if (this._useMouse && this.handleMouseData(data)) {
|
|
12460
12923
|
return;
|
|
12461
12924
|
}
|
|
@@ -13095,7 +13558,7 @@ Captured output:
|
|
|
13095
13558
|
}
|
|
13096
13559
|
}
|
|
13097
13560
|
|
|
13098
|
-
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, 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, ExtmarksController, createExtmarksController, 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 };
|
|
13561
|
+
export { __toESM, __commonJS, __export, __require, Edge, Gutter, exports_src, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, nonAlphanumericKeys, parseKeypress, ANSI, StdinBuffer, 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, 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, ExtmarksController, createExtmarksController, 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 };
|
|
13099
13562
|
|
|
13100
|
-
//# debugId=
|
|
13101
|
-
//# sourceMappingURL=index-
|
|
13563
|
+
//# debugId=4704E8A57986003964756E2164756E21
|
|
13564
|
+
//# sourceMappingURL=index-rzgaxyf4.js.map
|