@fairyhunter13/opentui-core 0.1.88 → 0.1.90

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 (570) hide show
  1. package/dev/keypress-debug-renderer.ts +148 -0
  2. package/dev/keypress-debug.ts +43 -0
  3. package/dev/print-env-vars.ts +32 -0
  4. package/dev/test-tmux-graphics-334.sh +68 -0
  5. package/dev/thai-debug-test.ts +68 -0
  6. package/docs/development.md +141 -0
  7. package/docs/env-vars.md +140 -0
  8. package/docs/getting-started.md +353 -0
  9. package/docs/renderables-vs-constructs.md +159 -0
  10. package/docs/tree-sitter.md +311 -0
  11. package/package.json +61 -52
  12. package/scripts/build.ts +400 -0
  13. package/scripts/publish.ts +60 -0
  14. package/src/3d/SpriteResourceManager.ts +286 -0
  15. package/src/3d/SpriteUtils.ts +71 -0
  16. package/src/3d/TextureUtils.ts +196 -0
  17. package/src/3d/ThreeRenderable.ts +197 -0
  18. package/src/3d/WGPURenderer.ts +294 -0
  19. package/src/3d/animation/ExplodingSpriteEffect.ts +513 -0
  20. package/src/3d/animation/PhysicsExplodingSpriteEffect.ts +429 -0
  21. package/src/3d/animation/SpriteAnimator.ts +633 -0
  22. package/src/3d/animation/SpriteParticleGenerator.ts +435 -0
  23. package/src/3d/canvas.ts +464 -0
  24. package/src/3d/index.ts +12 -0
  25. package/src/3d/physics/PlanckPhysicsAdapter.ts +72 -0
  26. package/src/3d/physics/RapierPhysicsAdapter.ts +66 -0
  27. package/src/3d/physics/physics-interface.ts +31 -0
  28. package/src/3d/shaders/supersampling.wgsl +201 -0
  29. package/src/3d.ts +3 -0
  30. package/src/NativeSpanFeed.ts +300 -0
  31. package/src/Renderable.ts +1698 -0
  32. package/src/__snapshots__/buffer.test.ts.snap +28 -0
  33. package/src/animation/Timeline.test.ts +2709 -0
  34. package/src/animation/Timeline.ts +598 -0
  35. package/src/ansi.ts +18 -0
  36. package/src/benchmark/latest-all-bench-run.json +707 -0
  37. package/src/benchmark/latest-async-bench-run.json +336 -0
  38. package/src/benchmark/latest-default-bench-run.json +657 -0
  39. package/src/benchmark/latest-large-bench-run.json +707 -0
  40. package/src/benchmark/latest-quick-bench-run.json +207 -0
  41. package/src/benchmark/markdown-benchmark.ts +1804 -0
  42. package/src/benchmark/native-span-feed-async-benchmark.ts +355 -0
  43. package/src/benchmark/native-span-feed-benchmark.md +56 -0
  44. package/src/benchmark/native-span-feed-benchmark.ts +596 -0
  45. package/src/benchmark/native-span-feed-compare.ts +280 -0
  46. package/src/benchmark/renderer-benchmark.ts +754 -0
  47. package/src/benchmark/text-table-benchmark.ts +947 -0
  48. package/src/buffer.test.ts +291 -0
  49. package/src/buffer.ts +519 -0
  50. package/src/console.test.ts +612 -0
  51. package/src/console.ts +1255 -0
  52. package/src/edit-buffer.test.ts +1769 -0
  53. package/src/edit-buffer.ts +411 -0
  54. package/src/editor-view.test.ts +1032 -0
  55. package/src/editor-view.ts +284 -0
  56. package/src/examples/ascii-font-selection-demo.ts +245 -0
  57. package/src/examples/assets/Water_2_M_Normal.jpg +0 -0
  58. package/src/examples/assets/concrete.png +0 -0
  59. package/src/examples/assets/crate.png +0 -0
  60. package/src/examples/assets/crate_emissive.png +0 -0
  61. package/src/examples/assets/forrest_background.png +0 -0
  62. package/src/examples/assets/hast-example.json +1018 -0
  63. package/src/examples/assets/heart.png +0 -0
  64. package/src/examples/assets/main_char_heavy_attack.png +0 -0
  65. package/src/examples/assets/main_char_idle.png +0 -0
  66. package/src/examples/assets/main_char_jump_end.png +0 -0
  67. package/src/examples/assets/main_char_jump_landing.png +0 -0
  68. package/src/examples/assets/main_char_jump_start.png +0 -0
  69. package/src/examples/assets/main_char_run_loop.png +0 -0
  70. package/src/examples/assets/roughness_map.jpg +0 -0
  71. package/src/examples/build.ts +115 -0
  72. package/src/examples/code-demo.ts +584 -0
  73. package/src/examples/console-demo.ts +358 -0
  74. package/src/examples/core-plugin-slots-demo.ts +759 -0
  75. package/src/examples/diff-demo.ts +699 -0
  76. package/src/examples/draggable-three-demo.ts +259 -0
  77. package/src/examples/editor-demo.ts +322 -0
  78. package/src/examples/extmarks-demo.ts +204 -0
  79. package/src/examples/focus-restore-demo.ts +310 -0
  80. package/src/examples/fonts.ts +245 -0
  81. package/src/examples/fractal-shader-demo.ts +268 -0
  82. package/src/examples/framebuffer-demo.ts +674 -0
  83. package/src/examples/full-unicode-demo.ts +181 -0
  84. package/src/examples/golden-star-demo.ts +933 -0
  85. package/src/examples/grayscale-buffer-demo.ts +249 -0
  86. package/src/examples/hast-syntax-highlighting-demo.ts +129 -0
  87. package/src/examples/index.ts +925 -0
  88. package/src/examples/input-demo.ts +377 -0
  89. package/src/examples/input-select-layout-demo.ts +425 -0
  90. package/src/examples/install.sh +143 -0
  91. package/src/examples/keypress-debug-demo.ts +452 -0
  92. package/src/examples/lib/HexList.ts +122 -0
  93. package/src/examples/lib/PaletteGrid.ts +125 -0
  94. package/src/examples/lib/standalone-keys.ts +25 -0
  95. package/src/examples/lib/tab-controller.ts +243 -0
  96. package/src/examples/lights-phong-demo.ts +290 -0
  97. package/src/examples/link-demo.ts +220 -0
  98. package/src/examples/live-state-demo.ts +480 -0
  99. package/src/examples/markdown-demo.ts +620 -0
  100. package/src/examples/mouse-interaction-demo.ts +428 -0
  101. package/src/examples/nested-zindex-demo.ts +357 -0
  102. package/src/examples/opacity-example.ts +235 -0
  103. package/src/examples/opentui-demo.ts +1057 -0
  104. package/src/examples/physx-planck-2d-demo.ts +507 -0
  105. package/src/examples/physx-rapier-2d-demo.ts +526 -0
  106. package/src/examples/relative-positioning-demo.ts +323 -0
  107. package/src/examples/scroll-example.ts +214 -0
  108. package/src/examples/scrollbox-mouse-test.ts +112 -0
  109. package/src/examples/scrollbox-overlay-hit-test.ts +206 -0
  110. package/src/examples/select-demo.ts +237 -0
  111. package/src/examples/shader-cube-demo.ts +772 -0
  112. package/src/examples/simple-layout-example.ts +591 -0
  113. package/src/examples/slider-demo.ts +617 -0
  114. package/src/examples/split-mode-demo.ts +445 -0
  115. package/src/examples/sprite-animation-demo.ts +443 -0
  116. package/src/examples/sprite-particle-generator-demo.ts +486 -0
  117. package/src/examples/static-sprite-demo.ts +193 -0
  118. package/src/examples/sticky-scroll-example.ts +308 -0
  119. package/src/examples/styled-text-demo.ts +282 -0
  120. package/src/examples/tab-select-demo.ts +219 -0
  121. package/src/examples/terminal-title.ts +29 -0
  122. package/src/examples/terminal.ts +305 -0
  123. package/src/examples/text-node-demo.ts +416 -0
  124. package/src/examples/text-selection-demo.ts +377 -0
  125. package/src/examples/text-table-demo.ts +503 -0
  126. package/src/examples/text-truncation-demo.ts +481 -0
  127. package/src/examples/text-wrap.ts +757 -0
  128. package/src/examples/texture-loading-demo.ts +259 -0
  129. package/src/examples/timeline-example.ts +670 -0
  130. package/src/examples/transparency-demo.ts +241 -0
  131. package/src/examples/vnode-composition-demo.ts +404 -0
  132. package/src/index.ts +22 -0
  133. package/src/lib/KeyHandler.integration.test.ts +292 -0
  134. package/src/lib/KeyHandler.stopPropagation.test.ts +289 -0
  135. package/src/lib/KeyHandler.test.ts +662 -0
  136. package/src/lib/KeyHandler.ts +222 -0
  137. package/src/lib/RGBA.test.ts +984 -0
  138. package/src/lib/RGBA.ts +204 -0
  139. package/src/lib/ascii.font.ts +330 -0
  140. package/src/lib/border.test.ts +83 -0
  141. package/src/lib/border.ts +168 -0
  142. package/src/lib/bunfs.test.ts +27 -0
  143. package/src/lib/bunfs.ts +18 -0
  144. package/src/lib/clipboard.test.ts +41 -0
  145. package/src/lib/clipboard.ts +47 -0
  146. package/src/lib/clock.ts +31 -0
  147. package/src/lib/data-paths.test.ts +133 -0
  148. package/src/lib/data-paths.ts +109 -0
  149. package/src/lib/debounce.ts +106 -0
  150. package/src/lib/detect-links.test.ts +98 -0
  151. package/src/lib/detect-links.ts +56 -0
  152. package/src/lib/env.test.ts +228 -0
  153. package/src/lib/env.ts +209 -0
  154. package/src/lib/extmarks-history.ts +51 -0
  155. package/src/lib/extmarks-multiwidth.test.ts +322 -0
  156. package/src/lib/extmarks.test.ts +3457 -0
  157. package/src/lib/extmarks.ts +843 -0
  158. package/src/lib/fonts/block.json +405 -0
  159. package/src/lib/fonts/grid.json +265 -0
  160. package/src/lib/fonts/huge.json +741 -0
  161. package/src/lib/fonts/pallet.json +314 -0
  162. package/src/lib/fonts/shade.json +591 -0
  163. package/src/lib/fonts/slick.json +321 -0
  164. package/src/lib/fonts/tiny.json +69 -0
  165. package/src/lib/hast-styled-text.ts +59 -0
  166. package/src/lib/index.ts +21 -0
  167. package/src/lib/keymapping.test.ts +280 -0
  168. package/src/lib/keymapping.ts +87 -0
  169. package/src/lib/objects-in-viewport.test.ts +787 -0
  170. package/src/lib/objects-in-viewport.ts +153 -0
  171. package/src/lib/output.capture.ts +58 -0
  172. package/src/lib/parse.keypress-kitty.protocol.test.ts +340 -0
  173. package/src/lib/parse.keypress-kitty.test.ts +663 -0
  174. package/src/lib/parse.keypress-kitty.ts +439 -0
  175. package/src/lib/parse.keypress.test.ts +1849 -0
  176. package/src/lib/parse.keypress.ts +397 -0
  177. package/src/lib/parse.mouse.test.ts +552 -0
  178. package/src/lib/parse.mouse.ts +232 -0
  179. package/src/lib/paste.ts +16 -0
  180. package/src/lib/queue.ts +65 -0
  181. package/src/lib/renderable.validations.test.ts +87 -0
  182. package/src/lib/renderable.validations.ts +83 -0
  183. package/src/lib/scroll-acceleration.ts +98 -0
  184. package/src/lib/selection.ts +240 -0
  185. package/src/lib/singleton.ts +28 -0
  186. package/src/lib/stdin-parser.test.ts +1676 -0
  187. package/src/lib/stdin-parser.ts +1248 -0
  188. package/src/lib/styled-text.ts +178 -0
  189. package/src/lib/terminal-capability-detection.test.ts +202 -0
  190. package/src/lib/terminal-capability-detection.ts +79 -0
  191. package/src/lib/terminal-palette.test.ts +878 -0
  192. package/src/lib/terminal-palette.ts +383 -0
  193. package/src/lib/tree-sitter/assets/README.md +118 -0
  194. package/src/lib/tree-sitter/assets/update.ts +331 -0
  195. package/src/lib/tree-sitter/assets.d.ts +9 -0
  196. package/src/lib/tree-sitter/cache.test.ts +270 -0
  197. package/src/lib/tree-sitter/client.test.ts +1061 -0
  198. package/src/lib/tree-sitter/client.ts +615 -0
  199. package/src/lib/tree-sitter/default-parsers.ts +80 -0
  200. package/src/lib/tree-sitter/download-utils.ts +148 -0
  201. package/src/lib/tree-sitter/index.ts +28 -0
  202. package/src/lib/tree-sitter/parser.worker.ts +1001 -0
  203. package/src/lib/tree-sitter/parsers-config.ts +75 -0
  204. package/src/lib/tree-sitter/resolve-ft.ts +62 -0
  205. package/src/lib/tree-sitter/types.ts +81 -0
  206. package/src/lib/tree-sitter-styled-text.test.ts +1253 -0
  207. package/src/lib/tree-sitter-styled-text.ts +306 -0
  208. package/src/lib/validate-dir-name.ts +55 -0
  209. package/src/lib/yoga.options.test.ts +628 -0
  210. package/src/lib/yoga.options.ts +346 -0
  211. package/src/plugins/core-slot.ts +579 -0
  212. package/src/plugins/registry.ts +377 -0
  213. package/src/plugins/types.ts +46 -0
  214. package/src/post/filters.ts +888 -0
  215. package/src/renderables/ASCIIFont.ts +219 -0
  216. package/src/renderables/Box.test.ts +160 -0
  217. package/src/renderables/Box.ts +295 -0
  218. package/src/renderables/Code.test.ts +2062 -0
  219. package/src/renderables/Code.ts +357 -0
  220. package/src/renderables/Diff.regression.test.ts +226 -0
  221. package/src/renderables/Diff.test.ts +3027 -0
  222. package/src/renderables/Diff.ts +1209 -0
  223. package/src/renderables/EditBufferRenderable.ts +764 -0
  224. package/src/renderables/FrameBuffer.ts +47 -0
  225. package/src/renderables/Input.test.ts +1228 -0
  226. package/src/renderables/Input.ts +245 -0
  227. package/src/renderables/LineNumberRenderable.ts +675 -0
  228. package/src/renderables/Markdown.ts +1106 -0
  229. package/src/renderables/ScrollBar.ts +422 -0
  230. package/src/renderables/ScrollBox.ts +883 -0
  231. package/src/renderables/Select.test.ts +1010 -0
  232. package/src/renderables/Select.ts +523 -0
  233. package/src/renderables/Slider.test.ts +456 -0
  234. package/src/renderables/Slider.ts +347 -0
  235. package/src/renderables/TabSelect.test.ts +197 -0
  236. package/src/renderables/TabSelect.ts +455 -0
  237. package/src/renderables/Text.selection-buffer.test.ts +123 -0
  238. package/src/renderables/Text.test.ts +2660 -0
  239. package/src/renderables/Text.ts +147 -0
  240. package/src/renderables/TextBufferRenderable.ts +518 -0
  241. package/src/renderables/TextNode.test.ts +1058 -0
  242. package/src/renderables/TextNode.ts +325 -0
  243. package/src/renderables/TextTable.test.ts +1421 -0
  244. package/src/renderables/TextTable.ts +1344 -0
  245. package/src/renderables/Textarea.ts +732 -0
  246. package/src/renderables/TimeToFirstDraw.ts +89 -0
  247. package/src/renderables/__snapshots__/Code.test.ts.snap +13 -0
  248. package/src/renderables/__snapshots__/Diff.test.ts.snap +785 -0
  249. package/src/renderables/__snapshots__/Text.test.ts.snap +421 -0
  250. package/src/renderables/__snapshots__/TextTable.test.ts.snap +215 -0
  251. package/src/renderables/__tests__/LineNumberRenderable.scrollbox-simple.test.ts +144 -0
  252. package/src/renderables/__tests__/LineNumberRenderable.scrollbox.test.ts +816 -0
  253. package/src/renderables/__tests__/LineNumberRenderable.test.ts +1787 -0
  254. package/src/renderables/__tests__/LineNumberRenderable.wrapping.test.ts +85 -0
  255. package/src/renderables/__tests__/Markdown.test.ts +2287 -0
  256. package/src/renderables/__tests__/MultiRenderable.selection.test.ts +87 -0
  257. package/src/renderables/__tests__/Textarea.buffer.test.ts +682 -0
  258. package/src/renderables/__tests__/Textarea.destroyed-events.test.ts +675 -0
  259. package/src/renderables/__tests__/Textarea.editing.test.ts +2041 -0
  260. package/src/renderables/__tests__/Textarea.error-handling.test.ts +35 -0
  261. package/src/renderables/__tests__/Textarea.events.test.ts +738 -0
  262. package/src/renderables/__tests__/Textarea.highlights.test.ts +590 -0
  263. package/src/renderables/__tests__/Textarea.keybinding.test.ts +3149 -0
  264. package/src/renderables/__tests__/Textarea.paste.test.ts +357 -0
  265. package/src/renderables/__tests__/Textarea.rendering.test.ts +1864 -0
  266. package/src/renderables/__tests__/Textarea.scroll.test.ts +733 -0
  267. package/src/renderables/__tests__/Textarea.selection.test.ts +1590 -0
  268. package/src/renderables/__tests__/Textarea.stress.test.ts +670 -0
  269. package/src/renderables/__tests__/Textarea.undo-redo.test.ts +383 -0
  270. package/src/renderables/__tests__/Textarea.visual-lines.test.ts +310 -0
  271. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.code.test.ts.snap +221 -0
  272. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.scrollbox-simple.test.ts.snap +89 -0
  273. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.scrollbox.test.ts.snap +457 -0
  274. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.test.ts.snap +158 -0
  275. package/src/renderables/__tests__/__snapshots__/Textarea.rendering.test.ts.snap +387 -0
  276. package/src/renderables/__tests__/markdown-parser.test.ts +217 -0
  277. package/src/renderables/__tests__/renderable-test-utils.ts +60 -0
  278. package/src/renderables/composition/README.md +8 -0
  279. package/src/renderables/composition/VRenderable.ts +32 -0
  280. package/src/renderables/composition/constructs.ts +127 -0
  281. package/src/renderables/composition/vnode.ts +289 -0
  282. package/src/renderables/index.ts +22 -0
  283. package/src/renderables/markdown-parser.ts +66 -0
  284. package/src/renderer.ts +2363 -0
  285. package/src/runtime-plugin-support.ts +39 -0
  286. package/src/runtime-plugin.ts +144 -0
  287. package/src/syntax-style.test.ts +841 -0
  288. package/src/syntax-style.ts +264 -0
  289. package/src/testing/README.md +210 -0
  290. package/src/testing/capture-spans.test.ts +194 -0
  291. package/src/testing/integration.test.ts +276 -0
  292. package/src/testing/manual-clock.ts +106 -0
  293. package/src/testing/mock-keys.test.ts +1356 -0
  294. package/src/testing/mock-keys.ts +449 -0
  295. package/src/testing/mock-mouse.test.ts +218 -0
  296. package/src/testing/mock-mouse.ts +247 -0
  297. package/src/testing/mock-tree-sitter-client.ts +73 -0
  298. package/src/testing/spy.ts +13 -0
  299. package/src/testing/test-recorder.test.ts +415 -0
  300. package/src/testing/test-recorder.ts +145 -0
  301. package/src/testing/test-renderer.ts +116 -0
  302. package/src/testing.ts +7 -0
  303. package/src/tests/__snapshots__/absolute-positioning.snapshot.test.ts.snap +481 -0
  304. package/src/tests/__snapshots__/renderable.snapshot.test.ts.snap +19 -0
  305. package/src/tests/__snapshots__/scrollbox.test.ts.snap +29 -0
  306. package/src/tests/absolute-positioning.snapshot.test.ts +638 -0
  307. package/src/tests/allocator-stats.test.ts +38 -0
  308. package/src/tests/destroy-during-render.test.ts +200 -0
  309. package/src/tests/hover-cursor.test.ts +98 -0
  310. package/src/tests/native-span-feed-async.test.ts +173 -0
  311. package/src/tests/native-span-feed-close.test.ts +120 -0
  312. package/src/tests/native-span-feed-coverage.test.ts +227 -0
  313. package/src/tests/native-span-feed-edge-cases.test.ts +352 -0
  314. package/src/tests/native-span-feed-use-after-free.test.ts +45 -0
  315. package/src/tests/opacity.test.ts +123 -0
  316. package/src/tests/renderable.snapshot.test.ts +524 -0
  317. package/src/tests/renderable.test.ts +1281 -0
  318. package/src/tests/renderer.console-startup.test.ts +65 -0
  319. package/src/tests/renderer.control.test.ts +364 -0
  320. package/src/tests/renderer.core-slot-binding.test.ts +952 -0
  321. package/src/tests/renderer.cursor.test.ts +26 -0
  322. package/src/tests/renderer.destroy-during-render.test.ts +110 -0
  323. package/src/tests/renderer.focus-restore.test.ts +228 -0
  324. package/src/tests/renderer.focus.test.ts +251 -0
  325. package/src/tests/renderer.idle.test.ts +219 -0
  326. package/src/tests/renderer.input.test.ts +2145 -0
  327. package/src/tests/renderer.kitty-flags.test.ts +195 -0
  328. package/src/tests/renderer.mouse.test.ts +1269 -0
  329. package/src/tests/renderer.palette.test.ts +629 -0
  330. package/src/tests/renderer.selection.test.ts +49 -0
  331. package/src/tests/renderer.slot-registry.test.ts +649 -0
  332. package/src/tests/renderer.useMouse.test.ts +50 -0
  333. package/src/tests/runtime-plugin-support.fixture.ts +11 -0
  334. package/src/tests/runtime-plugin-support.test.ts +28 -0
  335. package/src/tests/runtime-plugin.fixture.ts +40 -0
  336. package/src/tests/runtime-plugin.test.ts +190 -0
  337. package/src/tests/scrollbox-culling-bug.test.ts +114 -0
  338. package/src/tests/scrollbox-hitgrid-resize.test.ts +136 -0
  339. package/src/tests/scrollbox-hitgrid.test.ts +909 -0
  340. package/src/tests/scrollbox.test.ts +1530 -0
  341. package/src/tests/wrap-resize-perf.test.ts +229 -0
  342. package/src/tests/yoga-setters.test.ts +921 -0
  343. package/src/text-buffer-view.test.ts +705 -0
  344. package/src/text-buffer-view.ts +189 -0
  345. package/src/text-buffer.test.ts +347 -0
  346. package/src/text-buffer.ts +250 -0
  347. package/src/types.ts +152 -0
  348. package/src/utils.ts +88 -0
  349. package/src/zig/ansi.zig +268 -0
  350. package/src/zig/bench/README.md +50 -0
  351. package/src/zig/bench/buffer-draw-text-buffer_bench.zig +887 -0
  352. package/src/zig/bench/edit-buffer_bench.zig +476 -0
  353. package/src/zig/bench/native-span-feed_bench.zig +100 -0
  354. package/src/zig/bench/rope-markers_bench.zig +713 -0
  355. package/src/zig/bench/rope_bench.zig +514 -0
  356. package/src/zig/bench/styled-text_bench.zig +470 -0
  357. package/src/zig/bench/text-buffer-coords_bench.zig +362 -0
  358. package/src/zig/bench/text-buffer-view_bench.zig +459 -0
  359. package/src/zig/bench/text-chunk-graphemes_bench.zig +273 -0
  360. package/src/zig/bench/utf8_bench.zig +799 -0
  361. package/src/zig/bench-utils.zig +431 -0
  362. package/src/zig/bench.zig +217 -0
  363. package/src/zig/buffer.zig +2223 -0
  364. package/src/zig/build.zig +289 -0
  365. package/src/zig/build.zig.zon +16 -0
  366. package/src/zig/edit-buffer.zig +825 -0
  367. package/src/zig/editor-view.zig +802 -0
  368. package/src/zig/event-bus.zig +13 -0
  369. package/src/zig/event-emitter.zig +65 -0
  370. package/src/zig/file-logger.zig +92 -0
  371. package/src/zig/grapheme.zig +599 -0
  372. package/src/zig/lib.zig +1834 -0
  373. package/src/zig/link.zig +333 -0
  374. package/src/zig/logger.zig +43 -0
  375. package/src/zig/mem-registry.zig +125 -0
  376. package/src/zig/native-span-feed-bench-lib.zig +7 -0
  377. package/src/zig/native-span-feed.zig +708 -0
  378. package/src/zig/renderer.zig +1386 -0
  379. package/src/zig/rope.zig +1220 -0
  380. package/src/zig/syntax-style.zig +161 -0
  381. package/src/zig/terminal.zig +975 -0
  382. package/src/zig/test.zig +70 -0
  383. package/src/zig/tests/README.md +18 -0
  384. package/src/zig/tests/buffer_test.zig +2526 -0
  385. package/src/zig/tests/edit-buffer-history_test.zig +271 -0
  386. package/src/zig/tests/edit-buffer_test.zig +1689 -0
  387. package/src/zig/tests/editor-view_test.zig +3299 -0
  388. package/src/zig/tests/event-emitter_test.zig +249 -0
  389. package/src/zig/tests/grapheme_test.zig +1304 -0
  390. package/src/zig/tests/link_test.zig +190 -0
  391. package/src/zig/tests/mem-registry_test.zig +473 -0
  392. package/src/zig/tests/memory_leak_regression_test.zig +159 -0
  393. package/src/zig/tests/native-span-feed_test.zig +1264 -0
  394. package/src/zig/tests/renderer_test.zig +1010 -0
  395. package/src/zig/tests/rope-nested_test.zig +712 -0
  396. package/src/zig/tests/rope_fuzz_test.zig +238 -0
  397. package/src/zig/tests/rope_test.zig +2362 -0
  398. package/src/zig/tests/segment-merge.test.zig +148 -0
  399. package/src/zig/tests/syntax-style_test.zig +557 -0
  400. package/src/zig/tests/terminal_test.zig +719 -0
  401. package/src/zig/tests/text-buffer-drawing_test.zig +3237 -0
  402. package/src/zig/tests/text-buffer-highlights_test.zig +666 -0
  403. package/src/zig/tests/text-buffer-iterators_test.zig +776 -0
  404. package/src/zig/tests/text-buffer-segment_test.zig +320 -0
  405. package/src/zig/tests/text-buffer-selection_test.zig +1035 -0
  406. package/src/zig/tests/text-buffer-selection_viewport_test.zig +358 -0
  407. package/src/zig/tests/text-buffer-view_test.zig +3649 -0
  408. package/src/zig/tests/text-buffer_test.zig +2191 -0
  409. package/src/zig/tests/unicode-width-map.zon +3909 -0
  410. package/src/zig/tests/utf8_no_zwj_test.zig +260 -0
  411. package/src/zig/tests/utf8_test.zig +4057 -0
  412. package/src/zig/tests/utf8_wcwidth_cursor_test.zig +267 -0
  413. package/src/zig/tests/utf8_wcwidth_test.zig +357 -0
  414. package/src/zig/tests/word-wrap-editing_test.zig +498 -0
  415. package/src/zig/tests/wrap-cache-perf_test.zig +113 -0
  416. package/src/zig/text-buffer-iterators.zig +499 -0
  417. package/src/zig/text-buffer-segment.zig +404 -0
  418. package/src/zig/text-buffer-view.zig +1371 -0
  419. package/src/zig/text-buffer.zig +1180 -0
  420. package/src/zig/utf8.zig +1948 -0
  421. package/src/zig/utils.zig +9 -0
  422. package/src/zig-structs.ts +261 -0
  423. package/src/zig.ts +3843 -0
  424. package/tsconfig.build.json +22 -0
  425. package/tsconfig.json +28 -0
  426. package/3d/SpriteResourceManager.d.ts +0 -74
  427. package/3d/SpriteUtils.d.ts +0 -13
  428. package/3d/TextureUtils.d.ts +0 -24
  429. package/3d/ThreeRenderable.d.ts +0 -40
  430. package/3d/WGPURenderer.d.ts +0 -61
  431. package/3d/animation/ExplodingSpriteEffect.d.ts +0 -71
  432. package/3d/animation/PhysicsExplodingSpriteEffect.d.ts +0 -76
  433. package/3d/animation/SpriteAnimator.d.ts +0 -124
  434. package/3d/animation/SpriteParticleGenerator.d.ts +0 -62
  435. package/3d/canvas.d.ts +0 -44
  436. package/3d/index.d.ts +0 -12
  437. package/3d/physics/PlanckPhysicsAdapter.d.ts +0 -19
  438. package/3d/physics/RapierPhysicsAdapter.d.ts +0 -19
  439. package/3d/physics/physics-interface.d.ts +0 -27
  440. package/3d.d.ts +0 -2
  441. package/3d.js +0 -34042
  442. package/3d.js.map +0 -155
  443. package/LICENSE +0 -21
  444. package/NativeSpanFeed.d.ts +0 -41
  445. package/Renderable.d.ts +0 -334
  446. package/animation/Timeline.d.ts +0 -126
  447. package/ansi.d.ts +0 -13
  448. package/buffer.d.ts +0 -107
  449. package/console.d.ts +0 -143
  450. package/edit-buffer.d.ts +0 -98
  451. package/editor-view.d.ts +0 -73
  452. package/index-e4hzc2j2.js +0 -113
  453. package/index-e4hzc2j2.js.map +0 -10
  454. package/index-nkrr8a4c.js +0 -18415
  455. package/index-nkrr8a4c.js.map +0 -64
  456. package/index-nyw5p3ep.js +0 -12619
  457. package/index-nyw5p3ep.js.map +0 -43
  458. package/index.d.ts +0 -21
  459. package/index.js +0 -430
  460. package/index.js.map +0 -9
  461. package/lib/KeyHandler.d.ts +0 -61
  462. package/lib/RGBA.d.ts +0 -25
  463. package/lib/ascii.font.d.ts +0 -508
  464. package/lib/border.d.ts +0 -49
  465. package/lib/bunfs.d.ts +0 -7
  466. package/lib/clipboard.d.ts +0 -17
  467. package/lib/clock.d.ts +0 -15
  468. package/lib/data-paths.d.ts +0 -26
  469. package/lib/debounce.d.ts +0 -42
  470. package/lib/detect-links.d.ts +0 -6
  471. package/lib/env.d.ts +0 -42
  472. package/lib/extmarks-history.d.ts +0 -17
  473. package/lib/extmarks.d.ts +0 -89
  474. package/lib/hast-styled-text.d.ts +0 -17
  475. package/lib/index.d.ts +0 -21
  476. package/lib/keymapping.d.ts +0 -25
  477. package/lib/objects-in-viewport.d.ts +0 -24
  478. package/lib/output.capture.d.ts +0 -24
  479. package/lib/parse.keypress-kitty.d.ts +0 -2
  480. package/lib/parse.keypress.d.ts +0 -26
  481. package/lib/parse.mouse.d.ts +0 -30
  482. package/lib/paste.d.ts +0 -7
  483. package/lib/queue.d.ts +0 -15
  484. package/lib/renderable.validations.d.ts +0 -12
  485. package/lib/scroll-acceleration.d.ts +0 -43
  486. package/lib/selection.d.ts +0 -63
  487. package/lib/singleton.d.ts +0 -7
  488. package/lib/stdin-parser.d.ts +0 -76
  489. package/lib/styled-text.d.ts +0 -63
  490. package/lib/terminal-capability-detection.d.ts +0 -30
  491. package/lib/terminal-palette.d.ts +0 -50
  492. package/lib/tree-sitter/assets/update.d.ts +0 -11
  493. package/lib/tree-sitter/client.d.ts +0 -47
  494. package/lib/tree-sitter/default-parsers.d.ts +0 -2
  495. package/lib/tree-sitter/download-utils.d.ts +0 -21
  496. package/lib/tree-sitter/index.d.ts +0 -8
  497. package/lib/tree-sitter/parser.worker.d.ts +0 -1
  498. package/lib/tree-sitter/parsers-config.d.ts +0 -38
  499. package/lib/tree-sitter/resolve-ft.d.ts +0 -2
  500. package/lib/tree-sitter/types.d.ts +0 -81
  501. package/lib/tree-sitter-styled-text.d.ts +0 -14
  502. package/lib/validate-dir-name.d.ts +0 -1
  503. package/lib/yoga.options.d.ts +0 -32
  504. package/parser.worker.js +0 -869
  505. package/parser.worker.js.map +0 -12
  506. package/plugins/core-slot.d.ts +0 -72
  507. package/plugins/registry.d.ts +0 -38
  508. package/plugins/types.d.ts +0 -34
  509. package/post/filters.d.ts +0 -105
  510. package/renderables/ASCIIFont.d.ts +0 -52
  511. package/renderables/Box.d.ts +0 -72
  512. package/renderables/Code.d.ts +0 -78
  513. package/renderables/Diff.d.ts +0 -142
  514. package/renderables/EditBufferRenderable.d.ts +0 -162
  515. package/renderables/FrameBuffer.d.ts +0 -16
  516. package/renderables/Input.d.ts +0 -67
  517. package/renderables/LineNumberRenderable.d.ts +0 -74
  518. package/renderables/Markdown.d.ts +0 -173
  519. package/renderables/ScrollBar.d.ts +0 -77
  520. package/renderables/ScrollBox.d.ts +0 -124
  521. package/renderables/Select.d.ts +0 -115
  522. package/renderables/Slider.d.ts +0 -44
  523. package/renderables/TabSelect.d.ts +0 -96
  524. package/renderables/Text.d.ts +0 -36
  525. package/renderables/TextBufferRenderable.d.ts +0 -105
  526. package/renderables/TextNode.d.ts +0 -91
  527. package/renderables/TextTable.d.ts +0 -140
  528. package/renderables/Textarea.d.ts +0 -114
  529. package/renderables/TimeToFirstDraw.d.ts +0 -24
  530. package/renderables/__tests__/renderable-test-utils.d.ts +0 -12
  531. package/renderables/composition/VRenderable.d.ts +0 -16
  532. package/renderables/composition/constructs.d.ts +0 -35
  533. package/renderables/composition/vnode.d.ts +0 -46
  534. package/renderables/index.d.ts +0 -22
  535. package/renderables/markdown-parser.d.ts +0 -10
  536. package/renderer.d.ts +0 -388
  537. package/runtime-plugin-support.d.ts +0 -3
  538. package/runtime-plugin-support.js +0 -29
  539. package/runtime-plugin-support.js.map +0 -10
  540. package/runtime-plugin.d.ts +0 -11
  541. package/runtime-plugin.js +0 -16
  542. package/runtime-plugin.js.map +0 -9
  543. package/syntax-style.d.ts +0 -54
  544. package/testing/manual-clock.d.ts +0 -16
  545. package/testing/mock-keys.d.ts +0 -81
  546. package/testing/mock-mouse.d.ts +0 -38
  547. package/testing/mock-tree-sitter-client.d.ts +0 -23
  548. package/testing/spy.d.ts +0 -7
  549. package/testing/test-recorder.d.ts +0 -61
  550. package/testing/test-renderer.d.ts +0 -23
  551. package/testing.d.ts +0 -6
  552. package/testing.js +0 -675
  553. package/testing.js.map +0 -15
  554. package/text-buffer-view.d.ts +0 -42
  555. package/text-buffer.d.ts +0 -67
  556. package/types.d.ts +0 -131
  557. package/utils.d.ts +0 -14
  558. package/zig-structs.d.ts +0 -155
  559. package/zig.d.ts +0 -351
  560. /package/{assets → src/lib/tree-sitter/assets}/javascript/highlights.scm +0 -0
  561. /package/{assets → src/lib/tree-sitter/assets}/javascript/tree-sitter-javascript.wasm +0 -0
  562. /package/{assets → src/lib/tree-sitter/assets}/markdown/highlights.scm +0 -0
  563. /package/{assets → src/lib/tree-sitter/assets}/markdown/injections.scm +0 -0
  564. /package/{assets → src/lib/tree-sitter/assets}/markdown/tree-sitter-markdown.wasm +0 -0
  565. /package/{assets → src/lib/tree-sitter/assets}/markdown_inline/highlights.scm +0 -0
  566. /package/{assets → src/lib/tree-sitter/assets}/markdown_inline/tree-sitter-markdown_inline.wasm +0 -0
  567. /package/{assets → src/lib/tree-sitter/assets}/typescript/highlights.scm +0 -0
  568. /package/{assets → src/lib/tree-sitter/assets}/typescript/tree-sitter-typescript.wasm +0 -0
  569. /package/{assets → src/lib/tree-sitter/assets}/zig/highlights.scm +0 -0
  570. /package/{assets → src/lib/tree-sitter/assets}/zig/tree-sitter-zig.wasm +0 -0
