@opentui/core 0.1.38 → 0.1.40

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.
@@ -27,7 +27,7 @@ var __export = (target, all) => {
27
27
  };
28
28
  var __require = import.meta.require;
29
29
 
30
- // ../../node_modules/.bun/yoga-layout@3.2.1/node_modules/yoga-layout/dist/src/index.js
30
+ // ../../node_modules/yoga-layout/dist/src/index.js
31
31
  var exports_src = {};
32
32
  __export(exports_src, {
33
33
  default: () => src_default,
@@ -51,7 +51,7 @@ __export(exports_src, {
51
51
  Align: () => Align
52
52
  });
53
53
 
54
- // ../../node_modules/.bun/yoga-layout@3.2.1/node_modules/yoga-layout/dist/binaries/yoga-wasm-base64-esm.js
54
+ // ../../node_modules/yoga-layout/dist/binaries/yoga-wasm-base64-esm.js
55
55
  var loadYoga = (() => {
56
56
  var _scriptDir = import.meta.url;
57
57
  return function(loadYoga2) {
@@ -1356,7 +1356,7 @@ var loadYoga = (() => {
1356
1356
  })();
1357
1357
  var yoga_wasm_base64_esm_default = loadYoga;
1358
1358
 
1359
- // ../../node_modules/.bun/yoga-layout@3.2.1/node_modules/yoga-layout/dist/src/generated/YGEnums.js
1359
+ // ../../node_modules/yoga-layout/dist/src/generated/YGEnums.js
1360
1360
  var Align = /* @__PURE__ */ function(Align2) {
1361
1361
  Align2[Align2["Auto"] = 0] = "Auto";
1362
1362
  Align2[Align2["FlexStart"] = 1] = "FlexStart";
@@ -1559,7 +1559,7 @@ var constants = {
1559
1559
  };
1560
1560
  var YGEnums_default = constants;
1561
1561
 
1562
- // ../../node_modules/.bun/yoga-layout@3.2.1/node_modules/yoga-layout/dist/src/wrapAssembly.js
1562
+ // ../../node_modules/yoga-layout/dist/src/wrapAssembly.js
1563
1563
  function wrapAssembly(lib) {
1564
1564
  function patch(prototype, name, fn) {
1565
1565
  const original = prototype[name];
@@ -1661,7 +1661,7 @@ function wrapAssembly(lib) {
1661
1661
  };
1662
1662
  }
1663
1663
 
1664
- // ../../node_modules/.bun/yoga-layout@3.2.1/node_modules/yoga-layout/dist/src/index.js
1664
+ // ../../node_modules/yoga-layout/dist/src/index.js
1665
1665
  var Yoga = wrapAssembly(await yoga_wasm_base64_esm_default());
1666
1666
  var src_default = Yoga;
1667
1667
 
@@ -2079,6 +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 modifyOtherKeysRe = /^\x1b\[27;(\d+);(\d+)~$/;
2082
2083
  var parseKeypress = (s = "", options = {}) => {
2083
2084
  let parts;
2084
2085
  if (Buffer2.isBuffer(s)) {
@@ -2099,6 +2100,27 @@ var parseKeypress = (s = "", options = {}) => {
2099
2100
  if (s.startsWith("\x1B[M") && s.length >= 6) {
2100
2101
  return null;
2101
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
+ }
2102
2124
  const key = {
2103
2125
  name: "",
2104
2126
  ctrl: false,
@@ -2118,6 +2140,29 @@ var parseKeypress = (s = "", options = {}) => {
2118
2140
  return kittyResult;
2119
2141
  }
2120
2142
  }
2143
+ const modifyOtherKeysMatch = modifyOtherKeysRe.exec(s);
2144
+ if (modifyOtherKeysMatch) {
2145
+ const modifier = parseInt(modifyOtherKeysMatch[1], 10) - 1;
2146
+ const charCode = parseInt(modifyOtherKeysMatch[2], 10);
2147
+ key.ctrl = !!(modifier & 4);
2148
+ key.meta = !!(modifier & 10);
2149
+ key.shift = !!(modifier & 1);
2150
+ key.option = !!(modifier & 2);
2151
+ if (charCode === 13) {
2152
+ key.name = "return";
2153
+ } else if (charCode === 27) {
2154
+ key.name = "escape";
2155
+ } else if (charCode === 9) {
2156
+ key.name = "tab";
2157
+ } else if (charCode === 32) {
2158
+ key.name = "space";
2159
+ } else if (charCode === 127 || charCode === 8) {
2160
+ key.name = "backspace";
2161
+ } else {
2162
+ key.name = String.fromCharCode(charCode);
2163
+ }
2164
+ return key;
2165
+ }
2121
2166
  if (s === "\r" || s === "\x1B\r") {
2122
2167
  key.name = "return";
2123
2168
  key.meta = s.length === 2;
@@ -2190,201 +2235,8 @@ var parseKeypress = (s = "", options = {}) => {
2190
2235
  return key;
2191
2236
  };
2192
2237
 
2193
- // src/lib/stdin-buffer.ts
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";
2371
-
2372
- // src/ansi.ts
2373
- var ANSI = {
2374
- switchToAlternateScreen: "\x1B[?1049h",
2375
- switchToMainScreen: "\x1B[?1049l",
2376
- reset: "\x1B[0m",
2377
- scrollDown: (lines) => `\x1B[${lines}T`,
2378
- scrollUp: (lines) => `\x1B[${lines}S`,
2379
- moveCursor: (row, col) => `\x1B[${row};${col}H`,
2380
- moveCursorAndClear: (row, col) => `\x1B[${row};${col}H\x1B[J`,
2381
- setRgbBackground: (r, g, b) => `\x1B[48;2;${r};${g};${b}m`,
2382
- resetBackground: "\x1B[49m",
2383
- bracketedPasteStart: "\x1B[200~",
2384
- bracketedPasteEnd: "\x1B[201~"
2385
- };
2386
-
2387
2238
  // src/lib/KeyHandler.ts
2239
+ import { EventEmitter } from "events";
2388
2240
  class KeyEvent {
2389
2241
  name;
2390
2242
  ctrl;
@@ -2443,40 +2295,20 @@ class PasteEvent {
2443
2295
  }
2444
2296
  }
2445
2297
 
2446
- class KeyHandler extends EventEmitter2 {
2447
- stdin;
2298
+ class KeyHandler extends EventEmitter {
2448
2299
  useKittyKeyboard;
2449
- pasteMode = false;
2450
- pasteBuffer = [];
2451
2300
  suspended = false;
2452
- stdinBuffer;
2453
- dataListener;
2454
- constructor(stdin, useKittyKeyboard = false) {
2301
+ constructor(useKittyKeyboard = false) {
2455
2302
  super();
2456
- this.stdin = stdin || process.stdin;
2457
2303
  this.useKittyKeyboard = useKittyKeyboard;
2458
- this.stdinBuffer = new StdinBuffer(this.stdin, { timeout: 5 });
2459
- this.dataListener = (sequence) => {
2460
- this.processSequence(sequence);
2461
- };
2462
- this.stdinBuffer.on("data", this.dataListener);
2463
2304
  }
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;
2305
+ processInput(data) {
2306
+ if (this.suspended) {
2307
+ return false;
2476
2308
  }
2477
2309
  const parsedKey = parseKeypress(data, { useKittyKeyboard: this.useKittyKeyboard });
2478
2310
  if (!parsedKey) {
2479
- return;
2311
+ return false;
2480
2312
  }
2481
2313
  switch (parsedKey.eventType) {
2482
2314
  case "press":
@@ -2492,29 +2324,27 @@ class KeyHandler extends EventEmitter2 {
2492
2324
  this.emit("keypress", new KeyEvent(parsedKey));
2493
2325
  break;
2494
2326
  }
2327
+ return true;
2495
2328
  }
2496
- destroy() {
2497
- this.stdinBuffer.removeListener("data", this.dataListener);
2498
- 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));
2499
2335
  }
2500
2336
  suspend() {
2501
- if (!this.suspended) {
2502
- this.suspended = true;
2503
- this.stdinBuffer.removeListener("data", this.dataListener);
2504
- }
2337
+ this.suspended = true;
2505
2338
  }
2506
2339
  resume() {
2507
- if (this.suspended) {
2508
- this.suspended = false;
2509
- this.stdinBuffer.on("data", this.dataListener);
2510
- }
2340
+ this.suspended = false;
2511
2341
  }
2512
2342
  }
2513
2343
 
2514
2344
  class InternalKeyHandler extends KeyHandler {
2515
2345
  renderableHandlers = new Map;
2516
- constructor(stdin, useKittyKeyboard = false) {
2517
- super(stdin, useKittyKeyboard);
2346
+ constructor(useKittyKeyboard = false) {
2347
+ super(useKittyKeyboard);
2518
2348
  }
2519
2349
  emit(event, ...args) {
2520
2350
  return this.emitWithPriority(event, ...args);
@@ -4500,87 +4330,327 @@ function t(strings, ...values) {
4500
4330
  });
4501
4331
  }
4502
4332
  }
4503
- return new StyledText(chunks);
4333
+ return new StyledText(chunks);
4334
+ }
4335
+
4336
+ // src/lib/hast-styled-text.ts
4337
+ function hastToTextChunks(node, syntaxStyle, parentStyles = []) {
4338
+ const chunks = [];
4339
+ if (node.type === "text") {
4340
+ const stylesToMerge = parentStyles.length > 0 ? parentStyles : ["default"];
4341
+ const mergedStyle = syntaxStyle.mergeStyles(...stylesToMerge);
4342
+ chunks.push({
4343
+ __isChunk: true,
4344
+ text: node.value,
4345
+ fg: mergedStyle.fg,
4346
+ bg: mergedStyle.bg,
4347
+ attributes: mergedStyle.attributes
4348
+ });
4349
+ } else if (node.type === "element") {
4350
+ let currentStyles = [...parentStyles];
4351
+ if (node.properties?.className) {
4352
+ const classes = node.properties.className.split(" ");
4353
+ for (const cls of classes) {
4354
+ currentStyles.push(cls);
4355
+ }
4356
+ }
4357
+ for (const child of node.children) {
4358
+ chunks.push(...hastToTextChunks(child, syntaxStyle, currentStyles));
4359
+ }
4360
+ }
4361
+ return chunks;
4362
+ }
4363
+ function hastToStyledText(hast, syntaxStyle) {
4364
+ const chunks = hastToTextChunks(hast, syntaxStyle);
4365
+ return new StyledText(chunks);
4366
+ }
4367
+
4368
+ // src/lib/scroll-acceleration.ts
4369
+ class LinearScrollAccel {
4370
+ tick(_now) {
4371
+ return 1;
4372
+ }
4373
+ reset() {}
4374
+ }
4375
+
4376
+ class MacOSScrollAccel {
4377
+ opts;
4378
+ lastTickTime = 0;
4379
+ velocityHistory = [];
4380
+ historySize = 3;
4381
+ streakTimeout = 150;
4382
+ minTickInterval = 6;
4383
+ constructor(opts = {}) {
4384
+ this.opts = opts;
4385
+ }
4386
+ tick(now = Date.now()) {
4387
+ const A = this.opts.A ?? 0.8;
4388
+ const tau = this.opts.tau ?? 3;
4389
+ const maxMultiplier = this.opts.maxMultiplier ?? 6;
4390
+ const dt = this.lastTickTime ? now - this.lastTickTime : Infinity;
4391
+ if (dt === Infinity || dt > this.streakTimeout) {
4392
+ this.lastTickTime = now;
4393
+ this.velocityHistory = [];
4394
+ return 1;
4395
+ }
4396
+ if (dt < this.minTickInterval) {
4397
+ return 1;
4398
+ }
4399
+ this.lastTickTime = now;
4400
+ this.velocityHistory.push(dt);
4401
+ if (this.velocityHistory.length > this.historySize) {
4402
+ this.velocityHistory.shift();
4403
+ }
4404
+ const avgInterval = this.velocityHistory.reduce((a, b) => a + b, 0) / this.velocityHistory.length;
4405
+ const referenceInterval = 100;
4406
+ const velocity = referenceInterval / avgInterval;
4407
+ const x = velocity / tau;
4408
+ const multiplier = 1 + A * (Math.exp(x) - 1);
4409
+ return Math.min(multiplier, maxMultiplier);
4410
+ }
4411
+ reset() {
4412
+ this.lastTickTime = 0;
4413
+ this.velocityHistory = [];
4414
+ }
4415
+ }
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: "" };
4504
4539
  }
4505
4540
 
4506
- // src/lib/hast-styled-text.ts
4507
- function hastToTextChunks(node, syntaxStyle, parentStyles = []) {
4508
- const chunks = [];
4509
- if (node.type === "text") {
4510
- const stylesToMerge = parentStyles.length > 0 ? parentStyles : ["default"];
4511
- const mergedStyle = syntaxStyle.mergeStyles(...stylesToMerge);
4512
- chunks.push({
4513
- __isChunk: true,
4514
- text: node.value,
4515
- fg: mergedStyle.fg,
4516
- bg: mergedStyle.bg,
4517
- attributes: mergedStyle.attributes
4518
- });
4519
- } else if (node.type === "element") {
4520
- let currentStyles = [...parentStyles];
4521
- if (node.properties?.className) {
4522
- const classes = node.properties.className.split(" ");
4523
- for (const cls of classes) {
4524
- currentStyles.push(cls);
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();
4525
4563
  }
4564
+ } else {
4565
+ str = data;
4526
4566
  }
4527
- for (const child of node.children) {
4528
- chunks.push(...hastToTextChunks(child, syntaxStyle, currentStyles));
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);
4529
4626
  }
4530
4627
  }
4531
- return chunks;
4532
- }
4533
- function hastToStyledText(hast, syntaxStyle) {
4534
- const chunks = hastToTextChunks(hast, syntaxStyle);
4535
- return new StyledText(chunks);
4536
- }
4537
-
4538
- // src/lib/scroll-acceleration.ts
4539
- class LinearScrollAccel {
4540
- tick(_now) {
4541
- return 1;
4542
- }
4543
- reset() {}
4544
- }
4545
-
4546
- class MacOSScrollAccel {
4547
- opts;
4548
- lastTickTime = 0;
4549
- velocityHistory = [];
4550
- historySize = 3;
4551
- streakTimeout = 150;
4552
- minTickInterval = 6;
4553
- constructor(opts = {}) {
4554
- this.opts = opts;
4555
- }
4556
- tick(now = Date.now()) {
4557
- const A = this.opts.A ?? 0.8;
4558
- const tau = this.opts.tau ?? 3;
4559
- const maxMultiplier = this.opts.maxMultiplier ?? 6;
4560
- const dt = this.lastTickTime ? now - this.lastTickTime : Infinity;
4561
- if (dt === Infinity || dt > this.streakTimeout) {
4562
- this.lastTickTime = now;
4563
- this.velocityHistory = [];
4564
- return 1;
4628
+ flush() {
4629
+ if (this.timeout) {
4630
+ clearTimeout(this.timeout);
4631
+ this.timeout = null;
4565
4632
  }
4566
- if (dt < this.minTickInterval) {
4567
- return 1;
4633
+ if (this.buffer.length === 0) {
4634
+ return [];
4568
4635
  }
4569
- this.lastTickTime = now;
4570
- this.velocityHistory.push(dt);
4571
- if (this.velocityHistory.length > this.historySize) {
4572
- this.velocityHistory.shift();
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;
4573
4644
  }
4574
- const avgInterval = this.velocityHistory.reduce((a, b) => a + b, 0) / this.velocityHistory.length;
4575
- const referenceInterval = 100;
4576
- const velocity = referenceInterval / avgInterval;
4577
- const x = velocity / tau;
4578
- const multiplier = 1 + A * (Math.exp(x) - 1);
4579
- return Math.min(multiplier, maxMultiplier);
4645
+ this.buffer = "";
4646
+ this.pasteMode = false;
4647
+ this.pasteBuffer = "";
4580
4648
  }
4581
- reset() {
4582
- this.lastTickTime = 0;
4583
- this.velocityHistory = [];
4649
+ getBuffer() {
4650
+ return this.buffer;
4651
+ }
4652
+ destroy() {
4653
+ this.clear();
4584
4654
  }
4585
4655
  }
4586
4656
 
@@ -7820,7 +7890,7 @@ class OptimizedBuffer {
7820
7890
  }
7821
7891
  }
7822
7892
 
7823
- // ../../node_modules/.bun/bun-ffi-structs@0.1.0+ca84541ac88a3075/node_modules/bun-ffi-structs/index.js
7893
+ // ../../node_modules/bun-ffi-structs/index.js
7824
7894
  import { ptr, toArrayBuffer as toArrayBuffer2 } from "bun:ffi";
7825
7895
  function fatalError(...args) {
7826
7896
  const message = args.join(" ");
@@ -7865,6 +7935,23 @@ function isObjectPointerDef(type) {
7865
7935
  function alignOffset(offset, align) {
7866
7936
  return offset + (align - 1) & ~(align - 1);
7867
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
+ }
7868
7955
  function isEnum(type) {
7869
7956
  return typeof type === "object" && type.__type === "enum";
7870
7957
  }
@@ -7941,6 +8028,7 @@ function packObjectArray(val) {
7941
8028
  return bufferView;
7942
8029
  }
7943
8030
  var encoder = new TextEncoder;
8031
+ var decoder = new TextDecoder;
7944
8032
  function defineStruct(fields, structDefOptions) {
7945
8033
  let offset = 0;
7946
8034
  let maxAlign = 1;
@@ -7983,6 +8071,7 @@ function defineStruct(fields, structDefOptions) {
7983
8071
  const ptrVal = pointerUnpacker(view, off);
7984
8072
  return ptrVal;
7985
8073
  };
8074
+ needsLengthOf = true;
7986
8075
  } else if (isEnum(typeOrStruct)) {
7987
8076
  const base = typeOrStruct.type;
7988
8077
  size = typeSizes[base];
@@ -8185,9 +8274,10 @@ function defineStruct(fields, structDefOptions) {
8185
8274
  lengthOfFields[options.lengthOf] = layoutField;
8186
8275
  }
8187
8276
  if (needsLengthOf) {
8188
- if (!lengthOfDef)
8189
- fatalError(`Internal error: needsLengthOf=true but lengthOfDef is null for ${name}`);
8190
- 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 });
8191
8281
  }
8192
8282
  offset += size;
8193
8283
  maxAlign = Math.max(maxAlign, align);
@@ -8195,9 +8285,26 @@ function defineStruct(fields, structDefOptions) {
8195
8285
  for (const { requester, def } of lengthOfRequested) {
8196
8286
  const lengthOfField = lengthOfFields[requester.name];
8197
8287
  if (!lengthOfField) {
8288
+ if (def === "char*") {
8289
+ continue;
8290
+ }
8198
8291
  throw new Error(`lengthOf field not found for array field ${requester.name}`);
8199
8292
  }
8200
- 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)) {
8201
8308
  const elemSize = typeSizes[def];
8202
8309
  const { unpack: primitiveUnpack } = primitivePackers(def);
8203
8310
  requester.unpack = (view, off) => {
@@ -8437,6 +8544,27 @@ var VisualCursorStruct = defineStruct([
8437
8544
  ["logicalCol", "u32"],
8438
8545
  ["offset", "u32"]
8439
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
+ ]);
8440
8568
 
8441
8569
  // src/zig.ts
8442
8570
  var module = await import(`@opentui/core-${process.platform}-${process.arch}/index.ts`);
@@ -8758,6 +8886,14 @@ function getOpenTUILib(libPath) {
8758
8886
  args: ["ptr", "u8"],
8759
8887
  returns: "void"
8760
8888
  },
8889
+ textBufferAppend: {
8890
+ args: ["ptr", "ptr", "usize"],
8891
+ returns: "void"
8892
+ },
8893
+ textBufferAppendFromMemId: {
8894
+ args: ["ptr", "u8"],
8895
+ returns: "void"
8896
+ },
8761
8897
  textBufferLoadFile: {
8762
8898
  args: ["ptr", "ptr", "usize"],
8763
8899
  returns: "bool"
@@ -9721,6 +9857,12 @@ class FFIRenderLib {
9721
9857
  textBufferSetTextFromMem(buffer, memId) {
9722
9858
  this.opentui.symbols.textBufferSetTextFromMem(buffer, memId);
9723
9859
  }
9860
+ textBufferAppend(buffer, bytes) {
9861
+ this.opentui.symbols.textBufferAppend(buffer, bytes, bytes.length);
9862
+ }
9863
+ textBufferAppendFromMemId(buffer, memId) {
9864
+ this.opentui.symbols.textBufferAppendFromMemId(buffer, memId);
9865
+ }
9724
9866
  textBufferLoadFile(buffer, path4) {
9725
9867
  const pathBytes = this.encoder.encode(path4);
9726
9868
  return this.opentui.symbols.textBufferLoadFile(buffer, pathBytes, pathBytes.length);
@@ -10252,25 +10394,29 @@ class FFIRenderLib {
10252
10394
  this.opentui.symbols.bufferClearScissorRects(buffer);
10253
10395
  }
10254
10396
  getTerminalCapabilities(renderer) {
10255
- const capsBuffer = new Uint8Array(64);
10256
- this.opentui.symbols.getTerminalCapabilities(renderer, capsBuffer);
10257
- let offset = 0;
10258
- const capabilities = {
10259
- kitty_keyboard: capsBuffer[offset++] !== 0,
10260
- kitty_graphics: capsBuffer[offset++] !== 0,
10261
- rgb: capsBuffer[offset++] !== 0,
10262
- unicode: capsBuffer[offset++] === 0 ? "wcwidth" : "unicode",
10263
- sgr_pixels: capsBuffer[offset++] !== 0,
10264
- color_scheme_updates: capsBuffer[offset++] !== 0,
10265
- explicit_width: capsBuffer[offset++] !== 0,
10266
- scaled_text: capsBuffer[offset++] !== 0,
10267
- sixel: capsBuffer[offset++] !== 0,
10268
- focus_tracking: capsBuffer[offset++] !== 0,
10269
- sync: capsBuffer[offset++] !== 0,
10270
- bracketed_paste: capsBuffer[offset++] !== 0,
10271
- 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
+ }
10272
10419
  };
10273
- return capabilities;
10274
10420
  }
10275
10421
  processCapabilityResponse(renderer, response) {
10276
10422
  const responseBytes = this.encoder.encode(response);
@@ -10362,6 +10508,7 @@ class TextBuffer {
10362
10508
  _syntaxStyle;
10363
10509
  _textBytes;
10364
10510
  _memId;
10511
+ _appendedChunks = [];
10365
10512
  constructor(lib, ptr4) {
10366
10513
  this.lib = lib;
10367
10514
  this.bufferPtr = ptr4;
@@ -10386,6 +10533,16 @@ class TextBuffer {
10386
10533
  this._length = this.lib.textBufferGetLength(this.bufferPtr);
10387
10534
  this._byteSize = this.lib.textBufferGetByteSize(this.bufferPtr);
10388
10535
  this._lineInfo = undefined;
10536
+ this._appendedChunks = [];
10537
+ }
10538
+ append(text) {
10539
+ this.guard();
10540
+ const textBytes = this.lib.encoder.encode(text);
10541
+ this._appendedChunks.push(textBytes);
10542
+ this.lib.textBufferAppend(this.bufferPtr, textBytes);
10543
+ this._length = this.lib.textBufferGetLength(this.bufferPtr);
10544
+ this._byteSize = this.lib.textBufferGetByteSize(this.bufferPtr);
10545
+ this._lineInfo = undefined;
10389
10546
  }
10390
10547
  loadFile(path4) {
10391
10548
  this.guard();
@@ -10511,6 +10668,7 @@ class TextBuffer {
10511
10668
  this._byteSize = 0;
10512
10669
  this._lineInfo = undefined;
10513
10670
  this._textBytes = undefined;
10671
+ this._appendedChunks = [];
10514
10672
  }
10515
10673
  reset() {
10516
10674
  this.guard();
@@ -10520,6 +10678,7 @@ class TextBuffer {
10520
10678
  this._lineInfo = undefined;
10521
10679
  this._textBytes = undefined;
10522
10680
  this._memId = undefined;
10681
+ this._appendedChunks = [];
10523
10682
  }
10524
10683
  destroy() {
10525
10684
  if (this._destroyed)
@@ -12583,6 +12742,21 @@ class TerminalConsole extends EventEmitter8 {
12583
12742
  }
12584
12743
  }
12585
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
+
12586
12760
  // src/renderer.ts
12587
12761
  import { EventEmitter as EventEmitter9 } from "events";
12588
12762
 
@@ -12676,6 +12850,42 @@ function getObjectsInViewport(viewport, objects, direction = "column", padding =
12676
12850
  return visibleChildren;
12677
12851
  }
12678
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
+
12679
12889
  // src/renderer.ts
12680
12890
  registerEnvVar({
12681
12891
  name: "OTUI_DUMP_CAPTURES",
@@ -12868,6 +13078,7 @@ class CliRenderer extends EventEmitter9 {
12868
13078
  _console;
12869
13079
  _resolution = null;
12870
13080
  _keyHandler;
13081
+ _stdinBuffer;
12871
13082
  animationRequest = new Map;
12872
13083
  resizeTimeoutId = null;
12873
13084
  resizeDebounceDelay = 100;
@@ -12907,6 +13118,8 @@ class CliRenderer extends EventEmitter9 {
12907
13118
  _paletteDetector = null;
12908
13119
  _cachedPalette = null;
12909
13120
  _paletteDetectionPromise = null;
13121
+ inputHandlers = [];
13122
+ prependedInputHandlers = [];
12910
13123
  handleError = ((error) => {
12911
13124
  console.error(error);
12912
13125
  if (this._openConsoleOnError) {
@@ -12980,6 +13193,7 @@ Captured output:
12980
13193
  this.nextRenderBuffer = this.lib.getNextBuffer(this.rendererPtr);
12981
13194
  this.currentRenderBuffer = this.lib.getCurrentBuffer(this.rendererPtr);
12982
13195
  this.postProcessFns = config.postProcessFns || [];
13196
+ this.prependedInputHandlers = config.prependInputHandlers || [];
12983
13197
  this.root = new RootRenderable(this);
12984
13198
  if (this.memorySnapshotInterval > 0) {
12985
13199
  this.startMemorySnapshotTimer();
@@ -12992,10 +13206,7 @@ Captured output:
12992
13206
  process.on("uncaughtException", this.handleError);
12993
13207
  process.on("unhandledRejection", this.handleError);
12994
13208
  process.on("exit", this.exitHandler);
12995
- this._console = new TerminalConsole(this, config.consoleOptions);
12996
- this.useConsole = config.useConsole ?? true;
12997
- this._openConsoleOnError = config.openConsoleOnError ?? true;
12998
- this._keyHandler = new InternalKeyHandler(this.stdin, config.useKittyKeyboard ?? true);
13209
+ this._keyHandler = new InternalKeyHandler(config.useKittyKeyboard ?? true);
12999
13210
  this._keyHandler.on("keypress", (event) => {
13000
13211
  if (this.exitOnCtrlC && event.name === "c" && event.ctrl) {
13001
13212
  process.nextTick(() => {
@@ -13004,6 +13215,10 @@ Captured output:
13004
13215
  return;
13005
13216
  }
13006
13217
  });
13218
+ this._stdinBuffer = new StdinBuffer({ timeout: 5 });
13219
+ this._console = new TerminalConsole(this, config.consoleOptions);
13220
+ this.useConsole = config.useConsole ?? true;
13221
+ this._openConsoleOnError = config.openConsoleOnError ?? true;
13007
13222
  global.requestAnimationFrame = (callback) => {
13008
13223
  const id = CliRenderer.animationFrameId++;
13009
13224
  this.animationRequest.set(id, callback);
@@ -13235,52 +13450,86 @@ Captured output:
13235
13450
  if (this._terminalIsSetup)
13236
13451
  return;
13237
13452
  this._terminalIsSetup = true;
13238
- await new Promise((resolve4) => {
13239
- const timeout = setTimeout(() => {
13240
- this.stdin.off("data", capListener);
13241
- resolve4(true);
13242
- }, 100);
13243
- const capListener = (str) => {
13244
- clearTimeout(timeout);
13245
- this.lib.processCapabilityResponse(this.rendererPtr, str);
13246
- this.stdin.off("data", capListener);
13247
- resolve4(true);
13248
- };
13249
- this.stdin.on("data", capListener);
13250
- this.lib.setupTerminal(this.rendererPtr, this._useAlternateScreen);
13251
- });
13453
+ this.lib.setupTerminal(this.rendererPtr, this._useAlternateScreen);
13252
13454
  this._capabilities = this.lib.getTerminalCapabilities(this.rendererPtr);
13455
+ setTimeout(() => {
13456
+ this.removeInputHandler(this.capabilityHandler);
13457
+ }, 5000);
13253
13458
  if (this._useMouse) {
13254
13459
  this.enableMouse();
13255
13460
  }
13256
13461
  this.queryPixelResolution();
13257
13462
  }
13258
13463
  stdinListener = ((data) => {
13259
- const str = data.toString();
13260
- if (this.waitingForPixelResolution && /\x1b\[4;\d+;\d+t/.test(str)) {
13261
- const match = str.match(/\x1b\[4;(\d+);(\d+)t/);
13262
- if (match) {
13263
- const resolution = {
13264
- width: parseInt(match[2]),
13265
- height: parseInt(match[1])
13266
- };
13267
- this._resolution = resolution;
13268
- this.waitingForPixelResolution = false;
13269
- return;
13270
- }
13271
- }
13272
13464
  if (this._useMouse && this.handleMouseData(data)) {
13273
13465
  return;
13274
13466
  }
13275
- 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;
13276
13496
  }).bind(this);
13277
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
+ });
13278
13517
  if (this.stdin.setRawMode) {
13279
13518
  this.stdin.setRawMode(true);
13280
13519
  }
13281
13520
  this.stdin.resume();
13282
13521
  this.stdin.setEncoding("utf8");
13283
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
+ });
13284
13533
  }
13285
13534
  handleMouseData(data) {
13286
13535
  const mouseEvent = this.mouseParser.parseMouseEvent(data);
@@ -13606,6 +13855,7 @@ Captured output:
13606
13855
  this._suspendedMouseEnabled = this._useMouse;
13607
13856
  this.disableMouse();
13608
13857
  this._keyHandler.suspend();
13858
+ this._stdinBuffer.clear();
13609
13859
  if (this.stdin.setRawMode) {
13610
13860
  this.stdin.setRawMode(false);
13611
13861
  }
@@ -13675,7 +13925,7 @@ Captured output:
13675
13925
  } catch (e) {
13676
13926
  console.error("Error destroying root renderable:", e instanceof Error ? e.stack : String(e));
13677
13927
  }
13678
- this._keyHandler.destroy();
13928
+ this._stdinBuffer.destroy();
13679
13929
  this._console.deactivate();
13680
13930
  this.disableStdoutInterception();
13681
13931
  if (this._splitHeight > 0) {
@@ -13948,7 +14198,7 @@ Captured output:
13948
14198
  }
13949
14199
  }
13950
14200
 
13951
- 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 };
13952
14202
 
13953
- //# debugId=ADDED20480B66A0A64756E2164756E21
13954
- //# sourceMappingURL=index-7bav3fax.js.map
14203
+ //# debugId=7BD9FAB5ED52E27064756E2164756E21
14204
+ //# sourceMappingURL=index-kj9k00yt.js.map