@opentui/core 0.0.0-20251008-63d6b70d → 0.0.0-20251026-8b7fde6b

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.
Files changed (43) hide show
  1. package/3d.js +140 -140
  2. package/3d.js.map +3 -3
  3. package/README.md +10 -0
  4. package/Renderable.d.ts +25 -24
  5. package/buffer.d.ts +4 -7
  6. package/edit-buffer.d.ts +77 -0
  7. package/editor-view.d.ts +55 -0
  8. package/{index-pxa2sv92.js → index-hgxcxzxa.js} +2606 -462
  9. package/index-hgxcxzxa.js.map +55 -0
  10. package/index.d.ts +4 -0
  11. package/index.js +3529 -2025
  12. package/index.js.map +19 -12
  13. package/lib/KeyHandler.d.ts +3 -0
  14. package/lib/extmarks-history.d.ts +17 -0
  15. package/lib/extmarks.d.ts +80 -0
  16. package/lib/hast-styled-text.d.ts +2 -3
  17. package/lib/index.d.ts +1 -1
  18. package/lib/keymapping.d.ts +10 -0
  19. package/lib/objects-in-viewport.d.ts +14 -0
  20. package/lib/parse.keypress.d.ts +1 -1
  21. package/lib/tree-sitter/index.d.ts +0 -2
  22. package/lib/tree-sitter-styled-text.d.ts +1 -1
  23. package/lib/yoga.options.d.ts +6 -6
  24. package/package.json +9 -7
  25. package/renderables/Code.d.ts +1 -1
  26. package/renderables/EditBufferRenderable.d.ts +119 -0
  27. package/renderables/Text.d.ts +0 -3
  28. package/renderables/TextBufferRenderable.d.ts +8 -14
  29. package/renderables/TextNode.d.ts +2 -1
  30. package/renderables/Textarea.d.ts +95 -0
  31. package/renderables/index.d.ts +11 -9
  32. package/renderer.d.ts +20 -3
  33. package/{lib/syntax-style.d.ts → syntax-style.d.ts} +21 -5
  34. package/testing/mock-keys.d.ts +39 -2
  35. package/testing.js +54 -6
  36. package/testing.js.map +3 -3
  37. package/text-buffer-view.d.ts +31 -0
  38. package/text-buffer.d.ts +28 -21
  39. package/types.d.ts +10 -0
  40. package/zig-structs.d.ts +22 -0
  41. package/zig.d.ts +147 -23
  42. package/index-pxa2sv92.js.map +0 -52
  43. package/lib/word-jumps.d.ts +0 -2
@@ -27,7 +27,7 @@ var __export = (target, all) => {
27
27
  };
28
28
  var __require = import.meta.require;
29
29
 
30
- // ../../node_modules/yoga-layout/dist/src/index.js
30
+ // ../../node_modules/.bun/yoga-layout@3.2.1/node_modules/yoga-layout/dist/src/index.js
31
31
  var exports_src = {};
