@xincli/opentui-core 0.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (476) hide show
  1. package/README.md +63 -0
  2. package/dev/keypress-debug-renderer.ts +148 -0
  3. package/dev/keypress-debug.ts +43 -0
  4. package/dev/print-env-vars.ts +32 -0
  5. package/dev/test-tmux-graphics-334.sh +68 -0
  6. package/dev/test-tmux-theme-queries.sh +151 -0
  7. package/dev/thai-debug-test.ts +68 -0
  8. package/dev/theme-mode.ts +290 -0
  9. package/docs/development.md +144 -0
  10. package/package.json +102 -0
  11. package/prebuilt/aarch64-android/libopentui.so +0 -0
  12. package/scripts/build-android.ts +226 -0
  13. package/scripts/build-native-termux.sh +525 -0
  14. package/scripts/build.ts +530 -0
  15. package/scripts/dist-test.ts +312 -0
  16. package/scripts/package-prebuilt.ts +110 -0
  17. package/scripts/publish.ts +60 -0
  18. package/scripts/test-node-hook.mjs +16 -0
  19. package/scripts/test-node.ts +241 -0
  20. package/scripts/vendor-deps.sh +73 -0
  21. package/src/NativeSpanFeed.ts +375 -0
  22. package/src/Renderable.ts +1878 -0
  23. package/src/__snapshots__/buffer.test.ts.snap +28 -0
  24. package/src/animation/Timeline.test.ts +2709 -0
  25. package/src/animation/Timeline.ts +598 -0
  26. package/src/ansi.ts +22 -0
  27. package/src/audio.ts +479 -0
  28. package/src/benchmark/attenuation-benchmark.ts +81 -0
  29. package/src/benchmark/audio-playback-benchmark.ts +344 -0
  30. package/src/benchmark/box-draw-benchmark.ts +1042 -0
  31. package/src/benchmark/colormatrix-benchmark.ts +123 -0
  32. package/src/benchmark/gain-benchmark.ts +80 -0
  33. package/src/benchmark/latest-all-bench-run.json +707 -0
  34. package/src/benchmark/latest-async-bench-run.json +336 -0
  35. package/src/benchmark/latest-default-bench-run.json +657 -0
  36. package/src/benchmark/latest-large-bench-run.json +707 -0
  37. package/src/benchmark/latest-quick-bench-run.json +207 -0
  38. package/src/benchmark/layout-benchmark.ts +2547 -0
  39. package/src/benchmark/markdown-benchmark.ts +1796 -0
  40. package/src/benchmark/native-span-feed-async-benchmark.ts +355 -0
  41. package/src/benchmark/native-span-feed-benchmark.md +56 -0
  42. package/src/benchmark/native-span-feed-benchmark.ts +596 -0
  43. package/src/benchmark/native-span-feed-compare.ts +280 -0
  44. package/src/benchmark/render-traversal-benchmark.ts +928 -0
  45. package/src/benchmark/text-buffer-render-benchmark.ts +874 -0
  46. package/src/benchmark/text-table-benchmark.ts +948 -0
  47. package/src/buffer.test.ts +292 -0
  48. package/src/buffer.ts +564 -0
  49. package/src/console.test.ts +629 -0
  50. package/src/console.ts +1253 -0
  51. package/src/edit-buffer.test.ts +1852 -0
  52. package/src/edit-buffer.ts +417 -0
  53. package/src/editor-view.test.ts +1056 -0
  54. package/src/editor-view.ts +290 -0
  55. package/src/index.ts +25 -0
  56. package/src/lib/KeyHandler.integration.test.ts +292 -0
  57. package/src/lib/KeyHandler.stopPropagation.test.ts +289 -0
  58. package/src/lib/KeyHandler.test.ts +662 -0
  59. package/src/lib/KeyHandler.ts +222 -0
  60. package/src/lib/RGBA.test.ts +60 -0
  61. package/src/lib/RGBA.ts +343 -0
  62. package/src/lib/ascii.font.ts +330 -0
  63. package/src/lib/border.test.ts +83 -0
  64. package/src/lib/border.ts +170 -0
  65. package/src/lib/bunfs.test.ts +27 -0
  66. package/src/lib/bunfs.ts +18 -0
  67. package/src/lib/clipboard.test.ts +63 -0
  68. package/src/lib/clipboard.ts +41 -0
  69. package/src/lib/clock.ts +35 -0
  70. package/src/lib/data-paths.test.ts +133 -0
  71. package/src/lib/data-paths.ts +109 -0
  72. package/src/lib/debounce.ts +106 -0
  73. package/src/lib/detect-links.test.ts +98 -0
  74. package/src/lib/detect-links.ts +56 -0
  75. package/src/lib/env.test.ts +228 -0
  76. package/src/lib/env.ts +209 -0
  77. package/src/lib/extmarks-history.ts +51 -0
  78. package/src/lib/extmarks-multiwidth.test.ts +324 -0
  79. package/src/lib/extmarks.test.ts +3547 -0
  80. package/src/lib/extmarks.ts +861 -0
  81. package/src/lib/fonts/block.json +405 -0
  82. package/src/lib/fonts/grid.json +265 -0
  83. package/src/lib/fonts/huge.json +741 -0
  84. package/src/lib/fonts/pallet.json +314 -0
  85. package/src/lib/fonts/shade.json +591 -0
  86. package/src/lib/fonts/slick.json +321 -0
  87. package/src/lib/fonts/tiny.json +69 -0
  88. package/src/lib/hast-styled-text.ts +59 -0
  89. package/src/lib/index.ts +22 -0
  90. package/src/lib/keybinding.internal.test.ts +342 -0
  91. package/src/lib/keybinding.internal.ts +182 -0
  92. package/src/lib/objects-in-viewport.test.ts +789 -0
  93. package/src/lib/objects-in-viewport.ts +153 -0
  94. package/src/lib/output.capture.ts +58 -0
  95. package/src/lib/parse.keypress-kitty.protocol.test.ts +347 -0
  96. package/src/lib/parse.keypress-kitty.test.ts +712 -0
  97. package/src/lib/parse.keypress-kitty.ts +470 -0
  98. package/src/lib/parse.keypress.test.ts +2020 -0
  99. package/src/lib/parse.keypress.ts +480 -0
  100. package/src/lib/parse.mouse.test.ts +552 -0
  101. package/src/lib/parse.mouse.ts +232 -0
  102. package/src/lib/paste.ts +18 -0
  103. package/src/lib/queue.ts +65 -0
  104. package/src/lib/render-geometry.ts +36 -0
  105. package/src/lib/renderable.validations.test.ts +87 -0
  106. package/src/lib/renderable.validations.ts +83 -0
  107. package/src/lib/scroll-acceleration.ts +98 -0
  108. package/src/lib/selection.ts +261 -0
  109. package/src/lib/singleton.ts +34 -0
  110. package/src/lib/stdin-parser.test.ts +2439 -0
  111. package/src/lib/stdin-parser.ts +2007 -0
  112. package/src/lib/styled-text.ts +178 -0
  113. package/src/lib/terminal-capability-detection.test.ts +226 -0
  114. package/src/lib/terminal-capability-detection.ts +98 -0
  115. package/src/lib/terminal-palette.test.ts +954 -0
  116. package/src/lib/terminal-palette.ts +441 -0
  117. package/src/lib/tree-sitter/assets/README.md +119 -0
  118. package/src/lib/tree-sitter/assets/javascript/highlights.scm +205 -0
  119. package/src/lib/tree-sitter/assets/javascript/tree-sitter-javascript.wasm +0 -0
  120. package/src/lib/tree-sitter/assets/markdown/highlights.scm +150 -0
  121. package/src/lib/tree-sitter/assets/markdown/injections.scm +27 -0
  122. package/src/lib/tree-sitter/assets/markdown/tree-sitter-markdown.wasm +0 -0
  123. package/src/lib/tree-sitter/assets/markdown_inline/highlights.scm +115 -0
  124. package/src/lib/tree-sitter/assets/markdown_inline/tree-sitter-markdown_inline.wasm +0 -0
  125. package/src/lib/tree-sitter/assets/typescript/highlights.scm +604 -0
  126. package/src/lib/tree-sitter/assets/typescript/tree-sitter-typescript.wasm +0 -0
  127. package/src/lib/tree-sitter/assets/update.ts +360 -0
  128. package/src/lib/tree-sitter/assets/zig/highlights.scm +284 -0
  129. package/src/lib/tree-sitter/assets/zig/tree-sitter-zig.wasm +0 -0
  130. package/src/lib/tree-sitter/assets.d.ts +9 -0
  131. package/src/lib/tree-sitter/cache.test.ts +291 -0
  132. package/src/lib/tree-sitter/client.test.ts +1434 -0
  133. package/src/lib/tree-sitter/client.ts +847 -0
  134. package/src/lib/tree-sitter/default-parsers.ts +133 -0
  135. package/src/lib/tree-sitter/download-utils.ts +148 -0
  136. package/src/lib/tree-sitter/index.ts +75 -0
  137. package/src/lib/tree-sitter/parser.worker.ts +1098 -0
  138. package/src/lib/tree-sitter/parsers-config.ts +81 -0
  139. package/src/lib/tree-sitter/resolve-ft.test.ts +55 -0
  140. package/src/lib/tree-sitter/resolve-ft.ts +189 -0
  141. package/src/lib/tree-sitter/types.ts +132 -0
  142. package/src/lib/tree-sitter/update-assets.ts +10 -0
  143. package/src/lib/tree-sitter-styled-text.test.ts +1253 -0
  144. package/src/lib/tree-sitter-styled-text.ts +314 -0
  145. package/src/lib/validate-dir-name.ts +55 -0
  146. package/src/lib/yoga.options.test.ts +628 -0
  147. package/src/lib/yoga.options.ts +346 -0
  148. package/src/native-event-worker-repro.test.ts +48 -0
  149. package/src/native-event-worker-repro.worker.ts +9 -0
  150. package/src/native-handle.test.ts +221 -0
  151. package/src/platform/ffi.test.ts +516 -0
  152. package/src/platform/ffi.ts +653 -0
  153. package/src/platform/runtime.test.ts +52 -0
  154. package/src/platform/runtime.ts +121 -0
  155. package/src/platform/test.ts +45 -0
  156. package/src/platform/worker-handler-cleanup.fixture.ts +12 -0
  157. package/src/platform/worker-onmessage-startup.fixture.ts +10 -0
  158. package/src/platform/worker-startup.fixture.ts +9 -0
  159. package/src/platform/worker.node-test.ts +153 -0
  160. package/src/platform/worker.ts +425 -0
  161. package/src/plugins/core-slot.ts +579 -0
  162. package/src/plugins/registry.ts +402 -0
  163. package/src/plugins/types.ts +46 -0
  164. package/src/post/effects.ts +948 -0
  165. package/src/post/filters.ts +512 -0
  166. package/src/post/matrices.ts +288 -0
  167. package/src/renderables/ASCIIFont.ts +219 -0
  168. package/src/renderables/Box.test.ts +474 -0
  169. package/src/renderables/Box.ts +353 -0
  170. package/src/renderables/Code.test.ts +2388 -0
  171. package/src/renderables/Code.ts +555 -0
  172. package/src/renderables/Diff.regression.test.ts +381 -0
  173. package/src/renderables/Diff.test.ts +3212 -0
  174. package/src/renderables/Diff.ts +1278 -0
  175. package/src/renderables/EditBufferRenderable.test.ts +288 -0
  176. package/src/renderables/EditBufferRenderable.ts +1152 -0
  177. package/src/renderables/FrameBuffer.ts +47 -0
  178. package/src/renderables/Input.test.ts +1310 -0
  179. package/src/renderables/Input.ts +273 -0
  180. package/src/renderables/LineNumberRenderable.ts +725 -0
  181. package/src/renderables/Markdown.ts +2144 -0
  182. package/src/renderables/ScrollBar.ts +423 -0
  183. package/src/renderables/ScrollBox.ts +903 -0
  184. package/src/renderables/Select.test.ts +1134 -0
  185. package/src/renderables/Select.ts +535 -0
  186. package/src/renderables/Slider.test.ts +456 -0
  187. package/src/renderables/Slider.ts +342 -0
  188. package/src/renderables/TabSelect.test.ts +238 -0
  189. package/src/renderables/TabSelect.ts +447 -0
  190. package/src/renderables/Text.selection-buffer.test.ts +118 -0
  191. package/src/renderables/Text.test.ts +2662 -0
  192. package/src/renderables/Text.ts +147 -0
  193. package/src/renderables/TextBufferRenderable.ts +504 -0
  194. package/src/renderables/TextNode.test.ts +1137 -0
  195. package/src/renderables/TextNode.ts +379 -0
  196. package/src/renderables/TextTable.test.ts +1411 -0
  197. package/src/renderables/TextTable.ts +1434 -0
  198. package/src/renderables/Textarea.ts +425 -0
  199. package/src/renderables/TimeToFirstDraw.ts +89 -0
  200. package/src/renderables/__snapshots__/Code.test.ts.snap +13 -0
  201. package/src/renderables/__snapshots__/Diff.test.ts.snap +785 -0
  202. package/src/renderables/__snapshots__/Text.test.ts.snap +421 -0
  203. package/src/renderables/__snapshots__/TextTable.test.ts.snap +215 -0
  204. package/src/renderables/__tests__/Code.test.ts +55 -0
  205. package/src/renderables/__tests__/LineNumberRenderable.scrollbox-simple.test.ts +144 -0
  206. package/src/renderables/__tests__/LineNumberRenderable.scrollbox.test.ts +827 -0
  207. package/src/renderables/__tests__/LineNumberRenderable.test.ts +1906 -0
  208. package/src/renderables/__tests__/LineNumberRenderable.wrapping.test.ts +85 -0
  209. package/src/renderables/__tests__/Markdown.code-colors.test.ts +288 -0
  210. package/src/renderables/__tests__/Markdown.test.ts +4175 -0
  211. package/src/renderables/__tests__/MultiRenderable.selection.test.ts +87 -0
  212. package/src/renderables/__tests__/Textarea.buffer.test.ts +683 -0
  213. package/src/renderables/__tests__/Textarea.destroyed-events.test.ts +675 -0
  214. package/src/renderables/__tests__/Textarea.editing.test.ts +2120 -0
  215. package/src/renderables/__tests__/Textarea.error-handling.test.ts +35 -0
  216. package/src/renderables/__tests__/Textarea.events.test.ts +738 -0
  217. package/src/renderables/__tests__/Textarea.highlights.test.ts +590 -0
  218. package/src/renderables/__tests__/Textarea.keybinding.test.ts +3275 -0
  219. package/src/renderables/__tests__/Textarea.paste.test.ts +357 -0
  220. package/src/renderables/__tests__/Textarea.rendering.test.ts +1927 -0
  221. package/src/renderables/__tests__/Textarea.scroll.test.ts +733 -0
  222. package/src/renderables/__tests__/Textarea.selection.test.ts +1589 -0
  223. package/src/renderables/__tests__/Textarea.stress.test.ts +670 -0
  224. package/src/renderables/__tests__/Textarea.undo-redo.test.ts +383 -0
  225. package/src/renderables/__tests__/Textarea.visual-lines.test.ts +310 -0
  226. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.code.test.ts.snap +221 -0
  227. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.scrollbox-simple.test.ts.snap +89 -0
  228. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.scrollbox.test.ts.snap +457 -0
  229. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.test.ts.snap +158 -0
  230. package/src/renderables/__tests__/__snapshots__/Textarea.rendering.test.ts.snap +387 -0
  231. package/src/renderables/__tests__/markdown-parser.test.ts +241 -0
  232. package/src/renderables/__tests__/renderable-test-utils.ts +60 -0
  233. package/src/renderables/composition/README.md +8 -0
  234. package/src/renderables/composition/VRenderable.ts +32 -0
  235. package/src/renderables/composition/constructs.ts +127 -0
  236. package/src/renderables/composition/vnode.ts +277 -0
  237. package/src/renderables/index.ts +23 -0
  238. package/src/renderables/markdown-parser.ts +79 -0
  239. package/src/renderer-theme-mode.ts +199 -0
  240. package/src/renderer.ts +4975 -0
  241. package/src/runtime-plugin-support-configure.ts +63 -0
  242. package/src/runtime-plugin-support.ts +13 -0
  243. package/src/runtime-plugin.ts +626 -0
  244. package/src/specs/terminal-startup.md +64 -0
  245. package/src/syntax-style.test.ts +841 -0
  246. package/src/syntax-style.ts +274 -0
  247. package/src/testing/README.md +219 -0
  248. package/src/testing/bun-test-node.ts +880 -0
  249. package/src/testing/capture-spans.test.ts +216 -0
  250. package/src/testing/integration.test.ts +276 -0
  251. package/src/testing/manual-clock.ts +117 -0
  252. package/src/testing/mock-keys.test.ts +1378 -0
  253. package/src/testing/mock-keys.ts +457 -0
  254. package/src/testing/mock-mouse.test.ts +218 -0
  255. package/src/testing/mock-mouse.ts +247 -0
  256. package/src/testing/mock-tree-sitter-client.ts +81 -0
  257. package/src/testing/spy.ts +13 -0
  258. package/src/testing/terminal-capabilities.ts +47 -0
  259. package/src/testing/test-recorder.test.ts +410 -0
  260. package/src/testing/test-recorder.ts +133 -0
  261. package/src/testing/test-renderer.ts +375 -0
  262. package/src/testing/test-renderer.wait.test.ts +278 -0
  263. package/src/testing/test-streams.ts +31 -0
  264. package/src/testing.ts +9 -0
  265. package/src/tests/__snapshots__/absolute-positioning.snapshot.test.ts.snap +481 -0
  266. package/src/tests/__snapshots__/renderable.snapshot.test.ts.snap +19 -0
  267. package/src/tests/__snapshots__/scrollbox.test.ts.snap +29 -0
  268. package/src/tests/absolute-positioning.snapshot.test.ts +638 -0
  269. package/src/tests/allocator-stats.test.ts +53 -0
  270. package/src/tests/audio.test.ts +303 -0
  271. package/src/tests/destroy-during-render.test.ts +200 -0
  272. package/src/tests/destroy-on-exit.fixture.ts +36 -0
  273. package/src/tests/destroy-on-exit.test.ts +62 -0
  274. package/src/tests/ffi-borrowed-pointer-callsites.test.ts +153 -0
  275. package/src/tests/hover-cursor.test.ts +98 -0
  276. package/src/tests/native-backed-measurement-lifecycle.test.ts +133 -0
  277. package/src/tests/native-backed-measurement-parity.test.ts +322 -0
  278. package/src/tests/native-span-feed-async.test.ts +173 -0
  279. package/src/tests/native-span-feed-close.test.ts +120 -0
  280. package/src/tests/native-span-feed-coverage.test.ts +227 -0
  281. package/src/tests/native-span-feed-edge-cases.test.ts +384 -0
  282. package/src/tests/native-span-feed-use-after-free.test.ts +45 -0
  283. package/src/tests/opacity.test.ts +123 -0
  284. package/src/tests/renderable.snapshot.test.ts +524 -0
  285. package/src/tests/renderable.test.ts +1851 -0
  286. package/src/tests/renderer.clock.test.ts +270 -0
  287. package/src/tests/renderer.console-startup.test.ts +2151 -0
  288. package/src/tests/renderer.control.test.ts +458 -0
  289. package/src/tests/renderer.core-slot-binding.test.ts +962 -0
  290. package/src/tests/renderer.cursor.test.ts +26 -0
  291. package/src/tests/renderer.custom-stdout.test.ts +1112 -0
  292. package/src/tests/renderer.destroy-during-render.test.ts +147 -0
  293. package/src/tests/renderer.focus-restore.test.ts +257 -0
  294. package/src/tests/renderer.focus.test.ts +329 -0
  295. package/src/tests/renderer.idle.test.ts +219 -0
  296. package/src/tests/renderer.input.test.ts +2615 -0
  297. package/src/tests/renderer.kitty-flags.test.ts +195 -0
  298. package/src/tests/renderer.lifecycle.test.ts +34 -0
  299. package/src/tests/renderer.mouse.test.ts +1315 -0
  300. package/src/tests/renderer.notifications.test.ts +27 -0
  301. package/src/tests/renderer.palette.test.ts +1199 -0
  302. package/src/tests/renderer.remote.test.ts +247 -0
  303. package/src/tests/renderer.render-stats.test.ts +146 -0
  304. package/src/tests/renderer.scrollback-surface.test.ts +474 -0
  305. package/src/tests/renderer.selection.test.ts +138 -0
  306. package/src/tests/renderer.slot-registry.test.ts +684 -0
  307. package/src/tests/renderer.tracker.test.ts +202 -0
  308. package/src/tests/renderer.useMouse.test.ts +83 -0
  309. package/src/tests/runtime-plugin-node-modules-cycle.fixture.ts +76 -0
  310. package/src/tests/runtime-plugin-node-modules-import-like-string.fixture.ts +48 -0
  311. package/src/tests/runtime-plugin-node-modules-mjs.fixture.ts +43 -0
  312. package/src/tests/runtime-plugin-node-modules-no-bare-rewrite.fixture.ts +67 -0
  313. package/src/tests/runtime-plugin-node-modules-package-type-cache.fixture.ts +72 -0
  314. package/src/tests/runtime-plugin-node-modules-runtime-specifier.fixture.ts +44 -0
  315. package/src/tests/runtime-plugin-node-modules-scoped-package-bare-rewrite.fixture.ts +85 -0
  316. package/src/tests/runtime-plugin-path-alias.fixture.ts +43 -0
  317. package/src/tests/runtime-plugin-resolve-roots.fixture.ts +65 -0
  318. package/src/tests/runtime-plugin-support-configure.fixture.ts +31 -0
  319. package/src/tests/runtime-plugin-support-late-addition.fixture.ts +17 -0
  320. package/src/tests/runtime-plugin-support.fixture.ts +11 -0
  321. package/src/tests/runtime-plugin-support.test.ts +54 -0
  322. package/src/tests/runtime-plugin-windows-file-url.fixture.ts +30 -0
  323. package/src/tests/runtime-plugin.fixture.ts +40 -0
  324. package/src/tests/runtime-plugin.test.ts +369 -0
  325. package/src/tests/scrollbox-culling-bug.test.ts +114 -0
  326. package/src/tests/scrollbox-hitgrid-resize.test.ts +136 -0
  327. package/src/tests/scrollbox-hitgrid.test.ts +909 -0
  328. package/src/tests/scrollbox.test.ts +1895 -0
  329. package/src/tests/wrap-resize-perf.test.ts +276 -0
  330. package/src/tests/yoga-api-coverage.test.ts +409 -0
  331. package/src/tests/yoga-callback-stress.test.ts +122 -0
  332. package/src/tests/yoga-ffi.test.ts +117 -0
  333. package/src/tests/yoga-setters.test.ts +921 -0
  334. package/src/tests/yoga-upstream/YGAlignBaselineTest.test.ts +124 -0
  335. package/src/tests/yoga-upstream/YGComputedBorderTest.test.ts +27 -0
  336. package/src/tests/yoga-upstream/YGComputedMarginTest.test.ts +27 -0
  337. package/src/tests/yoga-upstream/YGComputedPaddingTest.test.ts +27 -0
  338. package/src/tests/yoga-upstream/YGDirtiedTest.test.ts +157 -0
  339. package/src/tests/yoga-upstream/YGErrataTest.test.ts +40 -0
  340. package/src/tests/yoga-upstream/YGFlexBasisAuto.test.ts +23 -0
  341. package/src/tests/yoga-upstream/YGHasNewLayout.test.ts +81 -0
  342. package/src/tests/yoga-upstream/YGMeasureCacheTest.test.ts +31 -0
  343. package/src/tests/yoga-upstream/YGMeasureTest.test.ts +70 -0
  344. package/src/tests/yoga-upstream/generated/YGAbsolutePositionTest.test.ts +1864 -0
  345. package/src/tests/yoga-upstream/generated/YGAlignContentTest.test.ts +5829 -0
  346. package/src/tests/yoga-upstream/generated/YGAlignItemsTest.test.ts +2444 -0
  347. package/src/tests/yoga-upstream/generated/YGAlignSelfTest.test.ts +293 -0
  348. package/src/tests/yoga-upstream/generated/YGAndroidNewsFeed.test.ts +315 -0
  349. package/src/tests/yoga-upstream/generated/YGAspectRatioTest.test.ts +231 -0
  350. package/src/tests/yoga-upstream/generated/YGAutoTest.test.ts +347 -0
  351. package/src/tests/yoga-upstream/generated/YGBorderTest.test.ts +256 -0
  352. package/src/tests/yoga-upstream/generated/YGBoxSizingTest.test.ts +2747 -0
  353. package/src/tests/yoga-upstream/generated/YGDimensionTest.test.ts +129 -0
  354. package/src/tests/yoga-upstream/generated/YGDisplayContentsTest.test.ts +109 -0
  355. package/src/tests/yoga-upstream/generated/YGDisplayTest.test.ts +1097 -0
  356. package/src/tests/yoga-upstream/generated/YGFlexDirectionTest.test.ts +4562 -0
  357. package/src/tests/yoga-upstream/generated/YGFlexTest.test.ts +677 -0
  358. package/src/tests/yoga-upstream/generated/YGFlexWrapTest.test.ts +2071 -0
  359. package/src/tests/yoga-upstream/generated/YGGapTest.test.ts +3303 -0
  360. package/src/tests/yoga-upstream/generated/YGIntrinsicSizeTest.test.ts +582 -0
  361. package/src/tests/yoga-upstream/generated/YGJustifyContentTest.test.ts +2150 -0
  362. package/src/tests/yoga-upstream/generated/YGMarginTest.test.ts +1963 -0
  363. package/src/tests/yoga-upstream/generated/YGMinMaxDimensionTest.test.ts +1446 -0
  364. package/src/tests/yoga-upstream/generated/YGPaddingTest.test.ts +354 -0
  365. package/src/tests/yoga-upstream/generated/YGPercentageTest.test.ts +1760 -0
  366. package/src/tests/yoga-upstream/generated/YGRoundingTest.test.ts +1161 -0
  367. package/src/tests/yoga-upstream/generated/YGSizeOverflowTest.test.ts +207 -0
  368. package/src/tests/yoga-upstream/generated/YGStaticPositionTest.test.ts +6338 -0
  369. package/src/tests/yoga-upstream/tools/MeasureCounter.ts +54 -0
  370. package/src/tests/yoga-upstream/tools/utils.ts +81 -0
  371. package/src/text-buffer-view.test.ts +722 -0
  372. package/src/text-buffer-view.ts +193 -0
  373. package/src/text-buffer.test.ts +512 -0
  374. package/src/text-buffer.ts +250 -0
  375. package/src/types.ts +199 -0
  376. package/src/utils.ts +88 -0
  377. package/src/yoga.ts +1146 -0
  378. package/src/zig/ansi.zig +502 -0
  379. package/src/zig/audio.zig +1206 -0
  380. package/src/zig/bench/README.md +50 -0
  381. package/src/zig/bench/buffer-color-blending_bench.zig +350 -0
  382. package/src/zig/bench/buffer-draw-box_bench.zig +786 -0
  383. package/src/zig/bench/buffer-draw-text-buffer_bench.zig +894 -0
  384. package/src/zig/bench/edit-buffer_bench.zig +476 -0
  385. package/src/zig/bench/editor-view_bench.zig +169 -0
  386. package/src/zig/bench/native-span-feed_bench.zig +107 -0
  387. package/src/zig/bench/rope-markers_bench.zig +713 -0
  388. package/src/zig/bench/rope_bench.zig +514 -0
  389. package/src/zig/bench/styled-text_bench.zig +476 -0
  390. package/src/zig/bench/text-buffer-coords_bench.zig +362 -0
  391. package/src/zig/bench/text-buffer-view_bench.zig +459 -0
  392. package/src/zig/bench/text-chunk-graphemes_bench.zig +272 -0
  393. package/src/zig/bench/utf8_bench.zig +799 -0
  394. package/src/zig/bench-utils.zig +431 -0
  395. package/src/zig/bench.zig +223 -0
  396. package/src/zig/buffer-methods.zig +215 -0
  397. package/src/zig/buffer.zig +2515 -0
  398. package/src/zig/build.zig +700 -0
  399. package/src/zig/build.zig.zon +19 -0
  400. package/src/zig/edit-buffer.zig +900 -0
  401. package/src/zig/editor-view.zig +812 -0
  402. package/src/zig/event-bus.zig +28 -0
  403. package/src/zig/event-emitter.zig +65 -0
  404. package/src/zig/file-logger.zig +92 -0
  405. package/src/zig/grapheme.zig +838 -0
  406. package/src/zig/handles.zig +267 -0
  407. package/src/zig/lib.zig +2813 -0
  408. package/src/zig/link.zig +349 -0
  409. package/src/zig/logger.zig +43 -0
  410. package/src/zig/mem-registry.zig +126 -0
  411. package/src/zig/miniaudio_shim.c +21 -0
  412. package/src/zig/native-renderable.zig +112 -0
  413. package/src/zig/native-span-feed-bench-lib.zig +7 -0
  414. package/src/zig/native-span-feed.zig +747 -0
  415. package/src/zig/renderer-output.zig +677 -0
  416. package/src/zig/renderer.zig +2106 -0
  417. package/src/zig/rope.zig +1220 -0
  418. package/src/zig/split-scrollback.zig +88 -0
  419. package/src/zig/syntax-style.zig +174 -0
  420. package/src/zig/terminal.zig +1652 -0
  421. package/src/zig/test.zig +82 -0
  422. package/src/zig/tests/README.md +18 -0
  423. package/src/zig/tests/ansi_test.zig +18 -0
  424. package/src/zig/tests/audio_test.zig +439 -0
  425. package/src/zig/tests/buffer-methods_test.zig +1111 -0
  426. package/src/zig/tests/buffer_test.zig +2926 -0
  427. package/src/zig/tests/edit-buffer-history_test.zig +299 -0
  428. package/src/zig/tests/edit-buffer_test.zig +1688 -0
  429. package/src/zig/tests/editor-view_test.zig +3454 -0
  430. package/src/zig/tests/event-emitter_test.zig +249 -0
  431. package/src/zig/tests/grapheme_test.zig +1329 -0
  432. package/src/zig/tests/handles_test.zig +123 -0
  433. package/src/zig/tests/link_test.zig +220 -0
  434. package/src/zig/tests/mem-registry_test.zig +473 -0
  435. package/src/zig/tests/memory_leak_regression_test.zig +234 -0
  436. package/src/zig/tests/native-renderable_test.zig +16 -0
  437. package/src/zig/tests/native-span-feed_test.zig +1266 -0
  438. package/src/zig/tests/renderer_test.zig +2604 -0
  439. package/src/zig/tests/rope-nested_test.zig +712 -0
  440. package/src/zig/tests/rope_fuzz_test.zig +238 -0
  441. package/src/zig/tests/rope_test.zig +2362 -0
  442. package/src/zig/tests/segment-merge.test.zig +148 -0
  443. package/src/zig/tests/split-scrollback_test.zig +70 -0
  444. package/src/zig/tests/syntax-style_test.zig +558 -0
  445. package/src/zig/tests/terminal_test.zig +1489 -0
  446. package/src/zig/tests/test-renderer.zig +126 -0
  447. package/src/zig/tests/text-buffer-drawing_test.zig +3291 -0
  448. package/src/zig/tests/text-buffer-highlights_test.zig +706 -0
  449. package/src/zig/tests/text-buffer-iterators_test.zig +776 -0
  450. package/src/zig/tests/text-buffer-segment_test.zig +320 -0
  451. package/src/zig/tests/text-buffer-selection_test.zig +1056 -0
  452. package/src/zig/tests/text-buffer-selection_viewport_test.zig +358 -0
  453. package/src/zig/tests/text-buffer-view_test.zig +3672 -0
  454. package/src/zig/tests/text-buffer_test.zig +2191 -0
  455. package/src/zig/tests/unicode-width-map.zon +3909 -0
  456. package/src/zig/tests/utf8_no_zwj_test.zig +260 -0
  457. package/src/zig/tests/utf8_test.zig +4060 -0
  458. package/src/zig/tests/utf8_wcwidth_cursor_test.zig +267 -0
  459. package/src/zig/tests/utf8_wcwidth_test.zig +357 -0
  460. package/src/zig/tests/word-wrap-editing_test.zig +498 -0
  461. package/src/zig/tests/wrap-cache-perf_test.zig +113 -0
  462. package/src/zig/tests/yoga_test.zig +65 -0
  463. package/src/zig/text-buffer-iterators.zig +496 -0
  464. package/src/zig/text-buffer-segment.zig +403 -0
  465. package/src/zig/text-buffer-view.zig +1428 -0
  466. package/src/zig/text-buffer.zig +1272 -0
  467. package/src/zig/utf8.zig +1954 -0
  468. package/src/zig/utils.zig +12 -0
  469. package/src/zig/uucode-stub.zig +76 -0
  470. package/src/zig/vendor/miniaudio/miniaudio.h +93468 -0
  471. package/src/zig/yoga.zig +658 -0
  472. package/src/zig-structs.ts +381 -0
  473. package/src/zig.ts +5260 -0
  474. package/tsconfig.build.json +17 -0
  475. package/tsconfig.json +27 -0
  476. package/tsconfig.node-test.json +138 -0
