@opentui/core 0.5.6 → 0.5.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,63 +1,70 @@
1
- # OpenTUI Core
1
+ <!-- Keep the project introduction aligned with the repository README and opentui.com. -->
2
2
 
3
- OpenTUI is a native terminal UI core written in Zig with TypeScript bindings. The native core exposes a C ABI and can be used from any language. OpenTUI powers OpenCode in production today and will also power terminal.shop. It is an extensible core with a focus on correctness, stability, and high performance. It provides a component-based architecture with flexible layout capabilities, allowing you to create complex terminal applications.
3
+ <p align="center">
4
+ <a href="https://opentui.com">
5
+ <img alt="OpenTUI logo" src="https://opentui.com/opentui-logo-auto.svg" width="270" />
6
+ </a>
7
+ </p>
4
8
 
5
- ## Documentation
9
+ <div align="center">
10
+ <a href="https://www.npmjs.com/package/@opentui/core"><img alt="npm version" src="https://img.shields.io/npm/v/@opentui/core?style=flat-square" /></a>
11
+ <a href="https://github.com/anomalyco/opentui/actions/workflows/build-core.yml"><img alt="Core build status" src="https://img.shields.io/github/actions/workflow/status/anomalyco/opentui/build-core.yml?style=flat-square&branch=main" /></a>
12
+ </div>
6
13
 
