@xincli/opentui-core 0.4.6

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 (476) hide show
  1. package/README.md +63 -0
  2. package/dev/keypress-debug-renderer.ts +148 -0
  3. package/dev/keypress-debug.ts +43 -0
  4. package/dev/print-env-vars.ts +32 -0
  5. package/dev/test-tmux-graphics-334.sh +68 -0
  6. package/dev/test-tmux-theme-queries.sh +151 -0
  7. package/dev/thai-debug-test.ts +68 -0
  8. package/dev/theme-mode.ts +290 -0
  9. package/docs/development.md +144 -0
  10. package/package.json +102 -0
  11. package/prebuilt/aarch64-android/libopentui.so +0 -0
  12. package/scripts/build-android.ts +226 -0
  13. package/scripts/build-native-termux.sh +525 -0
  14. package/scripts/build.ts +530 -0
  15. package/scripts/dist-test.ts +312 -0
  16. package/scripts/package-prebuilt.ts +110 -0
  17. package/scripts/publish.ts +60 -0
  18. package/scripts/test-node-hook.mjs +16 -0
  19. package/scripts/test-node.ts +241 -0
  20. package/scripts/vendor-deps.sh +73 -0
  21. package/src/NativeSpanFeed.ts +375 -0
  22. package/src/Renderable.ts +1878 -0
  23. package/src/__snapshots__/buffer.test.ts.snap +28 -0
  24. package/src/animation/Timeline.test.ts +2709 -0
  25. package/src/animation/Timeline.ts +598 -0
  26. package/src/ansi.ts +22 -0
  27. package/src/audio.ts +479 -0
  28. package/src/benchmark/attenuation-benchmark.ts +81 -0
  29. package/src/benchmark/audio-playback-benchmark.ts +344 -0
  30. package/src/benchmark/box-draw-benchmark.ts +1042 -0
  31. package/src/benchmark/colormatrix-benchmark.ts +123 -0
  32. package/src/benchmark/gain-benchmark.ts +80 -0
  33. package/src/benchmark/latest-all-bench-run.json +707 -0
  34. package/src/benchmark/latest-async-bench-run.json +336 -0
  35. package/src/benchmark/latest-default-bench-run.json +657 -0
  36. package/src/benchmark/latest-large-bench-run.json +707 -0
  37. package/src/benchmark/latest-quick-bench-run.json +207 -0
  38. package/src/benchmark/layout-benchmark.ts +2547 -0
  39. package/src/benchmark/markdown-benchmark.ts +1796 -0
  40. package/src/benchmark/native-span-feed-async-benchmark.ts +355 -0
  41. package/src/benchmark/native-span-feed-benchmark.md +56 -0
  42. package/src/benchmark/native-span-feed-benchmark.ts +596 -0
  43. package/src/benchmark/native-span-feed-compare.ts +280 -0
  44. package/src/benchmark/render-traversal-benchmark.ts +928 -0
  45. package/src/benchmark/text-buffer-render-benchmark.ts +874 -0
  46. package/src/benchmark/text-table-benchmark.ts +948 -0
  47. package/src/buffer.test.ts +292 -0
  48. package/src/buffer.ts +564 -0
  49. package/src/console.test.ts +629 -0
  50. package/src/console.ts +1253 -0
  51. package/src/edit-buffer.test.ts +1852 -0
  52. package/src/edit-buffer.ts +417 -0
  53. package/src/editor-view.test.ts +1056 -0
  54. package/src/editor-view.ts +290 -0
  55. package/src/index.ts +25 -0
  56. package/src/lib/KeyHandler.integration.test.ts +292 -0
  57. package/src/lib/KeyHandler.stopPropagation.test.ts +289 -0
  58. package/src/lib/KeyHandler.test.ts +662 -0
  59. package/src/lib/KeyHandler.ts +222 -0
  60. package/src/lib/RGBA.test.ts +60 -0
  61. package/src/lib/RGBA.ts +343 -0
  62. package/src/lib/ascii.font.ts +330 -0
  63. package/src/lib/border.test.ts +83 -0
  64. package/src/lib/border.ts +170 -0
  65. package/src/lib/bunfs.test.ts +27 -0
  66. package/src/lib/bunfs.ts +18 -0
  67. package/src/lib/clipboard.test.ts +63 -0
  68. package/src/lib/clipboard.ts +41 -0
  69. package/src/lib/clock.ts +35 -0
  70. package/src/lib/data-paths.test.ts +133 -0
  71. package/src/lib/data-paths.ts +109 -0
  72. package/src/lib/debounce.ts +106 -0
  73. package/src/lib/detect-links.test.ts +98 -0
  74. package/src/lib/detect-links.ts +56 -0
  75. package/src/lib/env.test.ts +228 -0
  76. package/src/lib/env.ts +209 -0
  77. package/src/lib/extmarks-history.ts +51 -0
  78. package/src/lib/extmarks-multiwidth.test.ts +324 -0
  79. package/src/lib/extmarks.test.ts +3547 -0
  80. package/src/lib/extmarks.ts +861 -0
  81. package/src/lib/fonts/block.json +405 -0
  82. package/src/lib/fonts/grid.json +265 -0
  83. package/src/lib/fonts/huge.json +741 -0
  84. package/src/lib/fonts/pallet.json +314 -0
  85. package/src/lib/fonts/shade.json +591 -0
  86. package/src/lib/fonts/slick.json +321 -0
  87. package/src/lib/fonts/tiny.json +69 -0
  88. package/src/lib/hast-styled-text.ts +59 -0
  89. package/src/lib/index.ts +22 -0
  90. package/src/lib/keybinding.internal.test.ts +342 -0
  91. package/src/lib/keybinding.internal.ts +182 -0
  92. package/src/lib/objects-in-viewport.test.ts +789 -0
  93. package/src/lib/objects-in-viewport.ts +153 -0
  94. package/src/lib/output.capture.ts +58 -0
  95. package/src/lib/parse.keypress-kitty.protocol.test.ts +347 -0
  96. package/src/lib/parse.keypress-kitty.test.ts +712 -0
  97. package/src/lib/parse.keypress-kitty.ts +470 -0
  98. package/src/lib/parse.keypress.test.ts +2020 -0
  99. package/src/lib/parse.keypress.ts +480 -0
  100. package/src/lib/parse.mouse.test.ts +552 -0
  101. package/src/lib/parse.mouse.ts +232 -0
  102. package/src/lib/paste.ts +18 -0
  103. package/src/lib/queue.ts +65 -0
  104. package/src/lib/render-geometry.ts +36 -0
  105. package/src/lib/renderable.validations.test.ts +87 -0
  106. package/src/lib/renderable.validations.ts +83 -0
  107. package/src/lib/scroll-acceleration.ts +98 -0
  108. package/src/lib/selection.ts +261 -0
  109. package/src/lib/singleton.ts +34 -0
  110. package/src/lib/stdin-parser.test.ts +2439 -0
  111. package/src/lib/stdin-parser.ts +2007 -0
  112. package/src/lib/styled-text.ts +178 -0
  113. package/src/lib/terminal-capability-detection.test.ts +226 -0
  114. package/src/lib/terminal-capability-detection.ts +98 -0
  115. package/src/lib/terminal-palette.test.ts +954 -0
  116. package/src/lib/terminal-palette.ts +441 -0
  117. package/src/lib/tree-sitter/assets/README.md +119 -0
  118. package/src/lib/tree-sitter/assets/javascript/highlights.scm +205 -0
  119. package/src/lib/tree-sitter/assets/javascript/tree-sitter-javascript.wasm +0 -0
  120. package/src/lib/tree-sitter/assets/markdown/highlights.scm +150 -0
  121. package/src/lib/tree-sitter/assets/markdown/injections.scm +27 -0
  122. package/src/lib/tree-sitter/assets/markdown/tree-sitter-markdown.wasm +0 -0
  123. package/src/lib/tree-sitter/assets/markdown_inline/highlights.scm +115 -0
  124. package/src/lib/tree-sitter/assets/markdown_inline/tree-sitter-markdown_inline.wasm +0 -0
  125. package/src/lib/tree-sitter/assets/typescript/highlights.scm +604 -0
  126. package/src/lib/tree-sitter/assets/typescript/tree-sitter-typescript.wasm +0 -0
  127. package/src/lib/tree-sitter/assets/update.ts +360 -0
  128. package/src/lib/tree-sitter/assets/zig/highlights.scm +284 -0
  129. package/src/lib/tree-sitter/assets/zig/tree-sitter-zig.wasm +0 -0
  130. package/src/lib/tree-sitter/assets.d.ts +9 -0
  131. package/src/lib/tree-sitter/cache.test.ts +291 -0
  132. package/src/lib/tree-sitter/client.test.ts +1434 -0
  133. package/src/lib/tree-sitter/client.ts +847 -0
  134. package/src/lib/tree-sitter/default-parsers.ts +133 -0
  135. package/src/lib/tree-sitter/download-utils.ts +148 -0
  136. package/src/lib/tree-sitter/index.ts +75 -0
  137. package/src/lib/tree-sitter/parser.worker.ts +1098 -0
  138. package/src/lib/tree-sitter/parsers-config.ts +81 -0
  139. package/src/lib/tree-sitter/resolve-ft.test.ts +55 -0
  140. package/src/lib/tree-sitter/resolve-ft.ts +189 -0
  141. package/src/lib/tree-sitter/types.ts +132 -0
  142. package/src/lib/tree-sitter/update-assets.ts +10 -0
  143. package/src/lib/tree-sitter-styled-text.test.ts +1253 -0
  144. package/src/lib/tree-sitter-styled-text.ts +314 -0
  145. package/src/lib/validate-dir-name.ts +55 -0
  146. package/src/lib/yoga.options.test.ts +628 -0
  147. package/src/lib/yoga.options.ts +346 -0
  148. package/src/native-event-worker-repro.test.ts +48 -0
  149. package/src/native-event-worker-repro.worker.ts +9 -0
  150. package/src/native-handle.test.ts +221 -0
  151. package/src/platform/ffi.test.ts +516 -0
  152. package/src/platform/ffi.ts +653 -0
  153. package/src/platform/runtime.test.ts +52 -0
  154. package/src/platform/runtime.ts +121 -0
  155. package/src/platform/test.ts +45 -0
  156. package/src/platform/worker-handler-cleanup.fixture.ts +12 -0
  157. package/src/platform/worker-onmessage-startup.fixture.ts +10 -0
  158. package/src/platform/worker-startup.fixture.ts +9 -0
  159. package/src/platform/worker.node-test.ts +153 -0
  160. package/src/platform/worker.ts +425 -0
  161. package/src/plugins/core-slot.ts +579 -0
  162. package/src/plugins/registry.ts +402 -0
  163. package/src/plugins/types.ts +46 -0
  164. package/src/post/effects.ts +948 -0
  165. package/src/post/filters.ts +512 -0
  166. package/src/post/matrices.ts +288 -0
  167. package/src/renderables/ASCIIFont.ts +219 -0
  168. package/src/renderables/Box.test.ts +474 -0
  169. package/src/renderables/Box.ts +353 -0
  170. package/src/renderables/Code.test.ts +2388 -0
  171. package/src/renderables/Code.ts +555 -0
  172. package/src/renderables/Diff.regression.test.ts +381 -0
  173. package/src/renderables/Diff.test.ts +3212 -0
  174. package/src/renderables/Diff.ts +1278 -0
  175. package/src/renderables/EditBufferRenderable.test.ts +288 -0
  176. package/src/renderables/EditBufferRenderable.ts +1152 -0
  177. package/src/renderables/FrameBuffer.ts +47 -0
  178. package/src/renderables/Input.test.ts +1310 -0
  179. package/src/renderables/Input.ts +273 -0
  180. package/src/renderables/LineNumberRenderable.ts +725 -0
  181. package/src/renderables/Markdown.ts +2144 -0
  182. package/src/renderables/ScrollBar.ts +423 -0
  183. package/src/renderables/ScrollBox.ts +903 -0
  184. package/src/renderables/Select.test.ts +1134 -0
  185. package/src/renderables/Select.ts +535 -0
  186. package/src/renderables/Slider.test.ts +456 -0
  187. package/src/renderables/Slider.ts +342 -0
  188. package/src/renderables/TabSelect.test.ts +238 -0
  189. package/src/renderables/TabSelect.ts +447 -0
  190. package/src/renderables/Text.selection-buffer.test.ts +118 -0
  191. package/src/renderables/Text.test.ts +2662 -0
  192. package/src/renderables/Text.ts +147 -0
  193. package/src/renderables/TextBufferRenderable.ts +504 -0
  194. package/src/renderables/TextNode.test.ts +1137 -0
  195. package/src/renderables/TextNode.ts +379 -0
  196. package/src/renderables/TextTable.test.ts +1411 -0
  197. package/src/renderables/TextTable.ts +1434 -0
  198. package/src/renderables/Textarea.ts +425 -0
  199. package/src/renderables/TimeToFirstDraw.ts +89 -0
  200. package/src/renderables/__snapshots__/Code.test.ts.snap +13 -0
  201. package/src/renderables/__snapshots__/Diff.test.ts.snap +785 -0
  202. package/src/renderables/__snapshots__/Text.test.ts.snap +421 -0
  203. package/src/renderables/__snapshots__/TextTable.test.ts.snap +215 -0
  204. package/src/renderables/__tests__/Code.test.ts +55 -0
  205. package/src/renderables/__tests__/LineNumberRenderable.scrollbox-simple.test.ts +144 -0
  206. package/src/renderables/__tests__/LineNumberRenderable.scrollbox.test.ts +827 -0
  207. package/src/renderables/__tests__/LineNumberRenderable.test.ts +1906 -0
  208. package/src/renderables/__tests__/LineNumberRenderable.wrapping.test.ts +85 -0
  209. package/src/renderables/__tests__/Markdown.code-colors.test.ts +288 -0
  210. package/src/renderables/__tests__/Markdown.test.ts +4175 -0
  211. package/src/renderables/__tests__/MultiRenderable.selection.test.ts +87 -0
  212. package/src/renderables/__tests__/Textarea.buffer.test.ts +683 -0
  213. package/src/renderables/__tests__/Textarea.destroyed-events.test.ts +675 -0
  214. package/src/renderables/__tests__/Textarea.editing.test.ts +2120 -0
  215. package/src/renderables/__tests__/Textarea.error-handling.test.ts +35 -0
  216. package/src/renderables/__tests__/Textarea.events.test.ts +738 -0
  217. package/src/renderables/__tests__/Textarea.highlights.test.ts +590 -0
  218. package/src/renderables/__tests__/Textarea.keybinding.test.ts +3275 -0
  219. package/src/renderables/__tests__/Textarea.paste.test.ts +357 -0
  220. package/src/renderables/__tests__/Textarea.rendering.test.ts +1927 -0
  221. package/src/renderables/__tests__/Textarea.scroll.test.ts +733 -0
  222. package/src/renderables/__tests__/Textarea.selection.test.ts +1589 -0
  223. package/src/renderables/__tests__/Textarea.stress.test.ts +670 -0
  224. package/src/renderables/__tests__/Textarea.undo-redo.test.ts +383 -0
  225. package/src/renderables/__tests__/Textarea.visual-lines.test.ts +310 -0
  226. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.code.test.ts.snap +221 -0
  227. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.scrollbox-simple.test.ts.snap +89 -0
  228. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.scrollbox.test.ts.snap +457 -0
  229. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.test.ts.snap +158 -0
  230. package/src/renderables/__tests__/__snapshots__/Textarea.rendering.test.ts.snap +387 -0
  231. package/src/renderables/__tests__/markdown-parser.test.ts +241 -0
  232. package/src/renderables/__tests__/renderable-test-utils.ts +60 -0
  233. package/src/renderables/composition/README.md +8 -0
  234. package/src/renderables/composition/VRenderable.ts +32 -0
  235. package/src/renderables/composition/constructs.ts +127 -0
  236. package/src/renderables/composition/vnode.ts +277 -0
  237. package/src/renderables/index.ts +23 -0
  238. package/src/renderables/markdown-parser.ts +79 -0
  239. package/src/renderer-theme-mode.ts +199 -0
  240. package/src/renderer.ts +4975 -0
  241. package/src/runtime-plugin-support-configure.ts +63 -0
  242. package/src/runtime-plugin-support.ts +13 -0
  243. package/src/runtime-plugin.ts +626 -0
  244. package/src/specs/terminal-startup.md +64 -0
  245. package/src/syntax-style.test.ts +841 -0
  246. package/src/syntax-style.ts +274 -0
  247. package/src/testing/README.md +219 -0
  248. package/src/testing/bun-test-node.ts +880 -0
  249. package/src/testing/capture-spans.test.ts +216 -0
  250. package/src/testing/integration.test.ts +276 -0
  251. package/src/testing/manual-clock.ts +117 -0
  252. package/src/testing/mock-keys.test.ts +1378 -0
  253. package/src/testing/mock-keys.ts +457 -0
  254. package/src/testing/mock-mouse.test.ts +218 -0
  255. package/src/testing/mock-mouse.ts +247 -0
  256. package/src/testing/mock-tree-sitter-client.ts +81 -0
  257. package/src/testing/spy.ts +13 -0
  258. package/src/testing/terminal-capabilities.ts +47 -0
  259. package/src/testing/test-recorder.test.ts +410 -0
  260. package/src/testing/test-recorder.ts +133 -0
  261. package/src/testing/test-renderer.ts +375 -0
  262. package/src/testing/test-renderer.wait.test.ts +278 -0
  263. package/src/testing/test-streams.ts +31 -0
  264. package/src/testing.ts +9 -0
  265. package/src/tests/__snapshots__/absolute-positioning.snapshot.test.ts.snap +481 -0
  266. package/src/tests/__snapshots__/renderable.snapshot.test.ts.snap +19 -0
  267. package/src/tests/__snapshots__/scrollbox.test.ts.snap +29 -0
  268. package/src/tests/absolute-positioning.snapshot.test.ts +638 -0
  269. package/src/tests/allocator-stats.test.ts +53 -0
  270. package/src/tests/audio.test.ts +303 -0
  271. package/src/tests/destroy-during-render.test.ts +200 -0
  272. package/src/tests/destroy-on-exit.fixture.ts +36 -0
  273. package/src/tests/destroy-on-exit.test.ts +62 -0
  274. package/src/tests/ffi-borrowed-pointer-callsites.test.ts +153 -0
  275. package/src/tests/hover-cursor.test.ts +98 -0
  276. package/src/tests/native-backed-measurement-lifecycle.test.ts +133 -0
  277. package/src/tests/native-backed-measurement-parity.test.ts +322 -0
  278. package/src/tests/native-span-feed-async.test.ts +173 -0
  279. package/src/tests/native-span-feed-close.test.ts +120 -0
  280. package/src/tests/native-span-feed-coverage.test.ts +227 -0
  281. package/src/tests/native-span-feed-edge-cases.test.ts +384 -0
  282. package/src/tests/native-span-feed-use-after-free.test.ts +45 -0
  283. package/src/tests/opacity.test.ts +123 -0
  284. package/src/tests/renderable.snapshot.test.ts +524 -0
  285. package/src/tests/renderable.test.ts +1851 -0
  286. package/src/tests/renderer.clock.test.ts +270 -0
  287. package/src/tests/renderer.console-startup.test.ts +2151 -0
  288. package/src/tests/renderer.control.test.ts +458 -0
  289. package/src/tests/renderer.core-slot-binding.test.ts +962 -0
  290. package/src/tests/renderer.cursor.test.ts +26 -0
  291. package/src/tests/renderer.custom-stdout.test.ts +1112 -0
  292. package/src/tests/renderer.destroy-during-render.test.ts +147 -0
  293. package/src/tests/renderer.focus-restore.test.ts +257 -0
  294. package/src/tests/renderer.focus.test.ts +329 -0
  295. package/src/tests/renderer.idle.test.ts +219 -0
  296. package/src/tests/renderer.input.test.ts +2615 -0
  297. package/src/tests/renderer.kitty-flags.test.ts +195 -0
  298. package/src/tests/renderer.lifecycle.test.ts +34 -0
  299. package/src/tests/renderer.mouse.test.ts +1315 -0
  300. package/src/tests/renderer.notifications.test.ts +27 -0
  301. package/src/tests/renderer.palette.test.ts +1199 -0
  302. package/src/tests/renderer.remote.test.ts +247 -0
  303. package/src/tests/renderer.render-stats.test.ts +146 -0
  304. package/src/tests/renderer.scrollback-surface.test.ts +474 -0
  305. package/src/tests/renderer.selection.test.ts +138 -0
  306. package/src/tests/renderer.slot-registry.test.ts +684 -0
  307. package/src/tests/renderer.tracker.test.ts +202 -0
  308. package/src/tests/renderer.useMouse.test.ts +83 -0
  309. package/src/tests/runtime-plugin-node-modules-cycle.fixture.ts +76 -0
  310. package/src/tests/runtime-plugin-node-modules-import-like-string.fixture.ts +48 -0
  311. package/src/tests/runtime-plugin-node-modules-mjs.fixture.ts +43 -0
  312. package/src/tests/runtime-plugin-node-modules-no-bare-rewrite.fixture.ts +67 -0
  313. package/src/tests/runtime-plugin-node-modules-package-type-cache.fixture.ts +72 -0
  314. package/src/tests/runtime-plugin-node-modules-runtime-specifier.fixture.ts +44 -0
  315. package/src/tests/runtime-plugin-node-modules-scoped-package-bare-rewrite.fixture.ts +85 -0
  316. package/src/tests/runtime-plugin-path-alias.fixture.ts +43 -0
  317. package/src/tests/runtime-plugin-resolve-roots.fixture.ts +65 -0
  318. package/src/tests/runtime-plugin-support-configure.fixture.ts +31 -0
  319. package/src/tests/runtime-plugin-support-late-addition.fixture.ts +17 -0
  320. package/src/tests/runtime-plugin-support.fixture.ts +11 -0
  321. package/src/tests/runtime-plugin-support.test.ts +54 -0
  322. package/src/tests/runtime-plugin-windows-file-url.fixture.ts +30 -0
  323. package/src/tests/runtime-plugin.fixture.ts +40 -0
  324. package/src/tests/runtime-plugin.test.ts +369 -0
  325. package/src/tests/scrollbox-culling-bug.test.ts +114 -0
  326. package/src/tests/scrollbox-hitgrid-resize.test.ts +136 -0
  327. package/src/tests/scrollbox-hitgrid.test.ts +909 -0
  328. package/src/tests/scrollbox.test.ts +1895 -0
  329. package/src/tests/wrap-resize-perf.test.ts +276 -0
  330. package/src/tests/yoga-api-coverage.test.ts +409 -0
  331. package/src/tests/yoga-callback-stress.test.ts +122 -0
  332. package/src/tests/yoga-ffi.test.ts +117 -0
  333. package/src/tests/yoga-setters.test.ts +921 -0
  334. package/src/tests/yoga-upstream/YGAlignBaselineTest.test.ts +124 -0
  335. package/src/tests/yoga-upstream/YGComputedBorderTest.test.ts +27 -0
  336. package/src/tests/yoga-upstream/YGComputedMarginTest.test.ts +27 -0
  337. package/src/tests/yoga-upstream/YGComputedPaddingTest.test.ts +27 -0
  338. package/src/tests/yoga-upstream/YGDirtiedTest.test.ts +157 -0
  339. package/src/tests/yoga-upstream/YGErrataTest.test.ts +40 -0
  340. package/src/tests/yoga-upstream/YGFlexBasisAuto.test.ts +23 -0
  341. package/src/tests/yoga-upstream/YGHasNewLayout.test.ts +81 -0
  342. package/src/tests/yoga-upstream/YGMeasureCacheTest.test.ts +31 -0
  343. package/src/tests/yoga-upstream/YGMeasureTest.test.ts +70 -0
  344. package/src/tests/yoga-upstream/generated/YGAbsolutePositionTest.test.ts +1864 -0
  345. package/src/tests/yoga-upstream/generated/YGAlignContentTest.test.ts +5829 -0
  346. package/src/tests/yoga-upstream/generated/YGAlignItemsTest.test.ts +2444 -0
  347. package/src/tests/yoga-upstream/generated/YGAlignSelfTest.test.ts +293 -0
  348. package/src/tests/yoga-upstream/generated/YGAndroidNewsFeed.test.ts +315 -0
  349. package/src/tests/yoga-upstream/generated/YGAspectRatioTest.test.ts +231 -0
  350. package/src/tests/yoga-upstream/generated/YGAutoTest.test.ts +347 -0
  351. package/src/tests/yoga-upstream/generated/YGBorderTest.test.ts +256 -0
  352. package/src/tests/yoga-upstream/generated/YGBoxSizingTest.test.ts +2747 -0
  353. package/src/tests/yoga-upstream/generated/YGDimensionTest.test.ts +129 -0
  354. package/src/tests/yoga-upstream/generated/YGDisplayContentsTest.test.ts +109 -0
  355. package/src/tests/yoga-upstream/generated/YGDisplayTest.test.ts +1097 -0
  356. package/src/tests/yoga-upstream/generated/YGFlexDirectionTest.test.ts +4562 -0
  357. package/src/tests/yoga-upstream/generated/YGFlexTest.test.ts +677 -0
  358. package/src/tests/yoga-upstream/generated/YGFlexWrapTest.test.ts +2071 -0
  359. package/src/tests/yoga-upstream/generated/YGGapTest.test.ts +3303 -0
  360. package/src/tests/yoga-upstream/generated/YGIntrinsicSizeTest.test.ts +582 -0
  361. package/src/tests/yoga-upstream/generated/YGJustifyContentTest.test.ts +2150 -0
  362. package/src/tests/yoga-upstream/generated/YGMarginTest.test.ts +1963 -0
  363. package/src/tests/yoga-upstream/generated/YGMinMaxDimensionTest.test.ts +1446 -0
  364. package/src/tests/yoga-upstream/generated/YGPaddingTest.test.ts +354 -0
  365. package/src/tests/yoga-upstream/generated/YGPercentageTest.test.ts +1760 -0
  366. package/src/tests/yoga-upstream/generated/YGRoundingTest.test.ts +1161 -0
  367. package/src/tests/yoga-upstream/generated/YGSizeOverflowTest.test.ts +207 -0
  368. package/src/tests/yoga-upstream/generated/YGStaticPositionTest.test.ts +6338 -0
  369. package/src/tests/yoga-upstream/tools/MeasureCounter.ts +54 -0
  370. package/src/tests/yoga-upstream/tools/utils.ts +81 -0
  371. package/src/text-buffer-view.test.ts +722 -0
  372. package/src/text-buffer-view.ts +193 -0
  373. package/src/text-buffer.test.ts +512 -0
  374. package/src/text-buffer.ts +250 -0
  375. package/src/types.ts +199 -0
  376. package/src/utils.ts +88 -0
  377. package/src/yoga.ts +1146 -0
  378. package/src/zig/ansi.zig +502 -0
  379. package/src/zig/audio.zig +1206 -0
  380. package/src/zig/bench/README.md +50 -0
  381. package/src/zig/bench/buffer-color-blending_bench.zig +350 -0
  382. package/src/zig/bench/buffer-draw-box_bench.zig +786 -0
  383. package/src/zig/bench/buffer-draw-text-buffer_bench.zig +894 -0
  384. package/src/zig/bench/edit-buffer_bench.zig +476 -0
  385. package/src/zig/bench/editor-view_bench.zig +169 -0
  386. package/src/zig/bench/native-span-feed_bench.zig +107 -0
  387. package/src/zig/bench/rope-markers_bench.zig +713 -0
  388. package/src/zig/bench/rope_bench.zig +514 -0
  389. package/src/zig/bench/styled-text_bench.zig +476 -0
  390. package/src/zig/bench/text-buffer-coords_bench.zig +362 -0
  391. package/src/zig/bench/text-buffer-view_bench.zig +459 -0
  392. package/src/zig/bench/text-chunk-graphemes_bench.zig +272 -0
  393. package/src/zig/bench/utf8_bench.zig +799 -0
  394. package/src/zig/bench-utils.zig +431 -0
  395. package/src/zig/bench.zig +223 -0
  396. package/src/zig/buffer-methods.zig +215 -0
  397. package/src/zig/buffer.zig +2515 -0
  398. package/src/zig/build.zig +700 -0
  399. package/src/zig/build.zig.zon +19 -0
  400. package/src/zig/edit-buffer.zig +900 -0
  401. package/src/zig/editor-view.zig +812 -0
  402. package/src/zig/event-bus.zig +28 -0
  403. package/src/zig/event-emitter.zig +65 -0
  404. package/src/zig/file-logger.zig +92 -0
  405. package/src/zig/grapheme.zig +838 -0
  406. package/src/zig/handles.zig +267 -0
  407. package/src/zig/lib.zig +2813 -0
  408. package/src/zig/link.zig +349 -0
  409. package/src/zig/logger.zig +43 -0
  410. package/src/zig/mem-registry.zig +126 -0
  411. package/src/zig/miniaudio_shim.c +21 -0
  412. package/src/zig/native-renderable.zig +112 -0
  413. package/src/zig/native-span-feed-bench-lib.zig +7 -0
  414. package/src/zig/native-span-feed.zig +747 -0
  415. package/src/zig/renderer-output.zig +677 -0
  416. package/src/zig/renderer.zig +2106 -0
  417. package/src/zig/rope.zig +1220 -0
  418. package/src/zig/split-scrollback.zig +88 -0
  419. package/src/zig/syntax-style.zig +174 -0
  420. package/src/zig/terminal.zig +1652 -0
  421. package/src/zig/test.zig +82 -0
  422. package/src/zig/tests/README.md +18 -0
  423. package/src/zig/tests/ansi_test.zig +18 -0
  424. package/src/zig/tests/audio_test.zig +439 -0
  425. package/src/zig/tests/buffer-methods_test.zig +1111 -0
  426. package/src/zig/tests/buffer_test.zig +2926 -0
  427. package/src/zig/tests/edit-buffer-history_test.zig +299 -0
  428. package/src/zig/tests/edit-buffer_test.zig +1688 -0
  429. package/src/zig/tests/editor-view_test.zig +3454 -0
  430. package/src/zig/tests/event-emitter_test.zig +249 -0
  431. package/src/zig/tests/grapheme_test.zig +1329 -0
  432. package/src/zig/tests/handles_test.zig +123 -0
  433. package/src/zig/tests/link_test.zig +220 -0
  434. package/src/zig/tests/mem-registry_test.zig +473 -0
  435. package/src/zig/tests/memory_leak_regression_test.zig +234 -0
  436. package/src/zig/tests/native-renderable_test.zig +16 -0
  437. package/src/zig/tests/native-span-feed_test.zig +1266 -0
  438. package/src/zig/tests/renderer_test.zig +2604 -0
  439. package/src/zig/tests/rope-nested_test.zig +712 -0
  440. package/src/zig/tests/rope_fuzz_test.zig +238 -0
  441. package/src/zig/tests/rope_test.zig +2362 -0
  442. package/src/zig/tests/segment-merge.test.zig +148 -0
  443. package/src/zig/tests/split-scrollback_test.zig +70 -0
  444. package/src/zig/tests/syntax-style_test.zig +558 -0
  445. package/src/zig/tests/terminal_test.zig +1489 -0
  446. package/src/zig/tests/test-renderer.zig +126 -0
  447. package/src/zig/tests/text-buffer-drawing_test.zig +3291 -0
  448. package/src/zig/tests/text-buffer-highlights_test.zig +706 -0
  449. package/src/zig/tests/text-buffer-iterators_test.zig +776 -0
  450. package/src/zig/tests/text-buffer-segment_test.zig +320 -0
  451. package/src/zig/tests/text-buffer-selection_test.zig +1056 -0
  452. package/src/zig/tests/text-buffer-selection_viewport_test.zig +358 -0
  453. package/src/zig/tests/text-buffer-view_test.zig +3672 -0
  454. package/src/zig/tests/text-buffer_test.zig +2191 -0
  455. package/src/zig/tests/unicode-width-map.zon +3909 -0
  456. package/src/zig/tests/utf8_no_zwj_test.zig +260 -0
  457. package/src/zig/tests/utf8_test.zig +4060 -0
  458. package/src/zig/tests/utf8_wcwidth_cursor_test.zig +267 -0
  459. package/src/zig/tests/utf8_wcwidth_test.zig +357 -0
  460. package/src/zig/tests/word-wrap-editing_test.zig +498 -0
  461. package/src/zig/tests/wrap-cache-perf_test.zig +113 -0
  462. package/src/zig/tests/yoga_test.zig +65 -0
  463. package/src/zig/text-buffer-iterators.zig +496 -0
  464. package/src/zig/text-buffer-segment.zig +403 -0
  465. package/src/zig/text-buffer-view.zig +1428 -0
  466. package/src/zig/text-buffer.zig +1272 -0
  467. package/src/zig/utf8.zig +1954 -0
  468. package/src/zig/utils.zig +12 -0
  469. package/src/zig/uucode-stub.zig +76 -0
  470. package/src/zig/vendor/miniaudio/miniaudio.h +93468 -0
  471. package/src/zig/yoga.zig +658 -0
  472. package/src/zig-structs.ts +381 -0
  473. package/src/zig.ts +5260 -0
  474. package/tsconfig.build.json +17 -0
  475. package/tsconfig.json +27 -0
  476. package/tsconfig.node-test.json +138 -0