32
32
  __export(exports_src, {
33
33
  default: () => src_default,
@@ -51,7 +51,7 @@ __export(exports_src, {
51
51
  Align: () => Align
52
52
  });
53
53
 
54
- // ../../node_modules/yoga-layout/dist/binaries/yoga-wasm-base64-esm.js
54
+ // ../../node_modules/.bun/yoga-layout@3.2.1/node_modules/yoga-layout/dist/binaries/yoga-wasm-base64-esm.js
55
55
  var loadYoga = (() => {
56
56
  var _scriptDir = import.meta.url;
57
57
  return function(loadYoga2) {
@@ -1356,7 +1356,7 @@ var loadYoga = (() => {
1356
1356
  })();
1357
1357
  var yoga_wasm_base64_esm_default = loadYoga;
1358
1358
 
1359
- // ../../node_modules/yoga-layout/dist/src/generated/YGEnums.js
1359
+ // ../../node_modules/.bun/yoga-layout@3.2.1/node_modules/yoga-layout/dist/src/generated/YGEnums.js
1360
1360
  var Align = /* @__PURE__ */ function(Align2) {
1361
1361
  Align2[Align2["Auto"] = 0] = "Auto";
1362
1362
  Align2[Align2["FlexStart"] = 1] = "FlexStart";
@@ -1559,7 +1559,7 @@ var constants = {
1559
1559
  };
1560
1560
  var YGEnums_default = constants;
1561
1561
 
1562
- // ../../node_modules/yoga-layout/dist/src/wrapAssembly.js
1562
+ // ../../node_modules/.bun/yoga-layout@3.2.1/node_modules/yoga-layout/dist/src/wrapAssembly.js
1563
1563
  function wrapAssembly(lib) {
1564
1564
  function patch(prototype, name, fn) {
1565
1565
  const original = prototype[name];
@@ -1661,7 +1661,7 @@ function wrapAssembly(lib) {
1661
1661
  };
1662
1662
  }
1663
1663
 
1664
- // ../../node_modules/yoga-layout/dist/src/index.js
1664
+ // ../../node_modules/.bun/yoga-layout@3.2.1/node_modules/yoga-layout/dist/src/index.js
1665
1665
  var Yoga = wrapAssembly(await yoga_wasm_base64_esm_default());
1666
1666
  var src_default = Yoga;
1667
1667
 
@@ -2092,6 +2092,12 @@ var parseKeypress = (s = "", options = {}) => {
2092
2092
  } else if (!s) {
2093
2093
  s = "";
2094
2094
  }
2095
+ if (/^\x1b\[<\d+;\d+;\d+[Mm]$/.test(s)) {
2096
+ return null;
2097
+ }
2098
+ if (s.startsWith("\x1B[M") && s.length >= 6) {
2099
+ return null;
2100
+ }
2095
2101
  const key = {
2096
2102
  name: "",
2097
2103
  ctrl: false,
@@ -2110,11 +2116,14 @@ var parseKeypress = (s = "", options = {}) => {
2110
2116
  return kittyResult;
2111
2117
  }
2112
2118
  }
2113
- if (s === "\r") {
2119
+ if (s === "\r" || s === "\x1B\r") {
2114
2120
  key.name = "return";
2121
+ key.meta = s.length === 2;
2115
2122
  } else if (s === `
2123
+ ` || s === `\x1B
2116
2124
  `) {
2117
2125
  key.name = "enter";
2126
+ key.meta = s.length === 2;
2118
2127
  } else if (s === "\t") {
2119
2128
  key.name = "tab";
2120
2129
  } else if (s === "\b" || s === "\x1B\b" || s === "\x7F" || s === "\x1B\x7F") {
@@ -2257,6 +2266,7 @@ class KeyHandler extends EventEmitter {
2257
2266
  listener;
2258
2267
  pasteMode = false;
2259
2268
  pasteBuffer = [];
2269
+ suspended = false;
2260
2270
  constructor(stdin, useKittyKeyboard = false) {
2261
2271
  super();
2262
2272
  this.stdin = stdin || process.stdin;
@@ -2276,6 +2286,9 @@ class KeyHandler extends EventEmitter {
2276
2286
  return;
2277
2287
  }
2278
2288
  const parsedKey = parseKeypress(key, { useKittyKeyboard: this.useKittyKeyboard });
2289
+ if (!parsedKey) {
2290
+ return;
2291
+ }
2279
2292
  switch (parsedKey.eventType) {
2280
2293
  case "press":
2281
2294
  this.emit("keypress", new KeyEvent(parsedKey));
@@ -2296,6 +2309,18 @@ class KeyHandler extends EventEmitter {
2296
2309
  destroy() {
2297
2310
  this.stdin.removeListener("data", this.listener);
2298
2311
  }
2312
+ suspend() {
2313
+ if (!this.suspended) {
2314
+ this.suspended = true;
2315
+ this.stdin.removeListener("data", this.listener);
2316
+ }
2317
+ }
2318
+ resume() {
2319
+ if (this.suspended) {
2320
+ this.suspended = false;
2321
+ this.stdin.on("data", this.listener);
2322
+ }
2323
+ }
2299
2324
  }
2300
2325
 
2301
2326
  class InternalKeyHandler extends KeyHandler {
@@ -2393,18 +2418,22 @@ function hexToRgb(hex) {
2393
2418
  hex = hex.replace(/^#/, "");
2394
2419
  if (hex.length === 3) {
2395
2420
  hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
2421
+ } else if (hex.length === 4) {
2422
+ hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2] + hex[3] + hex[3];
2396
2423
  }
2397
- if (!/^[0-9A-Fa-f]{6}$/.test(hex)) {
2424
+ if (!/^[0-9A-Fa-f]{6}$/.test(hex) && !/^[0-9A-Fa-f]{8}$/.test(hex)) {
2398
2425
  console.warn(`Invalid hex color: ${hex}, defaulting to magenta`);
2399
2426
  return RGBA.fromValues(1, 0, 1, 1);
2400
2427
  }
2401
2428
  const r = parseInt(hex.substring(0, 2), 16) / 255;
2402
2429
  const g = parseInt(hex.substring(2, 4), 16) / 255;
2403
2430
  const b = parseInt(hex.substring(4, 6), 16) / 255;
2404
- return RGBA.fromValues(r, g, b, 1);
2431
+ const a = hex.length === 8 ? parseInt(hex.substring(6, 8), 16) / 255 : 1;
2432
+ return RGBA.fromValues(r, g, b, a);
2405
2433
  }
2406
2434
  function rgbToHex(rgb) {
2407
- return "#" + [rgb.r, rgb.g, rgb.b].map((x) => {
2435
+ const components = rgb.a === 1 ? [rgb.r, rgb.g, rgb.b] : [rgb.r, rgb.g, rgb.b, rgb.a];
2436
+ return "#" + components.map((x) => {
2408
2437
  const hex = Math.floor(Math.max(0, Math.min(1, x) * 255)).toString(16);
2409
2438
  return hex.length === 1 ? "0" + hex : hex;
2410
2439
  }).join("");
@@ -4286,104 +4315,6 @@ function t(strings, ...values) {
4286
4315
  return new StyledText(chunks);
4287
4316
  }
4288
4317
 
4289
- // src/lib/syntax-style.ts
4290
- function convertThemeToStyles(theme) {
4291
- const flatStyles = {};
4292
- for (const tokenStyle of theme) {
4293
- const styleDefinition = {};
4294
- if (tokenStyle.style.foreground) {
4295
- styleDefinition.fg = parseColor(tokenStyle.style.foreground);
4296
- }
4297
- if (tokenStyle.style.background) {
4298
- styleDefinition.bg = parseColor(tokenStyle.style.background);
4299
- }
4300
- if (tokenStyle.style.bold !== undefined) {
4301
- styleDefinition.bold = tokenStyle.style.bold;
4302
- }
4303
- if (tokenStyle.style.italic !== undefined) {
4304
- styleDefinition.italic = tokenStyle.style.italic;
4305
- }
4306
- if (tokenStyle.style.underline !== undefined) {
4307
- styleDefinition.underline = tokenStyle.style.underline;
4308
- }
4309
- if (tokenStyle.style.dim !== undefined) {
4310
- styleDefinition.dim = tokenStyle.style.dim;
4311
- }
4312
- for (const scope of tokenStyle.scope) {
4313
- flatStyles[scope] = styleDefinition;
4314
- }
4315
- }
4316
- return flatStyles;
4317
- }
4318
-
4319
- class SyntaxStyle {
4320
- styles;
4321
- mergedStyleCache;
4322
- constructor(styles) {
4323
- this.styles = styles;
4324
- this.mergedStyleCache = new Map;
4325
- }
4326
- static fromTheme(theme) {
4327
- const flatStyles = convertThemeToStyles(theme);
4328
- return new SyntaxStyle(flatStyles);
4329
- }
4330
- mergeStyles(...styleNames) {
4331
- const cacheKey = styleNames.join(":");
4332
- const cached = this.mergedStyleCache.get(cacheKey);
4333
- if (cached)
4334
- return cached;
4335
- const styleDefinition = {};
4336
- for (const name of styleNames) {
4337
- const style = this.getStyle(name);
4338
- if (!style)
4339
- continue;
4340
- if (style.fg)
4341
- styleDefinition.fg = style.fg;
4342
- if (style.bg)
4343
- styleDefinition.bg = style.bg;
4344
- if (style.bold !== undefined)
4345
- styleDefinition.bold = style.bold;
4346
- if (style.italic !== undefined)
4347
- styleDefinition.italic = style.italic;
4348
- if (style.underline !== undefined)
4349
- styleDefinition.underline = style.underline;
4350
- if (style.dim !== undefined)
4351
- styleDefinition.dim = style.dim;
4352
- }
4353
- const attributes = createTextAttributes({
4354
- bold: styleDefinition.bold,
4355
- italic: styleDefinition.italic,
4356
- underline: styleDefinition.underline,
4357
- dim: styleDefinition.dim
4358
- });
4359
- const merged = {
4360
- fg: styleDefinition.fg,
4361
- bg: styleDefinition.bg,
4362
- attributes
4363
- };
4364
- this.mergedStyleCache.set(cacheKey, merged);
4365
- return merged;
4366
- }
4367
- getStyle(name) {
4368
- if (Object.prototype.hasOwnProperty.call(this.styles, name)) {
4369
- return this.styles[name];
4370
- }
4371
- if (name.includes(".")) {
4372
- const baseName = name.split(".")[0];
4373
- if (Object.prototype.hasOwnProperty.call(this.styles, baseName)) {
4374
- return this.styles[baseName];
4375
- }
4376
- }
4377
- return;
4378
- }
4379
- clearCache() {
4380
- this.mergedStyleCache.clear();
4381
- }
4382
- getCacheSize() {
4383
- return this.mergedStyleCache.size;
4384
- }
4385
- }
4386
-
4387
4318
  // src/lib/hast-styled-text.ts
4388
4319
  function hastToTextChunks(node, syntaxStyle, parentStyles = []) {
4389
4320
  const chunks = [];
@@ -4467,6 +4398,9 @@ class MacOSScrollAccel {
4467
4398
 
4468
4399
  // src/lib/yoga.options.ts
4469
4400
  function parseAlign(value) {
4401
+ if (value == null) {
4402
+ return Align.Auto;
4403
+ }
4470
4404
  switch (value.toLowerCase()) {
4471
4405
  case "auto":
4472
4406
  return Align.Auto;
@@ -4491,6 +4425,9 @@ function parseAlign(value) {
4491
4425
  }
4492
4426
  }
4493
4427
  function parseBoxSizing(value) {
4428
+ if (value == null) {
4429
+ return BoxSizing.BorderBox;
4430
+ }
4494
4431
  switch (value.toLowerCase()) {
4495
4432
  case "border-box":
4496
4433
  return BoxSizing.BorderBox;
@@ -4501,6 +4438,9 @@ function parseBoxSizing(value) {
4501
4438
  }
4502
4439
  }
4503
4440
  function parseDimension(value) {
4441
+ if (value == null) {
4442
+ return Dimension.Width;
4443
+ }
4504
4444
  switch (value.toLowerCase()) {
4505
4445
  case "width":
4506
4446
  return Dimension.Width;
@@ -4511,6 +4451,9 @@ function parseDimension(value) {
4511
4451
  }
4512
4452
  }
4513
4453
  function parseDirection(value) {
4454
+ if (value == null) {
4455
+ return Direction.LTR;
4456
+ }
4514
4457
  switch (value.toLowerCase()) {
4515
4458
  case "inherit":
4516
4459
  return Direction.Inherit;
@@ -4523,6 +4466,9 @@ function parseDirection(value) {
4523
4466
  }
4524
4467
  }
4525
4468
  function parseDisplay(value) {
4469
+ if (value == null) {
4470
+ return Display.Flex;
4471
+ }
4526
4472
  switch (value.toLowerCase()) {
4527
4473
  case "flex":
4528
4474
  return Display.Flex;
@@ -4535,6 +4481,9 @@ function parseDisplay(value) {
4535
4481
  }
4536
4482
  }
4537
4483
  function parseEdge(value) {
4484
+ if (value == null) {
4485
+ return Edge.All;
4486
+ }
4538
4487
  switch (value.toLowerCase()) {
4539
4488
  case "left":
4540
4489
  return Edge.Left;
@@ -4559,6 +4508,9 @@ function parseEdge(value) {
4559
4508
  }
4560
4509
  }
4561
4510
  function parseFlexDirection(value) {
4511
+ if (value == null) {
4512
+ return FlexDirection.Column;
4513
+ }
4562
4514
  switch (value.toLowerCase()) {
4563
4515
  case "column":
4564
4516
  return FlexDirection.Column;
@@ -4573,6 +4525,9 @@ function parseFlexDirection(value) {
4573
4525
  }
4574
4526
  }
4575
4527
  function parseGutter(value) {
4528
+ if (value == null) {
4529
+ return Gutter.All;
4530
+ }
4576
4531
  switch (value.toLowerCase()) {
4577
4532
  case "column":
4578
4533
  return Gutter.Column;
@@ -4585,6 +4540,9 @@ function parseGutter(value) {
4585
4540
  }
4586
4541
  }
4587
4542
  function parseJustify(value) {
4543
+ if (value == null) {
4544
+ return Justify.FlexStart;
4545
+ }
4588
4546
  switch (value.toLowerCase()) {
4589
4547
  case "flex-start":
4590
4548
  return Justify.FlexStart;
@@ -4603,6 +4561,9 @@ function parseJustify(value) {
4603
4561
  }
4604
4562
  }
4605
4563
  function parseLogLevel(value) {
4564
+ if (value == null) {
4565
+ return LogLevel.Info;
4566
+ }
4606
4567
  switch (value.toLowerCase()) {
4607
4568
  case "error":
4608
4569
  return LogLevel.Error;
@@ -4621,6 +4582,9 @@ function parseLogLevel(value) {
4621
4582
  }
4622
4583
  }
4623
4584
  function parseMeasureMode(value) {
4585
+ if (value == null) {
4586
+ return MeasureMode.Undefined;
4587
+ }
4624
4588
  switch (value.toLowerCase()) {
4625
4589
  case "undefined":
4626
4590
  return MeasureMode.Undefined;
@@ -4633,6 +4597,9 @@ function parseMeasureMode(value) {
4633
4597
  }
4634
4598
  }
4635
4599
  function parseOverflow(value) {
4600
+ if (value == null) {
4601
+ return Overflow.Visible;
4602
+ }
4636
4603
  switch (value.toLowerCase()) {
4637
4604
  case "visible":
4638
4605
  return Overflow.Visible;
@@ -4645,6 +4612,9 @@ function parseOverflow(value) {
4645
4612
  }
4646
4613
  }
4647
4614
  function parsePositionType(value) {
4615
+ if (value == null) {
4616
+ return PositionType.Relative;
4617
+ }
4648
4618
  switch (value.toLowerCase()) {
4649
4619
  case "static":
4650
4620
  return PositionType.Static;
@@ -4657,6 +4627,9 @@ function parsePositionType(value) {
4657
4627
  }
4658
4628
  }
4659
4629
  function parseUnit(value) {
4630
+ if (value == null) {
4631
+ return Unit.Point;
4632
+ }
4660
4633
  switch (value.toLowerCase()) {
4661
4634
  case "undefined":
4662
4635
  return Unit.Undefined;
@@ -4671,6 +4644,9 @@ function parseUnit(value) {
4671
4644
  }
4672
4645
  }
4673
4646
  function parseWrap(value) {
4647
+ if (value == null) {
4648
+ return Wrap.NoWrap;
4649
+ }
4674
4650
  switch (value.toLowerCase()) {
4675
4651
  case "no-wrap":
4676
4652
  return Wrap.NoWrap;
@@ -6240,9 +6216,719 @@ function getTreeSitterClient() {
6240
6216
  return client2;
6241
6217
  });
6242
6218
  }
6219
+
6220
+ // src/lib/extmarks.ts
6221
+ import { EventEmitter as EventEmitter4 } from "events";
6222
+
6223
+ // src/lib/extmarks-history.ts
6224
+ class ExtmarksHistory {
6225
+ undoStack = [];
6226
+ redoStack = [];
6227
+ saveSnapshot(extmarks, nextId) {
6228
+ const snapshot = {
6229
+ extmarks: new Map(Array.from(extmarks.entries()).map(([id, extmark]) => [id, { ...extmark }])),
6230
+ nextId
6231
+ };
6232
+ this.undoStack.push(snapshot);
6233
+ this.redoStack = [];
6234
+ }
6235
+ undo() {
6236
+ if (this.undoStack.length === 0)
6237
+ return null;
6238
+ return this.undoStack.pop();
6239
+ }
6240
+ redo() {
6241
+ if (this.redoStack.length === 0)
6242
+ return null;
6243
+ return this.redoStack.pop();
6244
+ }
6245
+ pushRedo(snapshot) {
6246
+ this.redoStack.push(snapshot);
6247
+ }
6248
+ pushUndo(snapshot) {
6249
+ this.undoStack.push(snapshot);
6250
+ }
6251
+ clear() {
6252
+ this.undoStack = [];
6253
+ this.redoStack = [];
6254
+ }
6255
+ canUndo() {
6256
+ return this.undoStack.length > 0;
6257
+ }
6258
+ canRedo() {
6259
+ return this.redoStack.length > 0;
6260
+ }
6261
+ }
6262
+
6263
+ // src/lib/extmarks.ts
6264
+ class ExtmarksController extends EventEmitter4 {
6265
+ editBuffer;
6266
+ editorView;
6267
+ extmarks = new Map;
6268
+ nextId = 1;
6269
+ destroyed = false;
6270
+ history = new ExtmarksHistory;
6271
+ originalMoveCursorLeft;
6272
+ originalMoveCursorRight;
6273
+ originalSetCursorByOffset;
6274
+ originalMoveUpVisual;
6275
+ originalMoveDownVisual;
6276
+ originalDeleteCharBackward;
6277
+ originalDeleteChar;
6278
+ originalInsertText;
6279
+ originalInsertChar;
6280
+ originalDeleteRange;
6281
+ originalSetText;
6282
+ originalClear;
6283
+ originalNewLine;
6284
+ originalDeleteLine;
6285
+ originalEditorViewDeleteSelectedText;
6286
+ originalUndo;
6287
+ originalRedo;
6288
+ constructor(editBuffer, editorView) {
6289
+ super();
6290
+ this.editBuffer = editBuffer;
6291
+ this.editorView = editorView;
6292
+ this.originalMoveCursorLeft = editBuffer.moveCursorLeft.bind(editBuffer);
6293
+ this.originalMoveCursorRight = editBuffer.moveCursorRight.bind(editBuffer);
6294
+ this.originalSetCursorByOffset = editBuffer.setCursorByOffset.bind(editBuffer);
6295
+ this.originalMoveUpVisual = editorView.moveUpVisual.bind(editorView);
6296
+ this.originalMoveDownVisual = editorView.moveDownVisual.bind(editorView);
6297
+ this.originalDeleteCharBackward = editBuffer.deleteCharBackward.bind(editBuffer);
6298
+ this.originalDeleteChar = editBuffer.deleteChar.bind(editBuffer);
6299
+ this.originalInsertText = editBuffer.insertText.bind(editBuffer);
6300
+ this.originalInsertChar = editBuffer.insertChar.bind(editBuffer);
6301
+ this.originalDeleteRange = editBuffer.deleteRange.bind(editBuffer);
6302
+ this.originalSetText = editBuffer.setText.bind(editBuffer);
6303
+ this.originalClear = editBuffer.clear.bind(editBuffer);
6304
+ this.originalNewLine = editBuffer.newLine.bind(editBuffer);
6305
+ this.originalDeleteLine = editBuffer.deleteLine.bind(editBuffer);
6306
+ this.originalEditorViewDeleteSelectedText = editorView.deleteSelectedText.bind(editorView);
6307
+ this.originalUndo = editBuffer.undo.bind(editBuffer);
6308
+ this.originalRedo = editBuffer.redo.bind(editBuffer);
6309
+ this.wrapCursorMovement();
6310
+ this.wrapDeletion();
6311
+ this.wrapInsertion();
6312
+ this.wrapEditorViewDeleteSelectedText();
6313
+ this.wrapUndoRedo();
6314
+ this.setupContentChangeListener();
6315
+ }
6316
+ wrapCursorMovement() {
6317
+ this.editBuffer.moveCursorLeft = () => {
6318
+ if (this.destroyed) {
6319
+ this.originalMoveCursorLeft();
6320
+ return;
6321
+ }
6322
+ const currentOffset = this.editorView.getVisualCursor().offset;
6323
+ const hasSelection = this.editorView.hasSelection();
6324
+ if (hasSelection) {
6325
+ this.originalMoveCursorLeft();
6326
+ return;
6327
+ }
6328
+ const targetOffset = currentOffset - 1;
6329
+ if (targetOffset < 0) {
6330
+ this.originalMoveCursorLeft();
6331
+ return;
6332
+ }
6333
+ const virtualExtmark = this.findVirtualExtmarkContaining(targetOffset);
6334
+ if (virtualExtmark && currentOffset >= virtualExtmark.end) {
6335
+ this.editBuffer.setCursorByOffset(virtualExtmark.start - 1);
6336
+ return;
6337
+ }
6338
+ this.originalMoveCursorLeft();
6339
+ };
6340
+ this.editBuffer.moveCursorRight = () => {
6341
+ if (this.destroyed) {
6342
+ this.originalMoveCursorRight();
6343
+ return;
6344
+ }
6345
+ const currentOffset = this.editorView.getVisualCursor().offset;
6346
+ const hasSelection = this.editorView.hasSelection();
6347
+ if (hasSelection) {
6348
+ this.originalMoveCursorRight();
6349
+ return;
6350
+ }
6351
+ const targetOffset = currentOffset + 1;
6352
+ const textLength = this.editBuffer.getText().length;
6353
+ if (targetOffset > textLength) {
6354
+ this.originalMoveCursorRight();
6355
+ return;
6356
+ }
6357
+ const virtualExtmark = this.findVirtualExtmarkContaining(targetOffset);
6358
+ if (virtualExtmark && currentOffset <= virtualExtmark.start) {
6359
+ this.editBuffer.setCursorByOffset(virtualExtmark.end);
6360
+ return;
6361
+ }
6362
+ this.originalMoveCursorRight();
6363
+ };
6364
+ this.editorView.moveUpVisual = () => {
6365
+ if (this.destroyed) {
6366
+ this.originalMoveUpVisual();
6367
+ return;
6368
+ }
6369
+ const hasSelection = this.editorView.hasSelection();
6370
+ if (hasSelection) {
6371
+ this.originalMoveUpVisual();
6372
+ return;
6373
+ }
6374
+ const currentOffset = this.editorView.getVisualCursor().offset;
6375
+ this.originalMoveUpVisual();
6376
+ const newOffset = this.editorView.getVisualCursor().offset;
6377
+ const virtualExtmark = this.findVirtualExtmarkContaining(newOffset);
6378
+ if (virtualExtmark) {
6379
+ const distanceToStart = newOffset - virtualExtmark.start;
6380
+ const distanceToEnd = virtualExtmark.end - newOffset;
6381
+ if (distanceToStart < distanceToEnd) {
6382
+ this.editorView.setCursorByOffset(virtualExtmark.start - 1);
6383
+ } else {
6384
+ this.editorView.setCursorByOffset(virtualExtmark.end);
6385
+ }
6386
+ }
6387
+ };
6388
+ this.editorView.moveDownVisual = () => {
6389
+ if (this.destroyed) {
6390
+ this.originalMoveDownVisual();
6391
+ return;
6392
+ }
6393
+ const hasSelection = this.editorView.hasSelection();
6394
+ if (hasSelection) {
6395
+ this.originalMoveDownVisual();
6396
+ return;
6397
+ }
6398
+ const currentOffset = this.editorView.getVisualCursor().offset;
6399
+ this.originalMoveDownVisual();
6400
+ const newOffset = this.editorView.getVisualCursor().offset;
6401
+ const virtualExtmark = this.findVirtualExtmarkContaining(newOffset);
6402
+ if (virtualExtmark) {
6403
+ const distanceToStart = newOffset - virtualExtmark.start;
6404
+ const distanceToEnd = virtualExtmark.end - newOffset;
6405
+ if (distanceToStart < distanceToEnd) {
6406
+ this.editorView.setCursorByOffset(virtualExtmark.start - 1);
6407
+ } else {
6408
+ this.editorView.setCursorByOffset(virtualExtmark.end);
6409
+ }
6410
+ }
6411
+ };
6412
+ this.editBuffer.setCursorByOffset = (offset) => {
6413
+ if (this.destroyed) {
6414
+ this.originalSetCursorByOffset(offset);
6415
+ return;
6416
+ }
6417
+ const currentOffset = this.editorView.getVisualCursor().offset;
6418
+ const hasSelection = this.editorView.hasSelection();
6419
+ if (hasSelection) {
6420
+ this.originalSetCursorByOffset(offset);
6421
+ return;
6422
+ }
6423
+ const movingForward = offset > currentOffset;
6424
+ if (movingForward) {
6425
+ const virtualExtmark = this.findVirtualExtmarkContaining(offset);
6426
+ if (virtualExtmark && currentOffset <= virtualExtmark.start) {
6427
+ this.originalSetCursorByOffset(virtualExtmark.end);
6428
+ return;
6429
+ }
6430
+ } else {
6431
+ for (const extmark of this.extmarks.values()) {
6432
+ if (extmark.virtual && currentOffset >= extmark.end && offset < extmark.end && offset >= extmark.start) {
6433
+ this.originalSetCursorByOffset(extmark.start - 1);
6434
+ return;
6435
+ }
6436
+ }
6437
+ }
6438
+ this.originalSetCursorByOffset(offset);
6439
+ };
6440
+ }
6441
+ wrapDeletion() {
6442
+ this.editBuffer.deleteCharBackward = () => {
6443
+ if (this.destroyed) {
6444
+ this.originalDeleteCharBackward();
6445
+ return;
6446
+ }
6447
+ this.saveSnapshot();
6448
+ const currentOffset = this.editorView.getVisualCursor().offset;
6449
+ const hadSelection = this.editorView.hasSelection();
6450
+ if (currentOffset === 0) {
6451
+ this.originalDeleteCharBackward();
6452
+ return;
6453
+ }
6454
+ if (hadSelection) {
6455
+ this.originalDeleteCharBackward();
6456
+ return;
6457
+ }
6458
+ const targetOffset = currentOffset - 1;
6459
+ const virtualExtmark = this.findVirtualExtmarkContaining(targetOffset);
6460
+ if (virtualExtmark && currentOffset === virtualExtmark.end) {
6461
+ const startCursor = this.offsetToPosition(virtualExtmark.start);
6462
+ const endCursor = this.offsetToPosition(virtualExtmark.end);
6463
+ const deleteOffset = virtualExtmark.start;
6464
+ const deleteLength = virtualExtmark.end - virtualExtmark.start;
6465
+ this.extmarks.delete(virtualExtmark.id);
6466
+ this.originalDeleteRange(startCursor.row, startCursor.col, endCursor.row, endCursor.col);
6467
+ this.adjustExtmarksAfterDeletion(deleteOffset, deleteLength);
6468
+ this.emit("extmark-deleted", {
6469
+ extmark: virtualExtmark,
6470
+ trigger: "backspace"
6471
+ });
6472
+ this.updateHighlights();
6473
+ return;
6474
+ }
6475
+ this.originalDeleteCharBackward();
6476
+ this.adjustExtmarksAfterDeletion(targetOffset, 1);
6477
+ };
6478
+ this.editBuffer.deleteChar = () => {
6479
+ if (this.destroyed) {
6480
+ this.originalDeleteChar();
6481
+ return;
6482
+ }
6483
+ this.saveSnapshot();
6484
+ const currentOffset = this.editorView.getVisualCursor().offset;
6485
+ const textLength = this.editBuffer.getText().length;
6486
+ const hadSelection = this.editorView.hasSelection();
6487
+ if (currentOffset >= textLength) {
6488
+ this.originalDeleteChar();
6489
+ return;
6490
+ }
6491
+ if (hadSelection) {
6492
+ this.originalDeleteChar();
6493
+ return;
6494
+ }
6495
+ const targetOffset = currentOffset;
6496
+ const virtualExtmark = this.findVirtualExtmarkContaining(targetOffset);
6497
+ if (virtualExtmark && currentOffset === virtualExtmark.start) {
6498
+ const startCursor = this.offsetToPosition(virtualExtmark.start);
6499
+ const endCursor = this.offsetToPosition(virtualExtmark.end);
6500
+ const deleteOffset = virtualExtmark.start;
6501
+ const deleteLength = virtualExtmark.end - virtualExtmark.start;
6502
+ this.extmarks.delete(virtualExtmark.id);
6503
+ this.originalDeleteRange(startCursor.row, startCursor.col, endCursor.row, endCursor.col);
6504
+ this.adjustExtmarksAfterDeletion(deleteOffset, deleteLength);
6505
+ this.emit("extmark-deleted", {
6506
+ extmark: virtualExtmark,
6507
+ trigger: "delete"
6508
+ });
6509
+ this.updateHighlights();
6510
+ return;
6511
+ }
6512
+ this.originalDeleteChar();
6513
+ this.adjustExtmarksAfterDeletion(targetOffset, 1);
6514
+ };
6515
+ this.editBuffer.deleteRange = (startLine, startCol, endLine, endCol) => {
6516
+ if (this.destroyed) {
6517
+ this.originalDeleteRange(startLine, startCol, endLine, endCol);
6518
+ return;
6519
+ }
6520
+ this.saveSnapshot();
6521
+ const startOffset = this.positionToOffset(startLine, startCol);
6522
+ const endOffset = this.positionToOffset(endLine, endCol);
6523
+ const length = endOffset - startOffset;
6524
+ this.originalDeleteRange(startLine, startCol, endLine, endCol);
6525
+ this.adjustExtmarksAfterDeletion(startOffset, length);
6526
+ };
6527
+ this.editBuffer.deleteLine = () => {
6528
+ if (this.destroyed) {
6529
+ this.originalDeleteLine();
6530
+ return;
6531
+ }
6532
+ this.saveSnapshot();
6533
+ const text = this.editBuffer.getText();
6534
+ const currentOffset = this.editorView.getVisualCursor().offset;
6535
+ let lineStart = 0;
6536
+ for (let i = currentOffset - 1;i >= 0; i--) {
6537
+ if (text[i] === `
6538
+ `) {
6539
+ lineStart = i + 1;
6540
+ break;
6541
+ }
6542
+ }
6543
+ let lineEnd = text.length;
6544
+ for (let i = currentOffset;i < text.length; i++) {
6545
+ if (text[i] === `
6546
+ `) {
6547
+ lineEnd = i + 1;
6548
+ break;
6549
+ }
6550
+ }
6551
+ const deleteLength = lineEnd - lineStart;
6552
+ this.originalDeleteLine();
6553
+ this.adjustExtmarksAfterDeletion(lineStart, deleteLength);
6554
+ };
6555
+ }
6556
+ wrapInsertion() {
6557
+ this.editBuffer.insertText = (text) => {
6558
+ if (this.destroyed) {
6559
+ this.originalInsertText(text);
6560
+ return;
6561
+ }
6562
+ this.saveSnapshot();
6563
+ const currentOffset = this.editorView.getVisualCursor().offset;
6564
+ this.originalInsertText(text);
6565
+ this.adjustExtmarksAfterInsertion(currentOffset, text.length);
6566
+ };
6567
+ this.editBuffer.insertChar = (char) => {
6568
+ if (this.destroyed) {
6569
+ this.originalInsertChar(char);
6570
+ return;
6571
+ }
6572
+ this.saveSnapshot();
6573
+ const currentOffset = this.editorView.getVisualCursor().offset;
6574
+ this.originalInsertChar(char);
6575
+ this.adjustExtmarksAfterInsertion(currentOffset, 1);
6576
+ };
6577
+ this.editBuffer.setText = (text, opts) => {
6578
+ if (this.destroyed) {
6579
+ this.originalSetText(text, opts);
6580
+ return;
6581
+ }
6582
+ if (opts?.history !== false) {
6583
+ this.saveSnapshot();
6584
+ }
6585
+ this.clear();
6586
+ this.originalSetText(text, opts);
6587
+ };
6588
+ this.editBuffer.clear = () => {
6589
+ if (this.destroyed) {
6590
+ this.originalClear();
6591
+ return;
6592
+ }
6593
+ this.saveSnapshot();
6594
+ this.clear();
6595
+ this.originalClear();
6596
+ };
6597
+ this.editBuffer.newLine = () => {
6598
+ if (this.destroyed) {
6599
+ this.originalNewLine();
6600
+ return;
6601
+ }
6602
+ this.saveSnapshot();
6603
+ const currentOffset = this.editorView.getVisualCursor().offset;
6604
+ this.originalNewLine();
6605
+ this.adjustExtmarksAfterInsertion(currentOffset, 1);
6606
+ };
6607
+ }
6608
+ wrapEditorViewDeleteSelectedText() {
6609
+ this.editorView.deleteSelectedText = () => {
6610
+ if (this.destroyed) {
6611
+ this.originalEditorViewDeleteSelectedText();
6612
+ return;
6613
+ }
6614
+ this.saveSnapshot();
6615
+ const selection = this.editorView.getSelection();
6616
+ if (!selection) {
6617
+ this.originalEditorViewDeleteSelectedText();
6618
+ return;
6619
+ }
6620
+ const deleteOffset = Math.min(selection.start, selection.end);
6621
+ const deleteLength = Math.abs(selection.end - selection.start);
6622
+ this.originalEditorViewDeleteSelectedText();
6623
+ if (deleteLength > 0) {
6624
+ this.adjustExtmarksAfterDeletion(deleteOffset, deleteLength);
6625
+ }
6626
+ };
6627
+ }
6628
+ setupContentChangeListener() {
6629
+ this.editBuffer.on("content-changed", () => {
6630
+ if (this.destroyed)
6631
+ return;
6632
+ this.updateHighlights();
6633
+ });
6634
+ }
6635
+ findVirtualExtmarkContaining(offset) {
6636
+ for (const extmark of this.extmarks.values()) {
6637
+ if (extmark.virtual && offset >= extmark.start && offset < extmark.end) {
6638
+ return extmark;
6639
+ }
6640
+ }
6641
+ return null;
6642
+ }
6643
+ adjustExtmarksAfterInsertion(insertOffset, length) {
6644
+ for (const extmark of this.extmarks.values()) {
6645
+ if (extmark.start >= insertOffset) {
6646
+ extmark.start += length;
6647
+ extmark.end += length;
6648
+ this.emit("extmark-updated", extmark);
6649
+ } else if (extmark.end > insertOffset) {
6650
+ extmark.end += length;
6651
+ this.emit("extmark-updated", extmark);
6652
+ }
6653
+ }
6654
+ this.updateHighlights();
6655
+ }
6656
+ adjustExtmarksAfterDeletion(deleteOffset, length) {
6657
+ const toDelete = [];
6658
+ for (const extmark of this.extmarks.values()) {
6659
+ if (extmark.end <= deleteOffset) {
6660
+ continue;
6661
+ }
6662
+ if (extmark.start >= deleteOffset + length) {
6663
+ extmark.start -= length;
6664
+ extmark.end -= length;
6665
+ this.emit("extmark-updated", extmark);
6666
+ } else if (extmark.start >= deleteOffset && extmark.end <= deleteOffset + length) {
6667
+ toDelete.push(extmark.id);
6668
+ } else if (extmark.start < deleteOffset && extmark.end > deleteOffset + length) {
6669
+ extmark.end -= length;
6670
+ this.emit("extmark-updated", extmark);
6671
+ } else if (extmark.start < deleteOffset && extmark.end > deleteOffset) {
6672
+ extmark.end -= Math.min(extmark.end, deleteOffset + length) - deleteOffset;
6673
+ this.emit("extmark-updated", extmark);
6674
+ } else if (extmark.start < deleteOffset + length && extmark.end > deleteOffset + length) {
6675
+ const overlap = deleteOffset + length - extmark.start;
6676
+ extmark.start = deleteOffset;
6677
+ extmark.end -= length;
6678
+ this.emit("extmark-updated", extmark);
6679
+ }
6680
+ }
6681
+ for (const id of toDelete) {
6682
+ const extmark = this.extmarks.get(id);
6683
+ if (extmark) {
6684
+ this.extmarks.delete(id);
6685
+ this.emit("extmark-deleted", {
6686
+ extmark,
6687
+ trigger: "manual"
6688
+ });
6689
+ }
6690
+ }
6691
+ this.updateHighlights();
6692
+ }
6693
+ offsetToPosition(offset) {
6694
+ const text = this.editBuffer.getText();
6695
+ let currentOffset = 0;
6696
+ let row = 0;
6697
+ let col = 0;
6698
+ for (let i = 0;i < text.length && currentOffset < offset; i++) {
6699
+ if (text[i] === `
6700
+ `) {
6701
+ row++;
6702
+ col = 0;
6703
+ } else {
6704
+ col++;
6705
+ }
6706
+ currentOffset++;
6707
+ }
6708
+ return { row, col };
6709
+ }
6710
+ positionToOffset(row, col) {
6711
+ const text = this.editBuffer.getText();
6712
+ let currentRow = 0;
6713
+ let offset = 0;
6714
+ for (let i = 0;i < text.length; i++) {
6715
+ if (currentRow === row && offset - this.getLineStartOffset(row) === col) {
6716
+ return offset;
6717
+ }
6718
+ if (text[i] === `
6719
+ `) {
6720
+ currentRow++;
6721
+ }
6722
+ offset++;
6723
+ }
6724
+ return offset;
6725
+ }
6726
+ getLineStartOffset(targetRow) {
6727
+ const text = this.editBuffer.getText();
6728
+ let row = 0;
6729
+ let offset = 0;
6730
+ for (let i = 0;i < text.length; i++) {
6731
+ if (row === targetRow) {
6732
+ return offset;
6733
+ }
6734
+ if (text[i] === `
6735
+ `) {
6736
+ row++;
6737
+ offset = i + 1;
6738
+ }
6739
+ }
6740
+ return offset;
6741
+ }
6742
+ updateHighlights() {
6743
+ this.editBuffer.clearAllHighlights();
6744
+ for (const extmark of this.extmarks.values()) {
6745
+ if (extmark.styleId !== undefined) {
6746
+ const startWithoutNewlines = this.offsetToCharOffset(extmark.start);
6747
+ const endWithoutNewlines = this.offsetToCharOffset(extmark.end);
6748
+ this.editBuffer.addHighlightByCharRange({
6749
+ start: startWithoutNewlines,
6750
+ end: endWithoutNewlines,
6751
+ styleId: extmark.styleId,
6752
+ priority: extmark.priority ?? 0,
6753
+ hlRef: extmark.id
6754
+ });
6755
+ }
6756
+ }
6757
+ }
6758
+ offsetToCharOffset(offset) {
6759
+ const text = this.editBuffer.getText();
6760
+ let charOffset = 0;
6761
+ for (let i = 0;i < offset && i < text.length; i++) {
6762
+ if (text[i] !== `
6763
+ `) {
6764
+ charOffset++;
6765
+ }
6766
+ }
6767
+ return charOffset;
6768
+ }
6769
+ create(options) {
6770
+ if (this.destroyed) {
6771
+ throw new Error("ExtmarksController is destroyed");
6772
+ }
6773
+ const id = this.nextId++;
6774
+ const extmark = {
6775
+ id,
6776
+ start: options.start,
6777
+ end: options.end,
6778
+ virtual: options.virtual ?? false,
6779
+ styleId: options.styleId,
6780
+ priority: options.priority,
6781
+ data: options.data
6782
+ };
6783
+ this.extmarks.set(id, extmark);
6784
+ this.updateHighlights();
6785
+ return id;
6786
+ }
6787
+ update(id, options) {
6788
+ if (this.destroyed) {
6789
+ throw new Error("ExtmarksController is destroyed");
6790
+ }
6791
+ const extmark = this.extmarks.get(id);
6792
+ if (!extmark)
6793
+ return false;
6794
+ if (options.start !== undefined)
6795
+ extmark.start = options.start;
6796
+ if (options.end !== undefined)
6797
+ extmark.end = options.end;
6798
+ if (options.virtual !== undefined)
6799
+ extmark.virtual = options.virtual;
6800
+ if (options.styleId !== undefined)
6801
+ extmark.styleId = options.styleId;
6802
+ if (options.priority !== undefined)
6803
+ extmark.priority = options.priority;
6804
+ if (options.data !== undefined)
6805
+ extmark.data = options.data;
6806
+ this.emit("extmark-updated", extmark);
6807
+ this.updateHighlights();
6808
+ return true;
6809
+ }
6810
+ delete(id) {
6811
+ if (this.destroyed) {
6812
+ throw new Error("ExtmarksController is destroyed");
6813
+ }
6814
+ const extmark = this.extmarks.get(id);
6815
+ if (!extmark)
6816
+ return false;
6817
+ this.extmarks.delete(id);
6818
+ this.emit("extmark-deleted", {
6819
+ extmark,
6820
+ trigger: "manual"
6821
+ });
6822
+ this.updateHighlights();
6823
+ return true;
6824
+ }
6825
+ get(id) {
6826
+ if (this.destroyed)
6827
+ return null;
6828
+ return this.extmarks.get(id) ?? null;
6829
+ }
6830
+ getAll() {
6831
+ if (this.destroyed)
6832
+ return [];
6833
+ return Array.from(this.extmarks.values());
6834
+ }
6835
+ getVirtual() {
6836
+ if (this.destroyed)
6837
+ return [];
6838
+ return Array.from(this.extmarks.values()).filter((e) => e.virtual);
6839
+ }
6840
+ getAtOffset(offset) {
6841
+ if (this.destroyed)
6842
+ return [];
6843
+ return Array.from(this.extmarks.values()).filter((e) => offset >= e.start && offset < e.end);
6844
+ }
6845
+ clear() {
6846
+ if (this.destroyed)
6847
+ return;
6848
+ for (const extmark of this.extmarks.values()) {
6849
+ this.emit("extmark-deleted", {
6850
+ extmark,
6851
+ trigger: "manual"
6852
+ });
6853
+ }
6854
+ this.extmarks.clear();
6855
+ this.updateHighlights();
6856
+ }
6857
+ saveSnapshot() {
6858
+ this.history.saveSnapshot(this.extmarks, this.nextId);
6859
+ }
6860
+ restoreSnapshot(snapshot) {
6861
+ this.extmarks = new Map(Array.from(snapshot.extmarks.entries()).map(([id, extmark]) => [id, { ...extmark }]));
6862
+ this.nextId = snapshot.nextId;
6863
+ this.updateHighlights();
6864
+ }
6865
+ wrapUndoRedo() {
6866
+ this.editBuffer.undo = () => {
6867
+ if (this.destroyed) {
6868
+ return this.originalUndo();
6869
+ }
6870
+ if (!this.history.canUndo()) {
6871
+ return this.originalUndo();
6872
+ }
6873
+ const currentSnapshot = {
6874
+ extmarks: new Map(Array.from(this.extmarks.entries()).map(([id, extmark]) => [id, { ...extmark }])),
6875
+ nextId: this.nextId
6876
+ };
6877
+ this.history.pushRedo(currentSnapshot);
6878
+ const snapshot = this.history.undo();
6879
+ this.restoreSnapshot(snapshot);
6880
+ return this.originalUndo();
6881
+ };
6882
+ this.editBuffer.redo = () => {
6883
+ if (this.destroyed) {
6884
+ return this.originalRedo();
6885
+ }
6886
+ if (!this.history.canRedo()) {
6887
+ return this.originalRedo();
6888
+ }
6889
+ const currentSnapshot = {
6890
+ extmarks: new Map(Array.from(this.extmarks.entries()).map(([id, extmark]) => [id, { ...extmark }])),
6891
+ nextId: this.nextId
6892
+ };
6893
+ this.history.pushUndo(currentSnapshot);
6894
+ const snapshot = this.history.redo();
6895
+ this.restoreSnapshot(snapshot);
6896
+ return this.originalRedo();
6897
+ };
6898
+ }
6899
+ destroy() {
6900
+ if (this.destroyed)
6901
+ return;
6902
+ this.editBuffer.moveCursorLeft = this.originalMoveCursorLeft;
6903
+ this.editBuffer.moveCursorRight = this.originalMoveCursorRight;
6904
+ this.editBuffer.setCursorByOffset = this.originalSetCursorByOffset;
6905
+ this.editorView.moveUpVisual = this.originalMoveUpVisual;
6906
+ this.editorView.moveDownVisual = this.originalMoveDownVisual;
6907
+ this.editBuffer.deleteCharBackward = this.originalDeleteCharBackward;
6908
+ this.editBuffer.deleteChar = this.originalDeleteChar;
6909
+ this.editBuffer.insertText = this.originalInsertText;
6910
+ this.editBuffer.insertChar = this.originalInsertChar;
6911
+ this.editBuffer.deleteRange = this.originalDeleteRange;
6912
+ this.editBuffer.setText = this.originalSetText;
6913
+ this.editBuffer.clear = this.originalClear;
6914
+ this.editBuffer.newLine = this.originalNewLine;
6915
+ this.editBuffer.deleteLine = this.originalDeleteLine;
6916
+ this.editorView.deleteSelectedText = this.originalEditorViewDeleteSelectedText;
6917
+ this.editBuffer.undo = this.originalUndo;
6918
+ this.editBuffer.redo = this.originalRedo;
6919
+ this.extmarks.clear();
6920
+ this.history.clear();
6921
+ this.destroyed = true;
6922
+ this.removeAllListeners();
6923
+ }
6924
+ }
6925
+ function createExtmarksController(editBuffer, editorView) {
6926
+ return new ExtmarksController(editBuffer, editorView);
6927
+ }
6243
6928
  // src/zig.ts
6244
- import { dlopen, toArrayBuffer as toArrayBuffer2, JSCallback, ptr } from "bun:ffi";
6929
+ import { dlopen, toArrayBuffer as toArrayBuffer4, JSCallback, ptr as ptr3 } from "bun:ffi";
6245
6930
  import { existsSync as existsSync2 } from "fs";
6931
+ import { EventEmitter as EventEmitter5 } from "events";
6246
6932
 
6247
6933
  // src/buffer.ts
6248
6934
  import { toArrayBuffer } from "bun:ffi";
@@ -6398,9 +7084,13 @@ class OptimizedBuffer {
6398
7084
  this._destroyed = true;
6399
7085
  this.lib.destroyOptimizedBuffer(this.bufferPtr);
6400
7086
  }
6401
- drawTextBuffer(textBuffer, x, y, clipRect) {
7087
+ drawTextBuffer(textBufferView, x, y) {
7088
+ this.guard();
7089
+ this.lib.bufferDrawTextBufferView(this.bufferPtr, textBufferView.ptr, x, y);
7090
+ }
7091
+ drawEditorView(editorView, x, y) {
6402
7092
  this.guard();
6403
- this.lib.bufferDrawTextBuffer(this.bufferPtr, textBuffer.ptr, x, y, clipRect);
7093
+ this.lib.bufferDrawEditorView(this.bufferPtr, editorView.ptr, x, y);
6404
7094
  }
6405
7095
  drawSuperSampleBuffer(x, y, pixelDataPtr, pixelDataLength, format, alignedBytesPerRow) {
6406
7096
  this.guard();
@@ -6440,6 +7130,624 @@ class OptimizedBuffer {
6440
7130
  }
6441
7131
  }
6442
7132
 
7133
+ // ../../node_modules/.bun/bun-ffi-structs@0.1.0+ca84541ac88a3075/node_modules/bun-ffi-structs/index.js
7134
+ import { ptr, toArrayBuffer as toArrayBuffer2 } from "bun:ffi";
7135
+ function fatalError(...args) {
7136
+ const message = args.join(" ");
7137
+ console.error("FATAL ERROR:", message);
7138
+ throw new Error(message);
7139
+ }
7140
+ var pointerSize = process.arch === "x64" || process.arch === "arm64" ? 8 : 4;
7141
+ var typeSizes = {
7142
+ u8: 1,
7143
+ bool_u8: 1,
7144
+ bool_u32: 4,
7145
+ u16: 2,
7146
+ i16: 2,
7147
+ u32: 4,
7148
+ u64: 8,
7149
+ f32: 4,
7150
+ f64: 8,
7151
+ pointer: pointerSize,
7152
+ i32: 4
7153
+ };
7154
+ var primitiveKeys = Object.keys(typeSizes);
7155
+ function isPrimitiveType(type) {
7156
+ return typeof type === "string" && primitiveKeys.includes(type);
7157
+ }
7158
+ var typeAlignments = { ...typeSizes };
7159
+ var typeGetters = {
7160
+ u8: (view, offset) => view.getUint8(offset),
7161
+ bool_u8: (view, offset) => Boolean(view.getUint8(offset)),
7162
+ bool_u32: (view, offset) => Boolean(view.getUint32(offset, true)),
7163
+ u16: (view, offset) => view.getUint16(offset, true),
7164
+ i16: (view, offset) => view.getInt16(offset, true),
7165
+ u32: (view, offset) => view.getUint32(offset, true),
7166
+ u64: (view, offset) => view.getBigUint64(offset, true),
7167
+ f32: (view, offset) => view.getFloat32(offset, true),
7168
+ f64: (view, offset) => view.getFloat64(offset, true),
7169
+ i32: (view, offset) => view.getInt32(offset, true),
7170
+ pointer: (view, offset) => pointerSize === 8 ? view.getBigUint64(offset, true) : BigInt(view.getUint32(offset, true))
7171
+ };
7172
+ function isObjectPointerDef(type) {
7173
+ return typeof type === "object" && type !== null && type.__type === "objectPointer";
7174
+ }
7175
+ function alignOffset(offset, align) {
7176
+ return offset + (align - 1) & ~(align - 1);
7177
+ }
7178
+ function isEnum(type) {
7179
+ return typeof type === "object" && type.__type === "enum";
7180
+ }
7181
+ function isStruct(type) {
7182
+ return typeof type === "object" && type.__type === "struct";
7183
+ }
7184
+ function primitivePackers(type) {
7185
+ let pack;
7186
+ let unpack;
7187
+ switch (type) {
7188
+ case "u8":
7189
+ pack = (view, off, val) => view.setUint8(off, val);
7190
+ unpack = (view, off) => view.getUint8(off);
7191
+ break;
7192
+ case "bool_u8":
7193
+ pack = (view, off, val) => view.setUint8(off, val ? 1 : 0);
7194
+ unpack = (view, off) => Boolean(view.getUint8(off));
7195
+ break;
7196
+ case "bool_u32":
7197
+ pack = (view, off, val) => view.setUint32(off, val ? 1 : 0, true);
7198
+ unpack = (view, off) => Boolean(view.getUint32(off, true));
7199
+ break;
7200
+ case "u16":
7201
+ pack = (view, off, val) => view.setUint16(off, val, true);
7202
+ unpack = (view, off) => view.getUint16(off, true);
7203
+ break;
7204
+ case "i16":
7205
+ pack = (view, off, val) => view.setInt16(off, val, true);
7206
+ unpack = (view, off) => view.getInt16(off, true);
7207
+ break;
7208
+ case "u32":
7209
+ pack = (view, off, val) => view.setUint32(off, val, true);
7210
+ unpack = (view, off) => view.getUint32(off, true);
7211
+ break;
7212
+ case "i32":
7213
+ pack = (view, off, val) => view.setInt32(off, val, true);
7214
+ unpack = (view, off) => view.getInt32(off, true);
7215
+ break;
7216
+ case "u64":
7217
+ pack = (view, off, val) => view.setBigUint64(off, BigInt(val), true);
7218
+ unpack = (view, off) => view.getBigUint64(off, true);
7219
+ break;
7220
+ case "f32":
7221
+ pack = (view, off, val) => view.setFloat32(off, val, true);
7222
+ unpack = (view, off) => view.getFloat32(off, true);
7223
+ break;
7224
+ case "f64":
7225
+ pack = (view, off, val) => view.setFloat64(off, val, true);
7226
+ unpack = (view, off) => view.getFloat64(off, true);
7227
+ break;
7228
+ case "pointer":
7229
+ pack = (view, off, val) => {
7230
+ pointerSize === 8 ? view.setBigUint64(off, val ? BigInt(val) : 0n, true) : view.setUint32(off, val ? Number(val) : 0, true);
7231
+ };
7232
+ unpack = (view, off) => {
7233
+ const bint = pointerSize === 8 ? view.getBigUint64(off, true) : BigInt(view.getUint32(off, true));
7234
+ return Number(bint);
7235
+ };
7236
+ break;
7237
+ default:
7238
+ fatalError(`Unsupported primitive type: ${type}`);
7239
+ }
7240
+ return { pack, unpack };
7241
+ }
7242
+ var { pack: pointerPacker, unpack: pointerUnpacker } = primitivePackers("pointer");
7243
+ function packObjectArray(val) {
7244
+ const buffer = new ArrayBuffer(val.length * pointerSize);
7245
+ const bufferView = new DataView(buffer);
7246
+ for (let i = 0;i < val.length; i++) {
7247
+ const instance = val[i];
7248
+ const ptrValue = instance?.ptr ?? null;
7249
+ pointerPacker(bufferView, i * pointerSize, ptrValue);
7250
+ }
7251
+ return bufferView;
7252
+ }
7253
+ var encoder = new TextEncoder;
7254
+ function defineStruct(fields, structDefOptions) {
7255
+ let offset = 0;
7256
+ let maxAlign = 1;
7257
+ const layout = [];
7258
+ const lengthOfFields = {};
7259
+ const lengthOfRequested = [];
7260
+ const arrayFieldsMetadata = {};
7261
+ for (const [name, typeOrStruct, options = {}] of fields) {
7262
+ if (options.condition && !options.condition()) {
7263
+ continue;
7264
+ }
7265
+ let size = 0, align = 0;
7266
+ let pack;
7267
+ let unpack;
7268
+ let needsLengthOf = false;
7269
+ let lengthOfDef = null;
7270
+ if (isPrimitiveType(typeOrStruct)) {
7271
+ size = typeSizes[typeOrStruct];
7272
+ align = typeAlignments[typeOrStruct];
7273
+ ({ pack, unpack } = primitivePackers(typeOrStruct));
7274
+ } else if (typeof typeOrStruct === "string" && typeOrStruct === "cstring") {
7275
+ size = pointerSize;
7276
+ align = pointerSize;
7277
+ pack = (view, off, val) => {
7278
+ const bufPtr = val ? ptr(encoder.encode(val + "\x00")) : null;
7279
+ pointerPacker(view, off, bufPtr);
7280
+ };
7281
+ unpack = (view, off) => {
7282
+ const ptrVal = pointerUnpacker(view, off);
7283
+ return ptrVal;
7284
+ };
7285
+ } else if (typeof typeOrStruct === "string" && typeOrStruct === "char*") {
7286
+ size = pointerSize;
7287
+ align = pointerSize;
7288
+ pack = (view, off, val) => {
7289
+ const bufPtr = val ? ptr(encoder.encode(val)) : null;
7290
+ pointerPacker(view, off, bufPtr);
7291
+ };
7292
+ unpack = (view, off) => {
7293
+ const ptrVal = pointerUnpacker(view, off);
7294
+ return ptrVal;
7295
+ };
7296
+ } else if (isEnum(typeOrStruct)) {
7297
+ const base = typeOrStruct.type;
7298
+ size = typeSizes[base];
7299
+ align = typeAlignments[base];
7300
+ const { pack: packEnum } = primitivePackers(base);
7301
+ pack = (view, off, val) => {
7302
+ const num = typeOrStruct.to(val);
7303
+ packEnum(view, off, num);
7304
+ };
7305
+ unpack = (view, off) => {
7306
+ const raw = typeGetters[base](view, off);
7307
+ return typeOrStruct.from(raw);
7308
+ };
7309
+ } else if (isStruct(typeOrStruct)) {
7310
+ if (options.asPointer === true) {
7311
+ size = pointerSize;
7312
+ align = pointerSize;
7313
+ pack = (view, off, val, obj, options2) => {
7314
+ if (!val) {
7315
+ pointerPacker(view, off, null);
7316
+ return;
7317
+ }
7318
+ const nestedBuf = typeOrStruct.pack(val, options2);
7319
+ pointerPacker(view, off, ptr(nestedBuf));
7320
+ };
7321
+ unpack = (view, off) => {
7322
+ throw new Error("Not implemented yet");
7323
+ };
7324
+ } else {
7325
+ size = typeOrStruct.size;
7326
+ align = typeOrStruct.align;
7327
+ pack = (view, off, val, obj, options2) => {
7328
+ const nestedBuf = typeOrStruct.pack(val, options2);
7329
+ const nestedView = new Uint8Array(nestedBuf);
7330
+ const dView = new Uint8Array(view.buffer);
7331
+ dView.set(nestedView, off);
7332
+ };
7333
+ unpack = (view, off) => {
7334
+ const slice = view.buffer.slice(off, off + size);
7335
+ return typeOrStruct.unpack(slice);
7336
+ };
7337
+ }
7338
+ } else if (isObjectPointerDef(typeOrStruct)) {
7339
+ size = pointerSize;
7340
+ align = pointerSize;
7341
+ pack = (view, off, value) => {
7342
+ const ptrValue = value?.ptr ?? null;
7343
+ if (ptrValue === undefined) {
7344
+ console.warn(`Field '${name}' expected object with '.ptr' property, but got undefined pointer value from:`, value);
7345
+ pointerPacker(view, off, null);
7346
+ } else {
7347
+ pointerPacker(view, off, ptrValue);
7348
+ }
7349
+ };
7350
+ unpack = (view, off) => {
7351
+ return pointerUnpacker(view, off);
7352
+ };
7353
+ } else if (Array.isArray(typeOrStruct) && typeOrStruct.length === 1 && typeOrStruct[0] !== undefined) {
7354
+ const [def] = typeOrStruct;
7355
+ size = pointerSize;
7356
+ align = pointerSize;
7357
+ let arrayElementSize;
7358
+ if (isEnum(def)) {
7359
+ arrayElementSize = typeSizes[def.type];
7360
+ pack = (view, off, val, obj) => {
7361
+ if (!val || val.length === 0) {
7362
+ pointerPacker(view, off, null);
7363
+ return;
7364
+ }
7365
+ const buffer = new ArrayBuffer(val.length * arrayElementSize);
7366
+ const bufferView = new DataView(buffer);
7367
+ for (let i = 0;i < val.length; i++) {
7368
+ const num = def.to(val[i]);
7369
+ bufferView.setUint32(i * arrayElementSize, num, true);
7370
+ }
7371
+ pointerPacker(view, off, ptr(buffer));
7372
+ };
7373
+ unpack = null;
7374
+ needsLengthOf = true;
7375
+ lengthOfDef = def;
7376
+ } else if (isStruct(def)) {
7377
+ arrayElementSize = def.size;
7378
+ pack = (view, off, val, obj, options2) => {
7379
+ if (!val || val.length === 0) {
7380
+ pointerPacker(view, off, null);
7381
+ return;
7382
+ }
7383
+ const buffer = new ArrayBuffer(val.length * arrayElementSize);
7384
+ const bufferView = new DataView(buffer);
7385
+ for (let i = 0;i < val.length; i++) {
7386
+ def.packInto(val[i], bufferView, i * arrayElementSize, options2);
7387
+ }
7388
+ pointerPacker(view, off, ptr(buffer));
7389
+ };
7390
+ unpack = (view, off) => {
7391
+ throw new Error("Not implemented yet");
7392
+ };
7393
+ } else if (isPrimitiveType(def)) {
7394
+ arrayElementSize = typeSizes[def];
7395
+ const { pack: primitivePack } = primitivePackers(def);
7396
+ pack = (view, off, val) => {
7397
+ if (!val || val.length === 0) {
7398
+ pointerPacker(view, off, null);
7399
+ return;
7400
+ }
7401
+ const buffer = new ArrayBuffer(val.length * arrayElementSize);
7402
+ const bufferView = new DataView(buffer);
7403
+ for (let i = 0;i < val.length; i++) {
7404
+ primitivePack(bufferView, i * arrayElementSize, val[i]);
7405
+ }
7406
+ pointerPacker(view, off, ptr(buffer));
7407
+ };
7408
+ unpack = null;
7409
+ needsLengthOf = true;
7410
+ lengthOfDef = def;
7411
+ } else if (isObjectPointerDef(def)) {
7412
+ arrayElementSize = pointerSize;
7413
+ pack = (view, off, val) => {
7414
+ if (!val || val.length === 0) {
7415
+ pointerPacker(view, off, null);
7416
+ return;
7417
+ }
7418
+ const packedView = packObjectArray(val);
7419
+ pointerPacker(view, off, ptr(packedView.buffer));
7420
+ };
7421
+ unpack = () => {
7422
+ throw new Error("not implemented yet");
7423
+ };
7424
+ } else {
7425
+ throw new Error(`Unsupported array element type for ${name}: ${JSON.stringify(def)}`);
7426
+ }
7427
+ const lengthOfField = Object.values(lengthOfFields).find((f) => f.lengthOf === name);
7428
+ if (lengthOfField && isPrimitiveType(lengthOfField.type)) {
7429
+ const { pack: lengthPack } = primitivePackers(lengthOfField.type);
7430
+ arrayFieldsMetadata[name] = {
7431
+ elementSize: arrayElementSize,
7432
+ arrayOffset: offset,
7433
+ lengthOffset: lengthOfField.offset,
7434
+ lengthPack
7435
+ };
7436
+ }
7437
+ } else {
7438
+ throw new Error(`Unsupported field type for ${name}: ${JSON.stringify(typeOrStruct)}`);
7439
+ }
7440
+ offset = alignOffset(offset, align);
7441
+ if (options.unpackTransform) {
7442
+ const originalUnpack = unpack;
7443
+ unpack = (view, off) => options.unpackTransform(originalUnpack(view, off));
7444
+ }
7445
+ if (options.packTransform) {
7446
+ const originalPack = pack;
7447
+ pack = (view, off, val, obj, packOptions) => originalPack(view, off, options.packTransform(val), obj, packOptions);
7448
+ }
7449
+ if (options.optional) {
7450
+ const originalPack = pack;
7451
+ if (isStruct(typeOrStruct) && !options.asPointer) {
7452
+ pack = (view, off, val, obj, packOptions) => {
7453
+ if (val || options.mapOptionalInline) {
7454
+ originalPack(view, off, val, obj, packOptions);
7455
+ }
7456
+ };
7457
+ } else {
7458
+ pack = (view, off, val, obj, packOptions) => originalPack(view, off, val ?? 0, obj, packOptions);
7459
+ }
7460
+ }
7461
+ if (options.lengthOf) {
7462
+ const originalPack = pack;
7463
+ pack = (view, off, val, obj, packOptions) => {
7464
+ const targetValue = obj[options.lengthOf];
7465
+ let length = 0;
7466
+ if (targetValue) {
7467
+ if (typeof targetValue === "string") {
7468
+ length = Buffer.byteLength(targetValue);
7469
+ } else {
7470
+ length = targetValue.length;
7471
+ }
7472
+ }
7473
+ return originalPack(view, off, length, obj, packOptions);
7474
+ };
7475
+ }
7476
+ let validateFunctions;
7477
+ if (options.validate) {
7478
+ validateFunctions = Array.isArray(options.validate) ? options.validate : [options.validate];
7479
+ }
7480
+ const layoutField = {
7481
+ name,
7482
+ offset,
7483
+ size,
7484
+ align,
7485
+ validate: validateFunctions,
7486
+ optional: !!options.optional || !!options.lengthOf || options.default !== undefined,
7487
+ default: options.default,
7488
+ pack,
7489
+ unpack,
7490
+ type: typeOrStruct,
7491
+ lengthOf: options.lengthOf
7492
+ };
7493
+ layout.push(layoutField);
7494
+ if (options.lengthOf) {
7495
+ lengthOfFields[options.lengthOf] = layoutField;
7496
+ }
7497
+ if (needsLengthOf) {
7498
+ if (!lengthOfDef)
7499
+ fatalError(`Internal error: needsLengthOf=true but lengthOfDef is null for ${name}`);
7500
+ lengthOfRequested.push({ requester: layoutField, def: lengthOfDef });
7501
+ }
7502
+ offset += size;
7503
+ maxAlign = Math.max(maxAlign, align);
7504
+ }
7505
+ for (const { requester, def } of lengthOfRequested) {
7506
+ const lengthOfField = lengthOfFields[requester.name];
7507
+ if (!lengthOfField) {
7508
+ throw new Error(`lengthOf field not found for array field ${requester.name}`);
7509
+ }
7510
+ if (isPrimitiveType(def)) {
7511
+ const elemSize = typeSizes[def];
7512
+ const { unpack: primitiveUnpack } = primitivePackers(def);
7513
+ requester.unpack = (view, off) => {
7514
+ const result = [];
7515
+ const length = lengthOfField.unpack(view, lengthOfField.offset);
7516
+ const ptrAddress = pointerUnpacker(view, off);
7517
+ if (ptrAddress === 0n && length > 0) {
7518
+ throw new Error(`Array field ${requester.name} has null pointer but length ${length}.`);
7519
+ }
7520
+ if (ptrAddress === 0n || length === 0) {
7521
+ return [];
7522
+ }
7523
+ const buffer = toArrayBuffer2(ptrAddress, 0, length * elemSize);
7524
+ const bufferView = new DataView(buffer);
7525
+ for (let i = 0;i < length; i++) {
7526
+ result.push(primitiveUnpack(bufferView, i * elemSize));
7527
+ }
7528
+ return result;
7529
+ };
7530
+ } else {
7531
+ const elemSize = def.type === "u32" ? 4 : 8;
7532
+ requester.unpack = (view, off) => {
7533
+ const result = [];
7534
+ const length = lengthOfField.unpack(view, lengthOfField.offset);
7535
+ const ptrAddress = pointerUnpacker(view, off);
7536
+ if (ptrAddress === 0n && length > 0) {
7537
+ throw new Error(`Array field ${requester.name} has null pointer but length ${length}.`);
7538
+ }
7539
+ if (ptrAddress === 0n || length === 0) {
7540
+ return [];
7541
+ }
7542
+ const buffer = toArrayBuffer2(ptrAddress, 0, length * elemSize);
7543
+ const bufferView = new DataView(buffer);
7544
+ for (let i = 0;i < length; i++) {
7545
+ result.push(def.from(bufferView.getUint32(i * elemSize, true)));
7546
+ }
7547
+ return result;
7548
+ };
7549
+ }
7550
+ }
7551
+ const totalSize = alignOffset(offset, maxAlign);
7552
+ const description = layout.map((f) => ({
7553
+ name: f.name,
7554
+ offset: f.offset,
7555
+ size: f.size,
7556
+ align: f.align,
7557
+ optional: f.optional,
7558
+ type: f.type,
7559
+ lengthOf: f.lengthOf
7560
+ }));
7561
+ const layoutByName = new Map(description.map((f) => [f.name, f]));
7562
+ const arrayFields = new Map(Object.entries(arrayFieldsMetadata));
7563
+ return {
7564
+ __type: "struct",
7565
+ size: totalSize,
7566
+ align: maxAlign,
7567
+ hasMapValue: !!structDefOptions?.mapValue,
7568
+ layoutByName,
7569
+ arrayFields,
7570
+ pack(obj, options) {
7571
+ const buf = new ArrayBuffer(totalSize);
7572
+ const view = new DataView(buf);
7573
+ let mappedObj = obj;
7574
+ if (structDefOptions?.mapValue) {
7575
+ mappedObj = structDefOptions.mapValue(obj);
7576
+ }
7577
+ for (const field of layout) {
7578
+ const value = mappedObj[field.name] ?? field.default;
7579
+ if (!field.optional && value === undefined) {
7580
+ fatalError(`Packing non-optional field '${field.name}' but value is undefined (and no default provided)`);
7581
+ }
7582
+ if (field.validate) {
7583
+ for (const validateFn of field.validate) {
7584
+ validateFn(value, field.name, {
7585
+ hints: options?.validationHints,
7586
+ input: mappedObj
7587
+ });
7588
+ }
7589
+ }
7590
+ field.pack(view, field.offset, value, mappedObj, options);
7591
+ }
7592
+ return view.buffer;
7593
+ },
7594
+ packInto(obj, view, offset2, options) {
7595
+ let mappedObj = obj;
7596
+ if (structDefOptions?.mapValue) {
7597
+ mappedObj = structDefOptions.mapValue(obj);
7598
+ }
7599
+ for (const field of layout) {
7600
+ const value = mappedObj[field.name] ?? field.default;
7601
+ if (!field.optional && value === undefined) {
7602
+ console.warn(`packInto missing value for non-optional field '${field.name}' at offset ${offset2 + field.offset}. Writing default or zero.`);
7603
+ }
7604
+ if (field.validate) {
7605
+ for (const validateFn of field.validate) {
7606
+ validateFn(value, field.name, {
7607
+ hints: options?.validationHints,
7608
+ input: mappedObj
7609
+ });
7610
+ }
7611
+ }
7612
+ field.pack(view, offset2 + field.offset, value, mappedObj, options);
7613
+ }
7614
+ },
7615
+ unpack(buf) {
7616
+ if (buf.byteLength < totalSize) {
7617
+ fatalError(`Buffer size (${buf.byteLength}) is smaller than struct size (${totalSize}) for unpacking.`);
7618
+ }
7619
+ const view = new DataView(buf);
7620
+ const result = structDefOptions?.default ? { ...structDefOptions.default } : {};
7621
+ for (const field of layout) {
7622
+ if (!field.unpack) {
7623
+ continue;
7624
+ }
7625
+ try {
7626
+ result[field.name] = field.unpack(view, field.offset);
7627
+ } catch (e) {
7628
+ console.error(`Error unpacking field '${field.name}' at offset ${field.offset}:`, e);
7629
+ throw e;
7630
+ }
7631
+ }
7632
+ if (structDefOptions?.reduceValue) {
7633
+ return structDefOptions.reduceValue(result);
7634
+ }
7635
+ return result;
7636
+ },
7637
+ packList(objects, options) {
7638
+ if (objects.length === 0) {
7639
+ return new ArrayBuffer(0);
7640
+ }
7641
+ const buffer = new ArrayBuffer(totalSize * objects.length);
7642
+ const view = new DataView(buffer);
7643
+ for (let i = 0;i < objects.length; i++) {
7644
+ let mappedObj = objects[i];
7645
+ if (structDefOptions?.mapValue) {
7646
+ mappedObj = structDefOptions.mapValue(objects[i]);
7647
+ }
7648
+ for (const field of layout) {
7649
+ const value = mappedObj[field.name] ?? field.default;
7650
+ if (!field.optional && value === undefined) {
7651
+ fatalError(`Packing non-optional field '${field.name}' at index ${i} but value is undefined (and no default provided)`);
7652
+ }
7653
+ if (field.validate) {
7654
+ for (const validateFn of field.validate) {
7655
+ validateFn(value, field.name, {
7656
+ hints: options?.validationHints,
7657
+ input: mappedObj
7658
+ });
7659
+ }
7660
+ }
7661
+ field.pack(view, i * totalSize + field.offset, value, mappedObj, options);
7662
+ }
7663
+ }
7664
+ return buffer;
7665
+ },
7666
+ unpackList(buf, count) {
7667
+ if (count === 0) {
7668
+ return [];
7669
+ }
7670
+ const expectedSize = totalSize * count;
7671
+ if (buf.byteLength < expectedSize) {
7672
+ fatalError(`Buffer size (${buf.byteLength}) is smaller than expected size (${expectedSize}) for unpacking ${count} structs.`);
7673
+ }
7674
+ const view = new DataView(buf);
7675
+ const results = [];
7676
+ for (let i = 0;i < count; i++) {
7677
+ const offset2 = i * totalSize;
7678
+ const result = structDefOptions?.default ? { ...structDefOptions.default } : {};
7679
+ for (const field of layout) {
7680
+ if (!field.unpack) {
7681
+ continue;
7682
+ }
7683
+ try {
7684
+ result[field.name] = field.unpack(view, offset2 + field.offset);
7685
+ } catch (e) {
7686
+ console.error(`Error unpacking field '${field.name}' at index ${i}, offset ${offset2 + field.offset}:`, e);
7687
+ throw e;
7688
+ }
7689
+ }
7690
+ if (structDefOptions?.reduceValue) {
7691
+ results.push(structDefOptions.reduceValue(result));
7692
+ } else {
7693
+ results.push(result);
7694
+ }
7695
+ }
7696
+ return results;
7697
+ },
7698
+ describe() {
7699
+ return description;
7700
+ }
7701
+ };
7702
+ }
7703
+
7704
+ // src/zig-structs.ts
7705
+ import { ptr as ptr2, toArrayBuffer as toArrayBuffer3 } from "bun:ffi";
7706
+ var rgbaPackTransform = (rgba) => rgba ? ptr2(rgba.buffer) : null;
7707
+ var rgbaUnpackTransform = (ptr3) => ptr3 ? RGBA.fromArray(new Float32Array(toArrayBuffer3(ptr3))) : undefined;
7708
+ var StyledChunkStruct = defineStruct([
7709
+ ["text", "char*"],
7710
+ ["text_len", "u64", { lengthOf: "text" }],
7711
+ [
7712
+ "fg",
7713
+ "pointer",
7714
+ {
7715
+ optional: true,
7716
+ packTransform: rgbaPackTransform,
7717
+ unpackTransform: rgbaUnpackTransform
7718
+ }
7719
+ ],
7720
+ [
7721
+ "bg",
7722
+ "pointer",
7723
+ {
7724
+ optional: true,
7725
+ packTransform: rgbaPackTransform,
7726
+ unpackTransform: rgbaUnpackTransform
7727
+ }
7728
+ ],
7729
+ ["attributes", "u8", { optional: true }]
7730
+ ]);
7731
+ var HighlightStruct = defineStruct([
7732
+ ["start", "u32"],
7733
+ ["end", "u32"],
7734
+ ["styleId", "u32"],
7735
+ ["priority", "u8", { default: 0 }],
7736
+ ["hlRef", "u16", { default: 0 }]
7737
+ ]);
7738
+ var LogicalCursorStruct = defineStruct([
7739
+ ["row", "u32"],
7740
+ ["col", "u32"],
7741
+ ["offset", "u32"]
7742
+ ]);
7743
+ var VisualCursorStruct = defineStruct([
7744
+ ["visualRow", "u32"],
7745
+ ["visualCol", "u32"],
7746
+ ["logicalRow", "u32"],
7747
+ ["logicalCol", "u32"],
7748
+ ["offset", "u32"]
7749
+ ]);
7750
+
6443
7751
  // src/zig.ts
6444
7752
  var module = await import(`@opentui/core-${process.platform}-${process.arch}/index.ts`);
6445
7753
  var targetLibPath = module.default;
@@ -6468,6 +7776,10 @@ function getOpenTUILib(libPath) {
6468
7776
  args: ["ptr"],
6469
7777
  returns: "void"
6470
7778
  },
7779
+ setEventCallback: {
7780
+ args: ["ptr"],
7781
+ returns: "void"
7782
+ },
6471
7783
  createRenderer: {
6472
7784
  args: ["u32", "u32", "bool"],
6473
7785
  returns: "ptr"
@@ -6696,15 +8008,15 @@ function getOpenTUILib(libPath) {
6696
8008
  args: ["ptr"],
6697
8009
  returns: "u32"
6698
8010
  },
6699
- textBufferReset: {
8011
+ textBufferGetByteSize: {
6700
8012
  args: ["ptr"],
6701
- returns: "void"
8013
+ returns: "u32"
6702
8014
  },
6703
- textBufferSetSelection: {
6704
- args: ["ptr", "u32", "u32", "ptr", "ptr"],
8015
+ textBufferReset: {
8016
+ args: ["ptr"],
6705
8017
  returns: "void"
6706
8018
  },
6707
- textBufferResetSelection: {
8019
+ textBufferClear: {
6708
8020
  args: ["ptr"],
6709
8021
  returns: "void"
6710
8022
  },
@@ -6724,74 +8036,402 @@ function getOpenTUILib(libPath) {
6724
8036
  args: ["ptr"],
6725
8037
  returns: "void"
6726
8038
  },
6727
- textBufferWriteChunk: {
6728
- args: ["ptr", "ptr", "u32", "ptr", "ptr", "ptr"],
6729
- returns: "u32"
8039
+ textBufferRegisterMemBuffer: {
8040
+ args: ["ptr", "ptr", "usize", "bool"],
8041
+ returns: "u16"
8042
+ },
8043
+ textBufferReplaceMemBuffer: {
8044
+ args: ["ptr", "u8", "ptr", "usize", "bool"],
8045
+ returns: "bool"
6730
8046
  },
6731
- textBufferFinalizeLineInfo: {
8047
+ textBufferClearMemRegistry: {
6732
8048
  args: ["ptr"],
6733
8049
  returns: "void"
6734
8050
  },
8051
+ textBufferSetTextFromMem: {
8052
+ args: ["ptr", "u8"],
8053
+ returns: "void"
8054
+ },
8055
+ textBufferLoadFile: {
8056
+ args: ["ptr", "ptr", "usize"],
8057
+ returns: "bool"
8058
+ },
8059
+ textBufferSetStyledText: {
8060
+ args: ["ptr", "ptr", "usize"],
8061
+ returns: "void"
8062
+ },
6735
8063
  textBufferGetLineCount: {
6736
8064
  args: ["ptr"],
6737
8065
  returns: "u32"
6738
8066
  },
6739
- textBufferGetLineInfoDirect: {
8067
+ textBufferGetPlainText: {
8068
+ args: ["ptr", "ptr", "usize"],
8069
+ returns: "usize"
8070
+ },
8071
+ textBufferAddHighlightByCharRange: {
8072
+ args: ["ptr", "ptr"],
8073
+ returns: "void"
8074
+ },
8075
+ textBufferAddHighlight: {
8076
+ args: ["ptr", "u32", "ptr"],
8077
+ returns: "void"
8078
+ },
8079
+ textBufferRemoveHighlightsByRef: {
8080
+ args: ["ptr", "u16"],
8081
+ returns: "void"
8082
+ },
8083
+ textBufferClearLineHighlights: {
8084
+ args: ["ptr", "u32"],
8085
+ returns: "void"
8086
+ },
8087
+ textBufferClearAllHighlights: {
8088
+ args: ["ptr"],
8089
+ returns: "void"
8090
+ },
8091
+ textBufferSetSyntaxStyle: {
8092
+ args: ["ptr", "ptr"],
8093
+ returns: "void"
8094
+ },
8095
+ textBufferGetLineHighlightsPtr: {
8096
+ args: ["ptr", "u32", "ptr"],
8097
+ returns: "ptr"
8098
+ },
8099
+ textBufferFreeLineHighlights: {
8100
+ args: ["ptr", "usize"],
8101
+ returns: "void"
8102
+ },
8103
+ createTextBufferView: {
8104
+ args: ["ptr"],
8105
+ returns: "ptr"
8106
+ },
8107
+ destroyTextBufferView: {
8108
+ args: ["ptr"],
8109
+ returns: "void"
8110
+ },
8111
+ textBufferViewSetSelection: {
8112
+ args: ["ptr", "u32", "u32", "ptr", "ptr"],
8113
+ returns: "void"
8114
+ },
8115
+ textBufferViewResetSelection: {
8116
+ args: ["ptr"],
8117
+ returns: "void"
8118
+ },
8119
+ textBufferViewGetSelectionInfo: {
8120
+ args: ["ptr"],
8121
+ returns: "u64"
8122
+ },
8123
+ textBufferViewSetLocalSelection: {
8124
+ args: ["ptr", "i32", "i32", "i32", "i32", "ptr", "ptr"],
8125
+ returns: "bool"
8126
+ },
8127
+ textBufferViewResetLocalSelection: {
8128
+ args: ["ptr"],
8129
+ returns: "void"
8130
+ },
8131
+ textBufferViewSetWrapWidth: {
8132
+ args: ["ptr", "u32"],
8133
+ returns: "void"
8134
+ },
8135
+ textBufferViewSetWrapMode: {
8136
+ args: ["ptr", "u8"],
8137
+ returns: "void"
8138
+ },
8139
+ textBufferViewSetViewportSize: {
8140
+ args: ["ptr", "u32", "u32"],
8141
+ returns: "void"
8142
+ },
8143
+ textBufferViewGetVirtualLineCount: {
8144
+ args: ["ptr"],
8145
+ returns: "u32"
8146
+ },
8147
+ textBufferViewGetLineInfoDirect: {
6740
8148
  args: ["ptr", "ptr", "ptr"],
6741
8149
  returns: "u32"
6742
8150
  },
6743
- textBufferGetSelectionInfo: {
8151
+ textBufferViewGetLogicalLineInfoDirect: {
8152
+ args: ["ptr", "ptr", "ptr"],
8153
+ returns: "u32"
8154
+ },
8155
+ textBufferViewGetSelectedText: {
8156
+ args: ["ptr", "ptr", "usize"],
8157
+ returns: "usize"
8158
+ },
8159
+ textBufferViewGetPlainText: {
8160
+ args: ["ptr", "ptr", "usize"],
8161
+ returns: "usize"
8162
+ },
8163
+ bufferDrawTextBufferView: {
8164
+ args: ["ptr", "ptr", "i32", "i32"],
8165
+ returns: "void"
8166
+ },
8167
+ bufferDrawEditorView: {
8168
+ args: ["ptr", "ptr", "i32", "i32"],
8169
+ returns: "void"
8170
+ },
8171
+ createEditorView: {
8172
+ args: ["ptr", "u32", "u32"],
8173
+ returns: "ptr"
8174
+ },
8175
+ destroyEditorView: {
6744
8176
  args: ["ptr"],
6745
- returns: "u64"
8177
+ returns: "void"
8178
+ },
8179
+ editorViewSetViewportSize: {
8180
+ args: ["ptr", "u32", "u32"],
8181
+ returns: "void"
8182
+ },
8183
+ editorViewGetViewport: {
8184
+ args: ["ptr", "ptr", "ptr", "ptr", "ptr"],
8185
+ returns: "void"
8186
+ },
8187
+ editorViewSetScrollMargin: {
8188
+ args: ["ptr", "f32"],
8189
+ returns: "void"
8190
+ },
8191
+ editorViewSetWrapMode: {
8192
+ args: ["ptr", "u8"],
8193
+ returns: "void"
8194
+ },
8195
+ editorViewGetVirtualLineCount: {
8196
+ args: ["ptr"],
8197
+ returns: "u32"
8198
+ },
8199
+ editorViewGetTotalVirtualLineCount: {
8200
+ args: ["ptr"],
8201
+ returns: "u32"
6746
8202
  },
6747
- textBufferGetSelectedText: {
8203
+ editorViewGetTextBufferView: {
8204
+ args: ["ptr"],
8205
+ returns: "ptr"
8206
+ },
8207
+ createEditBuffer: {
8208
+ args: ["u8"],
8209
+ returns: "ptr"
8210
+ },
8211
+ destroyEditBuffer: {
8212
+ args: ["ptr"],
8213
+ returns: "void"
8214
+ },
8215
+ editBufferSetText: {
8216
+ args: ["ptr", "ptr", "usize", "bool"],
8217
+ returns: "void"
8218
+ },
8219
+ editBufferSetTextFromMem: {
8220
+ args: ["ptr", "u8", "bool"],
8221
+ returns: "void"
8222
+ },
8223
+ editBufferGetText: {
6748
8224
  args: ["ptr", "ptr", "usize"],
6749
8225
  returns: "usize"
6750
8226
  },
6751
- textBufferGetPlainText: {
8227
+ editBufferInsertChar: {
8228
+ args: ["ptr", "ptr", "usize"],
8229
+ returns: "void"
8230
+ },
8231
+ editBufferInsertText: {
8232
+ args: ["ptr", "ptr", "usize"],
8233
+ returns: "void"
8234
+ },
8235
+ editBufferDeleteChar: {
8236
+ args: ["ptr"],
8237
+ returns: "void"
8238
+ },
8239
+ editBufferDeleteCharBackward: {
8240
+ args: ["ptr"],
8241
+ returns: "void"
8242
+ },
8243
+ editBufferDeleteRange: {
8244
+ args: ["ptr", "u32", "u32", "u32", "u32"],
8245
+ returns: "void"
8246
+ },
8247
+ editBufferNewLine: {
8248
+ args: ["ptr"],
8249
+ returns: "void"
8250
+ },
8251
+ editBufferDeleteLine: {
8252
+ args: ["ptr"],
8253
+ returns: "void"
8254
+ },
8255
+ editBufferMoveCursorLeft: {
8256
+ args: ["ptr"],
8257
+ returns: "void"
8258
+ },
8259
+ editBufferMoveCursorRight: {
8260
+ args: ["ptr"],
8261
+ returns: "void"
8262
+ },
8263
+ editBufferMoveCursorUp: {
8264
+ args: ["ptr"],
8265
+ returns: "void"
8266
+ },
8267
+ editBufferMoveCursorDown: {
8268
+ args: ["ptr"],
8269
+ returns: "void"
8270
+ },
8271
+ editBufferGotoLine: {
8272
+ args: ["ptr", "u32"],
8273
+ returns: "void"
8274
+ },
8275
+ editBufferSetCursor: {
8276
+ args: ["ptr", "u32", "u32"],
8277
+ returns: "void"
8278
+ },
8279
+ editBufferSetCursorToLineCol: {
8280
+ args: ["ptr", "u32", "u32"],
8281
+ returns: "void"
8282
+ },
8283
+ editBufferSetCursorByOffset: {
8284
+ args: ["ptr", "u32"],
8285
+ returns: "void"
8286
+ },
8287
+ editBufferGetCursorPosition: {
8288
+ args: ["ptr", "ptr"],
8289
+ returns: "void"
8290
+ },
8291
+ editBufferGetId: {
8292
+ args: ["ptr"],
8293
+ returns: "u16"
8294
+ },
8295
+ editBufferGetTextBuffer: {
8296
+ args: ["ptr"],
8297
+ returns: "ptr"
8298
+ },
8299
+ editBufferDebugLogRope: {
8300
+ args: ["ptr"],
8301
+ returns: "void"
8302
+ },
8303
+ editBufferUndo: {
8304
+ args: ["ptr", "ptr", "usize"],
8305
+ returns: "usize"
8306
+ },
8307
+ editBufferRedo: {
6752
8308
  args: ["ptr", "ptr", "usize"],
6753
8309
  returns: "usize"
6754
8310
  },
6755
- textBufferSetLocalSelection: {
8311
+ editBufferCanUndo: {
8312
+ args: ["ptr"],
8313
+ returns: "bool"
8314
+ },
8315
+ editBufferCanRedo: {
8316
+ args: ["ptr"],
8317
+ returns: "bool"
8318
+ },
8319
+ editBufferClearHistory: {
8320
+ args: ["ptr"],
8321
+ returns: "void"
8322
+ },
8323
+ editBufferSetPlaceholder: {
8324
+ args: ["ptr", "ptr", "usize"],
8325
+ returns: "void"
8326
+ },
8327
+ editBufferSetPlaceholderColor: {
8328
+ args: ["ptr", "ptr"],
8329
+ returns: "void"
8330
+ },
8331
+ editBufferClear: {
8332
+ args: ["ptr"],
8333
+ returns: "void"
8334
+ },
8335
+ editBufferGetNextWordBoundary: {
8336
+ args: ["ptr", "ptr"],
8337
+ returns: "void"
8338
+ },
8339
+ editBufferGetPrevWordBoundary: {
8340
+ args: ["ptr", "ptr"],
8341
+ returns: "void"
8342
+ },
8343
+ editBufferGetEOL: {
8344
+ args: ["ptr", "ptr"],
8345
+ returns: "void"
8346
+ },
8347
+ editorViewSetSelection: {
8348
+ args: ["ptr", "u32", "u32", "ptr", "ptr"],
8349
+ returns: "void"
8350
+ },
8351
+ editorViewResetSelection: {
8352
+ args: ["ptr"],
8353
+ returns: "void"
8354
+ },
8355
+ editorViewGetSelection: {
8356
+ args: ["ptr"],
8357
+ returns: "u64"
8358
+ },
8359
+ editorViewSetLocalSelection: {
6756
8360
  args: ["ptr", "i32", "i32", "i32", "i32", "ptr", "ptr"],
6757
8361
  returns: "bool"
6758
8362
  },
6759
- textBufferResetLocalSelection: {
8363
+ editorViewResetLocalSelection: {
8364
+ args: ["ptr"],
8365
+ returns: "void"
8366
+ },
8367
+ editorViewGetSelectedTextBytes: {
8368
+ args: ["ptr", "ptr", "usize"],
8369
+ returns: "usize"
8370
+ },
8371
+ editorViewGetCursor: {
8372
+ args: ["ptr", "ptr", "ptr"],
8373
+ returns: "void"
8374
+ },
8375
+ editorViewGetText: {
8376
+ args: ["ptr", "ptr", "usize"],
8377
+ returns: "usize"
8378
+ },
8379
+ editorViewGetVisualCursor: {
8380
+ args: ["ptr", "ptr"],
8381
+ returns: "void"
8382
+ },
8383
+ editorViewMoveUpVisual: {
6760
8384
  args: ["ptr"],
6761
8385
  returns: "void"
6762
8386
  },
6763
- textBufferInsertChunkGroup: {
6764
- args: ["ptr", "usize", "ptr", "u32", "ptr", "ptr", "u8"],
6765
- returns: "u32"
6766
- },
6767
- textBufferRemoveChunkGroup: {
6768
- args: ["ptr", "usize"],
6769
- returns: "u32"
6770
- },
6771
- textBufferReplaceChunkGroup: {
6772
- args: ["ptr", "usize", "ptr", "u32", "ptr", "ptr", "u8"],
6773
- returns: "u32"
8387
+ editorViewMoveDownVisual: {
8388
+ args: ["ptr"],
8389
+ returns: "void"
6774
8390
  },
6775
- textBufferGetChunkGroupCount: {
8391
+ editorViewDeleteSelectedText: {
6776
8392
  args: ["ptr"],
6777
- returns: "usize"
8393
+ returns: "void"
6778
8394
  },
6779
- textBufferSetWrapWidth: {
8395
+ editorViewSetCursorByOffset: {
6780
8396
  args: ["ptr", "u32"],
6781
8397
  returns: "void"
6782
8398
  },
6783
- textBufferSetWrapMode: {
6784
- args: ["ptr", "u8"],
8399
+ editorViewGetNextWordBoundary: {
8400
+ args: ["ptr", "ptr"],
8401
+ returns: "void"
8402
+ },
8403
+ editorViewGetPrevWordBoundary: {
8404
+ args: ["ptr", "ptr"],
8405
+ returns: "void"
8406
+ },
8407
+ editorViewGetEOL: {
8408
+ args: ["ptr", "ptr"],
6785
8409
  returns: "void"
6786
8410
  },
6787
8411
  getArenaAllocatedBytes: {
6788
8412
  args: [],
6789
8413
  returns: "usize"
6790
8414
  },
6791
- bufferDrawTextBuffer: {
6792
- args: ["ptr", "ptr", "i32", "i32", "i32", "i32", "u32", "u32", "bool"],
8415
+ createSyntaxStyle: {
8416
+ args: [],
8417
+ returns: "ptr"
8418
+ },
8419
+ destroySyntaxStyle: {
8420
+ args: ["ptr"],
6793
8421
  returns: "void"
6794
8422
  },
8423
+ syntaxStyleRegister: {
8424
+ args: ["ptr", "ptr", "usize", "ptr", "ptr", "u8"],
8425
+ returns: "u32"
8426
+ },
8427
+ syntaxStyleResolveByName: {
8428
+ args: ["ptr", "ptr", "usize"],
8429
+ returns: "u32"
8430
+ },
8431
+ syntaxStyleGetStyleCount: {
8432
+ args: ["ptr"],
8433
+ returns: "usize"
8434
+ },
6795
8435
  getTerminalCapabilities: {
6796
8436
  args: ["ptr", "ptr"],
6797
8437
  returns: "void"
@@ -6924,9 +8564,13 @@ class FFIRenderLib {
6924
8564
  encoder = new TextEncoder;
6925
8565
  decoder = new TextDecoder;
6926
8566
  logCallbackWrapper;
8567
+ eventCallbackWrapper;
8568
+ _nativeEvents = new EventEmitter5;
8569
+ _anyEventHandlers = [];
6927
8570
  constructor(libPath) {
6928
8571
  this.opentui = getOpenTUILib(libPath);
6929
8572
  this.setupLogging();
8573
+ this.setupEventBus();
6930
8574
  }
6931
8575
  setupLogging() {
6932
8576
  if (this.logCallbackWrapper) {
@@ -6938,7 +8582,7 @@ class FFIRenderLib {
6938
8582
  if (msgLen === 0 || !msgPtr) {
6939
8583
  return;
6940
8584
  }
6941
- const msgBuffer = toArrayBuffer2(msgPtr, 0, msgLen);
8585
+ const msgBuffer = toArrayBuffer4(msgPtr, 0, msgLen);
6942
8586
  const msgBytes = new Uint8Array(msgBuffer);
6943
8587
  const message = this.decoder.decode(msgBytes);
6944
8588
  switch (level) {
@@ -6973,6 +8617,48 @@ class FFIRenderLib {
6973
8617
  setLogCallback(callbackPtr) {
6974
8618
  this.opentui.symbols.setLogCallback(callbackPtr);
6975
8619
  }
8620
+ setupEventBus() {
8621
+ if (this.eventCallbackWrapper) {
8622
+ return;
8623
+ }
8624
+ const eventCallback = new JSCallback((namePtr, nameLenBigInt, dataPtr, dataLenBigInt) => {
8625
+ try {
8626
+ const nameLen = typeof nameLenBigInt === "bigint" ? Number(nameLenBigInt) : nameLenBigInt;
8627
+ const dataLen = typeof dataLenBigInt === "bigint" ? Number(dataLenBigInt) : dataLenBigInt;
8628
+ if (nameLen === 0 || !namePtr) {
8629
+ return;
8630
+ }
8631
+ const nameBuffer = toArrayBuffer4(namePtr, 0, nameLen);
8632
+ const nameBytes = new Uint8Array(nameBuffer);
8633
+ const eventName = this.decoder.decode(nameBytes);
8634
+ let eventData;
8635
+ if (dataLen > 0 && dataPtr) {
8636
+ eventData = toArrayBuffer4(dataPtr, 0, dataLen).slice();
8637
+ } else {
8638
+ eventData = new ArrayBuffer(0);
8639
+ }
8640
+ queueMicrotask(() => {
8641
+ this._nativeEvents.emit(eventName, eventData);
8642
+ for (const handler of this._anyEventHandlers) {
8643
+ handler(eventName, eventData);
8644
+ }
8645
+ });
8646
+ } catch (error) {
8647
+ console.error("Error in native event callback:", error);
8648
+ }
8649
+ }, {
8650
+ args: ["ptr", "usize", "ptr", "usize"],
8651
+ returns: "void"
8652
+ });
8653
+ this.eventCallbackWrapper = eventCallback;
8654
+ if (!eventCallback.ptr) {
8655
+ throw new Error("Failed to create event callback");
8656
+ }
8657
+ this.setEventCallback(eventCallback.ptr);
8658
+ }
8659
+ setEventCallback(callbackPtr) {
8660
+ this.opentui.symbols.setEventCallback(callbackPtr);
8661
+ }
6976
8662
  createRenderer(width, height, options = { testing: false }) {
6977
8663
  return this.opentui.symbols.createRenderer(width, height, options.testing);
6978
8664
  }
@@ -7013,32 +8699,32 @@ class FFIRenderLib {
7013
8699
  return new OptimizedBuffer(this, bufferPtr, width, height, { id: "current buffer" });
7014
8700
  }
7015
8701
  bufferGetCharPtr(buffer) {
7016
- const ptr2 = this.opentui.symbols.bufferGetCharPtr(buffer);
7017
- if (!ptr2) {
8702
+ const ptr4 = this.opentui.symbols.bufferGetCharPtr(buffer);
8703
+ if (!ptr4) {
7018
8704
  throw new Error("Failed to get char pointer");
7019
8705
  }
7020
- return ptr2;
8706
+ return ptr4;
7021
8707
  }
7022
8708
  bufferGetFgPtr(buffer) {
7023
- const ptr2 = this.opentui.symbols.bufferGetFgPtr(buffer);
7024
- if (!ptr2) {
8709
+ const ptr4 = this.opentui.symbols.bufferGetFgPtr(buffer);
8710
+ if (!ptr4) {
7025
8711
  throw new Error("Failed to get fg pointer");
7026
8712
  }
7027
- return ptr2;
8713
+ return ptr4;
7028
8714
  }
7029
8715
  bufferGetBgPtr(buffer) {
7030
- const ptr2 = this.opentui.symbols.bufferGetBgPtr(buffer);
7031
- if (!ptr2) {
8716
+ const ptr4 = this.opentui.symbols.bufferGetBgPtr(buffer);
8717
+ if (!ptr4) {
7032
8718
  throw new Error("Failed to get bg pointer");
7033
8719
  }
7034
- return ptr2;
8720
+ return ptr4;
7035
8721
  }
7036
8722
  bufferGetAttributesPtr(buffer) {
7037
- const ptr2 = this.opentui.symbols.bufferGetAttributesPtr(buffer);
7038
- if (!ptr2) {
8723
+ const ptr4 = this.opentui.symbols.bufferGetAttributesPtr(buffer);
8724
+ if (!ptr4) {
7039
8725
  throw new Error("Failed to get attributes pointer");
7040
8726
  }
7041
- return ptr2;
8727
+ return ptr4;
7042
8728
  }
7043
8729
  bufferGetRespectAlpha(buffer) {
7044
8730
  return this.opentui.symbols.bufferGetRespectAlpha(buffer);
@@ -7133,120 +8819,498 @@ class FFIRenderLib {
7133
8819
  const idBytes = this.encoder.encode(idToUse);
7134
8820
  const bufferPtr = this.opentui.symbols.createOptimizedBuffer(width, height, respectAlpha, widthMethodCode, idBytes, idBytes.length);
7135
8821
  if (!bufferPtr) {
7136
- throw new Error(`Failed to create optimized buffer: ${width}x${height}`);
8822
+ throw new Error(`Failed to create optimized buffer: ${width}x${height}`);
8823
+ }
8824
+ return new OptimizedBuffer(this, bufferPtr, width, height, { respectAlpha, id });
8825
+ }
8826
+ destroyOptimizedBuffer(bufferPtr) {
8827
+ this.opentui.symbols.destroyOptimizedBuffer(bufferPtr);
8828
+ }
8829
+ drawFrameBuffer(targetBufferPtr, destX, destY, bufferPtr, sourceX, sourceY, sourceWidth, sourceHeight) {
8830
+ const srcX = sourceX ?? 0;
8831
+ const srcY = sourceY ?? 0;
8832
+ const srcWidth = sourceWidth ?? 0;
8833
+ const srcHeight = sourceHeight ?? 0;
8834
+ this.opentui.symbols.drawFrameBuffer(targetBufferPtr, destX, destY, bufferPtr, srcX, srcY, srcWidth, srcHeight);
8835
+ }
8836
+ setDebugOverlay(renderer, enabled, corner) {
8837
+ this.opentui.symbols.setDebugOverlay(renderer, enabled, corner);
8838
+ }
8839
+ clearTerminal(renderer) {
8840
+ this.opentui.symbols.clearTerminal(renderer);
8841
+ }
8842
+ setTerminalTitle(renderer, title) {
8843
+ const titleBytes = this.encoder.encode(title);
8844
+ this.opentui.symbols.setTerminalTitle(renderer, titleBytes, titleBytes.length);
8845
+ }
8846
+ addToHitGrid(renderer, x, y, width, height, id) {
8847
+ this.opentui.symbols.addToHitGrid(renderer, x, y, width, height, id);
8848
+ }
8849
+ checkHit(renderer, x, y) {
8850
+ return this.opentui.symbols.checkHit(renderer, x, y);
8851
+ }
8852
+ dumpHitGrid(renderer) {
8853
+ this.opentui.symbols.dumpHitGrid(renderer);
8854
+ }
8855
+ dumpBuffers(renderer, timestamp) {
8856
+ const ts = timestamp ?? Date.now();
8857
+ this.opentui.symbols.dumpBuffers(renderer, ts);
8858
+ }
8859
+ dumpStdoutBuffer(renderer, timestamp) {
8860
+ const ts = timestamp ?? Date.now();
8861
+ this.opentui.symbols.dumpStdoutBuffer(renderer, ts);
8862
+ }
8863
+ enableMouse(renderer, enableMovement) {
8864
+ this.opentui.symbols.enableMouse(renderer, enableMovement);
8865
+ }
8866
+ disableMouse(renderer) {
8867
+ this.opentui.symbols.disableMouse(renderer);
8868
+ }
8869
+ enableKittyKeyboard(renderer, flags) {
8870
+ this.opentui.symbols.enableKittyKeyboard(renderer, flags);
8871
+ }
8872
+ disableKittyKeyboard(renderer) {
8873
+ this.opentui.symbols.disableKittyKeyboard(renderer);
8874
+ }
8875
+ setupTerminal(renderer, useAlternateScreen) {
8876
+ this.opentui.symbols.setupTerminal(renderer, useAlternateScreen);
8877
+ }
8878
+ queryPixelResolution(renderer) {
8879
+ this.opentui.symbols.queryPixelResolution(renderer);
8880
+ }
8881
+ createTextBuffer(widthMethod) {
8882
+ const widthMethodCode = widthMethod === "wcwidth" ? 0 : 1;
8883
+ const bufferPtr = this.opentui.symbols.createTextBuffer(widthMethodCode);
8884
+ if (!bufferPtr) {
8885
+ throw new Error(`Failed to create TextBuffer`);
8886
+ }
8887
+ return new TextBuffer(this, bufferPtr);
8888
+ }
8889
+ destroyTextBuffer(buffer) {
8890
+ this.opentui.symbols.destroyTextBuffer(buffer);
8891
+ }
8892
+ textBufferGetLength(buffer) {
8893
+ return this.opentui.symbols.textBufferGetLength(buffer);
8894
+ }
8895
+ textBufferGetByteSize(buffer) {
8896
+ return this.opentui.symbols.textBufferGetByteSize(buffer);
8897
+ }
8898
+ textBufferReset(buffer) {
8899
+ this.opentui.symbols.textBufferReset(buffer);
8900
+ }
8901
+ textBufferClear(buffer) {
8902
+ this.opentui.symbols.textBufferClear(buffer);
8903
+ }
8904
+ textBufferSetDefaultFg(buffer, fg2) {
8905
+ const fgPtr = fg2 ? fg2.buffer : null;
8906
+ this.opentui.symbols.textBufferSetDefaultFg(buffer, fgPtr);
8907
+ }
8908
+ textBufferSetDefaultBg(buffer, bg2) {
8909
+ const bgPtr = bg2 ? bg2.buffer : null;
8910
+ this.opentui.symbols.textBufferSetDefaultBg(buffer, bgPtr);
8911
+ }
8912
+ textBufferSetDefaultAttributes(buffer, attributes) {
8913
+ const attrValue = attributes === null ? null : new Uint8Array([attributes]);
8914
+ this.opentui.symbols.textBufferSetDefaultAttributes(buffer, attrValue);
8915
+ }
8916
+ textBufferResetDefaults(buffer) {
8917
+ this.opentui.symbols.textBufferResetDefaults(buffer);
8918
+ }
8919
+ textBufferRegisterMemBuffer(buffer, bytes, owned = false) {
8920
+ const result = this.opentui.symbols.textBufferRegisterMemBuffer(buffer, bytes, bytes.length, owned);
8921
+ if (result === 65535) {
8922
+ throw new Error("Failed to register memory buffer");
8923
+ }
8924
+ return result;
8925
+ }
8926
+ textBufferReplaceMemBuffer(buffer, memId, bytes, owned = false) {
8927
+ return this.opentui.symbols.textBufferReplaceMemBuffer(buffer, memId, bytes, bytes.length, owned);
8928
+ }
8929
+ textBufferClearMemRegistry(buffer) {
8930
+ this.opentui.symbols.textBufferClearMemRegistry(buffer);
8931
+ }
8932
+ textBufferSetTextFromMem(buffer, memId) {
8933
+ this.opentui.symbols.textBufferSetTextFromMem(buffer, memId);
8934
+ }
8935
+ textBufferLoadFile(buffer, path4) {
8936
+ const pathBytes = this.encoder.encode(path4);
8937
+ return this.opentui.symbols.textBufferLoadFile(buffer, pathBytes, pathBytes.length);
8938
+ }
8939
+ textBufferSetStyledText(buffer, chunks) {
8940
+ const nonEmptyChunks = chunks.filter((c) => c.text.length > 0);
8941
+ if (nonEmptyChunks.length === 0) {
8942
+ this.textBufferClear(buffer);
8943
+ return;
8944
+ }
8945
+ const chunksBuffer = StyledChunkStruct.packList(nonEmptyChunks);
8946
+ this.opentui.symbols.textBufferSetStyledText(buffer, ptr3(chunksBuffer), nonEmptyChunks.length);
8947
+ }
8948
+ textBufferGetLineCount(buffer) {
8949
+ return this.opentui.symbols.textBufferGetLineCount(buffer);
8950
+ }
8951
+ textBufferGetPlainText(buffer, outPtr, maxLen) {
8952
+ const result = this.opentui.symbols.textBufferGetPlainText(buffer, outPtr, maxLen);
8953
+ return typeof result === "bigint" ? Number(result) : result;
8954
+ }
8955
+ getPlainTextBytes(buffer, maxLength) {
8956
+ const outBuffer = new Uint8Array(maxLength);
8957
+ const actualLen = this.textBufferGetPlainText(buffer, ptr3(outBuffer), maxLength);
8958
+ if (actualLen === 0) {
8959
+ return null;
8960
+ }
8961
+ return outBuffer.slice(0, actualLen);
8962
+ }
8963
+ createTextBufferView(textBuffer) {
8964
+ const viewPtr = this.opentui.symbols.createTextBufferView(textBuffer);
8965
+ if (!viewPtr) {
8966
+ throw new Error("Failed to create TextBufferView");
8967
+ }
8968
+ return viewPtr;
8969
+ }
8970
+ destroyTextBufferView(view) {
8971
+ this.opentui.symbols.destroyTextBufferView(view);
8972
+ }
8973
+ textBufferViewSetSelection(view, start, end, bgColor, fgColor) {
8974
+ const bg2 = bgColor ? bgColor.buffer : null;
8975
+ const fg2 = fgColor ? fgColor.buffer : null;
8976
+ this.opentui.symbols.textBufferViewSetSelection(view, start, end, bg2, fg2);
8977
+ }
8978
+ textBufferViewResetSelection(view) {
8979
+ this.opentui.symbols.textBufferViewResetSelection(view);
8980
+ }
8981
+ textBufferViewGetSelection(view) {
8982
+ const packedInfo = this.textBufferViewGetSelectionInfo(view);
8983
+ if (packedInfo === 0xffff_ffff_ffff_ffffn) {
8984
+ return null;
8985
+ }
8986
+ const start = Number(packedInfo >> 32n);
8987
+ const end = Number(packedInfo & 0xffff_ffffn);
8988
+ return { start, end };
8989
+ }
8990
+ textBufferViewGetSelectionInfo(view) {
8991
+ return this.opentui.symbols.textBufferViewGetSelectionInfo(view);
8992
+ }
8993
+ textBufferViewSetLocalSelection(view, anchorX, anchorY, focusX, focusY, bgColor, fgColor) {
8994
+ const bg2 = bgColor ? bgColor.buffer : null;
8995
+ const fg2 = fgColor ? fgColor.buffer : null;
8996
+ return this.opentui.symbols.textBufferViewSetLocalSelection(view, anchorX, anchorY, focusX, focusY, bg2, fg2);
8997
+ }
8998
+ textBufferViewResetLocalSelection(view) {
8999
+ this.opentui.symbols.textBufferViewResetLocalSelection(view);
9000
+ }
9001
+ textBufferViewSetWrapWidth(view, width) {
9002
+ this.opentui.symbols.textBufferViewSetWrapWidth(view, width);
9003
+ }
9004
+ textBufferViewSetWrapMode(view, mode) {
9005
+ const modeValue = mode === "none" ? 0 : mode === "char" ? 1 : 2;
9006
+ this.opentui.symbols.textBufferViewSetWrapMode(view, modeValue);
9007
+ }
9008
+ textBufferViewSetViewportSize(view, width, height) {
9009
+ this.opentui.symbols.textBufferViewSetViewportSize(view, width, height);
9010
+ }
9011
+ textBufferViewGetLineInfo(view) {
9012
+ const lineCount = this.textBufferViewGetLineCount(view);
9013
+ if (lineCount === 0) {
9014
+ return { lineStarts: [], lineWidths: [], maxLineWidth: 0 };
9015
+ }
9016
+ const lineStarts = new Uint32Array(lineCount);
9017
+ const lineWidths = new Uint32Array(lineCount);
9018
+ const maxLineWidth = this.textBufferViewGetLineInfoDirect(view, ptr3(lineStarts), ptr3(lineWidths));
9019
+ return {
9020
+ maxLineWidth,
9021
+ lineStarts: Array.from(lineStarts),
9022
+ lineWidths: Array.from(lineWidths)
9023
+ };
9024
+ }
9025
+ textBufferViewGetLogicalLineInfo(view) {
9026
+ const lineCount = this.textBufferViewGetLineCount(view);
9027
+ if (lineCount === 0) {
9028
+ return { lineStarts: [], lineWidths: [], maxLineWidth: 0 };
9029
+ }
9030
+ const lineStarts = new Uint32Array(lineCount);
9031
+ const lineWidths = new Uint32Array(lineCount);
9032
+ const maxLineWidth = this.textBufferViewGetLogicalLineInfoDirect(view, ptr3(lineStarts), ptr3(lineWidths));
9033
+ return {
9034
+ maxLineWidth,
9035
+ lineStarts: Array.from(lineStarts),
9036
+ lineWidths: Array.from(lineWidths)
9037
+ };
9038
+ }
9039
+ textBufferViewGetLineCount(view) {
9040
+ return this.opentui.symbols.textBufferViewGetVirtualLineCount(view);
9041
+ }
9042
+ textBufferViewGetLineInfoDirect(view, lineStartsPtr, lineWidthsPtr) {
9043
+ return this.opentui.symbols.textBufferViewGetLineInfoDirect(view, lineStartsPtr, lineWidthsPtr);
9044
+ }
9045
+ textBufferViewGetLogicalLineInfoDirect(view, lineStartsPtr, lineWidthsPtr) {
9046
+ return this.opentui.symbols.textBufferViewGetLogicalLineInfoDirect(view, lineStartsPtr, lineWidthsPtr);
9047
+ }
9048
+ textBufferViewGetSelectedText(view, outPtr, maxLen) {
9049
+ const result = this.opentui.symbols.textBufferViewGetSelectedText(view, outPtr, maxLen);
9050
+ return typeof result === "bigint" ? Number(result) : result;
9051
+ }
9052
+ textBufferViewGetPlainText(view, outPtr, maxLen) {
9053
+ const result = this.opentui.symbols.textBufferViewGetPlainText(view, outPtr, maxLen);
9054
+ return typeof result === "bigint" ? Number(result) : result;
9055
+ }
9056
+ textBufferViewGetSelectedTextBytes(view, maxLength) {
9057
+ const outBuffer = new Uint8Array(maxLength);
9058
+ const actualLen = this.textBufferViewGetSelectedText(view, ptr3(outBuffer), maxLength);
9059
+ if (actualLen === 0) {
9060
+ return null;
9061
+ }
9062
+ return outBuffer.slice(0, actualLen);
9063
+ }
9064
+ textBufferViewGetPlainTextBytes(view, maxLength) {
9065
+ const outBuffer = new Uint8Array(maxLength);
9066
+ const actualLen = this.textBufferViewGetPlainText(view, ptr3(outBuffer), maxLength);
9067
+ if (actualLen === 0) {
9068
+ return null;
9069
+ }
9070
+ return outBuffer.slice(0, actualLen);
9071
+ }
9072
+ textBufferAddHighlightByCharRange(buffer, highlight) {
9073
+ const packedHighlight = HighlightStruct.pack(highlight);
9074
+ this.opentui.symbols.textBufferAddHighlightByCharRange(buffer, ptr3(packedHighlight));
9075
+ }
9076
+ textBufferAddHighlight(buffer, lineIdx, highlight) {
9077
+ const packedHighlight = HighlightStruct.pack(highlight);
9078
+ this.opentui.symbols.textBufferAddHighlight(buffer, lineIdx, ptr3(packedHighlight));
9079
+ }
9080
+ textBufferRemoveHighlightsByRef(buffer, hlRef) {
9081
+ this.opentui.symbols.textBufferRemoveHighlightsByRef(buffer, hlRef);
9082
+ }
9083
+ textBufferClearLineHighlights(buffer, lineIdx) {
9084
+ this.opentui.symbols.textBufferClearLineHighlights(buffer, lineIdx);
9085
+ }
9086
+ textBufferClearAllHighlights(buffer) {
9087
+ this.opentui.symbols.textBufferClearAllHighlights(buffer);
9088
+ }
9089
+ textBufferSetSyntaxStyle(buffer, style) {
9090
+ this.opentui.symbols.textBufferSetSyntaxStyle(buffer, style);
9091
+ }
9092
+ textBufferGetLineHighlights(buffer, lineIdx) {
9093
+ const outCountBuf = new BigUint64Array(1);
9094
+ const nativePtr = this.opentui.symbols.textBufferGetLineHighlightsPtr(buffer, lineIdx, ptr3(outCountBuf));
9095
+ if (!nativePtr)
9096
+ return [];
9097
+ const count = Number(outCountBuf[0]);
9098
+ const byteLen = count * HighlightStruct.size;
9099
+ const raw = toArrayBuffer4(nativePtr, 0, byteLen);
9100
+ const results = HighlightStruct.unpackList(raw, count);
9101
+ this.opentui.symbols.textBufferFreeLineHighlights(nativePtr, count);
9102
+ return results;
9103
+ }
9104
+ getArenaAllocatedBytes() {
9105
+ const result = this.opentui.symbols.getArenaAllocatedBytes();
9106
+ return typeof result === "bigint" ? Number(result) : result;
9107
+ }
9108
+ bufferDrawTextBufferView(buffer, view, x, y) {
9109
+ this.opentui.symbols.bufferDrawTextBufferView(buffer, view, x, y);
9110
+ }
9111
+ bufferDrawEditorView(buffer, view, x, y) {
9112
+ this.opentui.symbols.bufferDrawEditorView(buffer, view, x, y);
9113
+ }
9114
+ createEditorView(editBufferPtr, viewportWidth, viewportHeight) {
9115
+ const viewPtr = this.opentui.symbols.createEditorView(editBufferPtr, viewportWidth, viewportHeight);
9116
+ if (!viewPtr) {
9117
+ throw new Error("Failed to create EditorView");
9118
+ }
9119
+ return viewPtr;
9120
+ }
9121
+ destroyEditorView(view) {
9122
+ this.opentui.symbols.destroyEditorView(view);
9123
+ }
9124
+ editorViewSetViewportSize(view, width, height) {
9125
+ this.opentui.symbols.editorViewSetViewportSize(view, width, height);
9126
+ }
9127
+ editorViewGetViewport(view) {
9128
+ const x = new Uint32Array(1);
9129
+ const y = new Uint32Array(1);
9130
+ const width = new Uint32Array(1);
9131
+ const height = new Uint32Array(1);
9132
+ this.opentui.symbols.editorViewGetViewport(view, ptr3(x), ptr3(y), ptr3(width), ptr3(height));
9133
+ return {
9134
+ offsetX: x[0],
9135
+ offsetY: y[0],
9136
+ width: width[0],
9137
+ height: height[0]
9138
+ };
9139
+ }
9140
+ editorViewSetScrollMargin(view, margin) {
9141
+ this.opentui.symbols.editorViewSetScrollMargin(view, margin);
9142
+ }
9143
+ editorViewSetWrapMode(view, mode) {
9144
+ const modeValue = mode === "none" ? 0 : mode === "char" ? 1 : 2;
9145
+ this.opentui.symbols.editorViewSetWrapMode(view, modeValue);
9146
+ }
9147
+ editorViewGetVirtualLineCount(view) {
9148
+ return this.opentui.symbols.editorViewGetVirtualLineCount(view);
9149
+ }
9150
+ editorViewGetTotalVirtualLineCount(view) {
9151
+ return this.opentui.symbols.editorViewGetTotalVirtualLineCount(view);
9152
+ }
9153
+ editorViewGetTextBufferView(view) {
9154
+ const result = this.opentui.symbols.editorViewGetTextBufferView(view);
9155
+ if (!result) {
9156
+ throw new Error("Failed to get TextBufferView from EditorView");
9157
+ }
9158
+ return result;
9159
+ }
9160
+ createEditBuffer(widthMethod) {
9161
+ const widthMethodCode = widthMethod === "wcwidth" ? 0 : 1;
9162
+ const bufferPtr = this.opentui.symbols.createEditBuffer(widthMethodCode);
9163
+ if (!bufferPtr) {
9164
+ throw new Error("Failed to create EditBuffer");
7137
9165
  }
7138
- return new OptimizedBuffer(this, bufferPtr, width, height, { respectAlpha, id });
9166
+ return bufferPtr;
7139
9167
  }
7140
- destroyOptimizedBuffer(bufferPtr) {
7141
- this.opentui.symbols.destroyOptimizedBuffer(bufferPtr);
9168
+ destroyEditBuffer(buffer) {
9169
+ this.opentui.symbols.destroyEditBuffer(buffer);
7142
9170
  }
7143
- drawFrameBuffer(targetBufferPtr, destX, destY, bufferPtr, sourceX, sourceY, sourceWidth, sourceHeight) {
7144
- const srcX = sourceX ?? 0;
7145
- const srcY = sourceY ?? 0;
7146
- const srcWidth = sourceWidth ?? 0;
7147
- const srcHeight = sourceHeight ?? 0;
7148
- this.opentui.symbols.drawFrameBuffer(targetBufferPtr, destX, destY, bufferPtr, srcX, srcY, srcWidth, srcHeight);
9171
+ editBufferSetText(buffer, textBytes, retainHistory = true) {
9172
+ this.opentui.symbols.editBufferSetText(buffer, textBytes, textBytes.length, retainHistory);
7149
9173
  }
7150
- setDebugOverlay(renderer, enabled, corner) {
7151
- this.opentui.symbols.setDebugOverlay(renderer, enabled, corner);
9174
+ editBufferSetTextFromMem(buffer, memId, retainHistory = true) {
9175
+ this.opentui.symbols.editBufferSetTextFromMem(buffer, memId, retainHistory);
7152
9176
  }
7153
- clearTerminal(renderer) {
7154
- this.opentui.symbols.clearTerminal(renderer);
9177
+ editBufferGetText(buffer, maxLength) {
9178
+ const outBuffer = new Uint8Array(maxLength);
9179
+ const actualLen = this.opentui.symbols.editBufferGetText(buffer, ptr3(outBuffer), maxLength);
9180
+ const len = typeof actualLen === "bigint" ? Number(actualLen) : actualLen;
9181
+ if (len === 0)
9182
+ return null;
9183
+ return outBuffer.slice(0, len);
7155
9184
  }
7156
- setTerminalTitle(renderer, title) {
7157
- const titleBytes = this.encoder.encode(title);
7158
- this.opentui.symbols.setTerminalTitle(renderer, titleBytes, titleBytes.length);
9185
+ editBufferInsertChar(buffer, char) {
9186
+ const charBytes = this.encoder.encode(char);
9187
+ this.opentui.symbols.editBufferInsertChar(buffer, charBytes, charBytes.length);
7159
9188
  }
7160
- addToHitGrid(renderer, x, y, width, height, id) {
7161
- this.opentui.symbols.addToHitGrid(renderer, x, y, width, height, id);
9189
+ editBufferInsertText(buffer, text) {
9190
+ const textBytes = this.encoder.encode(text);
9191
+ this.opentui.symbols.editBufferInsertText(buffer, textBytes, textBytes.length);
7162
9192
  }
7163
- checkHit(renderer, x, y) {
7164
- return this.opentui.symbols.checkHit(renderer, x, y);
9193
+ editBufferDeleteChar(buffer) {
9194
+ this.opentui.symbols.editBufferDeleteChar(buffer);
7165
9195
  }
7166
- dumpHitGrid(renderer) {
7167
- this.opentui.symbols.dumpHitGrid(renderer);
9196
+ editBufferDeleteCharBackward(buffer) {
9197
+ this.opentui.symbols.editBufferDeleteCharBackward(buffer);
7168
9198
  }
7169
- dumpBuffers(renderer, timestamp) {
7170
- const ts = timestamp ?? Date.now();
7171
- this.opentui.symbols.dumpBuffers(renderer, ts);
9199
+ editBufferDeleteRange(buffer, startLine, startCol, endLine, endCol) {
9200
+ this.opentui.symbols.editBufferDeleteRange(buffer, startLine, startCol, endLine, endCol);
7172
9201
  }
7173
- dumpStdoutBuffer(renderer, timestamp) {
7174
- const ts = timestamp ?? Date.now();
7175
- this.opentui.symbols.dumpStdoutBuffer(renderer, ts);
9202
+ editBufferNewLine(buffer) {
9203
+ this.opentui.symbols.editBufferNewLine(buffer);
7176
9204
  }
7177
- enableMouse(renderer, enableMovement) {
7178
- this.opentui.symbols.enableMouse(renderer, enableMovement);
9205
+ editBufferDeleteLine(buffer) {
9206
+ this.opentui.symbols.editBufferDeleteLine(buffer);
7179
9207
  }
7180
- disableMouse(renderer) {
7181
- this.opentui.symbols.disableMouse(renderer);
9208
+ editBufferMoveCursorLeft(buffer) {
9209
+ this.opentui.symbols.editBufferMoveCursorLeft(buffer);
7182
9210
  }
7183
- enableKittyKeyboard(renderer, flags) {
7184
- this.opentui.symbols.enableKittyKeyboard(renderer, flags);
9211
+ editBufferMoveCursorRight(buffer) {
9212
+ this.opentui.symbols.editBufferMoveCursorRight(buffer);
7185
9213
  }
7186
- disableKittyKeyboard(renderer) {
7187
- this.opentui.symbols.disableKittyKeyboard(renderer);
9214
+ editBufferMoveCursorUp(buffer) {
9215
+ this.opentui.symbols.editBufferMoveCursorUp(buffer);
7188
9216
  }
7189
- setupTerminal(renderer, useAlternateScreen) {
7190
- this.opentui.symbols.setupTerminal(renderer, useAlternateScreen);
9217
+ editBufferMoveCursorDown(buffer) {
9218
+ this.opentui.symbols.editBufferMoveCursorDown(buffer);
7191
9219
  }
7192
- queryPixelResolution(renderer) {
7193
- this.opentui.symbols.queryPixelResolution(renderer);
9220
+ editBufferGotoLine(buffer, line) {
9221
+ this.opentui.symbols.editBufferGotoLine(buffer, line);
7194
9222
  }
7195
- createTextBuffer(widthMethod) {
7196
- const widthMethodCode = widthMethod === "wcwidth" ? 0 : 1;
7197
- const bufferPtr = this.opentui.symbols.createTextBuffer(widthMethodCode);
7198
- if (!bufferPtr) {
7199
- throw new Error(`Failed to create TextBuffer`);
9223
+ editBufferSetCursor(buffer, line, byteOffset) {
9224
+ this.opentui.symbols.editBufferSetCursor(buffer, line, byteOffset);
9225
+ }
9226
+ editBufferSetCursorToLineCol(buffer, line, col) {
9227
+ this.opentui.symbols.editBufferSetCursorToLineCol(buffer, line, col);
9228
+ }
9229
+ editBufferSetCursorByOffset(buffer, offset) {
9230
+ this.opentui.symbols.editBufferSetCursorByOffset(buffer, offset);
9231
+ }
9232
+ editBufferGetCursorPosition(buffer) {
9233
+ const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size);
9234
+ this.opentui.symbols.editBufferGetCursorPosition(buffer, ptr3(cursorBuffer));
9235
+ return LogicalCursorStruct.unpack(cursorBuffer);
9236
+ }
9237
+ editBufferGetId(buffer) {
9238
+ return this.opentui.symbols.editBufferGetId(buffer);
9239
+ }
9240
+ editBufferGetTextBuffer(buffer) {
9241
+ const result = this.opentui.symbols.editBufferGetTextBuffer(buffer);
9242
+ if (!result) {
9243
+ throw new Error("Failed to get TextBuffer from EditBuffer");
7200
9244
  }
7201
- return new TextBuffer(this, bufferPtr);
9245
+ return result;
7202
9246
  }
7203
- destroyTextBuffer(buffer) {
7204
- this.opentui.symbols.destroyTextBuffer(buffer);
9247
+ editBufferDebugLogRope(buffer) {
9248
+ this.opentui.symbols.editBufferDebugLogRope(buffer);
7205
9249
  }
7206
- textBufferGetLength(buffer) {
7207
- return this.opentui.symbols.textBufferGetLength(buffer);
9250
+ editBufferUndo(buffer, maxLength) {
9251
+ const outBuffer = new Uint8Array(maxLength);
9252
+ const actualLen = this.opentui.symbols.editBufferUndo(buffer, ptr3(outBuffer), maxLength);
9253
+ const len = typeof actualLen === "bigint" ? Number(actualLen) : actualLen;
9254
+ if (len === 0)
9255
+ return null;
9256
+ return outBuffer.slice(0, len);
7208
9257
  }
7209
- textBufferReset(buffer) {
7210
- this.opentui.symbols.textBufferReset(buffer);
9258
+ editBufferRedo(buffer, maxLength) {
9259
+ const outBuffer = new Uint8Array(maxLength);
9260
+ const actualLen = this.opentui.symbols.editBufferRedo(buffer, ptr3(outBuffer), maxLength);
9261
+ const len = typeof actualLen === "bigint" ? Number(actualLen) : actualLen;
9262
+ if (len === 0)
9263
+ return null;
9264
+ return outBuffer.slice(0, len);
7211
9265
  }
7212
- textBufferSetSelection(buffer, start, end, bgColor, fgColor) {
7213
- const bg2 = bgColor ? bgColor.buffer : null;
7214
- const fg2 = fgColor ? fgColor.buffer : null;
7215
- this.opentui.symbols.textBufferSetSelection(buffer, start, end, bg2, fg2);
9266
+ editBufferCanUndo(buffer) {
9267
+ return this.opentui.symbols.editBufferCanUndo(buffer);
7216
9268
  }
7217
- textBufferResetSelection(buffer) {
7218
- this.opentui.symbols.textBufferResetSelection(buffer);
9269
+ editBufferCanRedo(buffer) {
9270
+ return this.opentui.symbols.editBufferCanRedo(buffer);
7219
9271
  }
7220
- textBufferSetDefaultFg(buffer, fg2) {
7221
- const fgPtr = fg2 ? fg2.buffer : null;
7222
- this.opentui.symbols.textBufferSetDefaultFg(buffer, fgPtr);
9272
+ editBufferClearHistory(buffer) {
9273
+ this.opentui.symbols.editBufferClearHistory(buffer);
7223
9274
  }
7224
- textBufferSetDefaultBg(buffer, bg2) {
7225
- const bgPtr = bg2 ? bg2.buffer : null;
7226
- this.opentui.symbols.textBufferSetDefaultBg(buffer, bgPtr);
9275
+ editBufferSetPlaceholder(buffer, text) {
9276
+ if (text === null) {
9277
+ this.opentui.symbols.editBufferSetPlaceholder(buffer, null, 0);
9278
+ } else {
9279
+ const textBytes = this.encoder.encode(text);
9280
+ this.opentui.symbols.editBufferSetPlaceholder(buffer, textBytes, textBytes.length);
9281
+ }
7227
9282
  }
7228
- textBufferSetDefaultAttributes(buffer, attributes) {
7229
- const attrValue = attributes === null ? null : new Uint8Array([attributes]);
7230
- this.opentui.symbols.textBufferSetDefaultAttributes(buffer, attrValue);
9283
+ editBufferSetPlaceholderColor(buffer, color) {
9284
+ this.opentui.symbols.editBufferSetPlaceholderColor(buffer, color.buffer);
7231
9285
  }
7232
- textBufferResetDefaults(buffer) {
7233
- this.opentui.symbols.textBufferResetDefaults(buffer);
9286
+ editBufferClear(buffer) {
9287
+ this.opentui.symbols.editBufferClear(buffer);
7234
9288
  }
7235
- textBufferWriteChunk(buffer, textBytes, fg2, bg2, attributes) {
7236
- const attrValue = attributes === null ? null : new Uint8Array([attributes]);
7237
- return this.opentui.symbols.textBufferWriteChunk(buffer, textBytes, textBytes.length, fg2 ? fg2.buffer : null, bg2 ? bg2.buffer : null, attrValue);
9289
+ editBufferGetNextWordBoundary(buffer) {
9290
+ const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size);
9291
+ this.opentui.symbols.editBufferGetNextWordBoundary(buffer, ptr3(cursorBuffer));
9292
+ return LogicalCursorStruct.unpack(cursorBuffer);
7238
9293
  }
7239
- textBufferFinalizeLineInfo(buffer) {
7240
- this.opentui.symbols.textBufferFinalizeLineInfo(buffer);
9294
+ editBufferGetPrevWordBoundary(buffer) {
9295
+ const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size);
9296
+ this.opentui.symbols.editBufferGetPrevWordBoundary(buffer, ptr3(cursorBuffer));
9297
+ return LogicalCursorStruct.unpack(cursorBuffer);
7241
9298
  }
7242
- textBufferGetLineCount(buffer) {
7243
- return this.opentui.symbols.textBufferGetLineCount(buffer);
9299
+ editBufferGetEOL(buffer) {
9300
+ const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size);
9301
+ this.opentui.symbols.editBufferGetEOL(buffer, ptr3(cursorBuffer));
9302
+ return LogicalCursorStruct.unpack(cursorBuffer);
9303
+ }
9304
+ editorViewSetSelection(view, start, end, bgColor, fgColor) {
9305
+ const bg2 = bgColor ? bgColor.buffer : null;
9306
+ const fg2 = fgColor ? fgColor.buffer : null;
9307
+ this.opentui.symbols.editorViewSetSelection(view, start, end, bg2, fg2);
7244
9308
  }
7245
- textBufferGetLineInfoDirect(buffer, lineStartsPtr, lineWidthsPtr) {
7246
- return this.opentui.symbols.textBufferGetLineInfoDirect(buffer, lineStartsPtr, lineWidthsPtr);
9309
+ editorViewResetSelection(view) {
9310
+ this.opentui.symbols.editorViewResetSelection(view);
7247
9311
  }
7248
- textBufferGetSelection(buffer) {
7249
- const packedInfo = this.textBufferGetSelectionInfo(buffer);
9312
+ editorViewGetSelection(view) {
9313
+ const packedInfo = this.opentui.symbols.editorViewGetSelection(view);
7250
9314
  if (packedInfo === 0xffff_ffff_ffff_ffffn) {
7251
9315
  return null;
7252
9316
  }
@@ -7254,92 +9318,67 @@ class FFIRenderLib {
7254
9318
  const end = Number(packedInfo & 0xffff_ffffn);
7255
9319
  return { start, end };
7256
9320
  }
7257
- textBufferGetSelectionInfo(buffer) {
7258
- return this.opentui.symbols.textBufferGetSelectionInfo(buffer);
7259
- }
7260
- textBufferGetSelectedText(buffer, outPtr, maxLen) {
7261
- const result = this.opentui.symbols.textBufferGetSelectedText(buffer, outPtr, maxLen);
7262
- return typeof result === "bigint" ? Number(result) : result;
9321
+ editorViewSetLocalSelection(view, anchorX, anchorY, focusX, focusY, bgColor, fgColor) {
9322
+ const bg2 = bgColor ? bgColor.buffer : null;
9323
+ const fg2 = fgColor ? fgColor.buffer : null;
9324
+ return this.opentui.symbols.editorViewSetLocalSelection(view, anchorX, anchorY, focusX, focusY, bg2, fg2);
7263
9325
  }
7264
- textBufferGetPlainText(buffer, outPtr, maxLen) {
7265
- const result = this.opentui.symbols.textBufferGetPlainText(buffer, outPtr, maxLen);
7266
- return typeof result === "bigint" ? Number(result) : result;
9326
+ editorViewResetLocalSelection(view) {
9327
+ this.opentui.symbols.editorViewResetLocalSelection(view);
7267
9328
  }
7268
- getSelectedTextBytes(buffer, maxLength) {
9329
+ editorViewGetSelectedTextBytes(view, maxLength) {
7269
9330
  const outBuffer = new Uint8Array(maxLength);
7270
- const actualLen = this.textBufferGetSelectedText(buffer, ptr(outBuffer), maxLength);
7271
- if (actualLen === 0) {
9331
+ const actualLen = this.opentui.symbols.editorViewGetSelectedTextBytes(view, ptr3(outBuffer), maxLength);
9332
+ const len = typeof actualLen === "bigint" ? Number(actualLen) : actualLen;
9333
+ if (len === 0)
7272
9334
  return null;
7273
- }
7274
- return outBuffer.slice(0, actualLen);
9335
+ return outBuffer.slice(0, len);
7275
9336
  }
7276
- getPlainTextBytes(buffer, maxLength) {
9337
+ editorViewGetCursor(view) {
9338
+ const row = new Uint32Array(1);
9339
+ const col = new Uint32Array(1);
9340
+ this.opentui.symbols.editorViewGetCursor(view, ptr3(row), ptr3(col));
9341
+ return { row: row[0], col: col[0] };
9342
+ }
9343
+ editorViewGetText(view, maxLength) {
7277
9344
  const outBuffer = new Uint8Array(maxLength);
7278
- const actualLen = this.textBufferGetPlainText(buffer, ptr(outBuffer), maxLength);
7279
- if (actualLen === 0) {
9345
+ const actualLen = this.opentui.symbols.editorViewGetText(view, ptr3(outBuffer), maxLength);
9346
+ const len = typeof actualLen === "bigint" ? Number(actualLen) : actualLen;
9347
+ if (len === 0)
7280
9348
  return null;
7281
- }
7282
- return outBuffer.slice(0, actualLen);
7283
- }
7284
- textBufferSetLocalSelection(buffer, anchorX, anchorY, focusX, focusY, bgColor, fgColor) {
7285
- const bg2 = bgColor ? bgColor.buffer : null;
7286
- const fg2 = fgColor ? fgColor.buffer : null;
7287
- return this.opentui.symbols.textBufferSetLocalSelection(buffer, anchorX, anchorY, focusX, focusY, bg2, fg2);
7288
- }
7289
- textBufferResetLocalSelection(buffer) {
7290
- this.opentui.symbols.textBufferResetLocalSelection(buffer);
7291
- }
7292
- textBufferInsertChunkGroup(buffer, index, textBytes, fg2, bg2, attributes) {
7293
- const fgPtr = fg2 ? fg2.buffer : null;
7294
- const bgPtr = bg2 ? bg2.buffer : null;
7295
- const attr = attributes ?? 255;
7296
- return this.opentui.symbols.textBufferInsertChunkGroup(buffer, index, textBytes, textBytes.length, fgPtr, bgPtr, attr);
9349
+ return outBuffer.slice(0, len);
7297
9350
  }
7298
- textBufferRemoveChunkGroup(buffer, index) {
7299
- return this.opentui.symbols.textBufferRemoveChunkGroup(buffer, index);
9351
+ editorViewGetVisualCursor(view) {
9352
+ const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size);
9353
+ this.opentui.symbols.editorViewGetVisualCursor(view, ptr3(cursorBuffer));
9354
+ return VisualCursorStruct.unpack(cursorBuffer);
7300
9355
  }
7301
- textBufferReplaceChunkGroup(buffer, index, textBytes, fg2, bg2, attributes) {
7302
- const fgPtr = fg2 ? fg2.buffer : null;
7303
- const bgPtr = bg2 ? bg2.buffer : null;
7304
- const attr = attributes ?? 255;
7305
- return this.opentui.symbols.textBufferReplaceChunkGroup(buffer, index, textBytes, textBytes.length, fgPtr, bgPtr, attr);
9356
+ editorViewMoveUpVisual(view) {
9357
+ this.opentui.symbols.editorViewMoveUpVisual(view);
7306
9358
  }
7307
- textBufferGetChunkGroupCount(buffer) {
7308
- const result = this.opentui.symbols.textBufferGetChunkGroupCount(buffer);
7309
- return typeof result === "bigint" ? Number(result) : result;
9359
+ editorViewMoveDownVisual(view) {
9360
+ this.opentui.symbols.editorViewMoveDownVisual(view);
7310
9361
  }
7311
- textBufferSetWrapWidth(buffer, width) {
7312
- this.opentui.symbols.textBufferSetWrapWidth(buffer, width);
9362
+ editorViewDeleteSelectedText(view) {
9363
+ this.opentui.symbols.editorViewDeleteSelectedText(view);
7313
9364
  }
7314
- textBufferSetWrapMode(buffer, mode) {
7315
- const modeValue = mode === "char" ? 0 : 1;
7316
- this.opentui.symbols.textBufferSetWrapMode(buffer, modeValue);
9365
+ editorViewSetCursorByOffset(view, offset) {
9366
+ this.opentui.symbols.editorViewSetCursorByOffset(view, offset);
7317
9367
  }
7318
- getArenaAllocatedBytes() {
7319
- const result = this.opentui.symbols.getArenaAllocatedBytes();
7320
- return typeof result === "bigint" ? Number(result) : result;
9368
+ editorViewGetNextWordBoundary(view) {
9369
+ const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size);
9370
+ this.opentui.symbols.editorViewGetNextWordBoundary(view, ptr3(cursorBuffer));
9371
+ return VisualCursorStruct.unpack(cursorBuffer);
7321
9372
  }
7322
- textBufferGetLineInfo(buffer) {
7323
- const lineCount = this.textBufferGetLineCount(buffer);
7324
- if (lineCount === 0) {
7325
- return { lineStarts: [], lineWidths: [], maxLineWidth: 0 };
7326
- }
7327
- const lineStarts = new Uint32Array(lineCount);
7328
- const lineWidths = new Uint32Array(lineCount);
7329
- const maxLineWidth = this.textBufferGetLineInfoDirect(buffer, ptr(lineStarts), ptr(lineWidths));
7330
- return {
7331
- maxLineWidth,
7332
- lineStarts: Array.from(lineStarts),
7333
- lineWidths: Array.from(lineWidths)
7334
- };
9373
+ editorViewGetPrevWordBoundary(view) {
9374
+ const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size);
9375
+ this.opentui.symbols.editorViewGetPrevWordBoundary(view, ptr3(cursorBuffer));
9376
+ return VisualCursorStruct.unpack(cursorBuffer);
7335
9377
  }
7336
- bufferDrawTextBuffer(buffer, textBuffer, x, y, clipRect) {
7337
- const hasClipRect = clipRect !== undefined && clipRect !== null;
7338
- const clipX = clipRect?.x ?? 0;
7339
- const clipY = clipRect?.y ?? 0;
7340
- const clipWidth = clipRect?.width ?? 0;
7341
- const clipHeight = clipRect?.height ?? 0;
7342
- this.opentui.symbols.bufferDrawTextBuffer(buffer, textBuffer, x, y, clipX, clipY, clipWidth, clipHeight, hasClipRect);
9378
+ editorViewGetEOL(view) {
9379
+ const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size);
9380
+ this.opentui.symbols.editorViewGetEOL(view, ptr3(cursorBuffer));
9381
+ return VisualCursorStruct.unpack(cursorBuffer);
7343
9382
  }
7344
9383
  bufferPushScissorRect(buffer, x, y, width, height) {
7345
9384
  this.opentui.symbols.bufferPushScissorRect(buffer, x, y, width, height);
@@ -7375,6 +9414,43 @@ class FFIRenderLib {
7375
9414
  const responseBytes = this.encoder.encode(response);
7376
9415
  this.opentui.symbols.processCapabilityResponse(renderer, responseBytes, responseBytes.length);
7377
9416
  }
9417
+ createSyntaxStyle() {
9418
+ const stylePtr = this.opentui.symbols.createSyntaxStyle();
9419
+ if (!stylePtr) {
9420
+ throw new Error("Failed to create SyntaxStyle");
9421
+ }
9422
+ return stylePtr;
9423
+ }
9424
+ destroySyntaxStyle(style) {
9425
+ this.opentui.symbols.destroySyntaxStyle(style);
9426
+ }
9427
+ syntaxStyleRegister(style, name, fg2, bg2, attributes) {
9428
+ const nameBytes = this.encoder.encode(name);
9429
+ const fgPtr = fg2 ? fg2.buffer : null;
9430
+ const bgPtr = bg2 ? bg2.buffer : null;
9431
+ return this.opentui.symbols.syntaxStyleRegister(style, nameBytes, nameBytes.length, fgPtr, bgPtr, attributes);
9432
+ }
9433
+ syntaxStyleResolveByName(style, name) {
9434
+ const nameBytes = this.encoder.encode(name);
9435
+ const id = this.opentui.symbols.syntaxStyleResolveByName(style, nameBytes, nameBytes.length);
9436
+ return id === 0 ? null : id;
9437
+ }
9438
+ syntaxStyleGetStyleCount(style) {
9439
+ const result = this.opentui.symbols.syntaxStyleGetStyleCount(style);
9440
+ return typeof result === "bigint" ? Number(result) : result;
9441
+ }
9442
+ onNativeEvent(name, handler) {
9443
+ this._nativeEvents.on(name, handler);
9444
+ }
9445
+ onceNativeEvent(name, handler) {
9446
+ this._nativeEvents.once(name, handler);
9447
+ }
9448
+ offNativeEvent(name, handler) {
9449
+ this._nativeEvents.off(name, handler);
9450
+ }
9451
+ onAnyNativeEvent(handler) {
9452
+ this._anyEventHandlers.push(handler);
9453
+ }
7378
9454
  }
7379
9455
  var opentuiLibPath;
7380
9456
  var opentuiLib;
@@ -7403,11 +9479,15 @@ class TextBuffer {
7403
9479
  lib;
7404
9480
  bufferPtr;
7405
9481
  _length = 0;
9482
+ _byteSize = 0;
7406
9483
  _lineInfo;
7407
9484
  _destroyed = false;
7408
- constructor(lib, ptr2) {
9485
+ _syntaxStyle;
9486
+ _textBytes;
9487
+ _memId;
9488
+ constructor(lib, ptr4) {
7409
9489
  this.lib = lib;
7410
- this.bufferPtr = ptr2;
9490
+ this.bufferPtr = ptr4;
7411
9491
  }
7412
9492
  static create(widthMethod) {
7413
9493
  const lib = resolveRenderLib();
@@ -7417,17 +9497,42 @@ class TextBuffer {
7417
9497
  if (this._destroyed)
7418
9498
  throw new Error("TextBuffer is destroyed");
7419
9499
  }
7420
- setStyledText(text) {
9500
+ setText(text) {
7421
9501
  this.guard();
7422
- this.lib.textBufferReset(this.bufferPtr);
7423
- this._length = 0;
9502
+ this._textBytes = this.lib.encoder.encode(text);
9503
+ if (this._memId === undefined) {
9504
+ this._memId = this.lib.textBufferRegisterMemBuffer(this.bufferPtr, this._textBytes, false);
9505
+ } else {
9506
+ this.lib.textBufferReplaceMemBuffer(this.bufferPtr, this._memId, this._textBytes, false);
9507
+ }
9508
+ this.lib.textBufferSetTextFromMem(this.bufferPtr, this._memId);
9509
+ this._length = this.lib.textBufferGetLength(this.bufferPtr);
9510
+ this._byteSize = this.lib.textBufferGetByteSize(this.bufferPtr);
7424
9511
  this._lineInfo = undefined;
7425
- for (const chunk of text.chunks) {
7426
- const textBytes = this.lib.encoder.encode(chunk.text);
7427
- this.lib.textBufferWriteChunk(this.bufferPtr, textBytes, chunk.fg || null, chunk.bg || null, chunk.attributes ?? null);
9512
+ }
9513
+ loadFile(path4) {
9514
+ this.guard();
9515
+ const success = this.lib.textBufferLoadFile(this.bufferPtr, path4);
9516
+ if (!success) {
9517
+ throw new Error(`Failed to load file: ${path4}`);
7428
9518
  }
7429
- this.lib.textBufferFinalizeLineInfo(this.bufferPtr);
7430
9519
  this._length = this.lib.textBufferGetLength(this.bufferPtr);
9520
+ this._byteSize = this.lib.textBufferGetByteSize(this.bufferPtr);
9521
+ this._lineInfo = undefined;
9522
+ this._textBytes = undefined;
9523
+ }
9524
+ setStyledText(text) {
9525
+ this.guard();
9526
+ const chunks = text.chunks.map((chunk) => ({
9527
+ text: chunk.text,
9528
+ fg: chunk.fg || null,
9529
+ bg: chunk.bg || null,
9530
+ attributes: chunk.attributes ?? 0
9531
+ }));
9532
+ this.lib.textBufferSetStyledText(this.bufferPtr, chunks);
9533
+ this._length = this.lib.textBufferGetLength(this.bufferPtr);
9534
+ this._byteSize = this.lib.textBufferGetByteSize(this.bufferPtr);
9535
+ this._lineInfo = undefined;
7431
9536
  }
7432
9537
  setDefaultFg(fg2) {
7433
9538
  this.guard();
@@ -7449,97 +9554,72 @@ class TextBuffer {
7449
9554
  this.guard();
7450
9555
  return this._length;
7451
9556
  }
7452
- get ptr() {
9557
+ get byteSize() {
7453
9558
  this.guard();
7454
- return this.bufferPtr;
9559
+ return this._byteSize;
7455
9560
  }
7456
- getSelectedText() {
9561
+ get ptr() {
7457
9562
  this.guard();
7458
- if (this._length === 0)
7459
- return "";
7460
- const selectedBytes = this.lib.getSelectedTextBytes(this.bufferPtr, this.length * 4);
7461
- if (!selectedBytes)
7462
- return "";
7463
- return this.lib.decoder.decode(selectedBytes);
9563
+ return this.bufferPtr;
7464
9564
  }
7465
9565
  getPlainText() {
7466
9566
  this.guard();
7467
- if (this._length === 0)
9567
+ if (this._byteSize === 0)
7468
9568
  return "";
7469
- const plainBytes = this.lib.getPlainTextBytes(this.bufferPtr, this.length * 4);
9569
+ const plainBytes = this.lib.getPlainTextBytes(this.bufferPtr, this._byteSize);
7470
9570
  if (!plainBytes)
7471
9571
  return "";
7472
9572
  return this.lib.decoder.decode(plainBytes);
7473
9573
  }
7474
- get lineInfo() {
7475
- this.guard();
7476
- if (!this._lineInfo) {
7477
- this._lineInfo = this.lib.textBufferGetLineInfo(this.bufferPtr);
7478
- }
7479
- return this._lineInfo;
7480
- }
7481
- setSelection(start, end, bgColor, fgColor) {
7482
- this.guard();
7483
- this.lib.textBufferSetSelection(this.bufferPtr, start, end, bgColor || null, fgColor || null);
7484
- }
7485
- resetSelection() {
9574
+ addHighlightByCharRange(highlight) {
7486
9575
  this.guard();
7487
- this.lib.textBufferResetSelection(this.bufferPtr);
9576
+ this.lib.textBufferAddHighlightByCharRange(this.bufferPtr, highlight);
7488
9577
  }
7489
- setLocalSelection(anchorX, anchorY, focusX, focusY, bgColor, fgColor) {
7490
- this.guard();
7491
- return this.lib.textBufferSetLocalSelection(this.bufferPtr, anchorX, anchorY, focusX, focusY, bgColor || null, fgColor || null);
7492
- }
7493
- resetLocalSelection() {
7494
- this.guard();
7495
- this.lib.textBufferResetLocalSelection(this.bufferPtr);
7496
- }
7497
- getSelection() {
7498
- this.guard();
7499
- return this.lib.textBufferGetSelection(this.bufferPtr);
7500
- }
7501
- hasSelection() {
9578
+ addHighlight(lineIdx, highlight) {
7502
9579
  this.guard();
7503
- return this.getSelection() !== null;
9580
+ this.lib.textBufferAddHighlight(this.bufferPtr, lineIdx, highlight);
7504
9581
  }
7505
- insertChunkGroup(index, text, fg2, bg2, attributes) {
9582
+ removeHighlightsByRef(hlRef) {
7506
9583
  this.guard();
7507
- const textBytes = this.lib.encoder.encode(text);
7508
- this.insertEncodedChunkGroup(index, textBytes, fg2, bg2, attributes);
9584
+ this.lib.textBufferRemoveHighlightsByRef(this.bufferPtr, hlRef);
7509
9585
  }
7510
- insertEncodedChunkGroup(index, textBytes, fg2, bg2, attributes) {
9586
+ clearLineHighlights(lineIdx) {
7511
9587
  this.guard();
7512
- this._length = this.lib.textBufferInsertChunkGroup(this.bufferPtr, index, textBytes, fg2 || null, bg2 || null, attributes ?? null);
7513
- this._lineInfo = undefined;
9588
+ this.lib.textBufferClearLineHighlights(this.bufferPtr, lineIdx);
7514
9589
  }
7515
- removeChunkGroup(index) {
9590
+ clearAllHighlights() {
7516
9591
  this.guard();
7517
- this._length = this.lib.textBufferRemoveChunkGroup(this.bufferPtr, index);
7518
- this._lineInfo = undefined;
9592
+ this.lib.textBufferClearAllHighlights(this.bufferPtr);
7519
9593
  }
7520
- replaceChunkGroup(index, text, fg2, bg2, attributes) {
9594
+ getLineHighlights(lineIdx) {
7521
9595
  this.guard();
7522
- const textBytes = this.lib.encoder.encode(text);
7523
- this.replaceEncodedChunkGroup(index, textBytes, fg2, bg2, attributes);
9596
+ return this.lib.textBufferGetLineHighlights(this.bufferPtr, lineIdx);
7524
9597
  }
7525
- replaceEncodedChunkGroup(index, textBytes, fg2, bg2, attributes) {
9598
+ setSyntaxStyle(style) {
7526
9599
  this.guard();
7527
- this._length = this.lib.textBufferReplaceChunkGroup(this.bufferPtr, index, textBytes, fg2 || null, bg2 || null, attributes ?? null);
7528
- this._lineInfo = undefined;
9600
+ this._syntaxStyle = style ?? undefined;
9601
+ this.lib.textBufferSetSyntaxStyle(this.bufferPtr, style?.ptr ?? null);
7529
9602
  }
7530
- get chunkGroupCount() {
9603
+ getSyntaxStyle() {
7531
9604
  this.guard();
7532
- return this.lib.textBufferGetChunkGroupCount(this.bufferPtr);
9605
+ return this._syntaxStyle ?? null;
7533
9606
  }
7534
- setWrapWidth(width) {
9607
+ clear() {
7535
9608
  this.guard();
7536
- this.lib.textBufferSetWrapWidth(this.bufferPtr, width ?? 0);
9609
+ this.lib.textBufferClear(this.bufferPtr);
9610
+ this._length = 0;
9611
+ this._byteSize = 0;
7537
9612
  this._lineInfo = undefined;
9613
+ this._textBytes = undefined;
7538
9614
  }
7539
- setWrapMode(mode) {
9615
+ reset() {
7540
9616
  this.guard();
7541
- this.lib.textBufferSetWrapMode(this.bufferPtr, mode);
9617
+ this.lib.textBufferReset(this.bufferPtr);
9618
+ this._length = 0;
9619
+ this._byteSize = 0;
7542
9620
  this._lineInfo = undefined;
9621
+ this._textBytes = undefined;
9622
+ this._memId = undefined;
7543
9623
  }
7544
9624
  destroy() {
7545
9625
  if (this._destroyed)
@@ -7550,7 +9630,7 @@ class TextBuffer {
7550
9630
  }
7551
9631
 
7552
9632
  // src/Renderable.ts
7553
- import { EventEmitter as EventEmitter4 } from "events";
9633
+ import { EventEmitter as EventEmitter6 } from "events";
7554
9634
 
7555
9635
  // src/lib/renderable.validations.ts
7556
9636
  function validateOptions(id, options) {
@@ -7643,7 +9723,7 @@ function isRenderable(obj) {
7643
9723
  return !!obj?.[BrandedRenderable];
7644
9724
  }
7645
9725
 
7646
- class BaseRenderable extends EventEmitter4 {
9726
+ class BaseRenderable extends EventEmitter6 {
7647
9727
  [BrandedRenderable] = true;
7648
9728
  static renderableNumber = 1;
7649
9729
  _id;
@@ -7715,6 +9795,7 @@ class Renderable extends BaseRenderable {
7715
9795
  _positionType = "relative";
7716
9796
  _overflow = "visible";
7717
9797
  _position = {};
9798
+ _flexShrink = 1;
7718
9799
  renderableMapById = new Map;
7719
9800
  _childrenInLayoutOrder = [];
7720
9801
  _childrenInZIndexOrder = [];
@@ -7961,6 +10042,10 @@ class Renderable extends BaseRenderable {
7961
10042
  if (isDimensionType(value)) {
7962
10043
  this._width = value;
7963
10044
  this.yogaNode.setWidth(value);
10045
+ if (typeof value === "number" && this._flexShrink === 1) {
10046
+ this._flexShrink = 0;
10047
+ this.yogaNode.setFlexShrink(0);
10048
+ }
7964
10049
  this.requestRender();
7965
10050
  }
7966
10051
  }
@@ -7971,6 +10056,10 @@ class Renderable extends BaseRenderable {
7971
10056
  if (isDimensionType(value)) {
7972
10057
  this._height = value;
7973
10058
  this.yogaNode.setHeight(value);
10059
+ if (typeof value === "number" && this._flexShrink === 1) {
10060
+ this._flexShrink = 0;
10061
+ this.yogaNode.setFlexShrink(0);
10062
+ }
7974
10063
  this.requestRender();
7975
10064
  }
7976
10065
  }
@@ -8025,9 +10114,13 @@ class Renderable extends BaseRenderable {
8025
10114
  node.setFlexGrow(0);
8026
10115
  }
8027
10116
  if (options.flexShrink !== undefined) {
10117
+ this._flexShrink = options.flexShrink;
8028
10118
  node.setFlexShrink(options.flexShrink);
8029
10119
  } else {
8030
- node.setFlexShrink(1);
10120
+ const hasExplicitWidth = typeof options.width === "number";
10121
+ const hasExplicitHeight = typeof options.height === "number";
10122
+ this._flexShrink = hasExplicitWidth || hasExplicitHeight ? 0 : 1;
10123
+ node.setFlexShrink(this._flexShrink);
8031
10124
  }
8032
10125
  if (options.flexDirection !== undefined) {
8033
10126
  node.setFlexDirection(parseFlexDirection(options.flexDirection));
@@ -8172,11 +10265,17 @@ class Renderable extends BaseRenderable {
8172
10265
  this.requestRender();
8173
10266
  }
8174
10267
  set flexGrow(grow) {
8175
- this.yogaNode.setFlexGrow(grow);
10268
+ if (grow == null) {
10269
+ this.yogaNode.setFlexGrow(0);
10270
+ } else {
10271
+ this.yogaNode.setFlexGrow(grow);
10272
+ }
8176
10273
  this.requestRender();
8177
10274
  }
8178
10275
  set flexShrink(shrink) {
8179
- this.yogaNode.setFlexShrink(shrink);
10276
+ const value = shrink == null ? 1 : shrink;
10277
+ this._flexShrink = value;
10278
+ this.yogaNode.setFlexShrink(value);
8180
10279
  this.requestRender();
8181
10280
  }
8182
10281
  set flexDirection(direction) {
@@ -8377,34 +10476,31 @@ class Renderable extends BaseRenderable {
8377
10476
  }
8378
10477
  return -1;
8379
10478
  }
8380
- if (this.renderableMapById.has(renderable.id)) {
8381
- console.warn(`A renderable with id ${renderable.id} already exists in ${this.id}, removing it`);
8382
- this.remove(renderable.id);
10479
+ const anchorRenderable = index !== undefined ? this._childrenInLayoutOrder[index] : undefined;
10480
+ if (anchorRenderable) {
10481
+ return this.insertBefore(renderable, anchorRenderable);
8383
10482
  }
8384
- this.replaceParent(renderable);
8385
- const childLayoutNode = renderable.getLayoutNode();
8386
- let insertedIndex;
8387
- if (index !== undefined) {
8388
- insertedIndex = Math.max(0, Math.min(index, this._childrenInLayoutOrder.length));
8389
- this._childrenInLayoutOrder.splice(index, 0, renderable);
8390
- this._forceLayoutUpdateFor = this._childrenInLayoutOrder.slice(index);
8391
- this.yogaNode.insertChild(childLayoutNode, insertedIndex);
10483
+ if (renderable.parent === this) {
10484
+ this.yogaNode.removeChild(renderable.getLayoutNode());
10485
+ this._childrenInLayoutOrder.splice(this._childrenInLayoutOrder.indexOf(renderable), 1);
8392
10486
  } else {
8393
- insertedIndex = this._childrenInLayoutOrder.length;
8394
- this._childrenInLayoutOrder.push(renderable);
8395
- this.yogaNode.insertChild(childLayoutNode, insertedIndex);
8396
- }
8397
- this.needsZIndexSort = true;
8398
- this.childrenPrimarySortDirty = true;
8399
- this.renderableMapById.set(renderable.id, renderable);
8400
- this._childrenInZIndexOrder.push(renderable);
8401
- if (typeof renderable.onLifecyclePass === "function") {
8402
- this._ctx.registerLifecyclePass(renderable);
10487
+ this.replaceParent(renderable);
10488
+ this.needsZIndexSort = true;
10489
+ this.renderableMapById.set(renderable.id, renderable);
10490
+ this._childrenInZIndexOrder.push(renderable);
10491
+ if (typeof renderable.onLifecyclePass === "function") {
10492
+ this._ctx.registerLifecyclePass(renderable);
10493
+ }
10494
+ if (renderable._liveCount > 0) {
10495
+ this.propagateLiveCount(renderable._liveCount);
10496
+ }
8403
10497
  }
8404
10498
  this._newChildren.push(renderable);
8405
- if (renderable._liveCount > 0) {
8406
- this.propagateLiveCount(renderable._liveCount);
8407
- }
10499
+ const childLayoutNode = renderable.getLayoutNode();
10500
+ const insertedIndex = this._childrenInLayoutOrder.length;
10501
+ this._childrenInLayoutOrder.push(renderable);
10502
+ this.yogaNode.insertChild(childLayoutNode, insertedIndex);
10503
+ this.childrenPrimarySortDirty = true;
8408
10504
  this.requestRender();
8409
10505
  return insertedIndex;
8410
10506
  }
@@ -8459,6 +10555,7 @@ class Renderable extends BaseRenderable {
8459
10555
  this._forceLayoutUpdateFor = this._childrenInLayoutOrder.slice(insertedIndex);
8460
10556
  this._childrenInLayoutOrder.splice(insertedIndex, 0, renderable);
8461
10557
  this.yogaNode.insertChild(renderable.getLayoutNode(), insertedIndex);
10558
+ this.requestRender();
8462
10559
  return insertedIndex;
8463
10560
  }
8464
10561
  getRenderable(id) {
@@ -8947,7 +11044,7 @@ function delegate(mapping, vnode) {
8947
11044
  }
8948
11045
 
8949
11046
  // src/console.ts
8950
- import { EventEmitter as EventEmitter6 } from "events";
11047
+ import { EventEmitter as EventEmitter8 } from "events";
8951
11048
  import { Console } from "console";
8952
11049
  import fs from "fs";
8953
11050
  import path4 from "path";
@@ -8955,9 +11052,9 @@ import util2 from "util";
8955
11052
 
8956
11053
  // src/lib/output.capture.ts
8957
11054
  import { Writable } from "stream";
8958
- import { EventEmitter as EventEmitter5 } from "events";
11055
+ import { EventEmitter as EventEmitter7 } from "events";
8959
11056
 
8960
- class Capture extends EventEmitter5 {
11057
+ class Capture extends EventEmitter7 {
8961
11058
  output = [];
8962
11059
  constructor() {
8963
11060
  super();
@@ -9033,11 +11130,12 @@ registerEnvVar({
9033
11130
  default: false
9034
11131
  });
9035
11132
 
9036
- class TerminalConsoleCache extends EventEmitter6 {
11133
+ class TerminalConsoleCache extends EventEmitter8 {
9037
11134
  _cachedLogs = [];
9038
11135
  MAX_CACHE_SIZE = 1000;
9039
11136
  _collectCallerInfo = false;
9040
11137
  _cachingEnabled = true;
11138
+ _originalConsole = null;
9041
11139
  get cachedLogs() {
9042
11140
  return this._cachedLogs;
9043
11141
  }
@@ -9045,6 +11143,9 @@ class TerminalConsoleCache extends EventEmitter6 {
9045
11143
  super();
9046
11144
  }
9047
11145
  activate() {
11146
+ if (!this._originalConsole) {
11147
+ this._originalConsole = global.console;
11148
+ }
9048
11149
  this.setupConsoleCapture();
9049
11150
  this.overrideConsoleMethods();
9050
11151
  }
@@ -9094,8 +11195,9 @@ class TerminalConsoleCache extends EventEmitter6 {
9094
11195
  this.restoreOriginalConsole();
9095
11196
  }
9096
11197
  restoreOriginalConsole() {
9097
- const originalNodeConsole = __require("console");
9098
- global.console = originalNodeConsole;
11198
+ if (this._originalConsole) {
11199
+ global.console = this._originalConsole;
11200
+ }
9099
11201
  this.setupConsoleCapture();
9100
11202
  }
9101
11203
  addLogEntry(level, ...args) {
@@ -9154,7 +11256,7 @@ var DEFAULT_CONSOLE_OPTIONS = {
9154
11256
  };
9155
11257
  var INDENT_WIDTH = 2;
9156
11258
 
9157
- class TerminalConsole extends EventEmitter6 {
11259
+ class TerminalConsole extends EventEmitter8 {
9158
11260
  isVisible = false;
9159
11261
  isFocused = false;
9160
11262
  renderer;
@@ -9614,7 +11716,7 @@ class TerminalConsole extends EventEmitter6 {
9614
11716
  }
9615
11717
 
9616
11718
  // src/renderer.ts
9617
- import { EventEmitter as EventEmitter7 } from "events";
11719
+ import { EventEmitter as EventEmitter9 } from "events";
9618
11720
 
9619
11721
  // src/lib/objects-in-viewport.ts
9620
11722
  function getObjectsInViewport(viewport, objects, direction = "column", padding = 10, minTriggerSize = 16) {
@@ -9650,24 +11752,39 @@ function getObjectsInViewport(viewport, objects, direction = "column", padding =
9650
11752
  }
9651
11753
  const visibleChildren = [];
9652
11754
  if (candidate === -1) {
9653
- return visibleChildren;
11755
+ candidate = lo > 0 ? lo - 1 : 0;
9654
11756
  }
11757
+ const maxLookBehind = 50;
9655
11758
  let left = candidate;
11759
+ let gapCount = 0;
9656
11760
  while (left - 1 >= 0) {
9657
11761
  const prev = children[left - 1];
9658
- if ((isRow ? prev.x + prev.width : prev.y + prev.height) < vpStart)
9659
- break;
11762
+ const prevEnd = isRow ? prev.x + prev.width : prev.y + prev.height;
11763
+ if (prevEnd <= vpStart) {
11764
+ gapCount++;
11765
+ if (gapCount >= maxLookBehind) {
11766
+ break;
11767
+ }
11768
+ } else {
11769
+ gapCount = 0;
11770
+ }
9660
11771
  left--;
9661
11772
  }
9662
11773
  let right = candidate + 1;
9663
11774
  while (right < totalChildren) {
9664
11775
  const next = children[right];
9665
- if ((isRow ? next.x : next.y) > vpEnd)
11776
+ if ((isRow ? next.x : next.y) >= vpEnd)
9666
11777
  break;
9667
11778
  right++;
9668
11779
  }
9669
11780
  for (let i = left;i < right; i++) {
9670
11781
  const child = children[i];
11782
+ const start = isRow ? child.x : child.y;
11783
+ const end = isRow ? child.x + child.width : child.y + child.height;
11784
+ if (end <= vpStart)
11785
+ continue;
11786
+ if (start >= vpEnd)
11787
+ break;
9671
11788
  if (isRow) {
9672
11789
  const childBottom = child.y + child.height;
9673
11790
  if (childBottom < viewportTop)
@@ -9815,7 +11932,17 @@ var CliRenderEvents;
9815
11932
  ((CliRenderEvents2) => {
9816
11933
  CliRenderEvents2["DEBUG_OVERLAY_TOGGLE"] = "debugOverlay:toggle";
9817
11934
  })(CliRenderEvents ||= {});
9818
- class CliRenderer extends EventEmitter7 {
11935
+ var RendererControlState;
11936
+ ((RendererControlState2) => {
11937
+ RendererControlState2["IDLE"] = "idle";
11938
+ RendererControlState2["AUTO_STARTED"] = "auto_started";
11939
+ RendererControlState2["EXPLICIT_STARTED"] = "explicit_started";
11940
+ RendererControlState2["EXPLICIT_PAUSED"] = "explicit_paused";
11941
+ RendererControlState2["EXPLICIT_SUSPENDED"] = "explicit_suspended";
11942
+ RendererControlState2["EXPLICIT_STOPPED"] = "explicit_stopped";
11943
+ })(RendererControlState ||= {});
11944
+
11945
+ class CliRenderer extends EventEmitter9 {
9819
11946
  static animationFrameId = 0;
9820
11947
  lib;
9821
11948
  rendererPtr;
@@ -9856,7 +11983,7 @@ class CliRenderer extends EventEmitter7 {
9856
11983
  immediateRerenderRequested = false;
9857
11984
  updateScheduled = false;
9858
11985
  liveRequestCounter = 0;
9859
- controlState = "idle" /* IDLE */;
11986
+ _controlState = "idle" /* IDLE */;
9860
11987
  frameCallbacks = [];
9861
11988
  renderStats = {
9862
11989
  frameCount: 0,
@@ -9877,6 +12004,8 @@ class CliRenderer extends EventEmitter7 {
9877
12004
  enableMouseMovement = false;
9878
12005
  _useMouse = true;
9879
12006
  _useAlternateScreen = env.OTUI_USE_ALTERNATE_SCREEN;
12007
+ _suspendedMouseEnabled = false;
12008
+ _previousControlState = "idle" /* IDLE */;
9880
12009
  capturedRenderable;
9881
12010
  lastOverRenderableNum = 0;
9882
12011
  lastOverRenderable;
@@ -9905,30 +12034,10 @@ class CliRenderer extends EventEmitter7 {
9905
12034
  _currentFocusedRenderable = null;
9906
12035
  lifecyclePasses = new Set;
9907
12036
  handleError = ((error) => {
9908
- this.stop();
9909
- this.destroy();
9910
- new Promise((resolve4) => {
9911
- setTimeout(() => {
9912
- resolve4(true);
9913
- }, 100);
9914
- }).then(() => {
9915
- this.realStdoutWrite.call(this.stdout, `
9916
- `.repeat(this._terminalHeight));
9917
- this.realStdoutWrite.call(this.stdout, `
9918
- === FATAL ERROR OCCURRED ===
9919
- `);
9920
- this.dumpOutputCache();
9921
- this.realStdoutWrite.call(this.stdout, `
9922
- Error details:
9923
- `);
9924
- this.realStdoutWrite.call(this.stdout, error.message || "unknown error");
9925
- this.realStdoutWrite.call(this.stdout, `
9926
- `);
9927
- this.realStdoutWrite.call(this.stdout, error.stack || error.toString());
9928
- this.realStdoutWrite.call(this.stdout, `
9929
- `);
9930
- process.exit(1);
9931
- });
12037
+ console.error(error);
12038
+ if (true) {
12039
+ this.console.show();
12040
+ }
9932
12041
  }).bind(this);
9933
12042
  dumpOutputCache(optionalMessage = "") {
9934
12043
  const cachedLogs = this.console.getCachedLogs();
@@ -9953,13 +12062,18 @@ Captured output:
9953
12062
  exitHandler = (() => {
9954
12063
  this.destroy();
9955
12064
  if (env.OTUI_DUMP_CAPTURES) {
9956
- this.dumpOutputCache(`=== CAPTURED OUTPUT ===
12065
+ Bun.sleep(100).then(() => {
12066
+ this.dumpOutputCache(`=== CAPTURED OUTPUT ===
9957
12067
  `);
12068
+ });
9958
12069
  }
9959
12070
  }).bind(this);
9960
12071
  warningHandler = ((warning) => {
9961
12072
  console.warn(JSON.stringify(warning.message, null, 2));
9962
12073
  }).bind(this);
12074
+ get controlState() {
12075
+ return this._controlState;
12076
+ }
9963
12077
  constructor(lib, rendererPtr, stdin, stdout, width, height, config = {}) {
9964
12078
  super();
9965
12079
  rendererTracker.addRenderer(this);
@@ -10060,13 +12174,13 @@ Captured output:
10060
12174
  }
10061
12175
  get widthMethod() {
10062
12176
  const caps = this.capabilities;
10063
- return caps?.unicode === "unicode" ? "unicode" : "wcwidth";
12177
+ return caps?.unicode === "wcwidth" ? "wcwidth" : "unicode";
10064
12178
  }
10065
12179
  writeOut(chunk, encoding, callback) {
10066
12180
  return this.realStdoutWrite.call(this.stdout, chunk, encoding, callback);
10067
12181
  }
10068
12182
  requestRender() {
10069
- if (!this.rendering && !this.updateScheduled && !this._isRunning) {
12183
+ if (!this.rendering && !this.updateScheduled && !this._isRunning && this._controlState !== "explicit_suspended" /* EXPLICIT_SUSPENDED */) {
10070
12184
  this.updateScheduled = true;
10071
12185
  process.nextTick(() => {
10072
12186
  this.loop();
@@ -10129,7 +12243,7 @@ Captured output:
10129
12243
  return this.liveRequestCounter;
10130
12244
  }
10131
12245
  get currentControlState() {
10132
- return this.controlState;
12246
+ return this._controlState;
10133
12247
  }
10134
12248
  get capabilities() {
10135
12249
  return this._capabilities;
@@ -10209,9 +12323,11 @@ Captured output:
10209
12323
  return true;
10210
12324
  }
10211
12325
  enableMouse() {
12326
+ this._useMouse = true;
10212
12327
  this.lib.enableMouse(this.rendererPtr, this.enableMouseMovement);
10213
12328
  }
10214
12329
  disableMouse() {
12330
+ this._useMouse = false;
10215
12331
  this.capturedRenderable = undefined;
10216
12332
  this.mouseParser.reset();
10217
12333
  this.lib.disableMouse(this.rendererPtr);
@@ -10568,24 +12684,24 @@ Captured output:
10568
12684
  }
10569
12685
  requestLive() {
10570
12686
  this.liveRequestCounter++;
10571
- if (this.controlState === "idle" /* IDLE */ && this.liveRequestCounter > 0) {
10572
- this.controlState = "auto_started" /* AUTO_STARTED */;
12687
+ if (this._controlState === "idle" /* IDLE */ && this.liveRequestCounter > 0) {
12688
+ this._controlState = "auto_started" /* AUTO_STARTED */;
10573
12689
  this.internalStart();
10574
12690
  }
10575
12691
  }
10576
12692
  dropLive() {
10577
12693
  this.liveRequestCounter = Math.max(0, this.liveRequestCounter - 1);
10578
- if (this.controlState === "auto_started" /* AUTO_STARTED */ && this.liveRequestCounter === 0) {
10579
- this.controlState = "idle" /* IDLE */;
12694
+ if (this._controlState === "auto_started" /* AUTO_STARTED */ && this.liveRequestCounter === 0) {
12695
+ this._controlState = "idle" /* IDLE */;
10580
12696
  this.internalPause();
10581
12697
  }
10582
12698
  }
10583
12699
  start() {
10584
- this.controlState = "explicit_started" /* EXPLICIT_STARTED */;
12700
+ this._controlState = "explicit_started" /* EXPLICIT_STARTED */;
10585
12701
  this.internalStart();
10586
12702
  }
10587
12703
  auto() {
10588
- this.controlState = this._isRunning ? "auto_started" /* AUTO_STARTED */ : "idle" /* IDLE */;
12704
+ this._controlState = this._isRunning ? "auto_started" /* AUTO_STARTED */ : "idle" /* IDLE */;
10589
12705
  }
10590
12706
  internalStart() {
10591
12707
  if (!this._isRunning && !this._isDestroyed) {
@@ -10597,14 +12713,40 @@ Captured output:
10597
12713
  }
10598
12714
  }
10599
12715
  pause() {
10600
- this.controlState = "explicit_paused" /* EXPLICIT_PAUSED */;
12716
+ this._controlState = "explicit_paused" /* EXPLICIT_PAUSED */;
12717
+ this.internalPause();
12718
+ }
12719
+ suspend() {
12720
+ this._previousControlState = this._controlState;
12721
+ this._controlState = "explicit_suspended" /* EXPLICIT_SUSPENDED */;
10601
12722
  this.internalPause();
12723
+ this._suspendedMouseEnabled = this._useMouse;
12724
+ this.disableMouse();
12725
+ this._keyHandler.suspend();
12726
+ if (this.stdin.setRawMode) {
12727
+ this.stdin.setRawMode(false);
12728
+ }
12729
+ this.stdin.pause();
12730
+ }
12731
+ resume() {
12732
+ if (this.stdin.setRawMode) {
12733
+ this.stdin.setRawMode(true);
12734
+ }
12735
+ this.stdin.resume();
12736
+ this._keyHandler.resume();
12737
+ if (this._suspendedMouseEnabled) {
12738
+ this.enableMouse();
12739
+ }
12740
+ this._controlState = this._previousControlState;
12741
+ if (this._previousControlState === "auto_started" /* AUTO_STARTED */ || this._previousControlState === "explicit_started" /* EXPLICIT_STARTED */) {
12742
+ this.internalStart();
12743
+ }
10602
12744
  }
10603
12745
  internalPause() {
10604
12746
  this._isRunning = false;
10605
12747
  }
10606
12748
  stop() {
10607
- this.controlState = "explicit_stopped" /* EXPLICIT_STOPPED */;
12749
+ this._controlState = "explicit_stopped" /* EXPLICIT_STOPPED */;
10608
12750
  this.internalStop();
10609
12751
  }
10610
12752
  internalStop() {
@@ -10798,10 +12940,12 @@ Captured output:
10798
12940
  }
10799
12941
  this.selectionContainers = [];
10800
12942
  }
10801
- startSelection(startRenderable, x, y) {
12943
+ startSelection(renderable, x, y) {
12944
+ if (!renderable.selectable)
12945
+ return;
10802
12946
  this.clearSelection();
10803
- this.selectionContainers.push(startRenderable.parent || this.root);
10804
- this.currentSelection = new Selection(startRenderable, { x, y }, { x, y });
12947
+ this.selectionContainers.push(renderable.parent || this.root);
12948
+ this.currentSelection = new Selection(renderable, { x, y }, { x, y });
10805
12949
  this.notifySelectablesOfSelectionChange();
10806
12950
  }
10807
12951
  updateSelection(currentRenderable, x, y) {
@@ -10881,7 +13025,7 @@ Captured output:
10881
13025
  }
10882
13026
  }
10883
13027
 
10884
- export { __toESM, __commonJS, __export, __require, Edge, Gutter, exports_src, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, nonAlphanumericKeys, parseKeypress, ANSI, KeyEvent, PasteEvent, KeyHandler, InternalKeyHandler, RGBA, hexToRgb, rgbToHex, hsvToRgb, parseColor, fonts, measureText, getCharacterPositions, coordinateToCharacterIndex, renderFontToFrameBuffer, TextAttributes, DebugOverlayCorner, createTextAttributes, visualizeRenderableTree, isStyledText, StyledText, stringToStyledText, black, red, green, yellow, blue, magenta, cyan, white, brightBlack, brightRed, brightGreen, brightYellow, brightBlue, brightMagenta, brightCyan, brightWhite, bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite, bold, italic, underline, strikethrough, dim, reverse, blink, fg, bg, t, convertThemeToStyles, SyntaxStyle, hastToStyledText, LinearScrollAccel, MacOSScrollAccel, parseAlign, parseBoxSizing, parseDimension, parseDirection, parseDisplay, parseEdge, parseFlexDirection, parseGutter, parseJustify, parseLogLevel, parseMeasureMode, parseOverflow, parsePositionType, parseUnit, parseWrap, MouseParser, Selection, convertGlobalToLocalSelection, ASCIIFontSelectionHelper, envRegistry, registerEnvVar, clearEnvCache, generateEnvMarkdown, generateEnvColored, env, treeSitterToTextChunks, treeSitterToStyledText, addDefaultParsers, TreeSitterClient, DataPathsManager, getDataPaths, extToFiletype, pathToFiletype, main, getTreeSitterClient, TextBuffer, LogLevel2 as LogLevel, setRenderLibPath, resolveRenderLib, OptimizedBuffer, h, isVNode, maybeMakeRenderable, wrapWithDelegates, instantiate, delegate, isValidPercentage, LayoutEvents, RenderableEvents, isRenderable, BaseRenderable, Renderable, RootRenderable, capture, ConsolePosition, TerminalConsole, getObjectsInViewport, MouseEvent, MouseButton, createCliRenderer, CliRenderEvents, CliRenderer };
13028
+ 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 };
10885
13029
 
10886
- //# debugId=66FAF32C902A5E0B64756E2164756E21
10887
- //# sourceMappingURL=index-pxa2sv92.js.map
13030
+ //# debugId=73F3B7C93A2E540464756E2164756E21
13031
+ //# sourceMappingURL=index-hgxcxzxa.js.map