7
- - [Getting Started](https://opentui.com/docs/getting-started) - API and usage guide
8
- - [Development Guide](docs/development.md) - Building, testing, and contributing
9
- - [Tree-Sitter](https://opentui.com/docs/reference/tree-sitter) - Syntax highlighting integration
10
- - [Renderables](https://opentui.com/docs/core-concepts/renderables) - Understanding the component model
11
- - [Environment Variables](https://opentui.com/docs/reference/env-vars) - Configuration options
14
+ OpenTUI is a library to build terminal user interfaces.
12
15
 
13
- ## Install
16
+ - It is written in Zig.
17
+ - You write TypeScript directly or through React and Solid.
18
+ - You arrange boxes and text with flexbox.
19
+ - You add selects, inputs, and scroll boxes with keyboard and mouse controls.
20
+ - You can play sounds, show images, and render 3D graphics.
14
21
 
15
- ```bash
16
- bun install @opentui/core
17
- ```
22
+ OpenCode uses OpenTUI in production for millions of users.
18
23
 
19
- ## Build
24
+ [Website](https://opentui.com) | [Documentation](https://opentui.com/docs) | [Packages](https://opentui.com/packages)
20
25
 
21
- ```bash
22
- bun run build
23
- ```
26
+ ## OpenTUI Core
24
27
 
25
- This creates platform-specific libraries that are automatically loaded by the TypeScript layer.
28
+ `@opentui/core` supplies the renderer and TypeScript API. You use imperative renderables and events directly. The
29
+ TypeScript packages call native Zig through an internal foreign function interface (FFI) boundary.
26
30
 
27
- ## Examples
31
+ ```typescript
32
+ import { TextRenderable, createCliRenderer } from "@opentui/core"
28
33
 
29
- ```bash
30
- bun install
31
- cd ../examples
32
- bun run dev
34
+ const renderer = await createCliRenderer({ exitOnCtrlC: true })
35
+
36
+ renderer.root.add(new TextRenderable(renderer, { content: "Hello, OpenTUI!" }))
33
37
  ```
34
38
 
35
- ## Benchmarks
39
+ `exitOnCtrlC: true` calls `renderer.destroy()` when the user presses Ctrl+C. The code that creates the renderer must
40
+ call `renderer.destroy()` on every other shutdown path.
36
41
 
37
- Run native performance benchmarks:
42
+ Install the package:
38
43
 
39
44
  ```bash
40
- bun run bench:native
45
+ bun add @opentui/core
41
46
  ```
42
47
 
43
- See [the native benchmark runner](../native/src/bench.zig) for options such as `--filter` and `--mem`.
48
+ Then build your first app with the [quickstart](https://opentui.com/docs/getting-started/quickstart).
44
49
 
45
- NativeSpanFeed TypeScript benchmarks:
50
+ ## Runtime and platform support
46
51
 
47
- - [src/benchmark/native-span-feed-benchmark.md](src/benchmark/native-span-feed-benchmark.md)
52
+ `@opentui/core` runs on Bun 1.3.0 or later, or on Node.js 26.4.0 or later with ECMAScript modules (ESM) and
53
+ `--experimental-ffi`.
48
54
 
49
- ## CLI Renderer
55
+ The native ABI and the generated platform packages, such as `@opentui/core-linux-x64`, are internal distribution
56
+ surfaces, not application APIs.
50
57
 
51
- ### Renderables
58
+ ## AI agent skill
52
59
 
53
- Renderables are hierarchical objects that can be positioned, nested, styled and rendered to the terminal:
60
+ Install the OpenTUI documentation as a skill for your AI coding assistant with [`npx skills`](https://skills.sh):
54
61
 
55
- ```typescript
56
- import { createCliRenderer, TextRenderable } from "@opentui/core"
62
+ ```bash
63
+ npx skills add anomalyco/opentui --skill opentui
64
+ ```
57
65
 
58
- const renderer = await createCliRenderer()
66
+ Add `-g` to install the skill globally.
59
67
 
60
- const obj = new TextRenderable(renderer, { id: "my-obj", content: "Hello, world!" })
68
+ ## License
61
69
 
62
- renderer.root.add(obj)
63
- ```
70
+ OpenTUI is licensed under the [MIT License](https://github.com/anomalyco/opentui/blob/main/LICENSE).
@@ -5965,7 +5965,7 @@ class MouseParser {
5965
5965
  if (type === "down" && button !== 3) {
5966
5966
  this.mouseButtonsPressed.add(button);
5967
5967
  } else if (type === "up") {
5968
- this.mouseButtonsPressed.clear();
5968
+ this.mouseButtonsPressed.delete(button);
5969
5969
  }
5970
5970
  }
5971
5971
  return {
@@ -6040,9 +6040,11 @@ class Selection {
6040
6040
  _isActive = true;
6041
6041
  _isDragging = true;
6042
6042
  _isStart = false;
6043
- constructor(anchorRenderable, anchor, focus) {
6043
+ behavior;
6044
+ constructor(anchorRenderable, anchor, focus, behavior = "cell") {
6044
6045
  this._anchor = new SelectionAnchor(anchorRenderable, anchor.x, anchor.y);
6045
6046
  this._focus = { ...focus };
6047
+ this.behavior = behavior;
6046
6048
  }
6047
6049
  get isStart() {
6048
6050
  return this._isStart;
@@ -6133,7 +6135,8 @@ function convertGlobalToLocalSelection(globalSelection, localX, localY) {
6133
6135
  anchorY: globalSelection.anchor.y - localY,
6134
6136
  focusX: globalSelection.focus.x - localX,
6135
6137
  focusY: globalSelection.focus.y - localY,
6136
- isActive: true
6138
+ isActive: true,
6139
+ behavior: globalSelection.behavior
6137
6140
  };
6138
6141
  }
6139
6142
 
@@ -6168,36 +6171,37 @@ class ASCIIFontSelectionHelper {
6168
6171
  }
6169
6172
  const text = this.getText();
6170
6173
  const font = this.getFont();
6171
- const selStart = { x: localSelection.anchorX, y: localSelection.anchorY };
6172
- const selEnd = { x: localSelection.focusX, y: localSelection.focusY };
6173
- if (height - 1 < selStart.y || 0 > selEnd.y) {
6174
+ const positions = getCharacterPositions(text, font);
6175
+ const minY = Math.min(localSelection.anchorY, localSelection.focusY);
6176
+ const maxY = Math.max(localSelection.anchorY, localSelection.focusY);
6177
+ if (maxY < 0 || minY > height - 1) {
6174
6178
  this.localSelection = null;
6175
6179
  return previousSelection !== null;
6176
6180
  }
6177
- let startCharIndex = 0;
6178
- let endCharIndex = text.length;
6179
- if (selStart.y > height - 1) {
6180
- this.localSelection = null;
6181
- return previousSelection !== null;
6182
- } else if (selStart.y >= 0 && selStart.y <= height - 1) {
6183
- if (selStart.x > 0) {
6184
- startCharIndex = coordinateToCharacterIndex(selStart.x, text, font);
6181
+ const indexAt = (x, y) => {
6182
+ if (y < 0)
6183
+ return 0;
6184
+ if (y > height - 1)
6185
+ return text.length;
6186
+ if (x < 0)
6187
+ return 0;
6188
+ if (x >= width)
6189
+ return text.length;
6190
+ for (let index = 1;index < positions.length; index += 1) {
6191
+ if (x < positions[index])
6192
+ return index - 1;
6185
6193
  }
6186
- }
6187
- if (selEnd.y < 0) {
6194
+ return text.length;
6195
+ };
6196
+ const anchorIndex = indexAt(localSelection.anchorX, localSelection.anchorY);
6197
+ const focusIndex = indexAt(localSelection.focusX, localSelection.focusY);
6198
+ const start = Math.min(anchorIndex, focusIndex);
6199
+ const end = Math.min(Math.max(anchorIndex, focusIndex) + 1, text.length);
6200
+ const samePoint = localSelection.anchorX === localSelection.focusX && localSelection.anchorY === localSelection.focusY;
6201
+ if (samePoint || start >= end) {
6188
6202
  this.localSelection = null;
6189
- return previousSelection !== null;
6190
- } else if (selEnd.y >= 0 && selEnd.y <= height - 1) {
6191
- if (selEnd.x >= 0) {
6192
- endCharIndex = coordinateToCharacterIndex(selEnd.x, text, font);
6193
- } else {
6194
- endCharIndex = 0;
6195
- }
6196
- }
6197
- if (startCharIndex < endCharIndex && startCharIndex >= 0 && endCharIndex <= text.length) {
6198
- this.localSelection = { start: startCharIndex, end: endCharIndex };
6199
6203
  } else {
6200
- this.localSelection = null;
6204
+ this.localSelection = { start, end };
6201
6205
  }
6202
6206
  return previousSelection?.start !== this.localSelection?.start || previousSelection?.end !== this.localSelection?.end;
6203
6207
  }
@@ -13116,7 +13120,7 @@ var VisualCursorStruct = defineStruct([
13116
13120
  ["logicalCol", "u32"],
13117
13121
  ["offset", "u32"]
13118
13122
  ]);
13119
- var UnicodeMethodEnum = defineEnum({ wcwidth: 0, unicode: 1 }, "u8");
13123
+ var UnicodeMethodEnum = defineEnum({ wcwidth: 0, unicode: 1, "unicode-wide": 3 }, "u8");
13120
13124
  var TerminalMultiplexerEnum = defineEnum({ none: 0, tmux: 1, zellij: 2, screen: 3, unknown: 4 }, "u8");
13121
13125
  var Osc52SupportEnum = defineEnum({ unknown: 0, supported: 1, unsupported: 2 }, "u8");
13122
13126
  var ImageProtocolEnum = defineEnum({ auto: 0, kitty: 1, sixel: 2, blocks: 3 }, "u8");
@@ -13584,6 +13588,20 @@ function rgbaBuffer(value) {
13584
13588
  function optionalRgbaBuffer(value) {
13585
13589
  return value ? rgbaBuffer(value) : null;
13586
13590
  }
13591
+ function selectionBehaviorByte(behavior) {
13592
+ return behavior === "word" ? 1 : behavior === "line" ? 2 : 0;
13593
+ }
13594
+ function editorLocalSelectionFlags(updateCursor, followCursor, behavior) {
13595
+ return ffiBool(updateCursor) | ffiBool(followCursor) << 1 | selectionBehaviorByte(behavior) << 2;
13596
+ }
13597
+ function widthMethodCode(widthMethod) {
13598
+ return widthMethod === "wcwidth" ? 0 : widthMethod === "unicode-wide" ? 3 : 1;
13599
+ }
13600
+ function widthMethodFromCode(code) {
13601
+ if (code === 0)
13602
+ return "wcwidth";
13603
+ return code === 3 ? "unicode-wide" : "unicode";
13604
+ }
13587
13605
  function getOpenTUILib(libPath) {
13588
13606
  const resolvedLibPath = libPath || targetLibPath;
13589
13607
  if (!resolvedLibPath) {
@@ -13751,7 +13769,7 @@ function getOpenTUILib(libPath) {
13751
13769
  returns: "u64"
13752
13770
  },
13753
13771
  commitSplitFooterSnapshot: {
13754
- args: ["u32", "u32", "u32", "bool", "bool", "u32", "bool", "bool", "bool"],
13772
+ args: ["u32", "u32", "u32", "u8", "u32"],
13755
13773
  returns: "u64"
13756
13774
  },
13757
13775
  getNextBuffer: {
@@ -13775,7 +13793,7 @@ function getOpenTUILib(libPath) {
13775
13793
  returns: "void"
13776
13794
  },
13777
13795
  createOptimizedBuffer: {
13778
- args: ["u32", "u32", "bool", "u8", "buffer", "u32"],
13796
+ args: ["u32", "u32", "u8", "u8", "buffer", "u32"],
13779
13797
  returns: "u32"
13780
13798
  },
13781
13799
  destroyOptimizedBuffer: {
@@ -13794,6 +13812,10 @@ function getOpenTUILib(libPath) {
13794
13812
  args: ["u32"],
13795
13813
  returns: "u32"
13796
13814
  },
13815
+ getBufferWidthMethod: {
13816
+ args: ["u32"],
13817
+ returns: "u8"
13818
+ },
13797
13819
  bufferClear: {
13798
13820
  args: ["u32", "buffer"],
13799
13821
  returns: "void"
@@ -13899,7 +13921,7 @@ function getOpenTUILib(libPath) {
13899
13921
  returns: "void"
13900
13922
  },
13901
13923
  setDebugOverlay: {
13902
- args: ["u32", "bool", "u8"],
13924
+ args: ["u32", "u8", "u8"],
13903
13925
  returns: "void"
13904
13926
  },
13905
13927
  clearTerminal: {
@@ -14306,7 +14328,7 @@ function getOpenTUILib(libPath) {
14306
14328
  returns: "u64"
14307
14329
  },
14308
14330
  textBufferViewSetLocalSelection: {
14309
- args: ["u32", "i32", "i32", "i32", "i32", "ptr", "ptr"],
14331
+ args: ["u32", "i32", "i32", "i32", "i32", "ptr", "ptr", "u8"],
14310
14332
  returns: "bool"
14311
14333
  },
14312
14334
  textBufferViewUpdateSelection: {
@@ -14314,13 +14336,21 @@ function getOpenTUILib(libPath) {
14314
14336
  returns: "void"
14315
14337
  },
14316
14338
  textBufferViewUpdateLocalSelection: {
14317
- args: ["u32", "i32", "i32", "i32", "i32", "ptr", "ptr"],
14339
+ args: ["u32", "i32", "i32", "i32", "i32", "ptr", "ptr", "u8"],
14318
14340
  returns: "bool"
14319
14341
  },
14320
14342
  textBufferViewResetLocalSelection: {
14321
14343
  args: ["u32"],
14322
14344
  returns: "void"
14323
14345
  },
14346
+ textBufferViewSetSelectionOccupancy: {
14347
+ args: ["u32", "u8"],
14348
+ returns: "void"
14349
+ },
14350
+ textBufferViewGetSelectionOccupancy: {
14351
+ args: ["u32"],
14352
+ returns: "u8"
14353
+ },
14324
14354
  textBufferViewSetWrapWidth: {
14325
14355
  args: ["u32", "u32"],
14326
14356
  returns: "void"
@@ -14606,7 +14636,7 @@ function getOpenTUILib(libPath) {
14606
14636
  returns: "u64"
14607
14637
  },
14608
14638
  editorViewSetLocalSelection: {
14609
- args: ["u32", "i32", "i32", "i32", "i32", "ptr", "ptr", "bool", "bool"],
14639
+ args: ["u32", "i32", "i32", "i32", "i32", "ptr", "ptr", "u8"],
14610
14640
  returns: "bool"
14611
14641
  },
14612
14642
  editorViewUpdateSelection: {
@@ -14614,13 +14644,29 @@ function getOpenTUILib(libPath) {
14614
14644
  returns: "void"
14615
14645
  },
14616
14646
  editorViewUpdateLocalSelection: {
14617
- args: ["u32", "i32", "i32", "i32", "i32", "ptr", "ptr", "bool", "bool"],
14647
+ args: ["u32", "i32", "i32", "i32", "i32", "ptr", "ptr", "u8"],
14618
14648
  returns: "bool"
14619
14649
  },
14620
14650
  editorViewResetLocalSelection: {
14621
14651
  args: ["u32"],
14622
14652
  returns: "void"
14623
14653
  },
14654
+ editorViewConvertSelectionToCell: {
14655
+ args: ["u32"],
14656
+ returns: "bool"
14657
+ },
14658
+ editorViewSetSelectionOccupancy: {
14659
+ args: ["u32", "u8"],
14660
+ returns: "void"
14661
+ },
14662
+ editorViewSetSelectionInclusive: {
14663
+ args: ["u32", "u32", "u32", "ptr", "ptr"],
14664
+ returns: "void"
14665
+ },
14666
+ editorViewSetSelectionColors: {
14667
+ args: ["u32", "ptr", "ptr"],
14668
+ returns: "void"
14669
+ },
14624
14670
  editorViewGetSelectedTextBytes: {
14625
14671
  args: ["u32", "ptr", "u32"],
14626
14672
  returns: "u32"
@@ -14673,6 +14719,10 @@ function getOpenTUILib(libPath) {
14673
14719
  args: ["u32", "ptr"],
14674
14720
  returns: "void"
14675
14721
  },
14722
+ editorViewGotoVisualLineEnd: {
14723
+ args: ["u32"],
14724
+ returns: "void"
14725
+ },
14676
14726
  editorViewSetPlaceholderStyledText: {
14677
14727
  args: ["u32", "ptr", "u32"],
14678
14728
  returns: "void"
@@ -15117,7 +15167,7 @@ function getOpenTUILib(libPath) {
15117
15167
  returns: "i32"
15118
15168
  },
15119
15169
  audioEnableTap: {
15120
- args: ["u32", "bool", "u32"],
15170
+ args: ["u32", "u8", "u32"],
15121
15171
  returns: "i32"
15122
15172
  },
15123
15173
  audioReadTap: {
@@ -15742,7 +15792,8 @@ class FFIRenderLib {
15742
15792
  }
15743
15793
  const width = this.opentui.symbols.getBufferWidth(bufferPtr);
15744
15794
  const height = this.opentui.symbols.getBufferHeight(bufferPtr);
15745
- return new OptimizedBuffer(this, bufferPtr, width, height, { id: "next buffer", widthMethod: "unicode" });
15795
+ const widthMethod = widthMethodFromCode(this.opentui.symbols.getBufferWidthMethod(bufferPtr));
15796
+ return new OptimizedBuffer(this, bufferPtr, width, height, { id: "next buffer", widthMethod });
15746
15797
  }
15747
15798
  getCurrentBuffer(renderer) {
15748
15799
  const bufferPtr = this.opentui.symbols.getCurrentBuffer(renderer);
@@ -15751,7 +15802,8 @@ class FFIRenderLib {
15751
15802
  }
15752
15803
  const width = this.opentui.symbols.getBufferWidth(bufferPtr);
15753
15804
  const height = this.opentui.symbols.getBufferHeight(bufferPtr);
15754
- return new OptimizedBuffer(this, bufferPtr, width, height, { id: "current buffer", widthMethod: "unicode" });
15805
+ const widthMethod = widthMethodFromCode(this.opentui.symbols.getBufferWidthMethod(bufferPtr));
15806
+ return new OptimizedBuffer(this, bufferPtr, width, height, { id: "current buffer", widthMethod });
15755
15807
  }
15756
15808
  rendererSetPaletteState(renderer, palette, defaultForeground, defaultBackground, paletteEpoch) {
15757
15809
  const paletteBuffer = new Uint16Array(palette.length * 4);
@@ -15948,16 +16000,16 @@ class FFIRenderLib {
15948
16000
  return this.unpackRenderOperationResult(this.opentui.symbols.repaintSplitFooter(renderer, pinnedRenderOffset, ffiBool(force)));
15949
16001
  }
15950
16002
  commitSplitFooterSnapshot(renderer, snapshot, rowColumns, startOnNewLine, trailingNewline, pinnedRenderOffset, force, beginFrame = true, finalizeFrame = true) {
15951
- return this.unpackRenderOperationResult(this.opentui.symbols.commitSplitFooterSnapshot(renderer, snapshot.ptr, rowColumns, ffiBool(startOnNewLine), ffiBool(trailingNewline), pinnedRenderOffset, ffiBool(force), ffiBool(beginFrame), ffiBool(finalizeFrame)));
16003
+ const flags = ffiBool(startOnNewLine) | ffiBool(trailingNewline) << 1 | ffiBool(force) << 2 | ffiBool(beginFrame) << 3 | ffiBool(finalizeFrame) << 4;
16004
+ return this.unpackRenderOperationResult(this.opentui.symbols.commitSplitFooterSnapshot(renderer, snapshot.ptr, rowColumns, flags, pinnedRenderOffset));
15952
16005
  }
15953
16006
  createOptimizedBuffer(width, height, widthMethod, respectAlpha = false, id) {
15954
16007
  if (Number.isNaN(width) || Number.isNaN(height)) {
15955
16008
  console.error(new Error(`Invalid dimensions for OptimizedBuffer: ${width}x${height}`).stack);
15956
16009
  }
15957
- const widthMethodCode = widthMethod === "wcwidth" ? 0 : 1;
15958
16010
  const idToUse = id || "unnamed buffer";
15959
16011
  const idBytes = this.encoder.encode(idToUse);
15960
- const bufferPtr = this.opentui.symbols.createOptimizedBuffer(width, height, ffiBool(respectAlpha), widthMethodCode, idBytes, idBytes.byteLength);
16012
+ const bufferPtr = this.opentui.symbols.createOptimizedBuffer(width, height, ffiBool(respectAlpha), widthMethodCode(widthMethod), idBytes, idBytes.byteLength);
15961
16013
  if (!bufferPtr) {
15962
16014
  throw new Error(`Failed to create optimized buffer: ${width}x${height}`);
15963
16015
  }
@@ -16347,8 +16399,7 @@ class FFIRenderLib {
16347
16399
  });
16348
16400
  }
16349
16401
  createTextBuffer(widthMethod) {
16350
- const widthMethodCode = widthMethod === "wcwidth" ? 0 : 1;
16351
- const bufferPtr = this.opentui.symbols.createTextBuffer(widthMethodCode);
16402
+ const bufferPtr = this.opentui.symbols.createTextBuffer(widthMethodCode(widthMethod));
16352
16403
  if (!bufferPtr) {
16353
16404
  throw new Error(`Failed to create TextBuffer`);
16354
16405
  }
@@ -16486,24 +16537,30 @@ class FFIRenderLib {
16486
16537
  textBufferViewGetSelectionInfo(view) {
16487
16538
  return this.opentui.symbols.textBufferViewGetSelectionInfo(view);
16488
16539
  }
16489
- textBufferViewSetLocalSelection(view, anchorX, anchorY, focusX, focusY, bgColor, fgColor) {
16540
+ textBufferViewSetLocalSelection(view, anchorX, anchorY, focusX, focusY, bgColor, fgColor, behavior) {
16490
16541
  const bg2 = optionalRgbaBuffer(bgColor);
16491
16542
  const fg2 = optionalRgbaBuffer(fgColor);
16492
- return Boolean(this.opentui.symbols.textBufferViewSetLocalSelection(view, anchorX, anchorY, focusX, focusY, bg2, fg2));
16543
+ return Boolean(this.opentui.symbols.textBufferViewSetLocalSelection(view, anchorX, anchorY, focusX, focusY, bg2, fg2, selectionBehaviorByte(behavior)));
16493
16544
  }
16494
16545
  textBufferViewUpdateSelection(view, end, bgColor, fgColor) {
16495
16546
  const bg2 = optionalRgbaBuffer(bgColor);
16496
16547
  const fg2 = optionalRgbaBuffer(fgColor);
16497
16548
  this.opentui.symbols.textBufferViewUpdateSelection(view, end, bg2, fg2);
16498
16549
  }
16499
- textBufferViewUpdateLocalSelection(view, anchorX, anchorY, focusX, focusY, bgColor, fgColor) {
16550
+ textBufferViewUpdateLocalSelection(view, anchorX, anchorY, focusX, focusY, bgColor, fgColor, behavior) {
16500
16551
  const bg2 = optionalRgbaBuffer(bgColor);
16501
16552
  const fg2 = optionalRgbaBuffer(fgColor);
16502
- return Boolean(this.opentui.symbols.textBufferViewUpdateLocalSelection(view, anchorX, anchorY, focusX, focusY, bg2, fg2));
16553
+ return Boolean(this.opentui.symbols.textBufferViewUpdateLocalSelection(view, anchorX, anchorY, focusX, focusY, bg2, fg2, selectionBehaviorByte(behavior)));
16503
16554
  }
16504
16555
  textBufferViewResetLocalSelection(view) {
16505
16556
  this.opentui.symbols.textBufferViewResetLocalSelection(view);
16506
16557
  }
16558
+ textBufferViewSetSelectionOccupancy(view, occupancy) {
16559
+ this.opentui.symbols.textBufferViewSetSelectionOccupancy(view, occupancy === "boundary" ? 1 : 0);
16560
+ }
16561
+ textBufferViewGetSelectionOccupancy(view) {
16562
+ return this.opentui.symbols.textBufferViewGetSelectionOccupancy(view) === 1 ? "boundary" : "cell";
16563
+ }
16507
16564
  textBufferViewSetWrapWidth(view, width) {
16508
16565
  this.opentui.symbols.textBufferViewSetWrapWidth(view, width);
16509
16566
  }
@@ -16744,8 +16801,7 @@ class FFIRenderLib {
16744
16801
  };
16745
16802
  }
16746
16803
  createEditBuffer(widthMethod) {
16747
- const widthMethodCode = widthMethod === "wcwidth" ? 0 : 1;
16748
- const bufferPtr = this.opentui.symbols.createEditBuffer(widthMethodCode, this.eventSinkPtr ?? 0);
16804
+ const bufferPtr = this.opentui.symbols.createEditBuffer(widthMethodCode(widthMethod), this.eventSinkPtr ?? 0);
16749
16805
  if (!bufferPtr) {
16750
16806
  throw new Error("Failed to create EditBuffer");
16751
16807
  }
@@ -16933,24 +16989,40 @@ class FFIRenderLib {
16933
16989
  const end = Number(packedInfo & 0xffff_ffffn);
16934
16990
  return { start, end };
16935
16991
  }
16936
- editorViewSetLocalSelection(view, anchorX, anchorY, focusX, focusY, bgColor, fgColor, updateCursor, followCursor) {
16992
+ editorViewSetLocalSelection(view, anchorX, anchorY, focusX, focusY, bgColor, fgColor, updateCursor, followCursor, behavior) {
16937
16993
  const bg2 = optionalRgbaBuffer(bgColor);
16938
16994
  const fg2 = optionalRgbaBuffer(fgColor);
16939
- return Boolean(this.opentui.symbols.editorViewSetLocalSelection(view, anchorX, anchorY, focusX, focusY, bg2, fg2, ffiBool(updateCursor), ffiBool(followCursor)));
16995
+ return Boolean(this.opentui.symbols.editorViewSetLocalSelection(view, anchorX, anchorY, focusX, focusY, bg2, fg2, editorLocalSelectionFlags(updateCursor, followCursor, behavior)));
16940
16996
  }
16941
16997
  editorViewUpdateSelection(view, end, bgColor, fgColor) {
16942
16998
  const bg2 = optionalRgbaBuffer(bgColor);
16943
16999
  const fg2 = optionalRgbaBuffer(fgColor);
16944
17000
  this.opentui.symbols.editorViewUpdateSelection(view, end, bg2, fg2);
16945
17001
  }
16946
- editorViewUpdateLocalSelection(view, anchorX, anchorY, focusX, focusY, bgColor, fgColor, updateCursor, followCursor) {
17002
+ editorViewUpdateLocalSelection(view, anchorX, anchorY, focusX, focusY, bgColor, fgColor, updateCursor, followCursor, behavior) {
16947
17003
  const bg2 = optionalRgbaBuffer(bgColor);
16948
17004
  const fg2 = optionalRgbaBuffer(fgColor);
16949
- return Boolean(this.opentui.symbols.editorViewUpdateLocalSelection(view, anchorX, anchorY, focusX, focusY, bg2, fg2, ffiBool(updateCursor), ffiBool(followCursor)));
17005
+ return Boolean(this.opentui.symbols.editorViewUpdateLocalSelection(view, anchorX, anchorY, focusX, focusY, bg2, fg2, editorLocalSelectionFlags(updateCursor, followCursor, behavior)));
16950
17006
  }
16951
17007
  editorViewResetLocalSelection(view) {
16952
17008
  this.opentui.symbols.editorViewResetLocalSelection(view);
16953
17009
  }
17010
+ editorViewConvertSelectionToCell(view) {
17011
+ return Boolean(this.opentui.symbols.editorViewConvertSelectionToCell(view));
17012
+ }
17013
+ editorViewSetSelectionOccupancy(view, occupancy) {
17014
+ this.opentui.symbols.editorViewSetSelectionOccupancy(view, occupancy === "boundary" ? 1 : 0);
17015
+ }
17016
+ editorViewSetSelectionInclusive(view, start, end, bgColor, fgColor) {
17017
+ const bg2 = optionalRgbaBuffer(bgColor);
17018
+ const fg2 = optionalRgbaBuffer(fgColor);
17019
+ this.opentui.symbols.editorViewSetSelectionInclusive(view, start, end, bg2, fg2);
17020
+ }
17021
+ editorViewSetSelectionColors(view, bgColor, fgColor) {
17022
+ const bg2 = optionalRgbaBuffer(bgColor);
17023
+ const fg2 = optionalRgbaBuffer(fgColor);
17024
+ this.opentui.symbols.editorViewSetSelectionColors(view, bg2, fg2);
17025
+ }
16954
17026
  editorViewGetSelectedTextBytes(view, maxLength) {
16955
17027
  const outBuffer = new Uint8Array(maxLength);
16956
17028
  const actualLen = this.opentui.symbols.editorViewGetSelectedTextBytes(view, viewOrNull(outBuffer), maxLength);
@@ -17021,6 +17093,9 @@ class FFIRenderLib {
17021
17093
  const cursor = VisualCursorStruct.unpackInto(storage.view, storage.result);
17022
17094
  return { ...cursor };
17023
17095
  }
17096
+ editorViewGotoVisualLineEnd(view) {
17097
+ this.opentui.symbols.editorViewGotoVisualLineEnd(view);
17098
+ }
17024
17099
  bufferPushScissorRect(buffer, x, y, width, height) {
17025
17100
  this.opentui.symbols.bufferPushScissorRect(buffer, x, y, width, height);
17026
17101
  }
@@ -17081,10 +17156,9 @@ class FFIRenderLib {
17081
17156
  }
17082
17157
  encodeUnicode(text, widthMethod) {
17083
17158
  const textBytes = this.encoder.encode(text);
17084
- const widthMethodCode = widthMethod === "wcwidth" ? 0 : 1;
17085
17159
  const outPtrBuffer = new ArrayBuffer(8);
17086
17160
  const outLenBuffer = new ArrayBuffer(8);
17087
- const success = this.opentui.symbols.encodeUnicode(viewOrNull(textBytes), textBytes.byteLength, outPtrBuffer, outLenBuffer, widthMethodCode);
17161
+ const success = this.opentui.symbols.encodeUnicode(viewOrNull(textBytes), textBytes.byteLength, outPtrBuffer, outLenBuffer, widthMethodCode(widthMethod));
17088
17162
  if (!success) {
17089
17163
  return null;
17090
17164
  }
@@ -18535,5 +18609,5 @@ var yoga_default = Yoga;
18535
18609
 
18536
18610
  export { toArrayBuffer, singleton, envRegistry, registerEnvVar, clearEnvCache, generateEnvMarkdown, generateEnvColored, env, sleep, stringWidth2 as stringWidth, resolveBundledFilePath, DEFAULT_FOREGROUND_RGB, DEFAULT_BACKGROUND_RGB, normalizeIndexedColorIndex, ansi256IndexToRgb, RGBA, normalizeColorValue, hexToRgb, rgbToHex, hsvToRgb, parseColor, isValidBorderStyle, parseBorderStyle, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, KeyEvent, PasteEvent, KeyHandler, InternalKeyHandler, fonts, measureText, getCharacterPositions, coordinateToCharacterIndex, renderFontToFrameBuffer, TextAttributes, ATTRIBUTE_BASE_BITS, ATTRIBUTE_BASE_MASK, getBaseAttributes, DebugOverlayCorner, TargetChannel, createTextAttributes, attributesWithLink, getLinkId, 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, link, t, hastToStyledText, SystemClock, nonAlphanumericKeys, terminalNamedSingleStrokeKeys, parseKeypress, LinearScrollAccel, MacOSScrollAccel, parseAlign, parseAlignItems, parseBoxSizing, parseDimension, parseDirection, parseDisplay, parseEdge, parseFlexDirection, parseGutter, parseJustify, parseLogLevel, parseMeasureMode, parseOverflow, parsePositionType, parseUnit, parseWrap, MouseParser, Selection, convertGlobalToLocalSelection, ASCIIFontSelectionHelper, StdinParser, treeSitterToTextChunks, treeSitterToStyledText, addDefaultParsers, TreeSitterClient, DataPathsManager, getDataPaths, extensionToFiletype, basenameToFiletype, extToFiletype, pathToFiletype, infoStringToFiletype, getTreeSitterClient, destroyTreeSitterClient, ExtmarksController, createExtmarksController, TerminalPalette, createTerminalPalette, normalizeTerminalPalette, buildTerminalPaletteSignature, decodePasteBytes, stripAnsiSequences, createHostClipboard, createClipboard, ClipboardTarget, createRendererClipboardAdapter, Clipboard, detectLinks, OptimizedBuffer, TextBuffer, SpanInfoStruct, NativeAudioStreamFormat, NativeAudioStreamState, NativeAudioStreamStateNames, NativeAudioStreamCloseReason, NativeAudioStreamState2 as NativeAudioStreamState1, NativeAudioStreamCloseReason2 as NativeAudioStreamCloseReason1, NativeAudioStreamFormat2 as NativeAudioStreamFormat1, NativeClipboardOperationStatus, NativeClipboardStartStatus, NativeClipboardCancelStatus, NativeClipboardCopyStatus, NativeClipboardDestroyStatus, NativeClipboardShutdownStatus, LogLevel2 as LogLevel, NativeMeasureTargetKind, setRenderLibPath, resolveRenderLib, Align, BoxSizing, Dimension, Direction, Display, Edge, Errata, ExperimentalFeature, FlexDirection, Gutter, Justify, LogLevel as LogLevel1, MeasureMode, NodeType, Overflow, PositionType, Unit, Wrap, ALIGN_AUTO, ALIGN_FLEX_START, ALIGN_CENTER, ALIGN_FLEX_END, ALIGN_STRETCH, ALIGN_BASELINE, ALIGN_SPACE_BETWEEN, ALIGN_SPACE_AROUND, ALIGN_SPACE_EVENLY, BOX_SIZING_BORDER_BOX, BOX_SIZING_CONTENT_BOX, DIMENSION_WIDTH, DIMENSION_HEIGHT, DIRECTION_INHERIT, DIRECTION_LTR, DIRECTION_RTL, DISPLAY_FLEX, DISPLAY_NONE, DISPLAY_CONTENTS, EDGE_LEFT, EDGE_TOP, EDGE_RIGHT, EDGE_BOTTOM, EDGE_START, EDGE_END, EDGE_HORIZONTAL, EDGE_VERTICAL, EDGE_ALL, ERRATA_NONE, ERRATA_STRETCH_FLEX_BASIS, ERRATA_ABSOLUTE_POSITION_WITHOUT_INSETS_EXCLUDES_PADDING, ERRATA_ABSOLUTE_PERCENT_AGAINST_INNER_SIZE, ERRATA_ALL, ERRATA_CLASSIC, EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS, FLEX_DIRECTION_COLUMN, FLEX_DIRECTION_COLUMN_REVERSE, FLEX_DIRECTION_ROW, FLEX_DIRECTION_ROW_REVERSE, GUTTER_COLUMN, GUTTER_ROW, GUTTER_ALL, JUSTIFY_FLEX_START, JUSTIFY_CENTER, JUSTIFY_FLEX_END, JUSTIFY_SPACE_BETWEEN, JUSTIFY_SPACE_AROUND, JUSTIFY_SPACE_EVENLY, LOG_LEVEL_ERROR, LOG_LEVEL_WARN, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_VERBOSE, LOG_LEVEL_FATAL, MEASURE_MODE_UNDEFINED, MEASURE_MODE_EXACTLY, MEASURE_MODE_AT_MOST, NODE_TYPE_DEFAULT, NODE_TYPE_TEXT, OVERFLOW_VISIBLE, OVERFLOW_HIDDEN, OVERFLOW_SCROLL, POSITION_TYPE_STATIC, POSITION_TYPE_RELATIVE, POSITION_TYPE_ABSOLUTE, UNIT_UNDEFINED, UNIT_POINT, UNIT_PERCENT, UNIT_AUTO, WRAP_NO_WRAP, WRAP_WRAP, WRAP_WRAP_REVERSE, Config, Node, exports_yoga, yoga_default };
18537
18611
 
18538
- //# debugId=353B3B712CF6E51464756E2164756E21
18539
- //# sourceMappingURL=chunk-bun-9335djz2.js.map
18612
+ //# debugId=629581C67E2214E264756E2164756E21
18613
+ //# sourceMappingURL=chunk-bun-2956gvaq.js.map