@@ -0,0 +1,476 @@
1
+ const std = @import("std");
2
+ const bench_utils = @import("../bench-utils.zig");
3
+ const edit_buffer = @import("../edit-buffer.zig");
4
+ const gp = @import("../grapheme.zig");
5
+ const link = @import("../link.zig");
6
+
7
+ const EditBuffer = edit_buffer.EditBuffer;
8
+ const BenchResult = bench_utils.BenchResult;
9
+ const BenchStats = bench_utils.BenchStats;
10
+ const MemStat = bench_utils.MemStat;
11
+
12
+ pub const benchName = "EditBuffer Operations";
13
+
14
+ fn benchInsertOperations(
15
+ allocator: std.mem.Allocator,
16
+ pool: *gp.GraphemePool,
17
+ iterations: usize,
18
+ show_mem: bool,
19
+ bench_filter: ?[]const u8,
20
+ ) ![]BenchResult {
21
+ var results: std.ArrayListUnmanaged(BenchResult) = .{};
22
+ errdefer results.deinit(allocator);
23
+ const link_pool = link.initGlobalLinkPool(allocator);
24
+
25
+ // Single-line insert at start
26
+ {
27
+ const name = "EditBuffer insert 1k times at start";
28
+ if (bench_utils.matchesBenchFilter(name, bench_filter)) {
29
+ var stats: BenchStats = .{};
30
+ var final_mem: usize = 0;
31
+
32
+ for (0..iterations) |iter| {
33
+ var eb = try EditBuffer.init(allocator, pool, link_pool, .unicode, null);
34
+ defer eb.deinit();
35
+
36
+ const text = "Hello, world! ";
37
+ var timer = try std.time.Timer.start();
38
+ for (0..1000) |_| {
39
+ try eb.insertText(text);
40
+ try eb.setCursor(0, 0);
41
+ }
42
+ stats.record(timer.read());
43
+
44
+ if (iter == iterations - 1 and show_mem) {
45
+ final_mem = eb.getTextBuffer().getArenaAllocatedBytes();
46
+ }
47
+ }
48
+
49
+ const mem_stats: ?[]const MemStat = if (show_mem) blk: {
50
+ const s = try allocator.alloc(MemStat, 1);
51
+ s[0] = .{ .name = "TB", .bytes = final_mem };
52
+ break :blk s;
53
+ } else null;
54
+
55
+ try results.append(allocator, .{
56
+ .name = name,
57
+ .min_ns = stats.min_ns,
58
+ .avg_ns = stats.avg(),
59
+ .max_ns = stats.max_ns,
60
+ .total_ns = stats.total_ns,
61
+ .iterations = iterations,
62
+ .mem_stats = mem_stats,
63
+ });
64
+ }
65
+ }
66
+
67
+ // Multi-line insert
68
+ {
69
+ const name = "EditBuffer insert 500 multi-line blocks";
70
+ if (bench_utils.matchesBenchFilter(name, bench_filter)) {
71
+ var stats: BenchStats = .{};
72
+ var final_mem: usize = 0;
73
+
74
+ for (0..iterations) |iter| {
75
+ var eb = try EditBuffer.init(allocator, pool, link_pool, .unicode, null);
76
+ defer eb.deinit();
77
+
78
+ const text = "Line 1\nLine 2\nLine 3\n";
79
+ var timer = try std.time.Timer.start();
80
+ for (0..500) |_| {
81
+ try eb.insertText(text);
82
+ }
83
+ stats.record(timer.read());
84
+
85
+ if (iter == iterations - 1 and show_mem) {
86
+ final_mem = eb.getTextBuffer().getArenaAllocatedBytes();
87
+ }
88
+ }
89
+
90
+ const mem_stats: ?[]const MemStat = if (show_mem) blk: {
91
+ const s = try allocator.alloc(MemStat, 1);
92
+ s[0] = .{ .name = "TB", .bytes = final_mem };
93
+ break :blk s;
94
+ } else null;
95
+
96
+ try results.append(allocator, .{
97
+ .name = name,
98
+ .min_ns = stats.min_ns,
99
+ .avg_ns = stats.avg(),
100
+ .max_ns = stats.max_ns,
101
+ .total_ns = stats.total_ns,
102
+ .iterations = iterations,
103
+ .mem_stats = mem_stats,
104
+ });
105
+ }
106
+ }
107
+
108
+ return results.toOwnedSlice(allocator);
109
+ }
110
+
111
+ fn benchDeleteOperations(
112
+ allocator: std.mem.Allocator,
113
+ pool: *gp.GraphemePool,
114
+ iterations: usize,
115
+ show_mem: bool,
116
+ bench_filter: ?[]const u8,
117
+ ) ![]BenchResult {
118
+ var results: std.ArrayListUnmanaged(BenchResult) = .{};
119
+ errdefer results.deinit(allocator);
120
+ const link_pool = link.initGlobalLinkPool(allocator);
121
+
122
+ // Single-line delete with backspace
123
+ {
124
+ const name = "EditBuffer backspace 500 chars";
125
+ if (bench_utils.matchesBenchFilter(name, bench_filter)) {
126
+ var stats: BenchStats = .{};
127
+ var final_mem: usize = 0;
128
+
129
+ for (0..iterations) |iter| {
130
+ var eb = try EditBuffer.init(allocator, pool, link_pool, .unicode, null);
131
+ defer eb.deinit();
132
+
133
+ // Build up text
134
+ const text = "Hello, world! ";
135
+ for (0..1000) |_| {
136
+ try eb.insertText(text);
137
+ }
138
+
139
+ var timer = try std.time.Timer.start();
140
+ for (0..500) |_| {
141
+ try eb.backspace();
142
+ }
143
+ stats.record(timer.read());
144
+
145
+ if (iter == iterations - 1 and show_mem) {
146
+ final_mem = eb.getTextBuffer().getArenaAllocatedBytes();
147
+ }
148
+ }
149
+
150
+ const mem_stats: ?[]const MemStat = if (show_mem) blk: {
151
+ const s = try allocator.alloc(MemStat, 1);
152
+ s[0] = .{ .name = "TB", .bytes = final_mem };
153
+ break :blk s;
154
+ } else null;
155
+
156
+ try results.append(allocator, .{
157
+ .name = name,
158
+ .min_ns = stats.min_ns,
159
+ .avg_ns = stats.avg(),
160
+ .max_ns = stats.max_ns,
161
+ .total_ns = stats.total_ns,
162
+ .iterations = iterations,
163
+ .mem_stats = mem_stats,
164
+ });
165
+ }
166
+ }
167
+
168
+ // Multi-line delete range
169
+ {
170
+ const name = "EditBuffer delete 50-line range";
171
+ if (bench_utils.matchesBenchFilter(name, bench_filter)) {
172
+ var stats: BenchStats = .{};
173
+ var final_mem: usize = 0;
174
+
175
+ for (0..iterations) |iter| {
176
+ var eb = try EditBuffer.init(allocator, pool, link_pool, .unicode, null);
177
+ defer eb.deinit();
178
+
179
+ // Build up text with many lines
180
+ const text = "Line 1\nLine 2\nLine 3\n";
181
+ for (0..100) |_| {
182
+ try eb.insertText(text);
183
+ }
184
+
185
+ var timer = try std.time.Timer.start();
186
+ // Delete across 50 lines
187
+ try eb.deleteRange(.{ .row = 10, .col = 0 }, .{ .row = 60, .col = 0 });
188
+ stats.record(timer.read());
189
+
190
+ if (iter == iterations - 1 and show_mem) {
191
+ final_mem = eb.getTextBuffer().getArenaAllocatedBytes();
192
+ }
193
+ }
194
+
195
+ const mem_stats: ?[]const MemStat = if (show_mem) blk: {
196
+ const s = try allocator.alloc(MemStat, 1);
197
+ s[0] = .{ .name = "TB", .bytes = final_mem };
198
+ break :blk s;
199
+ } else null;
200
+
201
+ try results.append(allocator, .{
202
+ .name = name,
203
+ .min_ns = stats.min_ns,
204
+ .avg_ns = stats.avg(),
205
+ .max_ns = stats.max_ns,
206
+ .total_ns = stats.total_ns,
207
+ .iterations = iterations,
208
+ .mem_stats = mem_stats,
209
+ });
210
+ }
211
+ }
212
+
213
+ return results.toOwnedSlice(allocator);
214
+ }
215
+
216
+ fn benchMixedOperations(
217
+ allocator: std.mem.Allocator,
218
+ pool: *gp.GraphemePool,
219
+ iterations: usize,
220
+ show_mem: bool,
221
+ bench_filter: ?[]const u8,
222
+ ) ![]BenchResult {
223
+ var results: std.ArrayListUnmanaged(BenchResult) = .{};
224
+ errdefer results.deinit(allocator);
225
+ const link_pool = link.initGlobalLinkPool(allocator);
226
+
227
+ // Simulated typing session
228
+ {
229
+ const name = "EditBuffer mixed operations (300 lines)";
230
+ if (bench_utils.matchesBenchFilter(name, bench_filter)) {
231
+ var stats: BenchStats = .{};
232
+ var final_mem: usize = 0;
233
+
234
+ for (0..iterations) |iter| {
235
+ var eb = try EditBuffer.init(allocator, pool, link_pool, .unicode, null);
236
+ defer eb.deinit();
237
+
238
+ var timer = try std.time.Timer.start();
239
+
240
+ // Type some text
241
+ for (0..100) |_| {
242
+ try eb.insertText("function test() {\n");
243
+ try eb.insertText(" return 42;\n");
244
+ try eb.insertText("}\n");
245
+ }
246
+
247
+ // Navigate and edit
248
+ try eb.setCursor(50, 0);
249
+ try eb.insertText("// Comment\n");
250
+
251
+ // Delete a range
252
+ try eb.deleteRange(.{ .row = 100, .col = 0 }, .{ .row = 120, .col = 0 });
253
+
254
+ stats.record(timer.read());
255
+
256
+ if (iter == iterations - 1 and show_mem) {
257
+ final_mem = eb.getTextBuffer().getArenaAllocatedBytes();
258
+ }
259
+ }
260
+
261
+ const mem_stats: ?[]const MemStat = if (show_mem) blk: {
262
+ const s = try allocator.alloc(MemStat, 1);
263
+ s[0] = .{ .name = "TB", .bytes = final_mem };
264
+ break :blk s;
265
+ } else null;
266
+
267
+ try results.append(allocator, .{
268
+ .name = name,
269
+ .min_ns = stats.min_ns,
270
+ .avg_ns = stats.avg(),
271
+ .max_ns = stats.max_ns,
272
+ .total_ns = stats.total_ns,
273
+ .iterations = iterations,
274
+ .mem_stats = mem_stats,
275
+ });
276
+ }
277
+ }
278
+
279
+ return results.toOwnedSlice(allocator);
280
+ }
281
+
282
+ fn benchWordBoundaryOperations(
283
+ allocator: std.mem.Allocator,
284
+ pool: *gp.GraphemePool,
285
+ iterations: usize,
286
+ show_mem: bool,
287
+ bench_filter: ?[]const u8,
288
+ ) ![]BenchResult {
289
+ var results: std.ArrayListUnmanaged(BenchResult) = .{};
290
+ errdefer results.deinit(allocator);
291
+ const link_pool = link.initGlobalLinkPool(allocator);
292
+
293
+ // Next word boundary navigation
294
+ {
295
+ const name = "EditBuffer getNextWordBoundary 1k times";
296
+ if (bench_utils.matchesBenchFilter(name, bench_filter)) {
297
+ var stats: BenchStats = .{};
298
+ var final_mem: usize = 0;
299
+
300
+ for (0..iterations) |iter| {
301
+ var eb = try EditBuffer.init(allocator, pool, link_pool, .unicode, null);
302
+ defer eb.deinit();
303
+
304
+ // Build text with many words
305
+ const text = "The quick brown fox jumps over the lazy dog. ";
306
+ for (0..100) |_| {
307
+ try eb.insertText(text);
308
+ }
309
+
310
+ try eb.setCursor(0, 0);
311
+
312
+ var timer = try std.time.Timer.start();
313
+ // Navigate through 1000 word boundaries
314
+ for (0..1000) |_| {
315
+ const cursor = eb.getNextWordBoundary();
316
+ try eb.setCursor(cursor.row, cursor.col);
317
+ }
318
+ stats.record(timer.read());
319
+
320
+ if (iter == iterations - 1 and show_mem) {
321
+ final_mem = eb.getTextBuffer().getArenaAllocatedBytes();
322
+ }
323
+ }
324
+
325
+ const mem_stats: ?[]const MemStat = if (show_mem) blk: {
326
+ const s = try allocator.alloc(MemStat, 1);
327
+ s[0] = .{ .name = "TB", .bytes = final_mem };
328
+ break :blk s;
329
+ } else null;
330
+
331
+ try results.append(allocator, .{
332
+ .name = name,
333
+ .min_ns = stats.min_ns,
334
+ .avg_ns = stats.avg(),
335
+ .max_ns = stats.max_ns,
336
+ .total_ns = stats.total_ns,
337
+ .iterations = iterations,
338
+ .mem_stats = mem_stats,
339
+ });
340
+ }
341
+ }
342
+
343
+ // Previous word boundary navigation
344
+ {
345
+ const name = "EditBuffer getPrevWordBoundary 1k times";
346
+ if (bench_utils.matchesBenchFilter(name, bench_filter)) {
347
+ var stats: BenchStats = .{};
348
+ var final_mem: usize = 0;
349
+
350
+ for (0..iterations) |iter| {
351
+ var eb = try EditBuffer.init(allocator, pool, link_pool, .unicode, null);
352
+ defer eb.deinit();
353
+
354
+ // Build text with many words
355
+ const text = "The quick brown fox jumps over the lazy dog. ";
356
+ for (0..100) |_| {
357
+ try eb.insertText(text);
358
+ }
359
+
360
+ // Start at end
361
+ const line_count = eb.getTextBuffer().lineCount();
362
+ const last_line = if (line_count > 0) line_count - 1 else 0;
363
+ try eb.setCursor(last_line, 4500);
364
+
365
+ var timer = try std.time.Timer.start();
366
+ // Navigate backward through 1000 word boundaries
367
+ for (0..1000) |_| {
368
+ const cursor = eb.getPrevWordBoundary();
369
+ try eb.setCursor(cursor.row, cursor.col);
370
+ }
371
+ stats.record(timer.read());
372
+
373
+ if (iter == iterations - 1 and show_mem) {
374
+ final_mem = eb.getTextBuffer().getArenaAllocatedBytes();
375
+ }
376
+ }
377
+
378
+ const mem_stats: ?[]const MemStat = if (show_mem) blk: {
379
+ const s = try allocator.alloc(MemStat, 1);
380
+ s[0] = .{ .name = "TB", .bytes = final_mem };
381
+ break :blk s;
382
+ } else null;
383
+
384
+ try results.append(allocator, .{
385
+ .name = name,
386
+ .min_ns = stats.min_ns,
387
+ .avg_ns = stats.avg(),
388
+ .max_ns = stats.max_ns,
389
+ .total_ns = stats.total_ns,
390
+ .iterations = iterations,
391
+ .mem_stats = mem_stats,
392
+ });
393
+ }
394
+ }
395
+
396
+ // Word boundary with multi-line text
397
+ {
398
+ const name = "EditBuffer word boundary multi-line 500 times";
399
+ if (bench_utils.matchesBenchFilter(name, bench_filter)) {
400
+ var stats: BenchStats = .{};
401
+ var final_mem: usize = 0;
402
+
403
+ for (0..iterations) |iter| {
404
+ var eb = try EditBuffer.init(allocator, pool, link_pool, .unicode, null);
405
+ defer eb.deinit();
406
+
407
+ // Build multi-line text with words
408
+ const text = "Hello world test\nAnother line here\nThird line content\n";
409
+ for (0..100) |_| {
410
+ try eb.insertText(text);
411
+ }
412
+
413
+ try eb.setCursor(0, 0);
414
+
415
+ var timer = try std.time.Timer.start();
416
+ // Navigate through 500 word boundaries across lines
417
+ for (0..500) |_| {
418
+ const cursor = eb.getNextWordBoundary();
419
+ try eb.setCursor(cursor.row, cursor.col);
420
+ }
421
+ stats.record(timer.read());
422
+
423
+ if (iter == iterations - 1 and show_mem) {
424
+ final_mem = eb.getTextBuffer().getArenaAllocatedBytes();
425
+ }
426
+ }
427
+
428
+ const mem_stats: ?[]const MemStat = if (show_mem) blk: {
429
+ const s = try allocator.alloc(MemStat, 1);
430
+ s[0] = .{ .name = "TB", .bytes = final_mem };
431
+ break :blk s;
432
+ } else null;
433
+
434
+ try results.append(allocator, .{
435
+ .name = name,
436
+ .min_ns = stats.min_ns,
437
+ .avg_ns = stats.avg(),
438
+ .max_ns = stats.max_ns,
439
+ .total_ns = stats.total_ns,
440
+ .iterations = iterations,
441
+ .mem_stats = mem_stats,
442
+ });
443
+ }
444
+ }
445
+
446
+ return results.toOwnedSlice(allocator);
447
+ }
448
+
449
+ pub fn run(
450
+ allocator: std.mem.Allocator,
451
+ show_mem: bool,
452
+ bench_filter: ?[]const u8,
453
+ ) ![]BenchResult {
454
+ // Global pool and unicode data are initialized once in bench.zig
455
+ const pool = gp.initGlobalPool(allocator);
456
+
457
+ var all_results: std.ArrayListUnmanaged(BenchResult) = .{};
458
+ errdefer all_results.deinit(allocator);
459
+
460
+ const iterations: usize = 5;
461
+
462
+ // Run all benchmark categories and filter results
463
+ const insert_results = try benchInsertOperations(allocator, pool, iterations, show_mem, bench_filter);
464
+ try all_results.appendSlice(allocator, insert_results);
465
+
466
+ const delete_results = try benchDeleteOperations(allocator, pool, iterations, show_mem, bench_filter);
467
+ try all_results.appendSlice(allocator, delete_results);
468
+
469
+ const mixed_results = try benchMixedOperations(allocator, pool, iterations, show_mem, bench_filter);
470
+ try all_results.appendSlice(allocator, mixed_results);
471
+
472
+ const word_boundary_results = try benchWordBoundaryOperations(allocator, pool, iterations, show_mem, bench_filter);
473
+ try all_results.appendSlice(allocator, word_boundary_results);
474
+
475
+ return all_results.toOwnedSlice(allocator);
476
+ }
@@ -0,0 +1,169 @@
1
+ const std = @import("std");
2
+ const bench_utils = @import("../bench-utils.zig");
3
+ const edit_buffer = @import("../edit-buffer.zig");
4
+ const editor_view = @import("../editor-view.zig");
5
+ const gp = @import("../grapheme.zig");
6
+ const link = @import("../link.zig");
7
+
8
+ const BenchResult = bench_utils.BenchResult;
9
+ const BenchStats = bench_utils.BenchStats;
10
+ const EditBuffer = edit_buffer.EditBuffer;
11
+ const EditorView = editor_view.EditorView;
12
+
13
+ pub const benchName = "EditorView Visual Navigation";
14
+
15
+ const calls_per_iteration = 10_000;
16
+
17
+ fn appendResult(allocator: std.mem.Allocator, results: *std.ArrayListUnmanaged(BenchResult), name: []const u8, stats: BenchStats) !void {
18
+ try results.append(allocator, .{
19
+ .name = name,
20
+ .min_ns = stats.min_ns,
21
+ .avg_ns = stats.avg(),
22
+ .max_ns = stats.max_ns,
23
+ .total_ns = stats.total_ns,
24
+ .iterations = stats.count,
25
+ .mem_stats = null,
26
+ });
27
+ }
28
+
29
+ fn resetPrimaryCursor(eb: *EditBuffer, row: u32, col: u32, offset: u32) void {
30
+ eb.cursors.items[0] = .{
31
+ .row = row,
32
+ .col = col,
33
+ .desired_col = col,
34
+ .offset = offset,
35
+ };
36
+ }
37
+
38
+ fn keepAlive(checksum: u64) !void {
39
+ if (checksum == std.math.maxInt(u64)) return error.InvalidBenchmarkChecksum;
40
+ }
41
+
42
+ fn benchMoveDownBoundary(
43
+ allocator: std.mem.Allocator,
44
+ pool: *gp.GraphemePool,
45
+ link_pool: *link.LinkPool,
46
+ iterations: usize,
47
+ bench_filter: ?[]const u8,
48
+ results: *std.ArrayListUnmanaged(BenchResult),
49
+ ) !void {
50
+ const name = "moveDownVisual wrapped boundary: 10k calls";
51
+ if (!bench_utils.matchesBenchFilter(name, bench_filter)) return;
52
+
53
+ var eb = try EditBuffer.init(allocator, pool, link_pool, .wcwidth, null);
54
+ defer eb.deinit();
55
+ var ev = try EditorView.init(allocator, eb, 10, 10);
56
+ defer ev.deinit();
57
+
58
+ ev.setWrapMode(.word);
59
+ try eb.setText("0123456789\nquick brown fox");
60
+ _ = ev.getCachedLineInfo();
61
+
62
+ var stats: BenchStats = .{};
63
+ var checksum: u64 = 0;
64
+ for (0..iterations) |_| {
65
+ var timer = try std.time.Timer.start();
66
+ for (0..calls_per_iteration) |_| {
67
+ resetPrimaryCursor(eb, 0, 10, 10);
68
+ ev.desired_visual_col = null;
69
+ ev.moveDownVisual();
70
+ const cursor = eb.getPrimaryCursor();
71
+ checksum +%= cursor.row + cursor.col;
72
+ }
73
+ stats.record(timer.read());
74
+ }
75
+ try keepAlive(checksum);
76
+ try appendResult(allocator, results, name, stats);
77
+ }
78
+
79
+ fn benchMoveUpBoundary(
80
+ allocator: std.mem.Allocator,
81
+ pool: *gp.GraphemePool,
82
+ link_pool: *link.LinkPool,
83
+ iterations: usize,
84
+ bench_filter: ?[]const u8,
85
+ results: *std.ArrayListUnmanaged(BenchResult),
86
+ ) !void {
87
+ const name = "moveUpVisual wrapped boundary: 10k calls";
88
+ if (!bench_utils.matchesBenchFilter(name, bench_filter)) return;
89
+
90
+ const text = "quick brown fox";
91
+ var eb = try EditBuffer.init(allocator, pool, link_pool, .wcwidth, null);
92
+ defer eb.deinit();
93
+ var ev = try EditorView.init(allocator, eb, 10, 10);
94
+ defer ev.deinit();
95
+
96
+ ev.setWrapMode(.word);
97
+ try eb.setText(text);
98
+ _ = ev.getCachedLineInfo();
99
+
100
+ var stats: BenchStats = .{};
101
+ var checksum: u64 = 0;
102
+ for (0..iterations) |_| {
103
+ var timer = try std.time.Timer.start();
104
+ for (0..calls_per_iteration) |_| {
105
+ resetPrimaryCursor(eb, 0, text.len, @intCast(text.len));
106
+ ev.desired_visual_col = null;
107
+ ev.moveUpVisual();
108
+ const cursor = eb.getPrimaryCursor();
109
+ checksum +%= cursor.row + cursor.col;
110
+ }
111
+ stats.record(timer.read());
112
+ }
113
+ try keepAlive(checksum);
114
+ try appendResult(allocator, results, name, stats);
115
+ }
116
+
117
+ fn benchVisualEOLBoundary(
118
+ allocator: std.mem.Allocator,
119
+ pool: *gp.GraphemePool,
120
+ link_pool: *link.LinkPool,
121
+ iterations: usize,
122
+ bench_filter: ?[]const u8,
123
+ results: *std.ArrayListUnmanaged(BenchResult),
124
+ ) !void {
125
+ const name = "getVisualEOL wrapped boundary: 10k calls";
126
+ if (!bench_utils.matchesBenchFilter(name, bench_filter)) return;
127
+
128
+ var eb = try EditBuffer.init(allocator, pool, link_pool, .wcwidth, null);
129
+ defer eb.deinit();
130
+ var ev = try EditorView.init(allocator, eb, 10, 10);
131
+ defer ev.deinit();
132
+
133
+ ev.setWrapMode(.word);
134
+ try eb.setText("quick brown fox");
135
+ try eb.setCursor(0, 3);
136
+ _ = ev.getCachedLineInfo();
137
+
138
+ var stats: BenchStats = .{};
139
+ var checksum: u64 = 0;
140
+ for (0..iterations) |_| {
141
+ var timer = try std.time.Timer.start();
142
+ for (0..calls_per_iteration) |_| {
143
+ const cursor = ev.getVisualEOL();
144
+ checksum +%= cursor.visual_row + cursor.visual_col + cursor.logical_col;
145
+ }
146
+ stats.record(timer.read());
147
+ }
148
+ try keepAlive(checksum);
149
+ try appendResult(allocator, results, name, stats);
150
+ }
151
+
152
+ pub fn run(
153
+ allocator: std.mem.Allocator,
154
+ _: bool,
155
+ bench_filter: ?[]const u8,
156
+ ) ![]BenchResult {
157
+ const pool = gp.initGlobalPool(allocator);
158
+ const link_pool = link.initGlobalLinkPool(allocator);
159
+
160
+ var results: std.ArrayListUnmanaged(BenchResult) = .{};
161
+ errdefer results.deinit(allocator);
162
+
163
+ const iterations: usize = 20;
164
+ try benchMoveDownBoundary(allocator, pool, link_pool, iterations, bench_filter, &results);
165
+ try benchMoveUpBoundary(allocator, pool, link_pool, iterations, bench_filter, &results);
166
+ try benchVisualEOLBoundary(allocator, pool, link_pool, iterations, bench_filter, &results);
167
+
168
+ return results.toOwnedSlice(allocator);
169
+ }