@opentui/core 0.0.0-20251108-0c7899b1 → 0.0.0-20251112-a24ada2d

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.
@@ -2079,7 +2079,7 @@ var isShiftKey = (code) => {
2079
2079
  var isCtrlKey = (code) => {
2080
2080
  return ["Oa", "Ob", "Oc", "Od", "Oe", "[2^", "[3^", "[5^", "[6^", "[7^", "[8^"].includes(code);
2081
2081
  };
2082
- var ghosttyModifiedKeyRe = /^\x1b\[27;(\d+);(\d+)~$/;
2082
+ var modifyOtherKeysRe = /^\x1b\[27;(\d+);(\d+)~$/;
2083
2083
  var parseKeypress = (s = "", options = {}) => {
2084
2084
  let parts;
2085
2085
  if (Buffer2.isBuffer(s)) {
@@ -2100,6 +2100,27 @@ var parseKeypress = (s = "", options = {}) => {
2100
2100
  if (s.startsWith("\x1B[M") && s.length >= 6) {
2101
2101
  return null;
2102
2102
  }
2103
+ if (/^\x1b\[\d+;\d+;\d+t$/.test(s)) {
2104
+ return null;
2105
+ }
2106
+ if (/^\x1b\[\d+;\d+R$/.test(s)) {
2107
+ return null;
2108
+ }
2109
+ if (/^\x1b\[\?[\d;]+c$/.test(s)) {
2110
+ return null;
2111
+ }
2112
+ if (/^\x1b\[\?[\d;]+\$y$/.test(s)) {
2113
+ return null;
2114
+ }
2115
+ if (s === "\x1B[I" || s === "\x1B[O") {
2116
+ return null;
2117
+ }
2118
+ if (/^\x1b\][\d;].*(\x1b\\|\x07)$/.test(s)) {
2119
+ return null;
2120
+ }
2121
+ if (s === "\x1B[200~" || s === "\x1B[201~") {
2122
+ return null;
2123
+ }
2103
2124
  const key = {
2104
2125
  name: "",
2105
2126
  ctrl: false,
@@ -2119,10 +2140,10 @@ var parseKeypress = (s = "", options = {}) => {
2119
2140
  return kittyResult;
2120
2141
  }
2121
2142
  }
2122
- const ghosttyMatch = ghosttyModifiedKeyRe.exec(s);
2123
- if (ghosttyMatch) {
2124
- const modifier = parseInt(ghosttyMatch[1], 10) - 1;
2125
- const charCode = parseInt(ghosttyMatch[2], 10);
2143
+ const modifyOtherKeysMatch = modifyOtherKeysRe.exec(s);
2144
+ if (modifyOtherKeysMatch) {
2145
+ const modifier = parseInt(modifyOtherKeysMatch[1], 10) - 1;
2146
+ const charCode = parseInt(modifyOtherKeysMatch[2], 10);
2126
2147
  key.ctrl = !!(modifier & 4);
2127
2148
  key.meta = !!(modifier & 10);
2128
2149
  key.shift = !!(modifier & 1);
@@ -2214,201 +2235,8 @@ var parseKeypress = (s = "", options = {}) => {
2214
2235
  return key;
2215
2236
  };
2216
2237
 
2217
- // src/lib/stdin-buffer.ts
2218
- import { EventEmitter } from "events";
2219
- var ESC = "\x1B";
2220
- function isCompleteSequence(data) {
2221
- if (!data.startsWith(ESC)) {
2222
- return "not-escape";
2223
- }
2224
- if (data.length === 1) {
2225
- return "incomplete";
2226
- }
2227
- const afterEsc = data.slice(1);
2228
- if (afterEsc.startsWith("[")) {
2229
- if (afterEsc.startsWith("[M")) {
2230
- return data.length >= 6 ? "complete" : "incomplete";
2231
- }
2232
- return isCompleteCsiSequence(data);
2233
- }
2234
- if (afterEsc.startsWith("]")) {
2235
- return isCompleteOscSequence(data);
2236
- }
2237
- if (afterEsc.startsWith("O")) {
2238
- return afterEsc.length >= 2 ? "complete" : "incomplete";
2239
- }
2240
- if (afterEsc.length === 1) {
2241
- return "complete";
2242
- }
2243
- return "complete";
2244
- }
2245
- function isCompleteCsiSequence(data) {
2246
- if (!data.startsWith(ESC + "[")) {
2247
- return "complete";
2248
- }
2249
- if (data.length < 3) {
2250
- return "incomplete";
2251
- }
2252
- const payload = data.slice(2);
2253
- const lastChar = payload[payload.length - 1];
2254
- const lastCharCode = lastChar.charCodeAt(0);
2255
- if (lastCharCode >= 64 && lastCharCode <= 126) {
2256
- if (payload.startsWith("<")) {
2257
- const mouseMatch = /^<\d+;\d+;\d+[Mm]$/.test(payload);
2258
- if (mouseMatch) {
2259
- return "complete";
2260
- }
2261
- if (lastChar === "M" || lastChar === "m") {
2262
- const parts = payload.slice(1, -1).split(";");
2263
- if (parts.length === 3 && parts.every((p) => /^\d+$/.test(p))) {
2264
- return "complete";
2265
- }
2266
- }
2267
- return "incomplete";
2268
- }
2269
- return "complete";
2270
- }
2271
- return "incomplete";
2272
- }
2273
- function isCompleteOscSequence(data) {
2274
- if (!data.startsWith(ESC + "]")) {
2275
- return "complete";
2276
- }
2277
- if (data.endsWith(ESC + "\\") || data.endsWith("\x07")) {
2278
- return "complete";
2279
- }
2280
- return "incomplete";
2281
- }
2282
- function extractCompleteSequences(buffer) {
2283
- const sequences = [];
2284
- let pos = 0;
2285
- while (pos < buffer.length) {
2286
- const remaining = buffer.slice(pos);
2287
- if (remaining.startsWith(ESC)) {
2288
- let seqEnd = 1;
2289
- while (seqEnd <= remaining.length) {
2290
- const candidate = remaining.slice(0, seqEnd);
2291
- const status = isCompleteSequence(candidate);
2292
- if (status === "complete") {
2293
- sequences.push(candidate);
2294
- pos += seqEnd;
2295
- break;
2296
- } else if (status === "incomplete") {
2297
- seqEnd++;
2298
- } else {
2299
- sequences.push(candidate);
2300
- pos += seqEnd;
2301
- break;
2302
- }
2303
- }
2304
- if (seqEnd > remaining.length) {
2305
- return { sequences, remainder: remaining };
2306
- }
2307
- } else {
2308
- sequences.push(remaining[0]);
2309
- pos++;
2310
- }
2311
- }
2312
- return { sequences, remainder: "" };
2313
- }
2314
-
2315
- class StdinBuffer extends EventEmitter {
2316
- buffer = "";
2317
- timeout = null;
2318
- timeoutMs;
2319
- stdin;
2320
- stdinListener;
2321
- constructor(stdin, options = {}) {
2322
- super();
2323
- this.stdin = stdin;
2324
- this.timeoutMs = options.timeout ?? 10;
2325
- this.stdinListener = (data) => {
2326
- this.handleData(data);
2327
- };
2328
- this.stdin.on("data", this.stdinListener);
2329
- }
2330
- handleData(data) {
2331
- if (this.timeout) {
2332
- clearTimeout(this.timeout);
2333
- this.timeout = null;
2334
- }
2335
- let str;
2336
- if (Buffer.isBuffer(data)) {
2337
- if (data.length === 1 && data[0] > 127) {
2338
- const byte = data[0] - 128;
2339
- str = "\x1B" + String.fromCharCode(byte);
2340
- } else {
2341
- str = data.toString();
2342
- }
2343
- } else {
2344
- str = data;
2345
- }
2346
- if (str.length === 0 && this.buffer.length === 0) {
2347
- this.emit("data", "");
2348
- return;
2349
- }
2350
- this.buffer += str;
2351
- const result = extractCompleteSequences(this.buffer);
2352
- this.buffer = result.remainder;
2353
- for (const sequence of result.sequences) {
2354
- this.emit("data", sequence);
2355
- }
2356
- if (this.buffer.length > 0) {
2357
- this.timeout = setTimeout(() => {
2358
- const flushed = this.flush();
2359
- for (const sequence of flushed) {
2360
- this.emit("data", sequence);
2361
- }
2362
- }, this.timeoutMs);
2363
- }
2364
- }
2365
- flush() {
2366
- if (this.timeout) {
2367
- clearTimeout(this.timeout);
2368
- this.timeout = null;
2369
- }
2370
- if (this.buffer.length === 0) {
2371
- return [];
2372
- }
2373
- const sequences = [this.buffer];
2374
- this.buffer = "";
2375
- return sequences;
2376
- }
2377
- clear() {
2378
- if (this.timeout) {
2379
- clearTimeout(this.timeout);
2380
- this.timeout = null;
2381
- }
2382
- this.buffer = "";
2383
- }
2384
- getBuffer() {
2385
- return this.buffer;
2386
- }
2387
- destroy() {
2388
- this.stdin.removeListener("data", this.stdinListener);
2389
- this.clear();
2390
- }
2391
- }
2392
-
2393
- // src/lib/KeyHandler.ts
2394
- import { EventEmitter as EventEmitter2 } from "events";
2395
-
2396
- // src/ansi.ts
2397
- var ANSI = {
2398
- switchToAlternateScreen: "\x1B[?1049h",
2399
- switchToMainScreen: "\x1B[?1049l",
2400
- reset: "\x1B[0m",
2401
- scrollDown: (lines) => `\x1B[${lines}T`,
2402
- scrollUp: (lines) => `\x1B[${lines}S`,
2403
- moveCursor: (row, col) => `\x1B[${row};${col}H`,
2404
- moveCursorAndClear: (row, col) => `\x1B[${row};${col}H\x1B[J`,
2405
- setRgbBackground: (r, g, b) => `\x1B[48;2;${r};${g};${b}m`,
2406
- resetBackground: "\x1B[49m",
2407
- bracketedPasteStart: "\x1B[200~",
2408
- bracketedPasteEnd: "\x1B[201~"
2409
- };
2410
-
2411
2238
  // src/lib/KeyHandler.ts
2239
+ import { EventEmitter } from "events";
2412
2240
  class KeyEvent {
2413
2241
  name;
2414
2242
  ctrl;
@@ -2467,40 +2295,20 @@ class PasteEvent {
2467
2295
  }
2468
2296
  }
2469
2297
 
2470
- class KeyHandler extends EventEmitter2 {
2471
- stdin;
2298
+ class KeyHandler extends EventEmitter {
2472
2299
  useKittyKeyboard;
2473
- pasteMode = false;
2474
- pasteBuffer = [];
2475
2300
  suspended = false;
2476
- stdinBuffer;
2477
- dataListener;
2478
- constructor(stdin, useKittyKeyboard = false) {
2301
+ constructor(useKittyKeyboard = false) {
2479
2302
  super();
2480
- this.stdin = stdin || process.stdin;
2481
2303
  this.useKittyKeyboard = useKittyKeyboard;
2482
- this.stdinBuffer = new StdinBuffer(this.stdin, { timeout: 5 });
2483
- this.dataListener = (sequence) => {
2484
- this.processSequence(sequence);
2485
- };
2486
- this.stdinBuffer.on("data", this.dataListener);
2487
2304
  }
2488
- processSequence(data) {
2489
- if (data.startsWith(ANSI.bracketedPasteStart)) {
2490
- this.pasteMode = true;
2491
- }
2492
- if (this.pasteMode) {
2493
- this.pasteBuffer.push(Bun.stripANSI(data));
2494
- if (data.endsWith(ANSI.bracketedPasteEnd)) {
2495
- this.pasteMode = false;
2496
- this.emit("paste", new PasteEvent(this.pasteBuffer.join("")));
2497
- this.pasteBuffer = [];
2498
- }
2499
- return;
2305
+ processInput(data) {
2306
+ if (this.suspended) {
2307
+ return false;
2500
2308
  }
2501
2309
  const parsedKey = parseKeypress(data, { useKittyKeyboard: this.useKittyKeyboard });
2502
2310
  if (!parsedKey) {
2503
- return;
2311
+ return false;
2504
2312
  }
2505
2313
  switch (parsedKey.eventType) {
2506
2314
  case "press":
@@ -2516,29 +2324,27 @@ class KeyHandler extends EventEmitter2 {
2516
2324
  this.emit("keypress", new KeyEvent(parsedKey));
2517
2325
  break;
2518
2326
  }
2327
+ return true;
2519
2328
  }
2520
- destroy() {
2521
- this.stdinBuffer.removeListener("data", this.dataListener);
2522
- this.stdinBuffer.destroy();
2329
+ processPaste(data) {
2330
+ if (this.suspended) {
2331
+ return;
2332
+ }
2333
+ const cleanedData = Bun.stripANSI(data);
2334
+ this.emit("paste", new PasteEvent(cleanedData));
2523
2335
  }
2524
2336
  suspend() {
2525
- if (!this.suspended) {
2526
- this.suspended = true;
2527
- this.stdinBuffer.removeListener("data", this.dataListener);
2528
- }
2337
+ this.suspended = true;
2529
2338
  }
2530
2339
  resume() {
2531
- if (this.suspended) {
2532
- this.suspended = false;
2533
- this.stdinBuffer.on("data", this.dataListener);
2534
- }
2340
+ this.suspended = false;
2535
2341
  }
2536
2342
  }
2537
2343
 
2538
2344
  class InternalKeyHandler extends KeyHandler {
2539
2345
  renderableHandlers = new Map;
2540
- constructor(stdin, useKittyKeyboard = false) {
2541
- super(stdin, useKittyKeyboard);
2346
+ constructor(useKittyKeyboard = false) {
2347
+ super(useKittyKeyboard);
2542
2348
  }
2543
2349
  emit(event, ...args) {
2544
2350
  return this.emitWithPriority(event, ...args);
@@ -4608,6 +4414,246 @@ class MacOSScrollAccel {
4608
4414
  }
4609
4415
  }
4610
4416
 
4417
+ // src/lib/stdin-buffer.ts
4418
+ import { EventEmitter as EventEmitter2 } from "events";
4419
+ var ESC = "\x1B";
4420
+ var BRACKETED_PASTE_START = "\x1B[200~";
4421
+ var BRACKETED_PASTE_END = "\x1B[201~";
4422
+ function isCompleteSequence(data) {
4423
+ if (!data.startsWith(ESC)) {
4424
+ return "not-escape";
4425
+ }
4426
+ if (data.length === 1) {
4427
+ return "incomplete";
4428
+ }
4429
+ const afterEsc = data.slice(1);
4430
+ if (afterEsc.startsWith("[")) {
4431
+ if (afterEsc.startsWith("[M")) {
4432
+ return data.length >= 6 ? "complete" : "incomplete";
4433
+ }
4434
+ return isCompleteCsiSequence(data);
4435
+ }
4436
+ if (afterEsc.startsWith("]")) {
4437
+ return isCompleteOscSequence(data);
4438
+ }
4439
+ if (afterEsc.startsWith("P")) {
4440
+ return isCompleteDcsSequence(data);
4441
+ }
4442
+ if (afterEsc.startsWith("_")) {
4443
+ return isCompleteApcSequence(data);
4444
+ }
4445
+ if (afterEsc.startsWith("O")) {
4446
+ return afterEsc.length >= 2 ? "complete" : "incomplete";
4447
+ }
4448
+ if (afterEsc.length === 1) {
4449
+ return "complete";
4450
+ }
4451
+ return "complete";
4452
+ }
4453
+ function isCompleteCsiSequence(data) {
4454
+ if (!data.startsWith(ESC + "[")) {
4455
+ return "complete";
4456
+ }
4457
+ if (data.length < 3) {
4458
+ return "incomplete";
4459
+ }
4460
+ const payload = data.slice(2);
4461
+ const lastChar = payload[payload.length - 1];
4462
+ const lastCharCode = lastChar.charCodeAt(0);
4463
+ if (lastCharCode >= 64 && lastCharCode <= 126) {
4464
+ if (payload.startsWith("<")) {
4465
+ const mouseMatch = /^<\d+;\d+;\d+[Mm]$/.test(payload);
4466
+ if (mouseMatch) {
4467
+ return "complete";
4468
+ }
4469
+ if (lastChar === "M" || lastChar === "m") {
4470
+ const parts = payload.slice(1, -1).split(";");
4471
+ if (parts.length === 3 && parts.every((p) => /^\d+$/.test(p))) {
4472
+ return "complete";
4473
+ }
4474
+ }
4475
+ return "incomplete";
4476
+ }
4477
+ return "complete";
4478
+ }
4479
+ return "incomplete";
4480
+ }
4481
+ function isCompleteOscSequence(data) {
4482
+ if (!data.startsWith(ESC + "]")) {
4483
+ return "complete";
4484
+ }
4485
+ if (data.endsWith(ESC + "\\") || data.endsWith("\x07")) {
4486
+ return "complete";
4487
+ }
4488
+ return "incomplete";
4489
+ }
4490
+ function isCompleteDcsSequence(data) {
4491
+ if (!data.startsWith(ESC + "P")) {
4492
+ return "complete";
4493
+ }
4494
+ if (data.endsWith(ESC + "\\")) {
4495
+ return "complete";
4496
+ }
4497
+ return "incomplete";
4498
+ }
4499
+ function isCompleteApcSequence(data) {
4500
+ if (!data.startsWith(ESC + "_")) {
4501
+ return "complete";
4502
+ }
4503
+ if (data.endsWith(ESC + "\\")) {
4504
+ return "complete";
4505
+ }
4506
+ return "incomplete";
4507
+ }
4508
+ function extractCompleteSequences(buffer) {
4509
+ const sequences = [];
4510
+ let pos = 0;
4511
+ while (pos < buffer.length) {
4512
+ const remaining = buffer.slice(pos);
4513
+ if (remaining.startsWith(ESC)) {
4514
+ let seqEnd = 1;
4515
+ while (seqEnd <= remaining.length) {
4516
+ const candidate = remaining.slice(0, seqEnd);
4517
+ const status = isCompleteSequence(candidate);
4518
+ if (status === "complete") {
4519
+ sequences.push(candidate);
4520
+ pos += seqEnd;
4521
+ break;
4522
+ } else if (status === "incomplete") {
4523
+ seqEnd++;
4524
+ } else {
4525
+ sequences.push(candidate);
4526
+ pos += seqEnd;
4527
+ break;
4528
+ }
4529
+ }
4530
+ if (seqEnd > remaining.length) {
4531
+ return { sequences, remainder: remaining };
4532
+ }
4533
+ } else {
4534
+ sequences.push(remaining[0]);
4535
+ pos++;
4536
+ }
4537
+ }
4538
+ return { sequences, remainder: "" };
4539
+ }
4540
+
4541
+ class StdinBuffer extends EventEmitter2 {
4542
+ buffer = "";
4543
+ timeout = null;
4544
+ timeoutMs;
4545
+ pasteMode = false;
4546
+ pasteBuffer = "";
4547
+ constructor(options = {}) {
4548
+ super();
4549
+ this.timeoutMs = options.timeout ?? 10;
4550
+ }
4551
+ process(data) {
4552
+ if (this.timeout) {
4553
+ clearTimeout(this.timeout);
4554
+ this.timeout = null;
4555
+ }
4556
+ let str;
4557
+ if (Buffer.isBuffer(data)) {
4558
+ if (data.length === 1 && data[0] > 127) {
4559
+ const byte = data[0] - 128;
4560
+ str = "\x1B" + String.fromCharCode(byte);
4561
+ } else {
4562
+ str = data.toString();
4563
+ }
4564
+ } else {
4565
+ str = data;
4566
+ }
4567
+ if (str.length === 0 && this.buffer.length === 0) {
4568
+ this.emit("data", "");
4569
+ return;
4570
+ }
4571
+ this.buffer += str;
4572
+ if (this.pasteMode) {
4573
+ this.pasteBuffer += this.buffer;
4574
+ this.buffer = "";
4575
+ const endIndex = this.pasteBuffer.indexOf(BRACKETED_PASTE_END);
4576
+ if (endIndex !== -1) {
4577
+ const pastedContent = this.pasteBuffer.slice(0, endIndex);
4578
+ const remaining = this.pasteBuffer.slice(endIndex + BRACKETED_PASTE_END.length);
4579
+ this.pasteMode = false;
4580
+ this.pasteBuffer = "";
4581
+ this.emit("paste", pastedContent);
4582
+ if (remaining.length > 0) {
4583
+ this.process(remaining);
4584
+ }
4585
+ }
4586
+ return;
4587
+ }
4588
+ const startIndex = this.buffer.indexOf(BRACKETED_PASTE_START);
4589
+ if (startIndex !== -1) {
4590
+ if (startIndex > 0) {
4591
+ const beforePaste = this.buffer.slice(0, startIndex);
4592
+ const result2 = extractCompleteSequences(beforePaste);
4593
+ for (const sequence of result2.sequences) {
4594
+ this.emit("data", sequence);
4595
+ }
4596
+ }
4597
+ this.buffer = this.buffer.slice(startIndex + BRACKETED_PASTE_START.length);
4598
+ this.pasteMode = true;
4599
+ this.pasteBuffer = this.buffer;
4600
+ this.buffer = "";
4601
+ const endIndex = this.pasteBuffer.indexOf(BRACKETED_PASTE_END);
4602
+ if (endIndex !== -1) {
4603
+ const pastedContent = this.pasteBuffer.slice(0, endIndex);
4604
+ const remaining = this.pasteBuffer.slice(endIndex + BRACKETED_PASTE_END.length);
4605
+ this.pasteMode = false;
4606
+ this.pasteBuffer = "";
4607
+ this.emit("paste", pastedContent);
4608
+ if (remaining.length > 0) {
4609
+ this.process(remaining);
4610
+ }
4611
+ }
4612
+ return;
4613
+ }
4614
+ const result = extractCompleteSequences(this.buffer);
4615
+ this.buffer = result.remainder;
4616
+ for (const sequence of result.sequences) {
4617
+ this.emit("data", sequence);
4618
+ }
4619
+ if (this.buffer.length > 0) {
4620
+ this.timeout = setTimeout(() => {
4621
+ const flushed = this.flush();
4622
+ for (const sequence of flushed) {
4623
+ this.emit("data", sequence);
4624
+ }
4625
+ }, this.timeoutMs);
4626
+ }
4627
+ }
4628
+ flush() {
4629
+ if (this.timeout) {
4630
+ clearTimeout(this.timeout);
4631
+ this.timeout = null;
4632
+ }
4633
+ if (this.buffer.length === 0) {
4634
+ return [];
4635
+ }
4636
+ const sequences = [this.buffer];
4637
+ this.buffer = "";
4638
+ return sequences;
4639
+ }
4640
+ clear() {
4641
+ if (this.timeout) {
4642
+ clearTimeout(this.timeout);
4643
+ this.timeout = null;
4644
+ }
4645
+ this.buffer = "";
4646
+ this.pasteMode = false;
4647
+ this.pasteBuffer = "";
4648
+ }
4649
+ getBuffer() {
4650
+ return this.buffer;
4651
+ }
4652
+ destroy() {
4653
+ this.clear();
4654
+ }
4655
+ }
4656
+
4611
4657
  // src/lib/yoga.options.ts
4612
4658
  function parseAlign(value) {
4613
4659
  if (value == null) {
@@ -7889,6 +7935,23 @@ function isObjectPointerDef(type) {
7889
7935
  function alignOffset(offset, align) {
7890
7936
  return offset + (align - 1) & ~(align - 1);
7891
7937
  }
7938
+ function enumTypeError(value) {
7939
+ throw new TypeError(`Invalid enum value: ${value}`);
7940
+ }
7941
+ function defineEnum(mapping, base = "u32") {
7942
+ const reverse2 = Object.fromEntries(Object.entries(mapping).map(([k, v]) => [v, k]));
7943
+ return {
7944
+ __type: "enum",
7945
+ type: base,
7946
+ to(value) {
7947
+ return typeof value === "number" ? value : mapping[value] ?? enumTypeError(String(value));
7948
+ },
7949
+ from(value) {
7950
+ return reverse2[value] ?? enumTypeError(String(value));
7951
+ },
7952
+ enum: mapping
7953
+ };
7954
+ }
7892
7955
  function isEnum(type) {
7893
7956
  return typeof type === "object" && type.__type === "enum";
7894
7957
  }
@@ -7965,6 +8028,7 @@ function packObjectArray(val) {
7965
8028
  return bufferView;
7966
8029
  }
7967
8030
  var encoder = new TextEncoder;
8031
+ var decoder = new TextDecoder;
7968
8032
  function defineStruct(fields, structDefOptions) {
7969
8033
  let offset = 0;
7970
8034
  let maxAlign = 1;
@@ -8007,6 +8071,7 @@ function defineStruct(fields, structDefOptions) {
8007
8071
  const ptrVal = pointerUnpacker(view, off);
8008
8072
  return ptrVal;
8009
8073
  };
8074
+ needsLengthOf = true;
8010
8075
  } else if (isEnum(typeOrStruct)) {
8011
8076
  const base = typeOrStruct.type;
8012
8077
  size = typeSizes[base];
@@ -8209,9 +8274,10 @@ function defineStruct(fields, structDefOptions) {
8209
8274
  lengthOfFields[options.lengthOf] = layoutField;
8210
8275
  }
8211
8276
  if (needsLengthOf) {
8212
- if (!lengthOfDef)
8213
- fatalError(`Internal error: needsLengthOf=true but lengthOfDef is null for ${name}`);
8214
- lengthOfRequested.push({ requester: layoutField, def: lengthOfDef });
8277
+ const def = typeof typeOrStruct === "string" && typeOrStruct === "char*" ? "char*" : lengthOfDef;
8278
+ if (!def)
8279
+ fatalError(`Internal error: needsLengthOf=true but def is null for ${name}`);
8280
+ lengthOfRequested.push({ requester: layoutField, def });
8215
8281
  }
8216
8282
  offset += size;
8217
8283
  maxAlign = Math.max(maxAlign, align);
@@ -8219,9 +8285,26 @@ function defineStruct(fields, structDefOptions) {
8219
8285
  for (const { requester, def } of lengthOfRequested) {
8220
8286
  const lengthOfField = lengthOfFields[requester.name];
8221
8287
  if (!lengthOfField) {
8288
+ if (def === "char*") {
8289
+ continue;
8290
+ }
8222
8291
  throw new Error(`lengthOf field not found for array field ${requester.name}`);
8223
8292
  }
8224
- if (isPrimitiveType(def)) {
8293
+ if (def === "char*") {
8294
+ requester.unpack = (view, off) => {
8295
+ const ptrAddress = pointerUnpacker(view, off);
8296
+ const length = lengthOfField.unpack(view, lengthOfField.offset);
8297
+ if (ptrAddress === 0) {
8298
+ return null;
8299
+ }
8300
+ const byteLength = typeof length === "bigint" ? Number(length) : length;
8301
+ if (byteLength === 0) {
8302
+ return "";
8303
+ }
8304
+ const buffer = toArrayBuffer2(ptrAddress, 0, byteLength);
8305
+ return decoder.decode(buffer);
8306
+ };
8307
+ } else if (isPrimitiveType(def)) {
8225
8308
  const elemSize = typeSizes[def];
8226
8309
  const { unpack: primitiveUnpack } = primitivePackers(def);
8227
8310
  requester.unpack = (view, off) => {
@@ -8461,6 +8544,27 @@ var VisualCursorStruct = defineStruct([
8461
8544
  ["logicalCol", "u32"],
8462
8545
  ["offset", "u32"]
8463
8546
  ]);
8547
+ var UnicodeMethodEnum = defineEnum({ wcwidth: 0, unicode: 1 }, "u8");
8548
+ var TerminalCapabilitiesStruct = defineStruct([
8549
+ ["kitty_keyboard", "bool_u8"],
8550
+ ["kitty_graphics", "bool_u8"],
8551
+ ["rgb", "bool_u8"],
8552
+ ["unicode", UnicodeMethodEnum],
8553
+ ["sgr_pixels", "bool_u8"],
8554
+ ["color_scheme_updates", "bool_u8"],
8555
+ ["explicit_width", "bool_u8"],
8556
+ ["scaled_text", "bool_u8"],
8557
+ ["sixel", "bool_u8"],
8558
+ ["focus_tracking", "bool_u8"],
8559
+ ["sync", "bool_u8"],
8560
+ ["bracketed_paste", "bool_u8"],
8561
+ ["hyperlinks", "bool_u8"],
8562
+ ["term_name", "char*"],
8563
+ ["term_name_len", "u64", { lengthOf: "term_name" }],
8564
+ ["term_version", "char*"],
8565
+ ["term_version_len", "u64", { lengthOf: "term_version" }],
8566
+ ["term_from_xtversion", "bool_u8"]
8567
+ ]);
8464
8568
 
8465
8569
  // src/zig.ts
8466
8570
  var module = await import(`@opentui/core-${process.platform}-${process.arch}/index.ts`);
@@ -10290,25 +10394,29 @@ class FFIRenderLib {
10290
10394
  this.opentui.symbols.bufferClearScissorRects(buffer);
10291
10395
  }
10292
10396
  getTerminalCapabilities(renderer) {
10293
- const capsBuffer = new Uint8Array(64);
10294
- this.opentui.symbols.getTerminalCapabilities(renderer, capsBuffer);
10295
- let offset = 0;
10296
- const capabilities = {
10297
- kitty_keyboard: capsBuffer[offset++] !== 0,
10298
- kitty_graphics: capsBuffer[offset++] !== 0,
10299
- rgb: capsBuffer[offset++] !== 0,
10300
- unicode: capsBuffer[offset++] === 0 ? "wcwidth" : "unicode",
10301
- sgr_pixels: capsBuffer[offset++] !== 0,
10302
- color_scheme_updates: capsBuffer[offset++] !== 0,
10303
- explicit_width: capsBuffer[offset++] !== 0,
10304
- scaled_text: capsBuffer[offset++] !== 0,
10305
- sixel: capsBuffer[offset++] !== 0,
10306
- focus_tracking: capsBuffer[offset++] !== 0,
10307
- sync: capsBuffer[offset++] !== 0,
10308
- bracketed_paste: capsBuffer[offset++] !== 0,
10309
- hyperlinks: capsBuffer[offset++] !== 0
10397
+ const capsBuffer = new ArrayBuffer(TerminalCapabilitiesStruct.size);
10398
+ this.opentui.symbols.getTerminalCapabilities(renderer, ptr3(capsBuffer));
10399
+ const caps = TerminalCapabilitiesStruct.unpack(capsBuffer);
10400
+ return {
10401
+ kitty_keyboard: caps.kitty_keyboard,
10402
+ kitty_graphics: caps.kitty_graphics,
10403
+ rgb: caps.rgb,
10404
+ unicode: caps.unicode,
10405
+ sgr_pixels: caps.sgr_pixels,
10406
+ color_scheme_updates: caps.color_scheme_updates,
10407
+ explicit_width: caps.explicit_width,
10408
+ scaled_text: caps.scaled_text,
10409
+ sixel: caps.sixel,
10410
+ focus_tracking: caps.focus_tracking,
10411
+ sync: caps.sync,
10412
+ bracketed_paste: caps.bracketed_paste,
10413
+ hyperlinks: caps.hyperlinks,
10414
+ terminal: {
10415
+ name: caps.term_name ?? "",
10416
+ version: caps.term_version ?? "",
10417
+ from_xtversion: caps.term_from_xtversion
10418
+ }
10310
10419
  };
10311
- return capabilities;
10312
10420
  }
10313
10421
  processCapabilityResponse(renderer, response) {
10314
10422
  const responseBytes = this.encoder.encode(response);
@@ -12634,6 +12742,21 @@ class TerminalConsole extends EventEmitter8 {
12634
12742
  }
12635
12743
  }
12636
12744
 
12745
+ // src/ansi.ts
12746
+ var ANSI = {
12747
+ switchToAlternateScreen: "\x1B[?1049h",
12748
+ switchToMainScreen: "\x1B[?1049l",
12749
+ reset: "\x1B[0m",
12750
+ scrollDown: (lines) => `\x1B[${lines}T`,
12751
+ scrollUp: (lines) => `\x1B[${lines}S`,
12752
+ moveCursor: (row, col) => `\x1B[${row};${col}H`,
12753
+ moveCursorAndClear: (row, col) => `\x1B[${row};${col}H\x1B[J`,
12754
+ setRgbBackground: (r, g, b) => `\x1B[48;2;${r};${g};${b}m`,
12755
+ resetBackground: "\x1B[49m",
12756
+ bracketedPasteStart: "\x1B[200~",
12757
+ bracketedPasteEnd: "\x1B[201~"
12758
+ };
12759
+
12637
12760
  // src/renderer.ts
12638
12761
  import { EventEmitter as EventEmitter9 } from "events";
12639
12762
 
@@ -12727,6 +12850,42 @@ function getObjectsInViewport(viewport, objects, direction = "column", padding =
12727
12850
  return visibleChildren;
12728
12851
  }
12729
12852
 
12853
+ // src/lib/terminal-capability-detection.ts
12854
+ function isCapabilityResponse(sequence) {
12855
+ if (/\x1b\[\?\d+(?:;\d+)*\$y/.test(sequence)) {
12856
+ return true;
12857
+ }
12858
+ if (/\x1b\[1;(?!1R)\d+R/.test(sequence)) {
12859
+ return true;
12860
+ }
12861
+ if (/\x1bP>\|[\s\S]*?\x1b\\/.test(sequence)) {
12862
+ return true;
12863
+ }
12864
+ if (/\x1b_G[\s\S]*?\x1b\\/.test(sequence)) {
12865
+ return true;
12866
+ }
12867
+ if (/\x1b\[\?\d+(?:;\d+)?u/.test(sequence)) {
12868
+ return true;
12869
+ }
12870
+ if (/\x1b\[\?[0-9;]*c/.test(sequence)) {
12871
+ return true;
12872
+ }
12873
+ return false;
12874
+ }
12875
+ function isPixelResolutionResponse(sequence) {
12876
+ return /\x1b\[4;\d+;\d+t/.test(sequence);
12877
+ }
12878
+ function parsePixelResolution(sequence) {
12879
+ const match = sequence.match(/\x1b\[4;(\d+);(\d+)t/);
12880
+ if (match) {
12881
+ return {
12882
+ width: parseInt(match[2]),
12883
+ height: parseInt(match[1])
12884
+ };
12885
+ }
12886
+ return null;
12887
+ }
12888
+
12730
12889
  // src/renderer.ts
12731
12890
  registerEnvVar({
12732
12891
  name: "OTUI_DUMP_CAPTURES",
@@ -12919,6 +13078,7 @@ class CliRenderer extends EventEmitter9 {
12919
13078
  _console;
12920
13079
  _resolution = null;
12921
13080
  _keyHandler;
13081
+ _stdinBuffer;
12922
13082
  animationRequest = new Map;
12923
13083
  resizeTimeoutId = null;
12924
13084
  resizeDebounceDelay = 100;
@@ -12958,6 +13118,8 @@ class CliRenderer extends EventEmitter9 {
12958
13118
  _paletteDetector = null;
12959
13119
  _cachedPalette = null;
12960
13120
  _paletteDetectionPromise = null;
13121
+ inputHandlers = [];
13122
+ prependedInputHandlers = [];
12961
13123
  handleError = ((error) => {
12962
13124
  console.error(error);
12963
13125
  if (this._openConsoleOnError) {
@@ -13031,6 +13193,7 @@ Captured output:
13031
13193
  this.nextRenderBuffer = this.lib.getNextBuffer(this.rendererPtr);
13032
13194
  this.currentRenderBuffer = this.lib.getCurrentBuffer(this.rendererPtr);
13033
13195
  this.postProcessFns = config.postProcessFns || [];
13196
+ this.prependedInputHandlers = config.prependInputHandlers || [];
13034
13197
  this.root = new RootRenderable(this);
13035
13198
  if (this.memorySnapshotInterval > 0) {
13036
13199
  this.startMemorySnapshotTimer();
@@ -13043,7 +13206,7 @@ Captured output:
13043
13206
  process.on("uncaughtException", this.handleError);
13044
13207
  process.on("unhandledRejection", this.handleError);
13045
13208
  process.on("exit", this.exitHandler);
13046
- this._keyHandler = new InternalKeyHandler(this.stdin, config.useKittyKeyboard ?? true);
13209
+ this._keyHandler = new InternalKeyHandler(config.useKittyKeyboard ?? true);
13047
13210
  this._keyHandler.on("keypress", (event) => {
13048
13211
  if (this.exitOnCtrlC && event.name === "c" && event.ctrl) {
13049
13212
  process.nextTick(() => {
@@ -13052,6 +13215,7 @@ Captured output:
13052
13215
  return;
13053
13216
  }
13054
13217
  });
13218
+ this._stdinBuffer = new StdinBuffer({ timeout: 5 });
13055
13219
  this._console = new TerminalConsole(this, config.consoleOptions);
13056
13220
  this.useConsole = config.useConsole ?? true;
13057
13221
  this._openConsoleOnError = config.openConsoleOnError ?? true;
@@ -13286,52 +13450,86 @@ Captured output:
13286
13450
  if (this._terminalIsSetup)
13287
13451
  return;
13288
13452
  this._terminalIsSetup = true;
13289
- await new Promise((resolve4) => {
13290
- const timeout = setTimeout(() => {
13291
- this.stdin.off("data", capListener);
13292
- resolve4(true);
13293
- }, 100);
13294
- const capListener = (str) => {
13295
- clearTimeout(timeout);
13296
- this.lib.processCapabilityResponse(this.rendererPtr, str);
13297
- this.stdin.off("data", capListener);
13298
- resolve4(true);
13299
- };
13300
- this.stdin.on("data", capListener);
13301
- this.lib.setupTerminal(this.rendererPtr, this._useAlternateScreen);
13302
- });
13453
+ this.lib.setupTerminal(this.rendererPtr, this._useAlternateScreen);
13303
13454
  this._capabilities = this.lib.getTerminalCapabilities(this.rendererPtr);
13455
+ setTimeout(() => {
13456
+ this.removeInputHandler(this.capabilityHandler);
13457
+ }, 5000);
13304
13458
  if (this._useMouse) {
13305
13459
  this.enableMouse();
13306
13460
  }
13307
13461
  this.queryPixelResolution();
13308
13462
  }
13309
13463
  stdinListener = ((data) => {
13310
- const str = data.toString();
13311
- if (this.waitingForPixelResolution && /\x1b\[4;\d+;\d+t/.test(str)) {
13312
- const match = str.match(/\x1b\[4;(\d+);(\d+)t/);
13313
- if (match) {
13314
- const resolution = {
13315
- width: parseInt(match[2]),
13316
- height: parseInt(match[1])
13317
- };
13318
- this._resolution = resolution;
13319
- this.waitingForPixelResolution = false;
13320
- return;
13321
- }
13322
- }
13323
13464
  if (this._useMouse && this.handleMouseData(data)) {
13324
13465
  return;
13325
13466
  }
13326
- this.emit("key", data);
13467
+ this._stdinBuffer.process(data);
13468
+ }).bind(this);
13469
+ addInputHandler(handler) {
13470
+ this.inputHandlers.push(handler);
13471
+ }
13472
+ prependInputHandler(handler) {
13473
+ this.inputHandlers.unshift(handler);
13474
+ }
13475
+ removeInputHandler(handler) {
13476
+ this.inputHandlers = this.inputHandlers.filter((h2) => h2 !== handler);
13477
+ }
13478
+ capabilityHandler = ((sequence) => {
13479
+ if (isCapabilityResponse(sequence)) {
13480
+ this.lib.processCapabilityResponse(this.rendererPtr, sequence);
13481
+ this._capabilities = this.lib.getTerminalCapabilities(this.rendererPtr);
13482
+ return true;
13483
+ }
13484
+ return false;
13485
+ }).bind(this);
13486
+ focusHandler = ((sequence) => {
13487
+ if (sequence === "\x1B[I") {
13488
+ this.emit("focus");
13489
+ return true;
13490
+ }
13491
+ if (sequence === "\x1B[O") {
13492
+ this.emit("blur");
13493
+ return true;
13494
+ }
13495
+ return false;
13327
13496
  }).bind(this);
13328
13497
  setupInput() {
13498
+ for (const handler of this.prependedInputHandlers) {
13499
+ this.addInputHandler(handler);
13500
+ }
13501
+ this.addInputHandler((sequence) => {
13502
+ if (isPixelResolutionResponse(sequence) && this.waitingForPixelResolution) {
13503
+ const resolution = parsePixelResolution(sequence);
13504
+ if (resolution) {
13505
+ this._resolution = resolution;
13506
+ this.waitingForPixelResolution = false;
13507
+ }
13508
+ return true;
13509
+ }
13510
+ return false;
13511
+ });
13512
+ this.addInputHandler(this.capabilityHandler);
13513
+ this.addInputHandler(this.focusHandler);
13514
+ this.addInputHandler((sequence) => {
13515
+ return this._keyHandler.processInput(sequence);
13516
+ });
13329
13517
  if (this.stdin.setRawMode) {
13330
13518
  this.stdin.setRawMode(true);
13331
13519
  }
13332
13520
  this.stdin.resume();
13333
13521
  this.stdin.setEncoding("utf8");
13334
13522
  this.stdin.on("data", this.stdinListener);
13523
+ this._stdinBuffer.on("data", (sequence) => {
13524
+ for (const handler of this.inputHandlers) {
13525
+ if (handler(sequence)) {
13526
+ return;
13527
+ }
13528
+ }
13529
+ });
13530
+ this._stdinBuffer.on("paste", (data) => {
13531
+ this._keyHandler.processPaste(data);
13532
+ });
13335
13533
  }
13336
13534
  handleMouseData(data) {
13337
13535
  const mouseEvent = this.mouseParser.parseMouseEvent(data);
@@ -13657,6 +13855,7 @@ Captured output:
13657
13855
  this._suspendedMouseEnabled = this._useMouse;
13658
13856
  this.disableMouse();
13659
13857
  this._keyHandler.suspend();
13858
+ this._stdinBuffer.clear();
13660
13859
  if (this.stdin.setRawMode) {
13661
13860
  this.stdin.setRawMode(false);
13662
13861
  }
@@ -13726,7 +13925,7 @@ Captured output:
13726
13925
  } catch (e) {
13727
13926
  console.error("Error destroying root renderable:", e instanceof Error ? e.stack : String(e));
13728
13927
  }
13729
- this._keyHandler.destroy();
13928
+ this._stdinBuffer.destroy();
13730
13929
  this._console.deactivate();
13731
13930
  this.disableStdoutInterception();
13732
13931
  if (this._splitHeight > 0) {
@@ -13999,7 +14198,7 @@ Captured output:
13999
14198
  }
14000
14199
  }
14001
14200
 
14002
- 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, TerminalPalette, createTerminalPalette, 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 };
14201
+ export { __toESM, __commonJS, __export, __require, Edge, Gutter, exports_src, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, nonAlphanumericKeys, parseKeypress, 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, StdinBuffer, 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, TerminalPalette, createTerminalPalette, TextBuffer, LogLevel2 as LogLevel, setRenderLibPath, resolveRenderLib, OptimizedBuffer, h, isVNode, maybeMakeRenderable, wrapWithDelegates, instantiate, delegate, isValidPercentage, LayoutEvents, RenderableEvents, isRenderable, BaseRenderable, Renderable, RootRenderable, ANSI, capture, ConsolePosition, TerminalConsole, getObjectsInViewport, MouseEvent, MouseButton, createCliRenderer, CliRenderEvents, RendererControlState, CliRenderer };
14003
14202
 
14004
- //# debugId=FE3334220FB993E564756E2164756E21
14005
- //# sourceMappingURL=index-z5bb2h2z.js.map
14203
+ //# debugId=7BD9FAB5ED52E27064756E2164756E21
14204
+ //# sourceMappingURL=index-kj9k00yt.js.map