@@ -0,0 +1,480 @@
1
+ // Copied from https://github.com/enquirer/enquirer/blob/36785f3399a41cd61e9d28d1eb9c2fcd73d69b4c/lib/keypress.js
2
+ import { Buffer } from "node:buffer"
3
+ import { kittyNamedSingleStrokeKeys, parseKittyKeyboard } from "./parse.keypress-kitty.js"
4
+
5
+ const metaKeyCodeRe = /^(?:\x1b)([a-zA-Z0-9])$/
6
+
7
+ const fnKeyRe = /^(?:\x1b+)(O|N|\[|\[\[)(?:(\d+)(?:;(\d+))?([~^$])|(?:1;)?(\d+)?([a-zA-Z]))/
8
+
9
+ const keyName: Record<string, string> = {
10
+ /* xterm/gnome ESC O letter */
11
+ OP: "f1",
12
+ OQ: "f2",
13
+ OR: "f3",
14
+ OS: "f4",
15
+ /* xterm/rxvt ESC [ number ~ */
16
+ "[11~": "f1",
17
+ "[12~": "f2",
18
+ "[13~": "f3",
19
+ "[14~": "f4",
20
+ /* from Cygwin and used in libuv */
21
+ "[[A": "f1",
22
+ "[[B": "f2",
23
+ "[[C": "f3",
24
+ "[[D": "f4",
25
+ "[[E": "f5",
26
+ /* common */
27
+ "[15~": "f5",
28
+ "[17~": "f6",
29
+ "[18~": "f7",
30
+ "[19~": "f8",
31
+ "[20~": "f9",
32
+ "[21~": "f10",
33
+ "[23~": "f11",
34
+ "[24~": "f12",
35
+ "[29~": "menu",
36
+ "[57427~": "clear",
37
+ /* xterm ESC [ letter */
38
+ "[A": "up",
39
+ "[B": "down",
40
+ "[C": "right",
41
+ "[D": "left",
42
+ "[E": "clear",
43
+ "[F": "end",
44
+ "[H": "home",
45
+ "[P": "f1",
46
+ "[Q": "f2",
47
+ "[S": "f4",
48
+ /* xterm/gnome ESC O letter */
49
+ OA: "up",
50
+ OB: "down",
51
+ OC: "right",
52
+ OD: "left",
53
+ OE: "clear",
54
+ OF: "end",
55
+ OH: "home",
56
+ /* VT100 application keypad (SS3) — sent when terminal enables DECKPAM (ESC =).
57
+ * macOS Terminal.app and other xterm-based terminals emit these when running
58
+ * full-screen apps with the alternate screen. */
59
+ OM: "return",
60
+ Oj: "*",
61
+ Ok: "+",
62
+ Ol: ",",
63
+ Om: "-",
64
+ On: ".",
65
+ Oo: "/",
66
+ Op: "0",
67
+ Oq: "1",
68
+ Or: "2",
69
+ Os: "3",
70
+ Ot: "4",
71
+ Ou: "5",
72
+ Ov: "6",
73
+ Ow: "7",
74
+ Ox: "8",
75
+ Oy: "9",
76
+ OX: "=",
77
+ /* xterm/rxvt ESC [ number ~ */
78
+ "[1~": "home",
79
+ "[2~": "insert",
80
+ "[3~": "delete",
81
+ "[4~": "end",
82
+ "[5~": "pageup",
83
+ "[6~": "pagedown",
84
+ /* putty */
85
+ "[[5~": "pageup",
86
+ "[[6~": "pagedown",
87
+ /* rxvt */
88
+ "[7~": "home",
89
+ "[8~": "end",
90
+ /* rxvt keys with modifiers */
91
+ "[a": "up",
92
+ "[b": "down",
93
+ "[c": "right",
94
+ "[d": "left",
95
+ "[e": "clear",
96
+ /* option + arrow keys (old style) */
97
+ f: "right",
98
+ b: "left",
99
+ p: "up",
100
+ n: "down",
101
+
102
+ "[2$": "insert",
103
+ "[3$": "delete",
104
+ "[5$": "pageup",
105
+ "[6$": "pagedown",
106
+ "[7$": "home",
107
+ "[8$": "end",
108
+
109
+ Oa: "up",
110
+ Ob: "down",
111
+ Oc: "right",
112
+ Od: "left",
113
+ Oe: "clear",
114
+
115
+ "[2^": "insert",
116
+ "[3^": "delete",
117
+ "[5^": "pageup",
118
+ "[6^": "pagedown",
119
+ "[7^": "home",
120
+ "[8^": "end",
121
+ /* misc. */
122
+ "[Z": "tab",
123
+ }
124
+
125
+ export const nonAlphanumericKeys = [...Object.values(keyName), "backspace"]
126
+
127
+ export const terminalNamedSingleStrokeKeys = [
128
+ ...new Set(["return", "linefeed", "tab", "escape", "space", ...nonAlphanumericKeys, ...kittyNamedSingleStrokeKeys]),
129
+ ]
130
+
131
+ const isShiftKey = (code: string) => {
132
+ return ["[a", "[b", "[c", "[d", "[e", "[2$", "[3$", "[5$", "[6$", "[7$", "[8$", "[Z"].includes(code)
133
+ }
134
+
135
+ const isCtrlKey = (code: string) => {
136
+ return ["Oa", "Ob", "Oc", "Od", "Oe", "[2^", "[3^", "[5^", "[6^", "[7^", "[8^"].includes(code)
137
+ }
138
+
139
+ // Map raw control bytes to the key names that bindings expect. Terminals send
140
+ // Ctrl+A..Ctrl+Z as 0x01..0x1a, and they send Ctrl+\\..Ctrl+_ as 0x1c..0x1f.
141
+ // The ESC-prefixed meta+ctrl path reuses this mapping, so the raw and meta
142
+ // forms stay aligned.
143
+ const getCtrlKeyName = (charCode: number): string | undefined => {
144
+ if (charCode === 0) {
145
+ return "space"
146
+ }
147
+
148
+ if (charCode >= 1 && charCode <= 26) {
149
+ return String.fromCharCode(charCode + "a".charCodeAt(0) - 1)
150
+ }
151
+
152
+ if (charCode >= 28 && charCode <= 31) {
153
+ return String.fromCharCode(charCode + 64)
154
+ }
155
+
156
+ return undefined
157
+ }
158
+
159
+ export type KeyEventType = "press" | "repeat" | "release"
160
+
161
+ export interface ParsedKey {
162
+ name: string
163
+ ctrl: boolean
164
+ meta: boolean
165
+ shift: boolean
166
+ option: boolean
167
+ sequence: string
168
+ number: boolean
169
+ raw: string
170
+ eventType: KeyEventType
171
+ source: "raw" | "kitty"
172
+ code?: string
173
+ super?: boolean
174
+ hyper?: boolean
175
+ capsLock?: boolean
176
+ numLock?: boolean
177
+ // Kitty's base-layout codepoint as a Unicode number. Example: 99 means "c".
178
+ // This lets shortcut matching recover Ctrl+C from an event whose printed name
179
+ // is something else under the active layout or IME.
180
+ baseCode?: number
181
+ repeated?: boolean
182
+ }
183
+
184
+ export type ParseKeypressOptions = {
185
+ useKittyKeyboard?: boolean
186
+ }
187
+
188
+ // Printable characters for VT100 SS3 application-keypad sequences.
189
+ // When the terminal is in application keypad mode (DECKPAM / ESC =), numpad keys
190
+ // send these SS3 codes instead of raw ASCII characters. The keys map to the same
191
+ // printable output as their regular-keyboard equivalents.
192
+ const ss3NumpadPrintable: Record<string, string> = {
193
+ Op: "0",
194
+ Oq: "1",
195
+ Or: "2",
196
+ Os: "3",
197
+ Ot: "4",
198
+ Ou: "5",
199
+ Ov: "6",
200
+ Ow: "7",
201
+ Ox: "8",
202
+ Oy: "9",
203
+ Oj: "*",
204
+ Ok: "+",
205
+ Ol: ",",
206
+ Om: "-",
207
+ On: ".",
208
+ Oo: "/",
209
+ OX: "=",
210
+ }
211
+
212
+ const modifyOtherKeysRe = /^\x1b\[27;(\d+);(\d+)~$/
213
+
214
+ export const parseKeypress = (s: Buffer | string = "", options: ParseKeypressOptions = {}): ParsedKey | null => {
215
+ let parts
216
+
217
+ if (Buffer.isBuffer(s)) {
218
+ if (s[0]! > 127 && s[1] === undefined) {
219
+ ;(s[0] as unknown as number) -= 128
220
+ s = "\x1b" + String(s)
221
+ } else {
222
+ s = String(s)
223
+ }
224
+ } else if (s !== undefined && typeof s !== "string") {
225
+ s = String(s)
226
+ } else if (!s) {
227
+ s = ""
228
+ }
229
+
230
+ // Filter out mouse events (SGR and basic)
231
+ // Complete SGR mouse: ESC[<btn;x;yM or ESC[<btn;x;ym
232
+ if (/^\x1b\[<\d+;\d+;\d+[Mm]$/.test(s)) {
233
+ return null
234
+ }
235
+ // Complete SGR mouse continuation without leading ESC. This can occur when
236
+ // ESC was flushed separately on timeout and the rest of the sequence arrived later.
237
+ if (/^\[<\d+;\d+;\d+[Mm]$/.test(s)) {
238
+ return null
239
+ }
240
+ // Incomplete/partial SGR mouse sequences (flushed by the zig parser when
241
+ // a new ESC arrives before the sequence is complete). These start with
242
+ // ESC[< followed by digits/semicolons but lack the terminal M/m.
243
+ if (/^\x1b\[<[\d;]*$/.test(s)) {
244
+ return null
245
+ }
246
+ // Incomplete/partial SGR mouse continuations without ESC.
247
+ if (/^\[<[\d;]*$/.test(s)) {
248
+ return null
249
+ }
250
+ if (s.startsWith("\x1b[M") && s.length >= 6) {
251
+ return null
252
+ }
253
+
254
+ // Filter out terminal response sequences (not keyboard events)
255
+ // These are responses to terminal queries and should not be treated as key presses
256
+
257
+ // Window/cell size reports: ESC[4;height;width t or ESC[8;rows;cols t
258
+ if (/^\x1b\[\d+;\d+;\d+t$/.test(s)) {
259
+ return null
260
+ }
261
+
262
+ // Cursor position reports (DSR): ESC[row;col R
263
+ if (/^\x1b\[\d+;\d+R$/.test(s)) {
264
+ return null
265
+ }
266
+
267
+ // Device Attributes (DA) responses: ESC[?...c
268
+ if (/^\x1b\[\?[\d;]+c$/.test(s)) {
269
+ return null
270
+ }
271
+
272
+ // Mode reports: ESC[?...;...$y
273
+ if (/^\x1b\[\?[\d;]+\$y$/.test(s)) {
274
+ return null
275
+ }
276
+
277
+ // Focus events: ESC[I (focus in), ESC[O (focus out)
278
+ // Note: ESC[O is also used for SS3 sequences (like arrow keys), but those have a character after O
279
+ if (s === "\x1b[I" || s === "\x1b[O") {
280
+ return null
281
+ }
282
+
283
+ // OSC (Operating System Command) responses: ESC]...ESC\ or ESC]...BEL
284
+ if (/^\x1b\][\d;].*(\x1b\\|\x07)$/.test(s)) {
285
+ return null
286
+ }
287
+
288
+ // Bracketed paste mode markers: ESC[200~ (start), ESC[201~ (end)
289
+ if (s === "\x1b[200~" || s === "\x1b[201~") {
290
+ return null
291
+ }
292
+
293
+ const key: ParsedKey = {
294
+ name: "",
295
+ ctrl: false,
296
+ meta: false,
297
+ shift: false,
298
+ option: false,
299
+ number: false,
300
+ sequence: s,
301
+ raw: s,
302
+ eventType: "press",
303
+ source: "raw",
304
+ }
305
+
306
+ key.sequence = key.sequence || s || key.name
307
+
308
+ const ctrlKeyName = s.length === 1 ? getCtrlKeyName(s.charCodeAt(0)) : undefined
309
+ const metaCtrlKeyName = s.length === 2 && s[0] === "\x1b" ? getCtrlKeyName(s.charCodeAt(1)) : undefined
310
+
311
+ // Check for Kitty keyboard protocol if enabled
312
+ if (options.useKittyKeyboard) {
313
+ const kittyResult = parseKittyKeyboard(s)
314
+ if (kittyResult) {
315
+ return kittyResult
316
+ }
317
+ }
318
+
319
+ // Check for modifyOtherKeys sequences (CSI u protocol variant)
320
+ // Format: CSI 27 ; modifier ; code ~
321
+ // This is sent by terminals (xterm, iTerm2, Ghostty, etc.) with modifyOtherKeys mode enabled
322
+ // to encode modified versions of keys that don't normally have modifier variants
323
+ // Examples: CSI 27;2;13~ (shift+enter), CSI 27;5;13~ (ctrl+enter), CSI 27;5;27~ (ctrl+escape)
324
+ const modifyOtherKeysMatch = modifyOtherKeysRe.exec(s)
325
+ if (modifyOtherKeysMatch) {
326
+ const modifier = parseInt(modifyOtherKeysMatch[1]!, 10) - 1
327
+ const charCode = parseInt(modifyOtherKeysMatch[2]!, 10)
328
+
329
+ key.ctrl = !!(modifier & 4)
330
+ key.meta = !!(modifier & 2) // Alt/Option sets meta
331
+ key.shift = !!(modifier & 1)
332
+ key.option = !!(modifier & 2)
333
+ key.super = !!(modifier & 8)
334
+ key.hyper = !!(modifier & 16)
335
+
336
+ // Handle common keys by their ASCII codes
337
+ if (charCode === 13) {
338
+ key.name = "return"
339
+ } else if (charCode === 27) {
340
+ key.name = "escape"
341
+ } else if (charCode === 9) {
342
+ key.name = "tab"
343
+ } else if (charCode === 32) {
344
+ key.name = "space"
345
+ } else if (charCode === 127 || charCode === 8) {
346
+ key.name = "backspace"
347
+ } else {
348
+ // For other character codes, use the character itself
349
+ const char = String.fromCharCode(charCode)
350
+ key.name = char
351
+ key.sequence = char
352
+ if (charCode >= 48 && charCode <= 57) {
353
+ key.number = true
354
+ }
355
+ }
356
+
357
+ return key
358
+ }
359
+
360
+ if (s === "\r" || s === "\x1b\r") {
361
+ // carriage return
362
+ key.name = "return"
363
+ key.meta = s.length === 2
364
+ } else if (s === "\n" || s === "\x1b\n") {
365
+ // linefeed
366
+ key.name = "linefeed"
367
+ key.meta = s.length === 2
368
+ } else if (s === "\t") {
369
+ // tab
370
+ key.name = "tab"
371
+ } else if (s === "\b" || s === "\x1b\b" || s === "\x7f" || s === "\x1b\x7f") {
372
+ // backspace or ctrl+h
373
+ // On OSX, \x7f is also backspace
374
+ key.name = "backspace"
375
+ key.meta = s.charAt(0) === "\x1b"
376
+ } else if (s === "\x1b" || s === "\x1b\x1b") {
377
+ // escape key
378
+ key.name = "escape"
379
+ key.meta = s.length === 2
380
+ } else if (s === " " || s === "\x1b ") {
381
+ key.name = "space"
382
+ key.meta = s.length === 2
383
+ } else if (ctrlKeyName) {
384
+ // ctrl+space, ctrl+letter, ctrl+\\, ctrl+], ctrl+^, ctrl+_
385
+ key.name = ctrlKeyName
386
+ key.ctrl = true
387
+ } else if (s.length === 1 && s >= "0" && s <= "9") {
388
+ // number - keep the actual number character for vim commands
389
+ key.name = s
390
+ key.number = true
391
+ } else if (s.length === 1 && s >= "a" && s <= "z") {
392
+ // lowercase letter
393
+ key.name = s
394
+ } else if (s.length === 1 && s >= "A" && s <= "Z") {
395
+ // shift+letter
396
+ key.name = s.toLowerCase()
397
+ key.shift = true
398
+ } else if (s.length === 1 || (s.length === 2 && s.codePointAt(0)! > 0xffff)) {
399
+ // Single character (including emoji/surrogate pairs above BMP)
400
+ key.name = s
401
+ } else if ((parts = metaKeyCodeRe.exec(s))) {
402
+ // meta+character key
403
+ key.meta = true
404
+ const char = parts[1]!
405
+ const isUpperCase = /^[A-Z]$/.test(char)
406
+
407
+ // Check if uppercase F or B map to arrow keys (old terminal style)
408
+ if (char === "F") {
409
+ key.name = "right"
410
+ } else if (char === "B") {
411
+ key.name = "left"
412
+ } else if (isUpperCase) {
413
+ key.shift = true
414
+ key.name = char
415
+ } else {
416
+ key.name = char
417
+ }
418
+ } else if (metaCtrlKeyName) {
419
+ // ESC + control byte is the raw meta+ctrl form. Reuse the same names as
420
+ // the plain ctrl path, so meta+ctrl+\\ and friends resolve consistently.
421
+ key.meta = true
422
+ key.ctrl = true
423
+ key.name = metaCtrlKeyName
424
+ } else if ((parts = fnKeyRe.exec(s))) {
425
+ const segs = [...s]
426
+
427
+ if (segs[0] === "\u001b" && segs[1] === "\u001b") {
428
+ key.option = true
429
+ key.meta = true
430
+ }
431
+
432
+ // ansi escape sequence
433
+ // reassemble the key code leaving out leading \x1b's,
434
+ // the modifier key bitflag and any meaningless "1;" sequence
435
+ const code = [parts[1], parts[2], parts[4], parts[6]].filter(Boolean).join("")
436
+
437
+ const modifier = parseInt(parts[3] || parts[5] || "1", 10) - 1
438
+
439
+ // Parse the key modifier
440
+ // Terminal modifier bits: 1=Shift, 2=Alt/Option, 4=Ctrl, 8=Super, 16=Hyper
441
+ // Note: meta flag is set for Alt/Option (bit 2)
442
+ key.ctrl = key.ctrl || !!(modifier & 4)
443
+ key.meta = key.meta || !!(modifier & 2)
444
+ key.shift = key.shift || !!(modifier & 1)
445
+ key.option = key.option || !!(modifier & 2)
446
+ key.super = !!(modifier & 8)
447
+ key.hyper = !!(modifier & 16)
448
+ key.code = code
449
+
450
+ const keyNameResult = keyName[code]
451
+ if (keyNameResult) {
452
+ key.name = keyNameResult
453
+ key.shift = isShiftKey(code) || key.shift
454
+ key.ctrl = isCtrlKey(code) || key.ctrl
455
+
456
+ // SS3 application-keypad sequences have a raw sequence starting with ESC
457
+ // which the text-insertion branch would filter out (charCode 27 < 32).
458
+ // Override sequence with the printable character so text input works.
459
+ const ss3Char = ss3NumpadPrintable[code]
460
+ if (ss3Char !== undefined) {
461
+ key.sequence = ss3Char
462
+ if (key.name >= "0" && key.name <= "9") {
463
+ key.number = true
464
+ }
465
+ }
466
+ } else {
467
+ // If we matched the regex but didn't find a valid key name,
468
+ // reset the key to default state (unknown sequence)
469
+ key.name = ""
470
+ key.code = undefined
471
+ }
472
+ } else if (s === "\x1b[3~") {
473
+ // delete key
474
+ key.name = "delete"
475
+ key.meta = false
476
+ key.code = "[3~"
477
+ }
478
+
479
+ return key
480
+ }