@@ -0,0 +1,764 @@
1
+ import { Renderable, type RenderableOptions } from "../Renderable.js"
2
+ import { convertGlobalToLocalSelection, Selection, type LocalSelectionBounds } from "../lib/selection.js"
3
+ import { EditBuffer, type LogicalCursor } from "../edit-buffer.js"
4
+ import { EditorView, type VisualCursor } from "../editor-view.js"
5
+ import { RGBA, parseColor } from "../lib/RGBA.js"
6
+ import type { RenderContext, Highlight, CursorStyleOptions, LineInfoProvider, LineInfo } from "../types.js"
7
+ import type { OptimizedBuffer } from "../buffer.js"
8
+ import { MeasureMode } from "yoga-layout"
9
+ import type { SyntaxStyle } from "../syntax-style.js"
10
+
11
+ export interface CursorChangeEvent {
12
+ line: number
13
+ visualColumn: number
14
+ }
15
+
16
+ export interface ContentChangeEvent {
17
+ // No payload - use getText() to retrieve content if needed
18
+ }
19
+
20
+ export interface EditBufferOptions extends RenderableOptions<EditBufferRenderable> {
21
+ textColor?: string | RGBA
22
+ backgroundColor?: string | RGBA
23
+ selectionBg?: string | RGBA
24
+ selectionFg?: string | RGBA
25
+ selectable?: boolean
26
+ attributes?: number
27
+ wrapMode?: "none" | "char" | "word"
28
+ scrollMargin?: number
29
+ scrollSpeed?: number
30
+ showCursor?: boolean
31
+ cursorColor?: string | RGBA
32
+ cursorStyle?: CursorStyleOptions
33
+ syntaxStyle?: SyntaxStyle
34
+ tabIndicator?: string | number
35
+ tabIndicatorColor?: string | RGBA
36
+ onCursorChange?: (event: CursorChangeEvent) => void
37
+ onContentChange?: (event: ContentChangeEvent) => void
38
+ }
39
+
40
+ export abstract class EditBufferRenderable extends Renderable implements LineInfoProvider {
41
+ protected _focusable: boolean = true
42
+ public selectable: boolean = true
43
+
44
+ protected _textColor: RGBA
45
+ protected _backgroundColor: RGBA
46
+ protected _defaultAttributes: number
47
+ protected _selectionBg: RGBA | undefined
48
+ protected _selectionFg: RGBA | undefined
49
+ protected _wrapMode: "none" | "char" | "word" = "word"
50
+ protected _scrollMargin: number = 0.2
51
+ protected _showCursor: boolean = true
52
+ protected _cursorColor: RGBA
53
+ protected _cursorStyle: CursorStyleOptions
54
+ protected lastLocalSelection: LocalSelectionBounds | null = null
55
+ protected _tabIndicator?: string | number
56
+ protected _tabIndicatorColor?: RGBA
57
+
58
+ private _cursorChangeListener: ((event: CursorChangeEvent) => void) | undefined = undefined
59
+ private _contentChangeListener: ((event: ContentChangeEvent) => void) | undefined = undefined
60
+
61
+ private _autoScrollVelocity: number = 0
62
+ private _autoScrollAccumulator: number = 0
63
+ private _scrollSpeed: number = 16
64
+ private _keyboardSelectionActive: boolean = false
65
+
66
+ public readonly editBuffer: EditBuffer
67
+ public readonly editorView: EditorView
68
+
69
+ protected _defaultOptions = {
70
+ textColor: RGBA.fromValues(1, 1, 1, 1),
71
+ backgroundColor: "transparent",
72
+ selectionBg: undefined,
73
+ selectionFg: undefined,
74
+ selectable: true,
75
+ attributes: 0,
76
+ wrapMode: "word" as "none" | "char" | "word",
77
+ scrollMargin: 0.2,
78
+ scrollSpeed: 16,
79
+ showCursor: true,
80
+ cursorColor: RGBA.fromValues(1, 1, 1, 1),
81
+ cursorStyle: {
82
+ style: "block",
83
+ blinking: true,
84
+ },
85
+ tabIndicator: undefined,
86
+ tabIndicatorColor: undefined,
87
+ } satisfies Partial<EditBufferOptions>
88
+
89
+ constructor(ctx: RenderContext, options: EditBufferOptions) {
90
+ super(ctx, options)
91
+
92
+ this._textColor = parseColor(options.textColor ?? this._defaultOptions.textColor)
93
+ this._backgroundColor = parseColor(options.backgroundColor ?? this._defaultOptions.backgroundColor)
94
+ this._defaultAttributes = options.attributes ?? this._defaultOptions.attributes
95
+ this._selectionBg = options.selectionBg ? parseColor(options.selectionBg) : this._defaultOptions.selectionBg
96
+ this._selectionFg = options.selectionFg ? parseColor(options.selectionFg) : this._defaultOptions.selectionFg
97
+ this.selectable = options.selectable ?? this._defaultOptions.selectable
98
+ this._wrapMode = options.wrapMode ?? this._defaultOptions.wrapMode
99
+ this._scrollMargin = options.scrollMargin ?? this._defaultOptions.scrollMargin
100
+ this._scrollSpeed = options.scrollSpeed ?? this._defaultOptions.scrollSpeed
101
+ this._showCursor = options.showCursor ?? this._defaultOptions.showCursor
102
+ this._cursorColor = parseColor(options.cursorColor ?? this._defaultOptions.cursorColor)
103
+ this._cursorStyle = options.cursorStyle ?? this._defaultOptions.cursorStyle
104
+ this._tabIndicator = options.tabIndicator ?? this._defaultOptions.tabIndicator
105
+ this._tabIndicatorColor = options.tabIndicatorColor
106
+ ? parseColor(options.tabIndicatorColor)
107
+ : this._defaultOptions.tabIndicatorColor
108
+
109
+ this.editBuffer = EditBuffer.create(this._ctx.widthMethod)
110
+ this.editorView = EditorView.create(this.editBuffer, this.width || 80, this.height || 24)
111
+
112
+ this.editorView.setWrapMode(this._wrapMode)
113
+ this.editorView.setScrollMargin(this._scrollMargin)
114
+
115
+ this.editBuffer.setDefaultFg(this._textColor)
116
+ this.editBuffer.setDefaultBg(this._backgroundColor)
117
+ this.editBuffer.setDefaultAttributes(this._defaultAttributes)
118
+
119
+ if (options.syntaxStyle) {
120
+ this.editBuffer.setSyntaxStyle(options.syntaxStyle)
121
+ }
122
+
123
+ if (this._tabIndicator !== undefined) {
124
+ this.editorView.setTabIndicator(this._tabIndicator)
125
+ }
126
+ if (this._tabIndicatorColor !== undefined) {
127
+ this.editorView.setTabIndicatorColor(this._tabIndicatorColor)
128
+ }
129
+
130
+ this.setupMeasureFunc()
131
+ this.setupEventListeners(options)
132
+ }
133
+
134
+ public get lineInfo(): LineInfo {
135
+ return this.editorView.getLogicalLineInfo()
136
+ }
137
+
138
+ private setupEventListeners(options: EditBufferOptions): void {
139
+ this._cursorChangeListener = options.onCursorChange
140
+ this._contentChangeListener = options.onContentChange
141
+
142
+ this.editBuffer.on("cursor-changed", () => {
143
+ if (this._cursorChangeListener) {
144
+ const cursor = this.editBuffer.getCursorPosition()
145
+ this._cursorChangeListener({
146
+ line: cursor.row,
147
+ visualColumn: cursor.col,
148
+ })
149
+ }
150
+ })
151
+
152
+ this.editBuffer.on("content-changed", () => {
153
+ this.yogaNode.markDirty()
154
+ this.requestRender()
155
+ this.emit("line-info-change")
156
+ if (this._contentChangeListener) {
157
+ this._contentChangeListener({})
158
+ }
159
+ })
160
+ }
161
+
162
+ public get lineCount(): number {
163
+ return this.editBuffer.getLineCount()
164
+ }
165
+
166
+ public get virtualLineCount(): number {
167
+ return this.editorView.getVirtualLineCount()
168
+ }
169
+
170
+ public get scrollY(): number {
171
+ return this.editorView.getViewport().offsetY
172
+ }
173
+
174
+ get plainText(): string {
175
+ return this.editBuffer.getText()
176
+ }
177
+
178
+ get logicalCursor(): LogicalCursor {
179
+ return this.editBuffer.getCursorPosition()
180
+ }
181
+
182
+ get visualCursor(): VisualCursor {
183
+ return this.editorView.getVisualCursor()
184
+ }
185
+
186
+ get cursorOffset(): number {
187
+ return this.editorView.getVisualCursor().offset
188
+ }
189
+
190
+ set cursorOffset(offset: number) {
191
+ this.editorView.setCursorByOffset(offset)
192
+ this.requestRender()
193
+ }
194
+
195
+ get textColor(): RGBA {
196
+ return this._textColor
197
+ }
198
+
199
+ set textColor(value: RGBA | string | undefined) {
200
+ const newColor = parseColor(value ?? this._defaultOptions.textColor)
201
+ if (this._textColor !== newColor) {
202
+ this._textColor = newColor
203
+ this.editBuffer.setDefaultFg(newColor)
204
+ this.requestRender()
205
+ }
206
+ }
207
+
208
+ get selectionBg(): RGBA | undefined {
209
+ return this._selectionBg
210
+ }
211
+
212
+ set selectionBg(value: RGBA | string | undefined) {
213
+ const newColor = value ? parseColor(value) : this._defaultOptions.selectionBg
214
+ if (this._selectionBg !== newColor) {
215
+ this._selectionBg = newColor
216
+ if (this.lastLocalSelection) {
217
+ this.updateLocalSelection(this.lastLocalSelection)
218
+ }
219
+ this.requestRender()
220
+ }
221
+ }
222
+
223
+ get selectionFg(): RGBA | undefined {
224
+ return this._selectionFg
225
+ }
226
+
227
+ set selectionFg(value: RGBA | string | undefined) {
228
+ const newColor = value ? parseColor(value) : this._defaultOptions.selectionFg
229
+ if (this._selectionFg !== newColor) {
230
+ this._selectionFg = newColor
231
+ if (this.lastLocalSelection) {
232
+ this.updateLocalSelection(this.lastLocalSelection)
233
+ }
234
+ this.requestRender()
235
+ }
236
+ }
237
+
238
+ get backgroundColor(): RGBA {
239
+ return this._backgroundColor
240
+ }
241
+
242
+ set backgroundColor(value: RGBA | string | undefined) {
243
+ const newColor = parseColor(value ?? this._defaultOptions.backgroundColor)
244
+ if (this._backgroundColor !== newColor) {
245
+ this._backgroundColor = newColor
246
+ this.editBuffer.setDefaultBg(newColor)
247
+ this.requestRender()
248
+ }
249
+ }
250
+
251
+ get attributes(): number {
252
+ return this._defaultAttributes
253
+ }
254
+
255
+ set attributes(value: number) {
256
+ if (this._defaultAttributes !== value) {
257
+ this._defaultAttributes = value
258
+ this.editBuffer.setDefaultAttributes(value)
259
+ this.requestRender()
260
+ }
261
+ }
262
+
263
+ get wrapMode(): "none" | "char" | "word" {
264
+ return this._wrapMode
265
+ }
266
+
267
+ set wrapMode(value: "none" | "char" | "word") {
268
+ if (this._wrapMode !== value) {
269
+ this._wrapMode = value
270
+ this.editorView.setWrapMode(value)
271
+ this.yogaNode.markDirty()
272
+ this.requestRender()
273
+ }
274
+ }
275
+
276
+ get showCursor(): boolean {
277
+ return this._showCursor
278
+ }
279
+
280
+ set showCursor(value: boolean) {
281
+ if (this._showCursor !== value) {
282
+ this._showCursor = value
283
+ if (!value && this._focused) {
284
+ this._ctx.setCursorPosition(0, 0, false)
285
+ }
286
+ this.requestRender()
287
+ }
288
+ }
289
+
290
+ get cursorColor(): RGBA {
291
+ return this._cursorColor
292
+ }
293
+
294
+ set cursorColor(value: RGBA | string) {
295
+ const newColor = parseColor(value)
296
+ if (this._cursorColor !== newColor) {
297
+ this._cursorColor = newColor
298
+ if (this._focused) {
299
+ this.requestRender()
300
+ }
301
+ }
302
+ }
303
+
304
+ get cursorStyle(): CursorStyleOptions {
305
+ return this._cursorStyle
306
+ }
307
+
308
+ set cursorStyle(style: CursorStyleOptions) {
309
+ const newStyle = style
310
+ if (this.cursorStyle.style !== newStyle.style || this.cursorStyle.blinking !== newStyle.blinking) {
311
+ this._cursorStyle = newStyle
312
+ if (this._focused) {
313
+ this.requestRender()
314
+ }
315
+ }
316
+ }
317
+
318
+ get tabIndicator(): string | number | undefined {
319
+ return this._tabIndicator
320
+ }
321
+
322
+ set tabIndicator(value: string | number | undefined) {
323
+ if (this._tabIndicator !== value) {
324
+ this._tabIndicator = value
325
+ if (value !== undefined) {
326
+ this.editorView.setTabIndicator(value)
327
+ }
328
+ this.requestRender()
329
+ }
330
+ }
331
+
332
+ get tabIndicatorColor(): RGBA | undefined {
333
+ return this._tabIndicatorColor
334
+ }
335
+
336
+ set tabIndicatorColor(value: RGBA | string | undefined) {
337
+ const newColor = value ? parseColor(value) : undefined
338
+ if (this._tabIndicatorColor !== newColor) {
339
+ this._tabIndicatorColor = newColor
340
+ if (newColor !== undefined) {
341
+ this.editorView.setTabIndicatorColor(newColor)
342
+ }
343
+ this.requestRender()
344
+ }
345
+ }
346
+
347
+ get scrollSpeed(): number {
348
+ return this._scrollSpeed
349
+ }
350
+
351
+ set scrollSpeed(value: number) {
352
+ this._scrollSpeed = Math.max(0, value)
353
+ }
354
+
355
+ protected override onMouseEvent(event: any): void {
356
+ if (event.type === "scroll") {
357
+ this.handleScroll(event)
358
+ }
359
+ }
360
+
361
+ protected handleScroll(event: any): void {
362
+ if (!event.scroll) return
363
+
364
+ const { direction, delta } = event.scroll
365
+ const viewport = this.editorView.getViewport()
366
+
367
+ if (direction === "up") {
368
+ const newOffsetY = Math.max(0, viewport.offsetY - delta)
369
+ this.editorView.setViewport(viewport.offsetX, newOffsetY, viewport.width, viewport.height, true)
370
+ this.requestRender()
371
+ } else if (direction === "down") {
372
+ const totalVirtualLines = this.editorView.getTotalVirtualLineCount()
373
+ const maxOffsetY = Math.max(0, totalVirtualLines - viewport.height)
374
+ const newOffsetY = Math.min(viewport.offsetY + delta, maxOffsetY)
375
+ this.editorView.setViewport(viewport.offsetX, newOffsetY, viewport.width, viewport.height, true)
376
+ this.requestRender()
377
+ }
378
+
379
+ if (this._wrapMode === "none") {
380
+ if (direction === "left") {
381
+ const newOffsetX = Math.max(0, viewport.offsetX - delta)
382
+ this.editorView.setViewport(newOffsetX, viewport.offsetY, viewport.width, viewport.height, true)
383
+ this.requestRender()
384
+ } else if (direction === "right") {
385
+ const newOffsetX = viewport.offsetX + delta
386
+ this.editorView.setViewport(newOffsetX, viewport.offsetY, viewport.width, viewport.height, true)
387
+ this.requestRender()
388
+ }
389
+ }
390
+ }
391
+
392
+ protected onResize(width: number, height: number): void {
393
+ this.editorView.setViewportSize(width, height)
394
+ }
395
+
396
+ protected refreshLocalSelection(): boolean {
397
+ if (this.lastLocalSelection) {
398
+ return this.updateLocalSelection(this.lastLocalSelection)
399
+ }
400
+ return false
401
+ }
402
+
403
+ private updateLocalSelection(localSelection: LocalSelectionBounds | null): boolean {
404
+ if (!localSelection?.isActive) {
405
+ this.editorView.resetLocalSelection()
406
+ return true
407
+ }
408
+ return this.editorView.setLocalSelection(
409
+ localSelection.anchorX,
410
+ localSelection.anchorY,
411
+ localSelection.focusX,
412
+ localSelection.focusY,
413
+ this._selectionBg,
414
+ this._selectionFg,
415
+ false,
416
+ )
417
+ }
418
+
419
+ shouldStartSelection(x: number, y: number): boolean {
420
+ if (!this.selectable) return false
421
+
422
+ const localX = x - this.x
423
+ const localY = y - this.y
424
+
425
+ return localX >= 0 && localX < this.width && localY >= 0 && localY < this.height
426
+ }
427
+
428
+ onSelectionChanged(selection: Selection | null): boolean {
429
+ const localSelection = convertGlobalToLocalSelection(selection, this.x, this.y)
430
+ this.lastLocalSelection = localSelection
431
+
432
+ const updateCursor = true
433
+ const followCursor = this._keyboardSelectionActive
434
+
435
+ let changed: boolean
436
+ if (!localSelection?.isActive) {
437
+ this._keyboardSelectionActive = false
438
+ this.editorView.resetLocalSelection()
439
+ changed = true
440
+ } else if (selection?.isStart) {
441
+ changed = this.editorView.setLocalSelection(
442
+ localSelection.anchorX,
443
+ localSelection.anchorY,
444
+ localSelection.focusX,
445
+ localSelection.focusY,
446
+ this._selectionBg,
447
+ this._selectionFg,
448
+ updateCursor,
449
+ followCursor,
450
+ )
451
+ } else {
452
+ changed = this.editorView.updateLocalSelection(
453
+ localSelection.anchorX,
454
+ localSelection.anchorY,
455
+ localSelection.focusX,
456
+ localSelection.focusY,
457
+ this._selectionBg,
458
+ this._selectionFg,
459
+ updateCursor,
460
+ followCursor,
461
+ )
462
+ }
463
+
464
+ if (changed && localSelection?.isActive && selection?.isDragging) {
465
+ const viewport = this.editorView.getViewport()
466
+ const focusY = localSelection.focusY
467
+ const scrollMargin = Math.max(1, Math.floor(viewport.height * this._scrollMargin))
468
+
469
+ if (focusY < scrollMargin) {
470
+ this._autoScrollVelocity = -this._scrollSpeed
471
+ } else if (focusY >= viewport.height - scrollMargin) {
472
+ this._autoScrollVelocity = this._scrollSpeed
473
+ } else {
474
+ this._autoScrollVelocity = 0
475
+ }
476
+ } else {
477
+ this._keyboardSelectionActive = false
478
+ this._autoScrollVelocity = 0
479
+ this._autoScrollAccumulator = 0
480
+ }
481
+
482
+ if (changed) {
483
+ this.requestRender()
484
+ }
485
+
486
+ return this.hasSelection()
487
+ }
488
+
489
+ protected override onUpdate(deltaTime: number): void {
490
+ super.onUpdate(deltaTime)
491
+
492
+ if (this._autoScrollVelocity !== 0 && this.hasSelection()) {
493
+ const deltaSeconds = deltaTime / 1000
494
+ this._autoScrollAccumulator += this._autoScrollVelocity * deltaSeconds
495
+
496
+ const linesToScroll = Math.floor(Math.abs(this._autoScrollAccumulator))
497
+ if (linesToScroll > 0) {
498
+ const direction = this._autoScrollVelocity > 0 ? 1 : -1
499
+ const viewport = this.editorView.getViewport()
500
+ const totalVirtualLines = this.editorView.getTotalVirtualLineCount()
501
+ const maxOffsetY = Math.max(0, totalVirtualLines - viewport.height)
502
+ const newOffsetY = Math.max(0, Math.min(viewport.offsetY + direction * linesToScroll, maxOffsetY))
503
+
504
+ if (newOffsetY !== viewport.offsetY) {
505
+ this.editorView.setViewport(viewport.offsetX, newOffsetY, viewport.width, viewport.height, false)
506
+
507
+ this._ctx.requestSelectionUpdate()
508
+ }
509
+
510
+ this._autoScrollAccumulator -= direction * linesToScroll
511
+ }
512
+ }
513
+ }
514
+
515
+ getSelectedText(): string {
516
+ return this.editorView.getSelectedText()
517
+ }
518
+
519
+ hasSelection(): boolean {
520
+ return this.editorView.hasSelection()
521
+ }
522
+
523
+ getSelection(): { start: number; end: number } | null {
524
+ return this.editorView.getSelection()
525
+ }
526
+
527
+ // Undefined = 0,
528
+ // Exactly = 1,
529
+ // AtMost = 2
530
+ private setupMeasureFunc(): void {
531
+ const measureFunc = (
532
+ width: number,
533
+ widthMode: MeasureMode,
534
+ height: number,
535
+ heightMode: MeasureMode,
536
+ ): { width: number; height: number } => {
537
+ // When widthMode is Undefined, Yoga is asking for the intrinsic/natural width
538
+ // Pass width=0 to measureForDimensions to signal we want max-content (no wrapping)
539
+ // The Zig code treats width=0 with wrap_mode != none as null wrap_width,
540
+ // which triggers no-wrap mode and returns the text's intrinsic width
541
+ let effectiveWidth: number
542
+ if (widthMode === MeasureMode.Undefined || isNaN(width)) {
543
+ effectiveWidth = 0
544
+ } else {
545
+ effectiveWidth = width
546
+ }
547
+
548
+ const effectiveHeight = isNaN(height) ? 1 : height
549
+
550
+ const measureResult = this.editorView.measureForDimensions(
551
+ Math.floor(effectiveWidth),
552
+ Math.floor(effectiveHeight),
553
+ )
554
+
555
+ const measuredWidth = measureResult ? Math.max(1, measureResult.widthColsMax) : 1
556
+ const measuredHeight = measureResult ? Math.max(1, measureResult.lineCount) : 1
557
+
558
+ if (widthMode === MeasureMode.AtMost && this._positionType !== "absolute") {
559
+ return {
560
+ width: Math.min(effectiveWidth, measuredWidth),
561
+ height: Math.min(effectiveHeight, measuredHeight),
562
+ }
563
+ }
564
+
565
+ return {
566
+ width: measuredWidth,
567
+ height: measuredHeight,
568
+ }
569
+ }
570
+
571
+ this.yogaNode.setMeasureFunc(measureFunc)
572
+ }
573
+
574
+ render(buffer: OptimizedBuffer, deltaTime: number): void {
575
+ if (!this.visible) return
576
+ if (this.isDestroyed) return
577
+
578
+ this.markClean()
579
+ this._ctx.addToHitGrid(this.x, this.y, this.width, this.height, this.num)
580
+
581
+ this.renderSelf(buffer)
582
+ this.renderCursor(buffer)
583
+ }
584
+
585
+ protected renderSelf(buffer: OptimizedBuffer): void {
586
+ buffer.drawEditorView(this.editorView, this.x, this.y)
587
+ }
588
+
589
+ protected renderCursor(buffer: OptimizedBuffer): void {
590
+ if (!this._showCursor || !this._focused) return
591
+
592
+ const visualCursor = this.editorView.getVisualCursor()
593
+
594
+ const cursorX = this.x + visualCursor.visualCol + 1 // +1 for 1-based terminal coords
595
+ const cursorY = this.y + visualCursor.visualRow + 1 // +1 for 1-based terminal coords
596
+
597
+ this._ctx.setCursorPosition(cursorX, cursorY, true)
598
+ this._ctx.setCursorStyle({ ...this._cursorStyle, color: this._cursorColor })
599
+ }
600
+
601
+ public focus(): void {
602
+ super.focus()
603
+ this._ctx.setCursorStyle({ ...this._cursorStyle, color: this._cursorColor })
604
+ this.requestRender()
605
+ }
606
+
607
+ public blur(): void {
608
+ super.blur()
609
+ this._ctx.setCursorPosition(0, 0, false)
610
+ this.requestRender()
611
+ }
612
+
613
+ protected onRemove(): void {
614
+ if (this._focused) {
615
+ this._ctx.setCursorPosition(0, 0, false)
616
+ }
617
+ }
618
+
619
+ override destroy(): void {
620
+ if (this.isDestroyed) return
621
+
622
+ if (this._focused) {
623
+ this._ctx.setCursorPosition(0, 0, false)
624
+ // Manually blur to unhook event handlers BEFORE setting destroyed flag
625
+ // This prevents the guard in super.destroy() from skipping blur()
626
+ this.blur()
627
+ }
628
+
629
+ // Destroy dependent resources in correct order BEFORE calling super
630
+ // EditorView depends on EditBuffer, so destroy it first
631
+ this.editorView.destroy()
632
+ this.editBuffer.destroy()
633
+
634
+ // Finally clean up parent resources
635
+ // Note: super.destroy() will try to blur() again, but blur() has guards to prevent double-blur
636
+ super.destroy()
637
+ }
638
+
639
+ public set onCursorChange(handler: ((event: CursorChangeEvent) => void) | undefined) {
640
+ this._cursorChangeListener = handler
641
+ }
642
+
643
+ public get onCursorChange(): ((event: CursorChangeEvent) => void) | undefined {
644
+ return this._cursorChangeListener
645
+ }
646
+
647
+ public set onContentChange(handler: ((event: ContentChangeEvent) => void) | undefined) {
648
+ this._contentChangeListener = handler
649
+ }
650
+
651
+ public get onContentChange(): ((event: ContentChangeEvent) => void) | undefined {
652
+ return this._contentChangeListener
653
+ }
654
+
655
+ get syntaxStyle(): SyntaxStyle | null {
656
+ return this.editBuffer.getSyntaxStyle()
657
+ }
658
+
659
+ set syntaxStyle(style: SyntaxStyle | null) {
660
+ this.editBuffer.setSyntaxStyle(style)
661
+ this.requestRender()
662
+ }
663
+
664
+ public addHighlight(lineIdx: number, highlight: Highlight): void {
665
+ this.editBuffer.addHighlight(lineIdx, highlight)
666
+ this.requestRender()
667
+ }
668
+
669
+ public addHighlightByCharRange(highlight: Highlight): void {
670
+ this.editBuffer.addHighlightByCharRange(highlight)
671
+ this.requestRender()
672
+ }
673
+
674
+ public removeHighlightsByRef(hlRef: number): void {
675
+ this.editBuffer.removeHighlightsByRef(hlRef)
676
+ this.requestRender()
677
+ }
678
+
679
+ public clearLineHighlights(lineIdx: number): void {
680
+ this.editBuffer.clearLineHighlights(lineIdx)
681
+ this.requestRender()
682
+ }
683
+
684
+ public clearAllHighlights(): void {
685
+ this.editBuffer.clearAllHighlights()
686
+ this.requestRender()
687
+ }
688
+
689
+ public getLineHighlights(lineIdx: number): Array<Highlight> {
690
+ return this.editBuffer.getLineHighlights(lineIdx)
691
+ }
692
+
693
+ /**
694
+ * Set text and completely reset the buffer state (clears history, resets add_buffer).
695
+ * Use this for initial text setting or when you want a clean slate.
696
+ */
697
+ public setText(text: string): void {
698
+ this.editBuffer.setText(text)
699
+ this.yogaNode.markDirty()
700
+ this.requestRender()
701
+ }
702
+
703
+ /**
704
+ * Replace text while preserving undo history (creates an undo point).
705
+ * Use this when you want the setText operation to be undoable.
706
+ */
707
+ public replaceText(text: string): void {
708
+ this.editBuffer.replaceText(text)
709
+ this.yogaNode.markDirty()
710
+ this.requestRender()
711
+ }
712
+
713
+ public clear(): void {
714
+ this.editBuffer.clear()
715
+ this.editBuffer.clearAllHighlights()
716
+ this.yogaNode.markDirty()
717
+ this.requestRender()
718
+ }
719
+
720
+ public deleteRange(startLine: number, startCol: number, endLine: number, endCol: number): void {
721
+ this.editBuffer.deleteRange(startLine, startCol, endLine, endCol)
722
+ this.yogaNode.markDirty()
723
+ this.requestRender()
724
+ }
725
+
726
+ public insertText(text: string): void {
727
+ this.editBuffer.insertText(text)
728
+ this.yogaNode.markDirty()
729
+ this.requestRender()
730
+ }
731
+
732
+ public getTextRange(startOffset: number, endOffset: number): string {
733
+ return this.editBuffer.getTextRange(startOffset, endOffset)
734
+ }
735
+
736
+ public getTextRangeByCoords(startRow: number, startCol: number, endRow: number, endCol: number): string {
737
+ return this.editBuffer.getTextRangeByCoords(startRow, startCol, endRow, endCol)
738
+ }
739
+
740
+ protected updateSelectionForMovement(shiftPressed: boolean, isBeforeMovement: boolean): void {
741
+ if (!this.selectable) return
742
+
743
+ if (!shiftPressed) {
744
+ this._keyboardSelectionActive = false
745
+ this._ctx.clearSelection()
746
+ return
747
+ }
748
+
749
+ this._keyboardSelectionActive = true
750
+
751
+ const visualCursor = this.editorView.getVisualCursor()
752
+ const cursorX = this.x + visualCursor.visualCol
753
+ const cursorY = this.y + visualCursor.visualRow
754
+
755
+ if (isBeforeMovement) {
756
+ if (!this._ctx.hasSelection) {
757
+ this._ctx.startSelection(this, cursorX, cursorY)
758
+ }
759
+ return
760
+ }
761
+
762
+ this._ctx.updateSelection(this, cursorX, cursorY, { finishDragging: true })
763
+ }
764
+ }