@fairyhunter13/opentui-core 0.1.113 → 0.1.114

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 (591) 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 +144 -0
  7. package/package.json +62 -53
  8. package/scripts/build.ts +400 -0
  9. package/scripts/publish.ts +60 -0
  10. package/src/3d/SpriteResourceManager.ts +286 -0
  11. package/src/3d/SpriteUtils.ts +70 -0
  12. package/src/3d/TextureUtils.ts +196 -0
  13. package/src/3d/ThreeRenderable.ts +197 -0
  14. package/src/3d/WGPURenderer.ts +294 -0
  15. package/src/3d/animation/ExplodingSpriteEffect.ts +513 -0
  16. package/src/3d/animation/PhysicsExplodingSpriteEffect.ts +429 -0
  17. package/src/3d/animation/SpriteAnimator.ts +633 -0
  18. package/src/3d/animation/SpriteParticleGenerator.ts +435 -0
  19. package/src/3d/canvas.ts +464 -0
  20. package/src/3d/index.ts +12 -0
  21. package/src/3d/physics/PlanckPhysicsAdapter.ts +72 -0
  22. package/src/3d/physics/RapierPhysicsAdapter.ts +66 -0
  23. package/src/3d/physics/physics-interface.ts +31 -0
  24. package/src/3d/shaders/supersampling.wgsl +201 -0
  25. package/src/3d.ts +3 -0
  26. package/src/NativeSpanFeed.ts +300 -0
  27. package/src/Renderable.ts +1704 -0
  28. package/src/__snapshots__/buffer.test.ts.snap +28 -0
  29. package/src/animation/Timeline.test.ts +2709 -0
  30. package/src/animation/Timeline.ts +598 -0
  31. package/src/ansi.ts +18 -0
  32. package/src/benchmark/attenuation-benchmark.ts +81 -0
  33. package/src/benchmark/colormatrix-benchmark.ts +128 -0
  34. package/src/benchmark/gain-benchmark.ts +80 -0
  35. package/src/benchmark/latest-all-bench-run.json +707 -0
  36. package/src/benchmark/latest-async-bench-run.json +336 -0
  37. package/src/benchmark/latest-default-bench-run.json +657 -0
  38. package/src/benchmark/latest-large-bench-run.json +707 -0
  39. package/src/benchmark/latest-quick-bench-run.json +207 -0
  40. package/src/benchmark/markdown-benchmark.ts +1796 -0
  41. package/src/benchmark/native-span-feed-async-benchmark.ts +355 -0
  42. package/src/benchmark/native-span-feed-benchmark.md +56 -0
  43. package/src/benchmark/native-span-feed-benchmark.ts +596 -0
  44. package/src/benchmark/native-span-feed-compare.ts +280 -0
  45. package/src/benchmark/renderer-benchmark.ts +754 -0
  46. package/src/benchmark/text-table-benchmark.ts +948 -0
  47. package/src/buffer.test.ts +291 -0
  48. package/src/buffer.ts +554 -0
  49. package/src/console.test.ts +612 -0
  50. package/src/console.ts +1254 -0
  51. package/src/edit-buffer.test.ts +1769 -0
  52. package/src/edit-buffer.ts +411 -0
  53. package/src/editor-view.test.ts +1032 -0
  54. package/src/editor-view.ts +284 -0
  55. package/src/examples/ascii-font-selection-demo.ts +245 -0
  56. package/src/examples/assets/Water_2_M_Normal.jpg +0 -0
  57. package/src/examples/assets/concrete.png +0 -0
  58. package/src/examples/assets/crate.png +0 -0
  59. package/src/examples/assets/crate_emissive.png +0 -0
  60. package/src/examples/assets/forrest_background.png +0 -0
  61. package/src/examples/assets/hast-example.json +1018 -0
  62. package/src/examples/assets/heart.png +0 -0
  63. package/src/examples/assets/main_char_heavy_attack.png +0 -0
  64. package/src/examples/assets/main_char_idle.png +0 -0
  65. package/src/examples/assets/main_char_jump_end.png +0 -0
  66. package/src/examples/assets/main_char_jump_landing.png +0 -0
  67. package/src/examples/assets/main_char_jump_start.png +0 -0
  68. package/src/examples/assets/main_char_run_loop.png +0 -0
  69. package/src/examples/assets/roughness_map.jpg +0 -0
  70. package/src/examples/build.ts +115 -0
  71. package/src/examples/code-demo.ts +924 -0
  72. package/src/examples/console-demo.ts +358 -0
  73. package/src/examples/core-plugin-slots-demo.ts +759 -0
  74. package/src/examples/diff-demo.ts +701 -0
  75. package/src/examples/draggable-three-demo.ts +259 -0
  76. package/src/examples/editor-demo.ts +322 -0
  77. package/src/examples/extmarks-demo.ts +196 -0
  78. package/src/examples/focus-restore-demo.ts +310 -0
  79. package/src/examples/fonts.ts +245 -0
  80. package/src/examples/fractal-shader-demo.ts +268 -0
  81. package/src/examples/framebuffer-demo.ts +674 -0
  82. package/src/examples/full-unicode-demo.ts +241 -0
  83. package/src/examples/golden-star-demo.ts +933 -0
  84. package/src/examples/grayscale-buffer-demo.ts +249 -0
  85. package/src/examples/hast-syntax-highlighting-demo.ts +129 -0
  86. package/src/examples/index.ts +926 -0
  87. package/src/examples/input-demo.ts +377 -0
  88. package/src/examples/input-select-layout-demo.ts +425 -0
  89. package/src/examples/install.sh +143 -0
  90. package/src/examples/keypress-debug-demo.ts +452 -0
  91. package/src/examples/lib/HexList.ts +122 -0
  92. package/src/examples/lib/PaletteGrid.ts +125 -0
  93. package/src/examples/lib/standalone-keys.ts +25 -0
  94. package/src/examples/lib/tab-controller.ts +243 -0
  95. package/src/examples/lights-phong-demo.ts +290 -0
  96. package/src/examples/link-demo.ts +220 -0
  97. package/src/examples/live-state-demo.ts +480 -0
  98. package/src/examples/markdown-demo.ts +725 -0
  99. package/src/examples/mouse-interaction-demo.ts +428 -0
  100. package/src/examples/nested-zindex-demo.ts +357 -0
  101. package/src/examples/opacity-example.ts +235 -0
  102. package/src/examples/opentui-demo.ts +1057 -0
  103. package/src/examples/physx-planck-2d-demo.ts +623 -0
  104. package/src/examples/physx-rapier-2d-demo.ts +655 -0
  105. package/src/examples/relative-positioning-demo.ts +323 -0
  106. package/src/examples/scroll-example.ts +214 -0
  107. package/src/examples/scrollbox-mouse-test.ts +112 -0
  108. package/src/examples/scrollbox-overlay-hit-test.ts +206 -0
  109. package/src/examples/select-demo.ts +237 -0
  110. package/src/examples/shader-cube-demo.ts +1015 -0
  111. package/src/examples/simple-layout-example.ts +591 -0
  112. package/src/examples/slider-demo.ts +617 -0
  113. package/src/examples/split-mode-demo.ts +453 -0
  114. package/src/examples/sprite-animation-demo.ts +443 -0
  115. package/src/examples/sprite-particle-generator-demo.ts +486 -0
  116. package/src/examples/static-sprite-demo.ts +193 -0
  117. package/src/examples/sticky-scroll-example.ts +308 -0
  118. package/src/examples/styled-text-demo.ts +282 -0
  119. package/src/examples/tab-select-demo.ts +219 -0
  120. package/src/examples/terminal-title.ts +29 -0
  121. package/src/examples/terminal.ts +305 -0
  122. package/src/examples/text-node-demo.ts +416 -0
  123. package/src/examples/text-selection-demo.ts +377 -0
  124. package/src/examples/text-table-demo.ts +503 -0
  125. package/src/examples/text-truncation-demo.ts +481 -0
  126. package/src/examples/text-wrap.ts +757 -0
  127. package/src/examples/texture-loading-demo.ts +259 -0
  128. package/src/examples/timeline-example.ts +670 -0
  129. package/src/examples/transparency-demo.ts +400 -0
  130. package/src/examples/vnode-composition-demo.ts +404 -0
  131. package/src/examples/wide-grapheme-overlay-demo.ts +280 -0
  132. package/src/index.ts +24 -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 +170 -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 +35 -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 +317 -0
  168. package/src/lib/keymapping.ts +115 -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 +2290 -0
  187. package/src/lib/stdin-parser.ts +1810 -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 +334 -0
  195. package/src/lib/tree-sitter/assets.d.ts +9 -0
  196. package/src/lib/tree-sitter/cache.test.ts +273 -0
  197. package/src/lib/tree-sitter/client.test.ts +1165 -0
  198. package/src/lib/tree-sitter/client.ts +607 -0
  199. package/src/lib/tree-sitter/default-parsers.ts +86 -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 +1042 -0
  203. package/src/lib/tree-sitter/parsers-config.ts +81 -0
  204. package/src/lib/tree-sitter/resolve-ft.test.ts +55 -0
  205. package/src/lib/tree-sitter/resolve-ft.ts +189 -0
  206. package/src/lib/tree-sitter/types.ts +82 -0
  207. package/src/lib/tree-sitter-styled-text.test.ts +1253 -0
  208. package/src/lib/tree-sitter-styled-text.ts +306 -0
  209. package/src/lib/validate-dir-name.ts +55 -0
  210. package/src/lib/yoga.options.test.ts +628 -0
  211. package/src/lib/yoga.options.ts +346 -0
  212. package/src/plugins/core-slot.ts +579 -0
  213. package/src/plugins/registry.ts +402 -0
  214. package/src/plugins/types.ts +46 -0
  215. package/src/post/effects.ts +930 -0
  216. package/src/post/filters.ts +489 -0
  217. package/src/post/matrices.ts +288 -0
  218. package/src/renderables/ASCIIFont.ts +219 -0
  219. package/src/renderables/Box.test.ts +205 -0
  220. package/src/renderables/Box.ts +326 -0
  221. package/src/renderables/Code.test.ts +2062 -0
  222. package/src/renderables/Code.ts +357 -0
  223. package/src/renderables/Diff.regression.test.ts +226 -0
  224. package/src/renderables/Diff.test.ts +3101 -0
  225. package/src/renderables/Diff.ts +1211 -0
  226. package/src/renderables/EditBufferRenderable.test.ts +288 -0
  227. package/src/renderables/EditBufferRenderable.ts +1166 -0
  228. package/src/renderables/FrameBuffer.ts +47 -0
  229. package/src/renderables/Input.test.ts +1228 -0
  230. package/src/renderables/Input.ts +247 -0
  231. package/src/renderables/LineNumberRenderable.ts +724 -0
  232. package/src/renderables/Markdown.ts +1393 -0
  233. package/src/renderables/ScrollBar.ts +422 -0
  234. package/src/renderables/ScrollBox.ts +883 -0
  235. package/src/renderables/Select.test.ts +1033 -0
  236. package/src/renderables/Select.ts +524 -0
  237. package/src/renderables/Slider.test.ts +456 -0
  238. package/src/renderables/Slider.ts +342 -0
  239. package/src/renderables/TabSelect.test.ts +197 -0
  240. package/src/renderables/TabSelect.ts +455 -0
  241. package/src/renderables/Text.selection-buffer.test.ts +123 -0
  242. package/src/renderables/Text.test.ts +2660 -0
  243. package/src/renderables/Text.ts +147 -0
  244. package/src/renderables/TextBufferRenderable.ts +518 -0
  245. package/src/renderables/TextNode.test.ts +1058 -0
  246. package/src/renderables/TextNode.ts +325 -0
  247. package/src/renderables/TextTable.test.ts +1421 -0
  248. package/src/renderables/TextTable.ts +1344 -0
  249. package/src/renderables/Textarea.ts +430 -0
  250. package/src/renderables/TimeToFirstDraw.ts +89 -0
  251. package/src/renderables/__snapshots__/Code.test.ts.snap +13 -0
  252. package/src/renderables/__snapshots__/Diff.test.ts.snap +785 -0
  253. package/src/renderables/__snapshots__/Text.test.ts.snap +421 -0
  254. package/src/renderables/__snapshots__/TextTable.test.ts.snap +215 -0
  255. package/src/renderables/__tests__/LineNumberRenderable.scrollbox-simple.test.ts +144 -0
  256. package/src/renderables/__tests__/LineNumberRenderable.scrollbox.test.ts +816 -0
  257. package/src/renderables/__tests__/LineNumberRenderable.test.ts +1865 -0
  258. package/src/renderables/__tests__/LineNumberRenderable.wrapping.test.ts +85 -0
  259. package/src/renderables/__tests__/Markdown.code-colors.test.ts +242 -0
  260. package/src/renderables/__tests__/Markdown.test.ts +2518 -0
  261. package/src/renderables/__tests__/MultiRenderable.selection.test.ts +87 -0
  262. package/src/renderables/__tests__/Textarea.buffer.test.ts +682 -0
  263. package/src/renderables/__tests__/Textarea.destroyed-events.test.ts +675 -0
  264. package/src/renderables/__tests__/Textarea.editing.test.ts +2041 -0
  265. package/src/renderables/__tests__/Textarea.error-handling.test.ts +35 -0
  266. package/src/renderables/__tests__/Textarea.events.test.ts +738 -0
  267. package/src/renderables/__tests__/Textarea.highlights.test.ts +590 -0
  268. package/src/renderables/__tests__/Textarea.keybinding.test.ts +3149 -0
  269. package/src/renderables/__tests__/Textarea.paste.test.ts +357 -0
  270. package/src/renderables/__tests__/Textarea.rendering.test.ts +1866 -0
  271. package/src/renderables/__tests__/Textarea.scroll.test.ts +733 -0
  272. package/src/renderables/__tests__/Textarea.selection.test.ts +1590 -0
  273. package/src/renderables/__tests__/Textarea.stress.test.ts +670 -0
  274. package/src/renderables/__tests__/Textarea.undo-redo.test.ts +383 -0
  275. package/src/renderables/__tests__/Textarea.visual-lines.test.ts +310 -0
  276. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.code.test.ts.snap +221 -0
  277. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.scrollbox-simple.test.ts.snap +89 -0
  278. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.scrollbox.test.ts.snap +457 -0
  279. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.test.ts.snap +158 -0
  280. package/src/renderables/__tests__/__snapshots__/Textarea.rendering.test.ts.snap +387 -0
  281. package/src/renderables/__tests__/markdown-parser.test.ts +217 -0
  282. package/src/renderables/__tests__/renderable-test-utils.ts +60 -0
  283. package/src/renderables/composition/README.md +8 -0
  284. package/src/renderables/composition/VRenderable.ts +32 -0
  285. package/src/renderables/composition/constructs.ts +127 -0
  286. package/src/renderables/composition/vnode.ts +289 -0
  287. package/src/renderables/index.ts +23 -0
  288. package/src/renderables/markdown-parser.ts +66 -0
  289. package/src/renderer.ts +2681 -0
  290. package/src/runtime-plugin-support.ts +39 -0
  291. package/src/runtime-plugin.ts +615 -0
  292. package/src/syntax-style.test.ts +841 -0
  293. package/src/syntax-style.ts +257 -0
  294. package/src/testing/README.md +210 -0
  295. package/src/testing/capture-spans.test.ts +194 -0
  296. package/src/testing/integration.test.ts +276 -0
  297. package/src/testing/manual-clock.ts +117 -0
  298. package/src/testing/mock-keys.test.ts +1378 -0
  299. package/src/testing/mock-keys.ts +457 -0
  300. package/src/testing/mock-mouse.test.ts +218 -0
  301. package/src/testing/mock-mouse.ts +247 -0
  302. package/src/testing/mock-tree-sitter-client.ts +73 -0
  303. package/src/testing/spy.ts +13 -0
  304. package/src/testing/test-recorder.test.ts +415 -0
  305. package/src/testing/test-recorder.ts +145 -0
  306. package/src/testing/test-renderer.ts +132 -0
  307. package/src/testing.ts +7 -0
  308. package/src/tests/__snapshots__/absolute-positioning.snapshot.test.ts.snap +481 -0
  309. package/src/tests/__snapshots__/renderable.snapshot.test.ts.snap +19 -0
  310. package/src/tests/__snapshots__/scrollbox.test.ts.snap +29 -0
  311. package/src/tests/absolute-positioning.snapshot.test.ts +638 -0
  312. package/src/tests/allocator-stats.test.ts +38 -0
  313. package/src/tests/destroy-during-render.test.ts +200 -0
  314. package/src/tests/destroy-on-exit.fixture.ts +36 -0
  315. package/src/tests/destroy-on-exit.test.ts +41 -0
  316. package/src/tests/hover-cursor.test.ts +98 -0
  317. package/src/tests/native-span-feed-async.test.ts +173 -0
  318. package/src/tests/native-span-feed-close.test.ts +120 -0
  319. package/src/tests/native-span-feed-coverage.test.ts +227 -0
  320. package/src/tests/native-span-feed-edge-cases.test.ts +352 -0
  321. package/src/tests/native-span-feed-use-after-free.test.ts +45 -0
  322. package/src/tests/opacity.test.ts +123 -0
  323. package/src/tests/renderable.snapshot.test.ts +524 -0
  324. package/src/tests/renderable.test.ts +1281 -0
  325. package/src/tests/renderer.clock.test.ts +158 -0
  326. package/src/tests/renderer.console-startup.test.ts +185 -0
  327. package/src/tests/renderer.control.test.ts +425 -0
  328. package/src/tests/renderer.core-slot-binding.test.ts +952 -0
  329. package/src/tests/renderer.cursor.test.ts +26 -0
  330. package/src/tests/renderer.destroy-during-render.test.ts +147 -0
  331. package/src/tests/renderer.focus-restore.test.ts +257 -0
  332. package/src/tests/renderer.focus.test.ts +294 -0
  333. package/src/tests/renderer.idle.test.ts +219 -0
  334. package/src/tests/renderer.input.test.ts +2237 -0
  335. package/src/tests/renderer.kitty-flags.test.ts +195 -0
  336. package/src/tests/renderer.mouse.test.ts +1274 -0
  337. package/src/tests/renderer.palette.test.ts +629 -0
  338. package/src/tests/renderer.selection.test.ts +49 -0
  339. package/src/tests/renderer.slot-registry.test.ts +684 -0
  340. package/src/tests/renderer.useMouse.test.ts +47 -0
  341. package/src/tests/runtime-plugin-node-modules-cycle.fixture.ts +76 -0
  342. package/src/tests/runtime-plugin-node-modules-mjs.fixture.ts +43 -0
  343. package/src/tests/runtime-plugin-node-modules-no-bare-rewrite.fixture.ts +67 -0
  344. package/src/tests/runtime-plugin-node-modules-package-type-cache.fixture.ts +72 -0
  345. package/src/tests/runtime-plugin-node-modules-runtime-specifier.fixture.ts +44 -0
  346. package/src/tests/runtime-plugin-node-modules-scoped-package-bare-rewrite.fixture.ts +85 -0
  347. package/src/tests/runtime-plugin-path-alias.fixture.ts +43 -0
  348. package/src/tests/runtime-plugin-resolve-roots.fixture.ts +65 -0
  349. package/src/tests/runtime-plugin-support.fixture.ts +11 -0
  350. package/src/tests/runtime-plugin-support.test.ts +19 -0
  351. package/src/tests/runtime-plugin-windows-file-url.fixture.ts +30 -0
  352. package/src/tests/runtime-plugin.fixture.ts +40 -0
  353. package/src/tests/runtime-plugin.test.ts +354 -0
  354. package/src/tests/scrollbox-culling-bug.test.ts +114 -0
  355. package/src/tests/scrollbox-hitgrid-resize.test.ts +136 -0
  356. package/src/tests/scrollbox-hitgrid.test.ts +909 -0
  357. package/src/tests/scrollbox.test.ts +1530 -0
  358. package/src/tests/wrap-resize-perf.test.ts +276 -0
  359. package/src/tests/yoga-setters.test.ts +921 -0
  360. package/src/text-buffer-view.test.ts +705 -0
  361. package/src/text-buffer-view.ts +189 -0
  362. package/src/text-buffer.test.ts +347 -0
  363. package/src/text-buffer.ts +250 -0
  364. package/src/types.ts +161 -0
  365. package/src/utils.ts +88 -0
  366. package/src/zig/ansi.zig +268 -0
  367. package/src/zig/bench/README.md +50 -0
  368. package/src/zig/bench/buffer-draw-text-buffer_bench.zig +887 -0
  369. package/src/zig/bench/edit-buffer_bench.zig +476 -0
  370. package/src/zig/bench/native-span-feed_bench.zig +100 -0
  371. package/src/zig/bench/rope-markers_bench.zig +713 -0
  372. package/src/zig/bench/rope_bench.zig +514 -0
  373. package/src/zig/bench/styled-text_bench.zig +470 -0
  374. package/src/zig/bench/text-buffer-coords_bench.zig +362 -0
  375. package/src/zig/bench/text-buffer-view_bench.zig +459 -0
  376. package/src/zig/bench/text-chunk-graphemes_bench.zig +273 -0
  377. package/src/zig/bench/utf8_bench.zig +799 -0
  378. package/src/zig/bench-utils.zig +431 -0
  379. package/src/zig/bench.zig +217 -0
  380. package/src/zig/buffer-methods.zig +211 -0
  381. package/src/zig/buffer.zig +2281 -0
  382. package/src/zig/build.zig +289 -0
  383. package/src/zig/build.zig.zon +16 -0
  384. package/src/zig/edit-buffer.zig +825 -0
  385. package/src/zig/editor-view.zig +802 -0
  386. package/src/zig/event-bus.zig +13 -0
  387. package/src/zig/event-emitter.zig +65 -0
  388. package/src/zig/file-logger.zig +92 -0
  389. package/src/zig/grapheme.zig +599 -0
  390. package/src/zig/lib.zig +1854 -0
  391. package/src/zig/link.zig +333 -0
  392. package/src/zig/logger.zig +43 -0
  393. package/src/zig/mem-registry.zig +125 -0
  394. package/src/zig/native-span-feed-bench-lib.zig +7 -0
  395. package/src/zig/native-span-feed.zig +708 -0
  396. package/src/zig/renderer.zig +1393 -0
  397. package/src/zig/rope.zig +1220 -0
  398. package/src/zig/syntax-style.zig +161 -0
  399. package/src/zig/terminal.zig +987 -0
  400. package/src/zig/test.zig +72 -0
  401. package/src/zig/tests/README.md +18 -0
  402. package/src/zig/tests/buffer-methods_test.zig +1109 -0
  403. package/src/zig/tests/buffer_test.zig +2557 -0
  404. package/src/zig/tests/edit-buffer-history_test.zig +271 -0
  405. package/src/zig/tests/edit-buffer_test.zig +1689 -0
  406. package/src/zig/tests/editor-view_test.zig +3299 -0
  407. package/src/zig/tests/event-emitter_test.zig +249 -0
  408. package/src/zig/tests/grapheme_test.zig +1304 -0
  409. package/src/zig/tests/link_test.zig +190 -0
  410. package/src/zig/tests/mem-registry_test.zig +473 -0
  411. package/src/zig/tests/memory_leak_regression_test.zig +159 -0
  412. package/src/zig/tests/native-span-feed_test.zig +1264 -0
  413. package/src/zig/tests/renderer_test.zig +1017 -0
  414. package/src/zig/tests/rope-nested_test.zig +712 -0
  415. package/src/zig/tests/rope_fuzz_test.zig +238 -0
  416. package/src/zig/tests/rope_test.zig +2362 -0
  417. package/src/zig/tests/segment-merge.test.zig +148 -0
  418. package/src/zig/tests/syntax-style_test.zig +557 -0
  419. package/src/zig/tests/terminal_test.zig +754 -0
  420. package/src/zig/tests/text-buffer-drawing_test.zig +3237 -0
  421. package/src/zig/tests/text-buffer-highlights_test.zig +666 -0
  422. package/src/zig/tests/text-buffer-iterators_test.zig +776 -0
  423. package/src/zig/tests/text-buffer-segment_test.zig +320 -0
  424. package/src/zig/tests/text-buffer-selection_test.zig +1035 -0
  425. package/src/zig/tests/text-buffer-selection_viewport_test.zig +358 -0
  426. package/src/zig/tests/text-buffer-view_test.zig +3649 -0
  427. package/src/zig/tests/text-buffer_test.zig +2191 -0
  428. package/src/zig/tests/unicode-width-map.zon +3909 -0
  429. package/src/zig/tests/utf8_no_zwj_test.zig +260 -0
  430. package/src/zig/tests/utf8_test.zig +4057 -0
  431. package/src/zig/tests/utf8_wcwidth_cursor_test.zig +267 -0
  432. package/src/zig/tests/utf8_wcwidth_test.zig +357 -0
  433. package/src/zig/tests/word-wrap-editing_test.zig +498 -0
  434. package/src/zig/tests/wrap-cache-perf_test.zig +113 -0
  435. package/src/zig/text-buffer-iterators.zig +499 -0
  436. package/src/zig/text-buffer-segment.zig +404 -0
  437. package/src/zig/text-buffer-view.zig +1371 -0
  438. package/src/zig/text-buffer.zig +1180 -0
  439. package/src/zig/utf8.zig +1948 -0
  440. package/src/zig/utils.zig +9 -0
  441. package/src/zig-structs.ts +261 -0
  442. package/src/zig.ts +3884 -0
  443. package/tsconfig.build.json +24 -0
  444. package/tsconfig.json +27 -0
  445. package/3d/SpriteResourceManager.d.ts +0 -74
  446. package/3d/SpriteUtils.d.ts +0 -13
  447. package/3d/TextureUtils.d.ts +0 -24
  448. package/3d/ThreeRenderable.d.ts +0 -40
  449. package/3d/WGPURenderer.d.ts +0 -61
  450. package/3d/animation/ExplodingSpriteEffect.d.ts +0 -71
  451. package/3d/animation/PhysicsExplodingSpriteEffect.d.ts +0 -76
  452. package/3d/animation/SpriteAnimator.d.ts +0 -124
  453. package/3d/animation/SpriteParticleGenerator.d.ts +0 -62
  454. package/3d/canvas.d.ts +0 -44
  455. package/3d/index.d.ts +0 -12
  456. package/3d/physics/PlanckPhysicsAdapter.d.ts +0 -19
  457. package/3d/physics/RapierPhysicsAdapter.d.ts +0 -19
  458. package/3d/physics/physics-interface.d.ts +0 -27
  459. package/3d.d.ts +0 -2
  460. package/3d.js +0 -34041
  461. package/3d.js.map +0 -155
  462. package/LICENSE +0 -21
  463. package/NativeSpanFeed.d.ts +0 -41
  464. package/Renderable.d.ts +0 -334
  465. package/animation/Timeline.d.ts +0 -126
  466. package/ansi.d.ts +0 -13
  467. package/buffer.d.ts +0 -111
  468. package/console.d.ts +0 -144
  469. package/edit-buffer.d.ts +0 -98
  470. package/editor-view.d.ts +0 -73
  471. package/index-9vwc3fg6.js +0 -12260
  472. package/index-9vwc3fg6.js.map +0 -42
  473. package/index-dcj62y8t.js +0 -20614
  474. package/index-dcj62y8t.js.map +0 -67
  475. package/index-f7n39gpy.js +0 -411
  476. package/index-f7n39gpy.js.map +0 -10
  477. package/index.d.ts +0 -23
  478. package/index.js +0 -478
  479. package/index.js.map +0 -9
  480. package/lib/KeyHandler.d.ts +0 -61
  481. package/lib/RGBA.d.ts +0 -25
  482. package/lib/ascii.font.d.ts +0 -508
  483. package/lib/border.d.ts +0 -51
  484. package/lib/bunfs.d.ts +0 -7
  485. package/lib/clipboard.d.ts +0 -17
  486. package/lib/clock.d.ts +0 -15
  487. package/lib/data-paths.d.ts +0 -26
  488. package/lib/debounce.d.ts +0 -42
  489. package/lib/detect-links.d.ts +0 -6
  490. package/lib/env.d.ts +0 -42
  491. package/lib/extmarks-history.d.ts +0 -17
  492. package/lib/extmarks.d.ts +0 -89
  493. package/lib/hast-styled-text.d.ts +0 -17
  494. package/lib/index.d.ts +0 -21
  495. package/lib/keymapping.d.ts +0 -25
  496. package/lib/objects-in-viewport.d.ts +0 -24
  497. package/lib/output.capture.d.ts +0 -24
  498. package/lib/parse.keypress-kitty.d.ts +0 -2
  499. package/lib/parse.keypress.d.ts +0 -26
  500. package/lib/parse.mouse.d.ts +0 -30
  501. package/lib/paste.d.ts +0 -7
  502. package/lib/queue.d.ts +0 -15
  503. package/lib/renderable.validations.d.ts +0 -12
  504. package/lib/scroll-acceleration.d.ts +0 -43
  505. package/lib/selection.d.ts +0 -63
  506. package/lib/singleton.d.ts +0 -7
  507. package/lib/stdin-parser.d.ts +0 -87
  508. package/lib/styled-text.d.ts +0 -63
  509. package/lib/terminal-capability-detection.d.ts +0 -30
  510. package/lib/terminal-palette.d.ts +0 -50
  511. package/lib/tree-sitter/assets/update.d.ts +0 -11
  512. package/lib/tree-sitter/client.d.ts +0 -47
  513. package/lib/tree-sitter/default-parsers.d.ts +0 -2
  514. package/lib/tree-sitter/download-utils.d.ts +0 -21
  515. package/lib/tree-sitter/index.d.ts +0 -8
  516. package/lib/tree-sitter/parser.worker.d.ts +0 -1
  517. package/lib/tree-sitter/parsers-config.d.ts +0 -53
  518. package/lib/tree-sitter/resolve-ft.d.ts +0 -5
  519. package/lib/tree-sitter/types.d.ts +0 -82
  520. package/lib/tree-sitter-styled-text.d.ts +0 -14
  521. package/lib/validate-dir-name.d.ts +0 -1
  522. package/lib/yoga.options.d.ts +0 -32
  523. package/parser.worker.js +0 -899
  524. package/parser.worker.js.map +0 -12
  525. package/plugins/core-slot.d.ts +0 -72
  526. package/plugins/registry.d.ts +0 -42
  527. package/plugins/types.d.ts +0 -34
  528. package/post/effects.d.ts +0 -147
  529. package/post/filters.d.ts +0 -65
  530. package/post/matrices.d.ts +0 -20
  531. package/renderables/ASCIIFont.d.ts +0 -52
  532. package/renderables/Box.d.ts +0 -81
  533. package/renderables/Code.d.ts +0 -78
  534. package/renderables/Diff.d.ts +0 -142
  535. package/renderables/EditBufferRenderable.d.ts +0 -237
  536. package/renderables/FrameBuffer.d.ts +0 -16
  537. package/renderables/Input.d.ts +0 -67
  538. package/renderables/LineNumberRenderable.d.ts +0 -78
  539. package/renderables/Markdown.d.ts +0 -185
  540. package/renderables/ScrollBar.d.ts +0 -77
  541. package/renderables/ScrollBox.d.ts +0 -124
  542. package/renderables/Select.d.ts +0 -115
  543. package/renderables/Slider.d.ts +0 -47
  544. package/renderables/TabSelect.d.ts +0 -96
  545. package/renderables/Text.d.ts +0 -36
  546. package/renderables/TextBufferRenderable.d.ts +0 -105
  547. package/renderables/TextNode.d.ts +0 -91
  548. package/renderables/TextTable.d.ts +0 -140
  549. package/renderables/Textarea.d.ts +0 -63
  550. package/renderables/TimeToFirstDraw.d.ts +0 -24
  551. package/renderables/__tests__/renderable-test-utils.d.ts +0 -12
  552. package/renderables/composition/VRenderable.d.ts +0 -16
  553. package/renderables/composition/constructs.d.ts +0 -35
  554. package/renderables/composition/vnode.d.ts +0 -46
  555. package/renderables/index.d.ts +0 -23
  556. package/renderables/markdown-parser.d.ts +0 -10
  557. package/renderer.d.ts +0 -419
  558. package/runtime-plugin-support.d.ts +0 -3
  559. package/runtime-plugin-support.js +0 -29
  560. package/runtime-plugin-support.js.map +0 -10
  561. package/runtime-plugin.d.ts +0 -16
  562. package/runtime-plugin.js +0 -16
  563. package/runtime-plugin.js.map +0 -9
  564. package/syntax-style.d.ts +0 -54
  565. package/testing/manual-clock.d.ts +0 -17
  566. package/testing/mock-keys.d.ts +0 -81
  567. package/testing/mock-mouse.d.ts +0 -38
  568. package/testing/mock-tree-sitter-client.d.ts +0 -23
  569. package/testing/spy.d.ts +0 -7
  570. package/testing/test-recorder.d.ts +0 -61
  571. package/testing/test-renderer.d.ts +0 -23
  572. package/testing.d.ts +0 -6
  573. package/testing.js +0 -697
  574. package/testing.js.map +0 -15
  575. package/text-buffer-view.d.ts +0 -42
  576. package/text-buffer.d.ts +0 -67
  577. package/types.d.ts +0 -139
  578. package/utils.d.ts +0 -14
  579. package/zig-structs.d.ts +0 -155
  580. package/zig.d.ts +0 -353
  581. /package/{assets → src/lib/tree-sitter/assets}/javascript/highlights.scm +0 -0
  582. /package/{assets → src/lib/tree-sitter/assets}/javascript/tree-sitter-javascript.wasm +0 -0
  583. /package/{assets → src/lib/tree-sitter/assets}/markdown/highlights.scm +0 -0
  584. /package/{assets → src/lib/tree-sitter/assets}/markdown/injections.scm +0 -0
  585. /package/{assets → src/lib/tree-sitter/assets}/markdown/tree-sitter-markdown.wasm +0 -0
  586. /package/{assets → src/lib/tree-sitter/assets}/markdown_inline/highlights.scm +0 -0
  587. /package/{assets → src/lib/tree-sitter/assets}/markdown_inline/tree-sitter-markdown_inline.wasm +0 -0
  588. /package/{assets → src/lib/tree-sitter/assets}/typescript/highlights.scm +0 -0
  589. /package/{assets → src/lib/tree-sitter/assets}/typescript/tree-sitter-typescript.wasm +0 -0
  590. /package/{assets → src/lib/tree-sitter/assets}/zig/highlights.scm +0 -0
  591. /package/{assets → src/lib/tree-sitter/assets}/zig/tree-sitter-zig.wasm +0 -0
