@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,662 @@
1
+ import { test, expect } from "bun:test"
2
+ import { InternalKeyHandler, KeyEvent } from "./KeyHandler.js"
3
+ import { type ParseKeypressOptions, parseKeypress } from "./parse.keypress.js"
4
+ import { decodePasteBytes } from "./paste.js"
5
+ import { createTestRenderer } from "../testing/test-renderer.js"
6
+ import { pasteBytes } from "../testing/mock-keys.js"
7
+
8
+ const { renderer, mockInput } = await createTestRenderer({})
9
+
10
+ function createKeyHandler(): InternalKeyHandler {
11
+ return new InternalKeyHandler()
12
+ }
13
+
14
+ function dispatchInput(handler: InternalKeyHandler, data: string, options: ParseKeypressOptions = {}): boolean {
15
+ const parsedKey = parseKeypress(data, options)
16
+ if (!parsedKey) {
17
+ return false
18
+ }
19
+
20
+ return handler.processParsedKey(parsedKey)
21
+ }
22
+
23
+ test("KeyHandler - parsed input emits keypress events", () => {
24
+ const handler = new InternalKeyHandler()
25
+
26
+ let receivedKey: KeyEvent | undefined
27
+ handler.on("keypress", (key: KeyEvent) => {
28
+ receivedKey = key
29
+ })
30
+
31
+ dispatchInput(handler, "a")
32
+
33
+ expect(receivedKey).toMatchObject({
34
+ name: "a",
35
+ ctrl: false,
36
+ meta: false,
37
+ shift: false,
38
+ option: false,
39
+ number: false,
40
+ sequence: "a",
41
+ raw: "a",
42
+ eventType: "press",
43
+ })
44
+ })
45
+
46
+ test("KeyHandler - emits keypress events", () => {
47
+ const handler = createKeyHandler()
48
+
49
+ let receivedKey: KeyEvent | undefined
50
+ handler.on("keypress", (key: KeyEvent) => {
51
+ receivedKey = key
52
+ })
53
+
54
+ dispatchInput(handler, "a")
55
+
56
+ expect(receivedKey).toMatchObject({
57
+ name: "a",
58
+ ctrl: false,
59
+ meta: false,
60
+ shift: false,
61
+ option: false,
62
+ number: false,
63
+ sequence: "a",
64
+ raw: "a",
65
+ eventType: "press",
66
+ })
67
+ })
68
+
69
+ test("KeyHandler - handles paste via processPaste", async () => {
70
+ const handler = createKeyHandler()
71
+
72
+ let receivedPaste: Uint8Array | undefined
73
+ handler.on("paste", (event) => {
74
+ receivedPaste = event.bytes
75
+ })
76
+
77
+ handler.processPaste(pasteBytes("pasted content"))
78
+
79
+ expect(receivedPaste).toEqual(pasteBytes("pasted content"))
80
+ })
81
+
82
+ test("KeyHandler - processPaste handles content directly", () => {
83
+ const handler = createKeyHandler()
84
+
85
+ let receivedPaste: Uint8Array | undefined
86
+ handler.on("paste", (event) => {
87
+ receivedPaste = event.bytes
88
+ })
89
+
90
+ // processPaste receives the full content, no chunking
91
+ handler.processPaste(pasteBytes("chunk1chunk2chunk3"))
92
+
93
+ expect(receivedPaste).toEqual(pasteBytes("chunk1chunk2chunk3"))
94
+ })
95
+
96
+ test("KeyHandler - preserves raw ANSI bytes in paste", () => {
97
+ const handler = createKeyHandler()
98
+
99
+ let receivedPaste: Uint8Array | undefined
100
+ handler.on("paste", (event) => {
101
+ receivedPaste = event.bytes
102
+ })
103
+
104
+ handler.processPaste(pasteBytes("text with \x1b[31mred\x1b[0m color"))
105
+
106
+ expect(receivedPaste).toEqual(pasteBytes("text with \x1b[31mred\x1b[0m color"))
107
+ })
108
+
109
+ test("KeyHandler - constructor creates a handler", () => {
110
+ const handler = createKeyHandler()
111
+
112
+ expect(handler).toBeDefined()
113
+ })
114
+
115
+ test("KeyHandler - handles string input", () => {
116
+ const handler = createKeyHandler()
117
+
118
+ let receivedKey: KeyEvent | undefined
119
+ handler.on("keypress", (key: KeyEvent) => {
120
+ receivedKey = key
121
+ })
122
+
123
+ dispatchInput(handler, "c")
124
+
125
+ expect(receivedKey).toMatchObject({
126
+ name: "c",
127
+ ctrl: false,
128
+ meta: false,
129
+ shift: false,
130
+ option: false,
131
+ number: false,
132
+ sequence: "c",
133
+ raw: "c",
134
+ eventType: "press",
135
+ })
136
+ })
137
+
138
+ test("KeyHandler - event inheritance from EventEmitter", () => {
139
+ const handler = createKeyHandler()
140
+
141
+ expect(typeof handler.on).toBe("function")
142
+ expect(typeof handler.emit).toBe("function")
143
+ expect(typeof handler.removeListener).toBe("function")
144
+ })
145
+
146
+ test("KeyHandler - preventDefault stops propagation", () => {
147
+ const handler = createKeyHandler()
148
+
149
+ let globalHandlerCalled = false
150
+ let secondHandlerCalled = false
151
+
152
+ handler.on("keypress", (key: KeyEvent) => {
153
+ globalHandlerCalled = true
154
+ key.preventDefault()
155
+ })
156
+
157
+ handler.on("keypress", (key: KeyEvent) => {
158
+ if (!key.defaultPrevented) {
159
+ secondHandlerCalled = true
160
+ }
161
+ })
162
+
163
+ dispatchInput(handler, "a")
164
+
165
+ expect(globalHandlerCalled).toBe(true)
166
+ expect(secondHandlerCalled).toBe(false)
167
+ })
168
+
169
+ test("InternalKeyHandler - onInternal handlers run after regular handlers", () => {
170
+ const handler = createKeyHandler()
171
+
172
+ const callOrder: string[] = []
173
+
174
+ handler.onInternal("keypress", (key: KeyEvent) => {
175
+ callOrder.push("internal")
176
+ })
177
+
178
+ handler.on("keypress", (key: KeyEvent) => {
179
+ callOrder.push("regular")
180
+ })
181
+
182
+ dispatchInput(handler, "a")
183
+
184
+ expect(callOrder).toEqual(["regular", "internal"])
185
+ })
186
+
187
+ test("InternalKeyHandler - preventDefault prevents internal handlers from running", () => {
188
+ const handler = createKeyHandler()
189
+
190
+ let regularHandlerCalled = false
191
+ let internalHandlerCalled = false
192
+
193
+ // Register regular handler that prevents default
194
+ handler.on("keypress", (key: KeyEvent) => {
195
+ regularHandlerCalled = true
196
+ key.preventDefault()
197
+ })
198
+
199
+ // Register internal handler (should not run if prevented)
200
+ handler.onInternal("keypress", (key: KeyEvent) => {
201
+ internalHandlerCalled = true
202
+ })
203
+
204
+ dispatchInput(handler, "a")
205
+
206
+ expect(regularHandlerCalled).toBe(true)
207
+ expect(internalHandlerCalled).toBe(false)
208
+ })
209
+
210
+ test("InternalKeyHandler - multiple internal handlers can be registered", () => {
211
+ const handler = createKeyHandler()
212
+
213
+ let handler1Called = false
214
+ let handler2Called = false
215
+ let handler3Called = false
216
+
217
+ const internalHandler1 = () => {
218
+ handler1Called = true
219
+ }
220
+ const internalHandler2 = () => {
221
+ handler2Called = true
222
+ }
223
+ const internalHandler3 = () => {
224
+ handler3Called = true
225
+ }
226
+
227
+ handler.onInternal("keypress", internalHandler1)
228
+ handler.onInternal("keypress", internalHandler2)
229
+ handler.onInternal("keypress", internalHandler3)
230
+
231
+ dispatchInput(handler, "a")
232
+
233
+ expect(handler1Called).toBe(true)
234
+ expect(handler2Called).toBe(true)
235
+ expect(handler3Called).toBe(true)
236
+ })
237
+
238
+ test("InternalKeyHandler - offInternal removes specific handlers", () => {
239
+ const handler = createKeyHandler()
240
+
241
+ let handler1Called = false
242
+ let handler2Called = false
243
+
244
+ const internalHandler1 = () => {
245
+ handler1Called = true
246
+ }
247
+ const internalHandler2 = () => {
248
+ handler2Called = true
249
+ }
250
+
251
+ handler.onInternal("keypress", internalHandler1)
252
+ handler.onInternal("keypress", internalHandler2)
253
+
254
+ // Remove only handler1
255
+ handler.offInternal("keypress", internalHandler1)
256
+
257
+ dispatchInput(handler, "a")
258
+
259
+ expect(handler1Called).toBe(false)
260
+ expect(handler2Called).toBe(true)
261
+ })
262
+
263
+ test("InternalKeyHandler - emit returns true when there are listeners", () => {
264
+ const handler = createKeyHandler()
265
+
266
+ // No listeners initially
267
+ let hasListeners = handler.emit(
268
+ "keypress",
269
+ new KeyEvent({
270
+ name: "a",
271
+ ctrl: false,
272
+ meta: false,
273
+ shift: false,
274
+ option: false,
275
+ sequence: "a",
276
+ number: false,
277
+ raw: "a",
278
+ eventType: "press",
279
+ source: "raw",
280
+ }),
281
+ )
282
+ expect(hasListeners).toBe(false)
283
+
284
+ // Add regular listener
285
+ handler.on("keypress", () => {})
286
+ hasListeners = handler.emit(
287
+ "keypress",
288
+ new KeyEvent({
289
+ name: "b",
290
+ ctrl: false,
291
+ meta: false,
292
+ shift: false,
293
+ option: false,
294
+ sequence: "b",
295
+ number: false,
296
+ raw: "b",
297
+ eventType: "press",
298
+ source: "raw",
299
+ }),
300
+ )
301
+ expect(hasListeners).toBe(true)
302
+
303
+ // Remove regular listener, add internal listener
304
+ handler.removeAllListeners("keypress")
305
+ handler.onInternal("keypress", () => {})
306
+ hasListeners = handler.emit(
307
+ "keypress",
308
+ new KeyEvent({
309
+ name: "c",
310
+ ctrl: false,
311
+ meta: false,
312
+ shift: false,
313
+ option: false,
314
+ sequence: "c",
315
+ number: false,
316
+ raw: "c",
317
+ eventType: "press",
318
+ source: "raw",
319
+ }),
320
+ )
321
+ expect(hasListeners).toBe(true)
322
+ })
323
+
324
+ test("InternalKeyHandler - paste events work with priority system", () => {
325
+ const handler = createKeyHandler()
326
+
327
+ const callOrder: string[] = []
328
+
329
+ handler.on("paste", (event) => {
330
+ callOrder.push(`regular:${decodePasteBytes(event.bytes)}`)
331
+ })
332
+
333
+ handler.onInternal("paste", (event) => {
334
+ callOrder.push(`internal:${decodePasteBytes(event.bytes)}`)
335
+ })
336
+
337
+ handler.processPaste(pasteBytes("hello"))
338
+
339
+ expect(callOrder).toEqual(["regular:hello", "internal:hello"])
340
+ })
341
+
342
+ test("InternalKeyHandler - paste preventDefault prevents internal handlers", () => {
343
+ const handler = createKeyHandler()
344
+
345
+ let regularHandlerCalled = false
346
+ let internalHandlerCalled = false
347
+ let receivedText = ""
348
+
349
+ handler.on("paste", (event) => {
350
+ regularHandlerCalled = true
351
+ receivedText = decodePasteBytes(event.bytes)
352
+ event.preventDefault()
353
+ })
354
+
355
+ handler.onInternal("paste", (event) => {
356
+ internalHandlerCalled = true
357
+ })
358
+
359
+ handler.processPaste(pasteBytes("test paste"))
360
+
361
+ expect(regularHandlerCalled).toBe(true)
362
+ expect(receivedText).toBe("test paste")
363
+ expect(internalHandlerCalled).toBe(false)
364
+ })
365
+
366
+ test("KeyHandler - emits paste event even with empty content", () => {
367
+ const handler = createKeyHandler()
368
+
369
+ let pasteEventReceived = false
370
+ let receivedPaste: Uint8Array = pasteBytes("not-empty")
371
+
372
+ handler.on("paste", (event) => {
373
+ pasteEventReceived = true
374
+ receivedPaste = event.bytes
375
+ })
376
+
377
+ handler.processPaste(pasteBytes(""))
378
+
379
+ expect(pasteEventReceived).toBe(true)
380
+ expect(receivedPaste).toEqual(pasteBytes(""))
381
+ })
382
+
383
+ test("KeyHandler - filters out mouse events", () => {
384
+ const handler = createKeyHandler()
385
+
386
+ let keypressCount = 0
387
+ handler.on("keypress", () => {
388
+ keypressCount++
389
+ })
390
+
391
+ // Mouse events should not generate keypresses
392
+ dispatchInput(handler, "\x1b[<0;10;5M")
393
+ expect(keypressCount).toBe(0)
394
+
395
+ dispatchInput(handler, "\x1b[<0;10;5m")
396
+ expect(keypressCount).toBe(0)
397
+
398
+ // Old-style mouse: \x1b[M + 3 bytes, then "c" is a separate keypress
399
+ dispatchInput(handler, "\x1b[M ab")
400
+ expect(keypressCount).toBe(0)
401
+
402
+ dispatchInput(handler, "c")
403
+ expect(keypressCount).toBe(1)
404
+
405
+ dispatchInput(handler, "a")
406
+ expect(keypressCount).toBe(2) // Now we have "c" and "a"
407
+ })
408
+
409
+ test("KeyHandler - KeyEvent has source field set to 'raw' by default", () => {
410
+ if (!renderer) {
411
+ throw new Error("Renderer not initialized")
412
+ }
413
+
414
+ let receivedKey: KeyEvent | undefined
415
+ renderer.keyInput.on("keypress", (key: KeyEvent) => {
416
+ receivedKey = key
417
+ })
418
+
419
+ mockInput.pressKey("a")
420
+
421
+ expect(receivedKey).toBeDefined()
422
+ expect(receivedKey?.source).toBe("raw")
423
+ expect(receivedKey?.name).toBe("a")
424
+
425
+ renderer.keyInput.removeAllListeners("keypress")
426
+ })
427
+
428
+ test("KeyHandler - KeyEvent has source field for different key types", () => {
429
+ if (!renderer) {
430
+ throw new Error("Renderer not initialized")
431
+ }
432
+
433
+ const receivedKeys: KeyEvent[] = []
434
+ renderer.keyInput.on("keypress", (key: KeyEvent) => {
435
+ receivedKeys.push(key)
436
+ })
437
+
438
+ // Test various key types
439
+ mockInput.pressKey("a")
440
+ mockInput.pressKey("A")
441
+ mockInput.pressKey("\x1b[A") // Up arrow
442
+ mockInput.pressKey("\x01") // Ctrl+A
443
+
444
+ expect(receivedKeys).toHaveLength(4)
445
+ expect(receivedKeys[0]?.source).toBe("raw")
446
+ expect(receivedKeys[1]?.source).toBe("raw")
447
+ expect(receivedKeys[2]?.source).toBe("raw")
448
+ expect(receivedKeys[3]?.source).toBe("raw")
449
+
450
+ renderer.keyInput.removeAllListeners("keypress")
451
+ })
452
+
453
+ test("KeyHandler - KeyEvent source is 'kitty' when using Kitty keyboard protocol", () => {
454
+ const handler = createKeyHandler()
455
+
456
+ let receivedKey: KeyEvent | undefined
457
+ handler.on("keypress", (key: KeyEvent) => {
458
+ receivedKey = key
459
+ })
460
+
461
+ // Send a Kitty keyboard protocol sequence for 'a' (codepoint 97)
462
+ dispatchInput(handler, "\x1b[97u", { useKittyKeyboard: true })
463
+
464
+ expect(receivedKey).toBeDefined()
465
+ expect(receivedKey?.source).toBe("kitty")
466
+ expect(receivedKey?.name).toBe("a")
467
+ })
468
+
469
+ test("KeyHandler - KeyEvent source is 'raw' for non-Kitty sequences even with Kitty enabled", () => {
470
+ if (!renderer) {
471
+ throw new Error("Renderer not initialized")
472
+ }
473
+
474
+ const receivedKeys: KeyEvent[] = []
475
+ renderer.keyInput.on("keypress", (key: KeyEvent) => {
476
+ receivedKeys.push(key)
477
+ })
478
+
479
+ // Send regular sequences that don't match Kitty protocol
480
+ mockInput.pressKey("a")
481
+ mockInput.pressKey("\x1b[A") // Up arrow (standard ANSI)
482
+
483
+ expect(receivedKeys).toHaveLength(2)
484
+ expect(receivedKeys[0]?.source).toBe("raw")
485
+ expect(receivedKeys[0]?.name).toBe("a")
486
+ expect(receivedKeys[1]?.source).toBe("raw")
487
+ expect(receivedKeys[1]?.name).toBe("up")
488
+
489
+ renderer.keyInput.removeAllListeners("keypress")
490
+ })
491
+
492
+ test("KeyHandler - source field persists through KeyEvent wrapper", () => {
493
+ if (!renderer) {
494
+ throw new Error("Renderer not initialized")
495
+ }
496
+
497
+ let receivedKey: KeyEvent | undefined
498
+ renderer.keyInput.on("keypress", (key: KeyEvent) => {
499
+ receivedKey = key
500
+ })
501
+
502
+ mockInput.pressKey("x")
503
+
504
+ expect(receivedKey).toBeInstanceOf(KeyEvent)
505
+ expect(receivedKey?.source).toBe("raw")
506
+ expect(receivedKey?.name).toBe("x")
507
+
508
+ // Verify it implements ParsedKey interface
509
+ const parsedKey: typeof receivedKey = receivedKey
510
+ expect(parsedKey?.source).toBe("raw")
511
+
512
+ renderer.keyInput.removeAllListeners("keypress")
513
+ })
514
+
515
+ test("KeyHandler - global handler error is caught and logged", () => {
516
+ const handler = createKeyHandler()
517
+
518
+ let handlerCalled = false
519
+ let errorThrown = false
520
+
521
+ // Handler throws an error
522
+ handler.on("keypress", (key: KeyEvent) => {
523
+ handlerCalled = true
524
+ errorThrown = true
525
+ throw new Error("Test error in global handler")
526
+ })
527
+
528
+ // Should not throw - error is caught and logged
529
+ expect(() => dispatchInput(handler, "a")).not.toThrow()
530
+
531
+ expect(handlerCalled).toBe(true)
532
+ expect(errorThrown).toBe(true)
533
+ })
534
+
535
+ test("KeyHandler - renderable handler error does not stop processing", () => {
536
+ const handler = createKeyHandler()
537
+
538
+ let firstInternalCalled = false
539
+ let secondInternalCalled = false
540
+ let errorThrown = false
541
+
542
+ // First internal handler throws
543
+ handler.onInternal("keypress", (key: KeyEvent) => {
544
+ firstInternalCalled = true
545
+ errorThrown = true
546
+ throw new Error("Test error in internal handler")
547
+ })
548
+
549
+ // Second internal handler should still be called
550
+ handler.onInternal("keypress", (key: KeyEvent) => {
551
+ secondInternalCalled = true
552
+ })
553
+
554
+ // Should not throw
555
+ expect(() => dispatchInput(handler, "a")).not.toThrow()
556
+
557
+ expect(firstInternalCalled).toBe(true)
558
+ expect(errorThrown).toBe(true)
559
+ expect(secondInternalCalled).toBe(true)
560
+ })
561
+
562
+ test("KeyHandler - global handler error stops further global handlers but allows internal handlers", () => {
563
+ const handler = createKeyHandler()
564
+
565
+ let globalCalled = false
566
+ let internalCalled = false
567
+
568
+ // Global handler throws - stops further global handlers
569
+ handler.on("keypress", (key: KeyEvent) => {
570
+ globalCalled = true
571
+ throw new Error("Global handler error")
572
+ })
573
+
574
+ // Internal handler should still be called (different priority level)
575
+ handler.onInternal("keypress", (key: KeyEvent) => {
576
+ internalCalled = true
577
+ })
578
+
579
+ // Should not throw - errors are caught
580
+ expect(() => dispatchInput(handler, "a")).not.toThrow()
581
+
582
+ expect(globalCalled).toBe(true)
583
+ expect(internalCalled).toBe(true)
584
+ })
585
+
586
+ test("KeyHandler - paste handler error is caught and logged", () => {
587
+ const handler = createKeyHandler()
588
+
589
+ let handlerCalled = false
590
+
591
+ // Paste handler throws
592
+ handler.on("paste", (event) => {
593
+ handlerCalled = true
594
+ throw new Error("Test error in paste handler")
595
+ })
596
+
597
+ // Should not throw - error is caught and logged
598
+ expect(() => handler.processPaste(pasteBytes("test"))).not.toThrow()
599
+
600
+ expect(handlerCalled).toBe(true)
601
+ })
602
+
603
+ test("KeyHandler - processParsedKey returns true even when handler throws", () => {
604
+ const handler = createKeyHandler()
605
+
606
+ handler.on("keypress", (key: KeyEvent) => {
607
+ throw new Error("Handler error")
608
+ })
609
+
610
+ // Should return true indicating the input was handled (even if handler errored)
611
+ const result = dispatchInput(handler, "a")
612
+ expect(result).toBe(true)
613
+ })
614
+
615
+ test("KeyHandler - internal handler error with preventDefault still respects prevention", () => {
616
+ const handler = createKeyHandler()
617
+
618
+ let globalCalled = false
619
+ let internalCalled = false
620
+
621
+ // Global handler prevents default
622
+ handler.on("keypress", (key: KeyEvent) => {
623
+ globalCalled = true
624
+ key.preventDefault()
625
+ })
626
+
627
+ // Internal handler should not be called (due to preventDefault)
628
+ handler.onInternal("keypress", (key: KeyEvent) => {
629
+ internalCalled = true
630
+ throw new Error("Should not reach here")
631
+ })
632
+
633
+ dispatchInput(handler, "a")
634
+
635
+ expect(globalCalled).toBe(true)
636
+ expect(internalCalled).toBe(false)
637
+ })
638
+
639
+ test("KeyHandler - error in one event type does not prevent other event types from working", () => {
640
+ const handler = createKeyHandler()
641
+
642
+ let keypressCalled = false
643
+ let pasteCalled = false
644
+
645
+ // Keypress handler throws
646
+ handler.on("keypress", (key: KeyEvent) => {
647
+ keypressCalled = true
648
+ throw new Error("Keypress error")
649
+ })
650
+
651
+ // Paste handler should work fine
652
+ handler.on("paste", (event) => {
653
+ pasteCalled = true
654
+ })
655
+
656
+ // Both should not throw - errors are caught and logged
657
+ expect(() => dispatchInput(handler, "a")).not.toThrow()
658
+ expect(() => handler.processPaste(pasteBytes("test"))).not.toThrow()
659
+
660
+ expect(keypressCalled).toBe(true)
661
+ expect(pasteCalled).toBe(true)
662
+ })