@@ -0,0 +1,754 @@
1
+ const std = @import("std");
2
+ const builtin = @import("builtin");
3
+ const testing = std.testing;
4
+ const ansi = @import("../ansi.zig");
5
+ const Terminal = @import("../terminal.zig");
6
+ const utf8 = @import("../utf8.zig");
7
+
8
+ test "parseXtversion - kitty format" {
9
+ var term = Terminal.init(.{});
10
+ const response = "\x1bP>|kitty(0.40.1)\x1b\\";
11
+ term.processCapabilityResponse(response);
12
+
13
+ try testing.expectEqualStrings("kitty", term.getTerminalName());
14
+ try testing.expectEqualStrings("0.40.1", term.getTerminalVersion());
15
+ try testing.expect(term.term_info.from_xtversion);
16
+ try testing.expect(term.caps.osc52);
17
+ }
18
+
19
+ test "parseXtversion - ghostty format" {
20
+ var term = Terminal.init(.{});
21
+ const response = "\x1bP>|ghostty 1.1.3\x1b\\";
22
+ term.processCapabilityResponse(response);
23
+
24
+ try testing.expectEqualStrings("ghostty", term.getTerminalName());
25
+ try testing.expectEqualStrings("1.1.3", term.getTerminalVersion());
26
+ try testing.expect(term.term_info.from_xtversion);
27
+ try testing.expect(term.caps.osc52);
28
+ }
29
+
30
+ test "parseXtversion - tmux format" {
31
+ var term = Terminal.init(.{});
32
+ const response = "\x1bP>|tmux 3.5a\x1b\\";
33
+ term.processCapabilityResponse(response);
34
+
35
+ try testing.expectEqualStrings("tmux", term.getTerminalName());
36
+ try testing.expectEqualStrings("3.5a", term.getTerminalVersion());
37
+ try testing.expect(term.term_info.from_xtversion);
38
+ try testing.expect(term.caps.osc52);
39
+ }
40
+
41
+ test "parseXtversion - with prefix data" {
42
+ var term = Terminal.init(.{});
43
+ const response = "\x1b[1;1R\x1bP>|tmux 3.5a\x1b\\";
44
+ term.processCapabilityResponse(response);
45
+
46
+ try testing.expectEqualStrings("tmux", term.getTerminalName());
47
+ try testing.expectEqualStrings("3.5a", term.getTerminalVersion());
48
+ try testing.expect(term.term_info.from_xtversion);
49
+ }
50
+
51
+ test "parseXtversion - full kitty response" {
52
+ var term = Terminal.init(.{});
53
+ const response = "\x1b[?1016;2$y\x1b[?2027;0$y\x1b[?2031;2$y\x1b[?1004;1$y\x1b[?2026;2$y\x1b[1;2R\x1b[1;3R\x1bP>|kitty(0.40.1)\x1b\\\x1b[?0u\x1b_Gi=1;EINVAL:Zero width/height not allowed\x1b\\\x1b[?62;c";
54
+ term.processCapabilityResponse(response);
55
+
56
+ try testing.expectEqualStrings("kitty", term.getTerminalName());
57
+ try testing.expectEqualStrings("0.40.1", term.getTerminalVersion());
58
+ try testing.expect(term.term_info.from_xtversion);
59
+ try testing.expect(term.caps.kitty_keyboard);
60
+ try testing.expect(term.caps.kitty_graphics);
61
+ try testing.expect(term.caps.osc52);
62
+ }
63
+
64
+ test "parseXtversion - full ghostty response" {
65
+ var term = Terminal.init(.{});
66
+ const response = "\x1b[?1016;1$y\x1b[?2027;1$y\x1b[?2031;2$y\x1b[?1004;1$y\x1b[?2004;2$y\x1b[?2026;2$y\x1b[1;1R\x1b[1;1R\x1bP>|ghostty 1.1.3\x1b\\\x1b[?0u\x1b_Gi=1;OK\x1b\\\x1b[?62;22c";
67
+ term.processCapabilityResponse(response);
68
+
69
+ try testing.expectEqualStrings("ghostty", term.getTerminalName());
70
+ try testing.expectEqualStrings("1.1.3", term.getTerminalVersion());
71
+ try testing.expect(term.term_info.from_xtversion);
72
+ }
73
+
74
+ test "environment variables - should be overridden by xtversion" {
75
+ var term = Terminal.init(.{});
76
+
77
+ // First check environment (simulated by setting values directly)
78
+ term.term_info.name_len = 6;
79
+ @memcpy(term.term_info.name[0..6], "vscode");
80
+ term.term_info.version_len = 5;
81
+ @memcpy(term.term_info.version[0..5], "1.0.0");
82
+ term.term_info.from_xtversion = false;
83
+
84
+ try testing.expectEqualStrings("vscode", term.getTerminalName());
85
+ try testing.expectEqualStrings("1.0.0", term.getTerminalVersion());
86
+ try testing.expect(!term.term_info.from_xtversion);
87
+
88
+ // Now process xtversion response - should override
89
+ const response = "\x1bP>|kitty(0.40.1)\x1b\\";
90
+ term.processCapabilityResponse(response);
91
+
92
+ try testing.expectEqualStrings("kitty", term.getTerminalName());
93
+ try testing.expectEqualStrings("0.40.1", term.getTerminalVersion());
94
+ try testing.expect(term.term_info.from_xtversion);
95
+ }
96
+
97
+ test "remote ignores env overrides but accepts capability responses" {
98
+ if (builtin.os.tag == .windows) return error.SkipZigTest;
99
+
100
+ var env = std.process.EnvMap.init(testing.allocator);
101
+ defer env.deinit();
102
+ try env.put("TMUX", "/tmp/tmux-1000/default,12345,0");
103
+ try env.put("TERM_PROGRAM", "iTerm.app");
104
+ try env.put("WT_SESSION", "test-session");
105
+
106
+ var term = Terminal.init(.{ .remote = true, .env_map = &env });
107
+
108
+ try testing.expect(!term.in_tmux);
109
+ try testing.expect(!term.caps.osc52);
110
+ try testing.expect(!term.caps.explicit_cursor_positioning);
111
+
112
+ term.processCapabilityResponse("\x1bP>|kitty(0.40.1)\x1b\\");
113
+ try testing.expect(term.caps.osc52);
114
+ }
115
+
116
+ test "setHostEnvVar applies env overrides in shared library mode" {
117
+ var term = Terminal.init(.{});
118
+ defer term.deinit();
119
+
120
+ try term.setHostEnvVar(testing.allocator, "TERM", "screen");
121
+ try testing.expect(term.skip_graphics_query);
122
+ try testing.expect(term.caps.unicode == .wcwidth);
123
+ try testing.expect(term.caps.explicit_cursor_positioning);
124
+
125
+ try term.setHostEnvVar(testing.allocator, "OPENTUI_FORCE_UNICODE", "1");
126
+ try testing.expect(term.caps.unicode == .unicode);
127
+
128
+ try term.setHostEnvVar(testing.allocator, "OPENTUI_GRAPHICS", "0");
129
+ try testing.expect(term.skip_graphics_query);
130
+ }
131
+
132
+ test "environment overrides - enables hyperlinks for WSL Windows Terminal xterm" {
133
+ var env = std.process.EnvMap.init(testing.allocator);
134
+ defer env.deinit();
135
+ try env.put("WSL_DISTRO_NAME", "Ubuntu");
136
+ try env.put("WT_SESSION", "test-session");
137
+ try env.put("TERM", "xterm-256color");
138
+
139
+ const term = Terminal.init(.{ .env_map = &env });
140
+
141
+ try testing.expect(term.caps.hyperlinks);
142
+ }
143
+
144
+ test "environment overrides - does not enable hyperlinks for WSL without WT_SESSION" {
145
+ var env = std.process.EnvMap.init(testing.allocator);
146
+ defer env.deinit();
147
+ try env.put("WSL_DISTRO_NAME", "Ubuntu");
148
+ try env.put("TERM", "xterm-256color");
149
+
150
+ const term = Terminal.init(.{ .env_map = &env });
151
+
152
+ try testing.expect(!term.caps.hyperlinks);
153
+ }
154
+
155
+ test "environment overrides - does not enable hyperlinks for WSL non-xterm terms" {
156
+ var env = std.process.EnvMap.init(testing.allocator);
157
+ defer env.deinit();
158
+ try env.put("WSL_INTEROP", "/run/WSL/123_interop");
159
+ try env.put("WT_SESSION", "test-session");
160
+ try env.put("TERM", "screen-256color");
161
+
162
+ const term = Terminal.init(.{ .env_map = &env });
163
+
164
+ try testing.expect(!term.caps.hyperlinks);
165
+ }
166
+
167
+ test "parseXtversion - terminal name only" {
168
+ var term = Terminal.init(.{});
169
+ const response = "\x1bP>|wezterm\x1b\\";
170
+ term.processCapabilityResponse(response);
171
+
172
+ try testing.expectEqualStrings("wezterm", term.getTerminalName());
173
+ try testing.expectEqualStrings("", term.getTerminalVersion());
174
+ try testing.expect(term.term_info.from_xtversion);
175
+ try testing.expect(term.caps.osc52);
176
+ }
177
+
178
+ test "parseXtversion - empty response" {
179
+ var term = Terminal.init(.{});
180
+
181
+ const initial_name_len = term.term_info.name_len;
182
+ const initial_version_len = term.term_info.version_len;
183
+
184
+ const response = "\x1bP>|\x1b\\";
185
+ term.processCapabilityResponse(response);
186
+
187
+ try testing.expectEqual(initial_name_len, term.term_info.name_len);
188
+ try testing.expectEqual(initial_version_len, term.term_info.version_len);
189
+ }
190
+
191
+ // Test buffer for capturing terminal output
192
+ const TestWriter = struct {
193
+ buffer: std.ArrayListUnmanaged(u8),
194
+ allocator: std.mem.Allocator,
195
+
196
+ pub fn init(allocator: std.mem.Allocator) TestWriter {
197
+ return .{ .buffer = .{}, .allocator = allocator };
198
+ }
199
+
200
+ pub fn deinit(self: *TestWriter) void {
201
+ self.buffer.deinit(self.allocator);
202
+ }
203
+
204
+ pub fn writeAll(self: *TestWriter, data: []const u8) !void {
205
+ try self.buffer.appendSlice(self.allocator, data);
206
+ }
207
+
208
+ pub fn print(self: *TestWriter, comptime fmt: []const u8, args: anytype) !void {
209
+ try self.buffer.writer(self.allocator).print(fmt, args);
210
+ }
211
+
212
+ pub fn getWritten(self: *TestWriter) []const u8 {
213
+ return self.buffer.items;
214
+ }
215
+
216
+ pub fn reset(self: *TestWriter) void {
217
+ self.buffer.clearRetainingCapacity();
218
+ }
219
+ };
220
+
221
+ test "queryTerminalSend - sends unwrapped queries when not in tmux" {
222
+ // Note: This test may fail if running inside tmux since checkEnvironmentOverrides
223
+ // reads TMUX/TERM env vars. We test the logic directly instead.
224
+ var term = Terminal.init(.{});
225
+
226
+ // Skip test if actually running in tmux
227
+ if (term.in_tmux) return error.SkipZigTest;
228
+
229
+ var writer = TestWriter.init(testing.allocator);
230
+ defer writer.deinit();
231
+
232
+ try term.queryTerminalSend(&writer);
233
+
234
+ const output = writer.getWritten();
235
+
236
+ // Should contain xtversion
237
+ try testing.expect(std.mem.indexOf(u8, output, "\x1b[>0q") != null);
238
+
239
+ // Should contain unwrapped DECRQM queries (single ESC)
240
+ try testing.expect(std.mem.indexOf(u8, output, "\x1b[?1016$p") != null);
241
+ try testing.expect(std.mem.indexOf(u8, output, "\x1b[?2027$p") != null);
242
+ try testing.expect(std.mem.indexOf(u8, output, "\x1b[?u") != null);
243
+
244
+ // Should NOT contain tmux DCS wrapper
245
+ try testing.expect(std.mem.indexOf(u8, output, "\x1bPtmux;") == null);
246
+
247
+ // Should mark capability queries as pending
248
+ try testing.expect(term.capability_queries_pending);
249
+ }
250
+
251
+ test "queryTerminalSend - sends DCS wrapped queries when in tmux" {
252
+ // Note: This test checks logic when in_tmux is true.
253
+ // We can't easily force in_tmux=true since checkEnvironmentOverrides resets it,
254
+ // so we test this via sendPendingQueries tests instead.
255
+ var term = Terminal.init(.{});
256
+
257
+ // Only run the DCS wrapping test if actually in tmux
258
+ if (!term.in_tmux) return error.SkipZigTest;
259
+
260
+ var writer = TestWriter.init(testing.allocator);
261
+ defer writer.deinit();
262
+
263
+ try term.queryTerminalSend(&writer);
264
+
265
+ const output = writer.getWritten();
266
+
267
+ // Should contain xtversion (unwrapped - used for detection)
268
+ try testing.expect(std.mem.indexOf(u8, output, "\x1b[>0q") != null);
269
+
270
+ // Should contain tmux DCS wrapper start and doubled ESC for queries
271
+ // wrapForTmux wraps all queries together with one DCS envelope
272
+ try testing.expect(std.mem.indexOf(u8, output, "\x1bPtmux;\x1b\x1b[?1016$p") != null);
273
+
274
+ // Should NOT mark capability queries as pending (already sent wrapped)
275
+ try testing.expect(!term.capability_queries_pending);
276
+ }
277
+
278
+ test "sendPendingQueries - sends wrapped queries after tmux detected via xtversion" {
279
+ var term = Terminal.init(.{});
280
+ term.in_tmux = false;
281
+ term.capability_queries_pending = true;
282
+ term.graphics_query_pending = true;
283
+
284
+ // Simulate tmux detected via xtversion
285
+ term.term_info.from_xtversion = true;
286
+ term.term_info.name_len = 4;
287
+ @memcpy(term.term_info.name[0..4], "tmux");
288
+
289
+ var writer = TestWriter.init(testing.allocator);
290
+ defer writer.deinit();
291
+
292
+ const did_send = try term.sendPendingQueries(&writer);
293
+
294
+ try testing.expect(did_send);
295
+
296
+ const output = writer.getWritten();
297
+
298
+ // Should send DCS wrapped capability queries (wrapForTmux wraps all queries together)
299
+ try testing.expect(std.mem.indexOf(u8, output, "\x1bPtmux;\x1b\x1b[?1016$p") != null);
300
+
301
+ // Should send DCS wrapped graphics query
302
+ try testing.expect(std.mem.indexOf(u8, output, "\x1bPtmux;\x1b\x1b_G") != null);
303
+
304
+ // Should clear pending flags
305
+ try testing.expect(!term.capability_queries_pending);
306
+ try testing.expect(!term.graphics_query_pending);
307
+ }
308
+
309
+ test "sendPendingQueries - sends unwrapped graphics query for non-tmux terminal" {
310
+ var term = Terminal.init(.{});
311
+ term.in_tmux = false;
312
+ term.capability_queries_pending = true;
313
+ term.graphics_query_pending = true;
314
+
315
+ // Simulate non-tmux terminal detected via xtversion
316
+ term.term_info.from_xtversion = true;
317
+ term.term_info.name_len = 5;
318
+ @memcpy(term.term_info.name[0..5], "kitty");
319
+
320
+ var writer = TestWriter.init(testing.allocator);
321
+ defer writer.deinit();
322
+
323
+ const did_send = try term.sendPendingQueries(&writer);
324
+
325
+ try testing.expect(did_send);
326
+
327
+ const output = writer.getWritten();
328
+
329
+ // Should NOT send DCS wrapped capability queries (not tmux)
330
+ try testing.expect(std.mem.indexOf(u8, output, "\x1bPtmux;") == null);
331
+
332
+ // Should send unwrapped graphics query
333
+ try testing.expect(std.mem.indexOf(u8, output, "\x1b_Gi=31337") != null);
334
+
335
+ // Should clear pending flags
336
+ try testing.expect(!term.capability_queries_pending);
337
+ try testing.expect(!term.graphics_query_pending);
338
+ }
339
+
340
+ test "sendPendingQueries - sends unwrapped graphics query even without xtversion response" {
341
+ // This covers terminals that support kitty graphics but don't respond to xtversion.
342
+ // The graphics query should still be sent (unwrapped) so we can detect graphics support.
343
+ var term = Terminal.init(.{});
344
+ term.in_tmux = false;
345
+ term.term_info.from_xtversion = false;
346
+ term.capability_queries_pending = true;
347
+ term.graphics_query_pending = true;
348
+
349
+ var writer = TestWriter.init(testing.allocator);
350
+ defer writer.deinit();
351
+
352
+ const did_send = try term.sendPendingQueries(&writer);
353
+
354
+ try testing.expect(did_send);
355
+
356
+ const output = writer.getWritten();
357
+
358
+ // Should send unwrapped graphics query (not tmux, so no DCS wrapper)
359
+ try testing.expect(std.mem.indexOf(u8, output, "\x1b_Gi=31337") != null);
360
+ try testing.expect(std.mem.indexOf(u8, output, "\x1bPtmux;") == null);
361
+
362
+ // Should clear graphics pending flag
363
+ try testing.expect(!term.graphics_query_pending);
364
+
365
+ // Capability queries should NOT be re-sent (no xtversion means we don't know if tmux,
366
+ // but they were already sent unwrapped in queryTerminalSend)
367
+ try testing.expect(!term.capability_queries_pending);
368
+ }
369
+
370
+ test "sendPendingQueries - skips graphics when skip_graphics_query is set" {
371
+ var term = Terminal.init(.{});
372
+ term.in_tmux = true;
373
+ term.skip_graphics_query = true;
374
+ term.graphics_query_pending = true;
375
+ term.capability_queries_pending = false;
376
+
377
+ var writer = TestWriter.init(testing.allocator);
378
+ defer writer.deinit();
379
+
380
+ const did_send = try term.sendPendingQueries(&writer);
381
+
382
+ try testing.expect(!did_send);
383
+
384
+ const output = writer.getWritten();
385
+ try testing.expect(std.mem.indexOf(u8, output, "Gi=31337") == null);
386
+ }
387
+
388
+ test "isXtversionTmux - detects tmux from xtversion" {
389
+ var term = Terminal.init(.{});
390
+
391
+ // Not from xtversion
392
+ term.term_info.from_xtversion = false;
393
+ term.term_info.name_len = 4;
394
+ @memcpy(term.term_info.name[0..4], "tmux");
395
+ try testing.expect(!term.isXtversionTmux());
396
+
397
+ // From xtversion but not tmux
398
+ term.term_info.from_xtversion = true;
399
+ term.term_info.name_len = 5;
400
+ @memcpy(term.term_info.name[0..5], "kitty");
401
+ try testing.expect(!term.isXtversionTmux());
402
+
403
+ // From xtversion and is tmux
404
+ term.term_info.name_len = 4;
405
+ @memcpy(term.term_info.name[0..4], "tmux");
406
+ try testing.expect(term.isXtversionTmux());
407
+ }
408
+
409
+ // ============================================================================
410
+ // GRAPHEME CURSOR POSITIONING CAPABILITY TESTS
411
+ // ============================================================================
412
+
413
+ test "processCapabilityResponse - tmux sets explicit_cursor_positioning" {
414
+ var term: Terminal = .{};
415
+
416
+ term.caps.explicit_cursor_positioning = false;
417
+ term.caps.unicode = .unicode;
418
+
419
+ const response = "\x1bP>|tmux 3.5a\x1b\\";
420
+ term.processCapabilityResponse(response);
421
+
422
+ try testing.expect(term.caps.explicit_cursor_positioning);
423
+ try testing.expectEqual(utf8.WidthMethod.wcwidth, term.caps.unicode);
424
+ }
425
+
426
+ test "processCapabilityResponse - alacritty sets explicit_cursor_positioning" {
427
+ var term: Terminal = .{};
428
+
429
+ term.caps.explicit_cursor_positioning = false;
430
+
431
+ const response = "\x1bP>|alacritty 0.13.0\x1b\\";
432
+ term.processCapabilityResponse(response);
433
+
434
+ try testing.expect(term.caps.explicit_cursor_positioning);
435
+ }
436
+
437
+ test "processCapabilityResponse - kitty does not set explicit_cursor_positioning" {
438
+ var term: Terminal = .{};
439
+
440
+ term.caps.explicit_cursor_positioning = false;
441
+
442
+ const response = "\x1bP>|kitty(0.40.1)\x1b\\";
443
+ term.processCapabilityResponse(response);
444
+
445
+ try testing.expect(!term.caps.explicit_cursor_positioning);
446
+ }
447
+
448
+ test "processCapabilityResponse - ghostty does not set explicit_cursor_positioning" {
449
+ var term: Terminal = .{};
450
+
451
+ term.caps.explicit_cursor_positioning = false;
452
+
453
+ const response = "\x1bP>|ghostty 1.1.3\x1b\\";
454
+ term.processCapabilityResponse(response);
455
+
456
+ try testing.expect(!term.caps.explicit_cursor_positioning);
457
+ }
458
+
459
+ // ============================================================================
460
+ // CLIPBOARD (OSC 52) TESTS
461
+ // ============================================================================
462
+
463
+ test "writeClipboard - generates basic OSC52 sequence" {
464
+ if (builtin.os.tag == .windows) return error.SkipZigTest;
465
+
466
+ var env = std.process.EnvMap.init(testing.allocator);
467
+ defer env.deinit();
468
+
469
+ var term = Terminal.init(.{ .env_map = &env });
470
+ term.caps.osc52 = true;
471
+
472
+ var writer = TestWriter.init(testing.allocator);
473
+ defer writer.deinit();
474
+
475
+ try term.writeClipboard(&writer, .clipboard, "aGVsbG8=");
476
+
477
+ const output = writer.getWritten();
478
+ // Should be: ESC]52;c;aGVsbG8=ESC\
479
+ try testing.expectEqualStrings("\x1b]52;c;aGVsbG8=\x1b\\", output);
480
+ }
481
+
482
+ test "writeClipboard - supports different targets" {
483
+ if (builtin.os.tag == .windows) return error.SkipZigTest;
484
+
485
+ var env = std.process.EnvMap.init(testing.allocator);
486
+ defer env.deinit();
487
+
488
+ var term = Terminal.init(.{ .env_map = &env });
489
+ term.caps.osc52 = true;
490
+
491
+ var writer = TestWriter.init(testing.allocator);
492
+ defer writer.deinit();
493
+
494
+ try term.writeClipboard(&writer, .primary, "test");
495
+ try testing.expect(std.mem.indexOf(u8, writer.getWritten(), "\x1b]52;p;") != null);
496
+
497
+ writer.reset();
498
+ try term.writeClipboard(&writer, .secondary, "test");
499
+ try testing.expect(std.mem.indexOf(u8, writer.getWritten(), "\x1b]52;s;") != null);
500
+
501
+ writer.reset();
502
+ try term.writeClipboard(&writer, .query, "test");
503
+ try testing.expect(std.mem.indexOf(u8, writer.getWritten(), "\x1b]52;q;") != null);
504
+ }
505
+
506
+ test "writeClipboard - returns error when OSC52 not supported" {
507
+ if (builtin.os.tag == .windows) return error.SkipZigTest;
508
+
509
+ var term = Terminal.init(.{});
510
+ term.caps.osc52 = false;
511
+
512
+ var writer = TestWriter.init(testing.allocator);
513
+ defer writer.deinit();
514
+
515
+ const result = term.writeClipboard(&writer, .clipboard, "test");
516
+ try testing.expectError(error.NotSupported, result);
517
+ }
518
+
519
+ test "writeClipboard - wraps in DCS passthrough for tmux" {
520
+ if (builtin.os.tag == .windows) return error.SkipZigTest;
521
+
522
+ var env = std.process.EnvMap.init(testing.allocator);
523
+ defer env.deinit();
524
+ try env.put("TMUX", "/tmp/tmux-1000/default,12345,0");
525
+
526
+ var term = Terminal.init(.{ .env_map = &env });
527
+ term.caps.osc52 = true;
528
+
529
+ var writer = TestWriter.init(testing.allocator);
530
+ defer writer.deinit();
531
+
532
+ try term.writeClipboard(&writer, .clipboard, "test");
533
+
534
+ const output = writer.getWritten();
535
+ // Should start with tmux DCS wrapper
536
+ try testing.expect(std.mem.startsWith(u8, output, "\x1bPtmux;"));
537
+ // Should end with DCS terminator
538
+ try testing.expect(std.mem.endsWith(u8, output, "\x1b\\"));
539
+ // Should have doubled ESC characters inside
540
+ try testing.expect(std.mem.indexOf(u8, output, "\x1b\x1b") != null);
541
+ }
542
+
543
+ test "writeClipboard - wraps in DCS passthrough for GNU Screen" {
544
+ if (builtin.os.tag == .windows) return error.SkipZigTest;
545
+
546
+ var env = std.process.EnvMap.init(testing.allocator);
547
+ defer env.deinit();
548
+ try env.put("STY", "12345.pts-0.hostname");
549
+
550
+ var term = Terminal.init(.{ .env_map = &env });
551
+ term.caps.osc52 = true;
552
+
553
+ var writer = TestWriter.init(testing.allocator);
554
+ defer writer.deinit();
555
+
556
+ try term.writeClipboard(&writer, .clipboard, "test");
557
+
558
+ const output = writer.getWritten();
559
+ // Should start with DCS (but not tmux prefix)
560
+ try testing.expect(std.mem.startsWith(u8, output, "\x1bP"));
561
+ try testing.expect(!std.mem.startsWith(u8, output, "\x1bPtmux;"));
562
+ // Should end with DCS terminator
563
+ try testing.expect(std.mem.endsWith(u8, output, "\x1b\\"));
564
+ // Should have doubled ESC characters
565
+ try testing.expect(std.mem.indexOf(u8, output, "\x1b\x1b") != null);
566
+ }
567
+
568
+ test "writeClipboard - handles tmux sessions" {
569
+ if (builtin.os.tag == .windows) return error.SkipZigTest;
570
+
571
+ var env = std.process.EnvMap.init(testing.allocator);
572
+ defer env.deinit();
573
+ try env.put("TMUX", "/tmp/tmux-1000/default,12345,0");
574
+
575
+ var term = Terminal.init(.{ .env_map = &env });
576
+ term.caps.osc52 = true;
577
+
578
+ var writer = TestWriter.init(testing.allocator);
579
+ defer writer.deinit();
580
+
581
+ try term.writeClipboard(&writer, .clipboard, "test");
582
+
583
+ const output = writer.getWritten();
584
+ // Should have tmux DCS wrapper
585
+ try testing.expect(std.mem.startsWith(u8, output, "\x1bPtmux;"));
586
+ // Should end with DCS terminator
587
+ try testing.expect(std.mem.endsWith(u8, output, "\x1b\\"));
588
+ // Should have doubled ESC characters
589
+ try testing.expect(std.mem.indexOf(u8, output, "\x1b\x1b") != null);
590
+ }
591
+
592
+ test "caps.osc52 - clipboard capability flag" {
593
+ var term = Terminal.init(.{});
594
+
595
+ term.caps.osc52 = false;
596
+ try testing.expect(!term.caps.osc52);
597
+
598
+ term.caps.osc52 = true;
599
+ try testing.expect(term.caps.osc52);
600
+ }
601
+
602
+ fn countSubstring(haystack: []const u8, needle: []const u8) usize {
603
+ var count: usize = 0;
604
+ var i: usize = 0;
605
+ while (i < haystack.len) {
606
+ if (std.mem.startsWith(u8, haystack[i..], needle)) {
607
+ count += 1;
608
+ i += needle.len;
609
+ } else {
610
+ i += 1;
611
+ }
612
+ }
613
+ return count;
614
+ }
615
+
616
+ test "queryTerminalSend - skips OSC 66 queries when OPENTUI_FORCE_EXPLICIT_WIDTH=false" {
617
+ if (builtin.os.tag == .windows) return error.SkipZigTest;
618
+
619
+ var env = std.process.EnvMap.init(testing.allocator);
620
+ defer env.deinit();
621
+ try env.put("OPENTUI_FORCE_EXPLICIT_WIDTH", "false");
622
+
623
+ var term = Terminal.init(.{ .env_map = &env });
624
+
625
+ var writer = TestWriter.init(testing.allocator);
626
+ defer writer.deinit();
627
+
628
+ try term.queryTerminalSend(&writer);
629
+
630
+ const output = writer.getWritten();
631
+
632
+ // Should not contain OSC 66 queries
633
+ try testing.expect(std.mem.indexOf(u8, output, "\x1b]66;") == null);
634
+
635
+ // Should still contain other queries
636
+ try testing.expect(std.mem.indexOf(u8, output, "\x1b[>0q") != null); // xtversion
637
+
638
+ // Verify the flag was set correctly
639
+ try testing.expect(term.skip_explicit_width_query);
640
+ try testing.expect(!term.caps.explicit_width);
641
+ }
642
+
643
+ test "queryTerminalSend - sends OSC 66 queries by default" {
644
+ if (builtin.os.tag == .windows) return error.SkipZigTest;
645
+
646
+ var env = std.process.EnvMap.init(testing.allocator);
647
+ defer env.deinit();
648
+
649
+ var term = Terminal.init(.{ .env_map = &env });
650
+
651
+ var writer = TestWriter.init(testing.allocator);
652
+ defer writer.deinit();
653
+
654
+ try term.queryTerminalSend(&writer);
655
+
656
+ const output = writer.getWritten();
657
+
658
+ // Should contain OSC 66 explicit width query
659
+ try testing.expect(std.mem.indexOf(u8, output, "\x1b]66;w=1; \x1b\\") != null);
660
+
661
+ // Should contain OSC 66 scaled text query
662
+ try testing.expect(std.mem.indexOf(u8, output, "\x1b]66;s=2; \x1b\\") != null);
663
+
664
+ // Verify the flag was not set
665
+ try testing.expect(!term.skip_explicit_width_query);
666
+ }
667
+
668
+ test "queryTerminalSend - sends OSC 66 queries when OPENTUI_FORCE_EXPLICIT_WIDTH=true" {
669
+ if (builtin.os.tag == .windows) return error.SkipZigTest;
670
+
671
+ var env = std.process.EnvMap.init(testing.allocator);
672
+ defer env.deinit();
673
+ try env.put("OPENTUI_FORCE_EXPLICIT_WIDTH", "true");
674
+
675
+ var term = Terminal.init(.{ .env_map = &env });
676
+
677
+ var writer = TestWriter.init(testing.allocator);
678
+ defer writer.deinit();
679
+
680
+ try term.queryTerminalSend(&writer);
681
+
682
+ const output = writer.getWritten();
683
+
684
+ // Should contain OSC 66 queries
685
+ try testing.expect(std.mem.indexOf(u8, output, "\x1b]66;w=1; \x1b\\") != null);
686
+ try testing.expect(std.mem.indexOf(u8, output, "\x1b]66;s=2; \x1b\\") != null);
687
+
688
+ // Verify the capability was forced on
689
+ try testing.expect(term.caps.explicit_width);
690
+ try testing.expect(!term.skip_explicit_width_query);
691
+ }
692
+
693
+ test "setMouseMode - enable without movement keeps click/drag only" {
694
+ var term = Terminal.init(.{});
695
+ var writer = TestWriter.init(testing.allocator);
696
+ defer writer.deinit();
697
+
698
+ try term.setMouseMode(&writer, true, false);
699
+
700
+ const output = writer.getWritten();
701
+ const idx_disable_any = std.mem.indexOf(u8, output, ansi.ANSI.disableAnyEventTracking).?;
702
+ const idx_enable_mouse = std.mem.indexOf(u8, output, ansi.ANSI.enableMouseTracking).?;
703
+ const idx_enable_button = std.mem.indexOf(u8, output, ansi.ANSI.enableButtonEventTracking).?;
704
+ const idx_enable_sgr = std.mem.indexOf(u8, output, ansi.ANSI.enableSGRMouseMode).?;
705
+ try testing.expect(std.mem.indexOf(u8, output, ansi.ANSI.enableAnyEventTracking) == null);
706
+ try testing.expect(idx_disable_any < idx_enable_mouse);
707
+ try testing.expect(idx_enable_mouse < idx_enable_button);
708
+ try testing.expect(idx_enable_button < idx_enable_sgr);
709
+
710
+ try testing.expect(term.state.mouse);
711
+ try testing.expect(!term.state.mouse_movement);
712
+ }
713
+
714
+ test "setMouseMode - enable with movement enables any-event tracking" {
715
+ var term = Terminal.init(.{});
716
+ var writer = TestWriter.init(testing.allocator);
717
+ defer writer.deinit();
718
+
719
+ try term.setMouseMode(&writer, true, true);
720
+
721
+ const output = writer.getWritten();
722
+ const idx_enable_mouse = std.mem.indexOf(u8, output, ansi.ANSI.enableMouseTracking).?;
723
+ const idx_enable_button = std.mem.indexOf(u8, output, ansi.ANSI.enableButtonEventTracking).?;
724
+ const idx_enable_any = std.mem.indexOf(u8, output, ansi.ANSI.enableAnyEventTracking).?;
725
+ const idx_enable_sgr = std.mem.indexOf(u8, output, ansi.ANSI.enableSGRMouseMode).?;
726
+ try testing.expect(idx_enable_mouse < idx_enable_button);
727
+ try testing.expect(idx_enable_button < idx_enable_any);
728
+ try testing.expect(idx_enable_any < idx_enable_sgr);
729
+ try testing.expect(std.mem.indexOf(u8, output, ansi.ANSI.disableAnyEventTracking) == null);
730
+
731
+ try testing.expect(term.state.mouse);
732
+ try testing.expect(term.state.mouse_movement);
733
+ }
734
+
735
+ test "restoreTerminalModes - respects mouse movement setting" {
736
+ var term = Terminal.init(.{});
737
+ term.state.mouse = true;
738
+ term.state.mouse_movement = false;
739
+
740
+ var writer = TestWriter.init(testing.allocator);
741
+ defer writer.deinit();
742
+
743
+ try term.restoreTerminalModes(&writer);
744
+
745
+ const output = writer.getWritten();
746
+ const idx_disable_any = std.mem.indexOf(u8, output, ansi.ANSI.disableAnyEventTracking).?;
747
+ const idx_enable_mouse = std.mem.indexOf(u8, output, ansi.ANSI.enableMouseTracking).?;
748
+ const idx_enable_button = std.mem.indexOf(u8, output, ansi.ANSI.enableButtonEventTracking).?;
749
+ const idx_enable_sgr = std.mem.indexOf(u8, output, ansi.ANSI.enableSGRMouseMode).?;
750
+ try testing.expect(idx_disable_any < idx_enable_mouse);
751
+ try testing.expect(idx_enable_mouse < idx_enable_button);
752
+ try testing.expect(idx_enable_button < idx_enable_sgr);
753
+ try testing.expect(std.mem.indexOf(u8, output, ansi.ANSI.enableAnyEventTracking) == null);
754
+ }