@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.
- package/README.md +63 -0
- package/dev/keypress-debug-renderer.ts +148 -0
- package/dev/keypress-debug.ts +43 -0
- package/dev/print-env-vars.ts +32 -0
- package/dev/test-tmux-graphics-334.sh +68 -0
- package/dev/test-tmux-theme-queries.sh +151 -0
- package/dev/thai-debug-test.ts +68 -0
- package/dev/theme-mode.ts +290 -0
- package/docs/development.md +144 -0
- package/package.json +102 -0
- package/prebuilt/aarch64-android/libopentui.so +0 -0
- package/scripts/build-android.ts +226 -0
- package/scripts/build-native-termux.sh +525 -0
- package/scripts/build.ts +530 -0
- package/scripts/dist-test.ts +312 -0
- package/scripts/package-prebuilt.ts +110 -0
- package/scripts/publish.ts +60 -0
- package/scripts/test-node-hook.mjs +16 -0
- package/scripts/test-node.ts +241 -0
- package/scripts/vendor-deps.sh +73 -0
- package/src/NativeSpanFeed.ts +375 -0
- package/src/Renderable.ts +1878 -0
- package/src/__snapshots__/buffer.test.ts.snap +28 -0
- package/src/animation/Timeline.test.ts +2709 -0
- package/src/animation/Timeline.ts +598 -0
- package/src/ansi.ts +22 -0
- package/src/audio.ts +479 -0
- package/src/benchmark/attenuation-benchmark.ts +81 -0
- package/src/benchmark/audio-playback-benchmark.ts +344 -0
- package/src/benchmark/box-draw-benchmark.ts +1042 -0
- package/src/benchmark/colormatrix-benchmark.ts +123 -0
- package/src/benchmark/gain-benchmark.ts +80 -0
- package/src/benchmark/latest-all-bench-run.json +707 -0
- package/src/benchmark/latest-async-bench-run.json +336 -0
- package/src/benchmark/latest-default-bench-run.json +657 -0
- package/src/benchmark/latest-large-bench-run.json +707 -0
- package/src/benchmark/latest-quick-bench-run.json +207 -0
- package/src/benchmark/layout-benchmark.ts +2547 -0
- package/src/benchmark/markdown-benchmark.ts +1796 -0
- package/src/benchmark/native-span-feed-async-benchmark.ts +355 -0
- package/src/benchmark/native-span-feed-benchmark.md +56 -0
- package/src/benchmark/native-span-feed-benchmark.ts +596 -0
- package/src/benchmark/native-span-feed-compare.ts +280 -0
- package/src/benchmark/render-traversal-benchmark.ts +928 -0
- package/src/benchmark/text-buffer-render-benchmark.ts +874 -0
- package/src/benchmark/text-table-benchmark.ts +948 -0
- package/src/buffer.test.ts +292 -0
- package/src/buffer.ts +564 -0
- package/src/console.test.ts +629 -0
- package/src/console.ts +1253 -0
- package/src/edit-buffer.test.ts +1852 -0
- package/src/edit-buffer.ts +417 -0
- package/src/editor-view.test.ts +1056 -0
- package/src/editor-view.ts +290 -0
- package/src/index.ts +25 -0
- package/src/lib/KeyHandler.integration.test.ts +292 -0
- package/src/lib/KeyHandler.stopPropagation.test.ts +289 -0
- package/src/lib/KeyHandler.test.ts +662 -0
- package/src/lib/KeyHandler.ts +222 -0
- package/src/lib/RGBA.test.ts +60 -0
- package/src/lib/RGBA.ts +343 -0
- package/src/lib/ascii.font.ts +330 -0
- package/src/lib/border.test.ts +83 -0
- package/src/lib/border.ts +170 -0
- package/src/lib/bunfs.test.ts +27 -0
- package/src/lib/bunfs.ts +18 -0
- package/src/lib/clipboard.test.ts +63 -0
- package/src/lib/clipboard.ts +41 -0
- package/src/lib/clock.ts +35 -0
- package/src/lib/data-paths.test.ts +133 -0
- package/src/lib/data-paths.ts +109 -0
- package/src/lib/debounce.ts +106 -0
- package/src/lib/detect-links.test.ts +98 -0
- package/src/lib/detect-links.ts +56 -0
- package/src/lib/env.test.ts +228 -0
- package/src/lib/env.ts +209 -0
- package/src/lib/extmarks-history.ts +51 -0
- package/src/lib/extmarks-multiwidth.test.ts +324 -0
- package/src/lib/extmarks.test.ts +3547 -0
- package/src/lib/extmarks.ts +861 -0
- package/src/lib/fonts/block.json +405 -0
- package/src/lib/fonts/grid.json +265 -0
- package/src/lib/fonts/huge.json +741 -0
- package/src/lib/fonts/pallet.json +314 -0
- package/src/lib/fonts/shade.json +591 -0
- package/src/lib/fonts/slick.json +321 -0
- package/src/lib/fonts/tiny.json +69 -0
- package/src/lib/hast-styled-text.ts +59 -0
- package/src/lib/index.ts +22 -0
- package/src/lib/keybinding.internal.test.ts +342 -0
- package/src/lib/keybinding.internal.ts +182 -0
- package/src/lib/objects-in-viewport.test.ts +789 -0
- package/src/lib/objects-in-viewport.ts +153 -0
- package/src/lib/output.capture.ts +58 -0
- package/src/lib/parse.keypress-kitty.protocol.test.ts +347 -0
- package/src/lib/parse.keypress-kitty.test.ts +712 -0
- package/src/lib/parse.keypress-kitty.ts +470 -0
- package/src/lib/parse.keypress.test.ts +2020 -0
- package/src/lib/parse.keypress.ts +480 -0
- package/src/lib/parse.mouse.test.ts +552 -0
- package/src/lib/parse.mouse.ts +232 -0
- package/src/lib/paste.ts +18 -0
- package/src/lib/queue.ts +65 -0
- package/src/lib/render-geometry.ts +36 -0
- package/src/lib/renderable.validations.test.ts +87 -0
- package/src/lib/renderable.validations.ts +83 -0
- package/src/lib/scroll-acceleration.ts +98 -0
- package/src/lib/selection.ts +261 -0
- package/src/lib/singleton.ts +34 -0
- package/src/lib/stdin-parser.test.ts +2439 -0
- package/src/lib/stdin-parser.ts +2007 -0
- package/src/lib/styled-text.ts +178 -0
- package/src/lib/terminal-capability-detection.test.ts +226 -0
- package/src/lib/terminal-capability-detection.ts +98 -0
- package/src/lib/terminal-palette.test.ts +954 -0
- package/src/lib/terminal-palette.ts +441 -0
- package/src/lib/tree-sitter/assets/README.md +119 -0
- package/src/lib/tree-sitter/assets/javascript/highlights.scm +205 -0
- package/src/lib/tree-sitter/assets/javascript/tree-sitter-javascript.wasm +0 -0
- package/src/lib/tree-sitter/assets/markdown/highlights.scm +150 -0
- package/src/lib/tree-sitter/assets/markdown/injections.scm +27 -0
- package/src/lib/tree-sitter/assets/markdown/tree-sitter-markdown.wasm +0 -0
- package/src/lib/tree-sitter/assets/markdown_inline/highlights.scm +115 -0
- package/src/lib/tree-sitter/assets/markdown_inline/tree-sitter-markdown_inline.wasm +0 -0
- package/src/lib/tree-sitter/assets/typescript/highlights.scm +604 -0
- package/src/lib/tree-sitter/assets/typescript/tree-sitter-typescript.wasm +0 -0
- package/src/lib/tree-sitter/assets/update.ts +360 -0
- package/src/lib/tree-sitter/assets/zig/highlights.scm +284 -0
- package/src/lib/tree-sitter/assets/zig/tree-sitter-zig.wasm +0 -0
- package/src/lib/tree-sitter/assets.d.ts +9 -0
- package/src/lib/tree-sitter/cache.test.ts +291 -0
- package/src/lib/tree-sitter/client.test.ts +1434 -0
- package/src/lib/tree-sitter/client.ts +847 -0
- package/src/lib/tree-sitter/default-parsers.ts +133 -0
- package/src/lib/tree-sitter/download-utils.ts +148 -0
- package/src/lib/tree-sitter/index.ts +75 -0
- package/src/lib/tree-sitter/parser.worker.ts +1098 -0
- package/src/lib/tree-sitter/parsers-config.ts +81 -0
- package/src/lib/tree-sitter/resolve-ft.test.ts +55 -0
- package/src/lib/tree-sitter/resolve-ft.ts +189 -0
- package/src/lib/tree-sitter/types.ts +132 -0
- package/src/lib/tree-sitter/update-assets.ts +10 -0
- package/src/lib/tree-sitter-styled-text.test.ts +1253 -0
- package/src/lib/tree-sitter-styled-text.ts +314 -0
- package/src/lib/validate-dir-name.ts +55 -0
- package/src/lib/yoga.options.test.ts +628 -0
- package/src/lib/yoga.options.ts +346 -0
- package/src/native-event-worker-repro.test.ts +48 -0
- package/src/native-event-worker-repro.worker.ts +9 -0
- package/src/native-handle.test.ts +221 -0
- package/src/platform/ffi.test.ts +516 -0
- package/src/platform/ffi.ts +653 -0
- package/src/platform/runtime.test.ts +52 -0
- package/src/platform/runtime.ts +121 -0
- package/src/platform/test.ts +45 -0
- package/src/platform/worker-handler-cleanup.fixture.ts +12 -0
- package/src/platform/worker-onmessage-startup.fixture.ts +10 -0
- package/src/platform/worker-startup.fixture.ts +9 -0
- package/src/platform/worker.node-test.ts +153 -0
- package/src/platform/worker.ts +425 -0
- package/src/plugins/core-slot.ts +579 -0
- package/src/plugins/registry.ts +402 -0
- package/src/plugins/types.ts +46 -0
- package/src/post/effects.ts +948 -0
- package/src/post/filters.ts +512 -0
- package/src/post/matrices.ts +288 -0
- package/src/renderables/ASCIIFont.ts +219 -0
- package/src/renderables/Box.test.ts +474 -0
- package/src/renderables/Box.ts +353 -0
- package/src/renderables/Code.test.ts +2388 -0
- package/src/renderables/Code.ts +555 -0
- package/src/renderables/Diff.regression.test.ts +381 -0
- package/src/renderables/Diff.test.ts +3212 -0
- package/src/renderables/Diff.ts +1278 -0
- package/src/renderables/EditBufferRenderable.test.ts +288 -0
- package/src/renderables/EditBufferRenderable.ts +1152 -0
- package/src/renderables/FrameBuffer.ts +47 -0
- package/src/renderables/Input.test.ts +1310 -0
- package/src/renderables/Input.ts +273 -0
- package/src/renderables/LineNumberRenderable.ts +725 -0
- package/src/renderables/Markdown.ts +2144 -0
- package/src/renderables/ScrollBar.ts +423 -0
- package/src/renderables/ScrollBox.ts +903 -0
- package/src/renderables/Select.test.ts +1134 -0
- package/src/renderables/Select.ts +535 -0
- package/src/renderables/Slider.test.ts +456 -0
- package/src/renderables/Slider.ts +342 -0
- package/src/renderables/TabSelect.test.ts +238 -0
- package/src/renderables/TabSelect.ts +447 -0
- package/src/renderables/Text.selection-buffer.test.ts +118 -0
- package/src/renderables/Text.test.ts +2662 -0
- package/src/renderables/Text.ts +147 -0
- package/src/renderables/TextBufferRenderable.ts +504 -0
- package/src/renderables/TextNode.test.ts +1137 -0
- package/src/renderables/TextNode.ts +379 -0
- package/src/renderables/TextTable.test.ts +1411 -0
- package/src/renderables/TextTable.ts +1434 -0
- package/src/renderables/Textarea.ts +425 -0
- package/src/renderables/TimeToFirstDraw.ts +89 -0
- package/src/renderables/__snapshots__/Code.test.ts.snap +13 -0
- package/src/renderables/__snapshots__/Diff.test.ts.snap +785 -0
- package/src/renderables/__snapshots__/Text.test.ts.snap +421 -0
- package/src/renderables/__snapshots__/TextTable.test.ts.snap +215 -0
- package/src/renderables/__tests__/Code.test.ts +55 -0
- package/src/renderables/__tests__/LineNumberRenderable.scrollbox-simple.test.ts +144 -0
- package/src/renderables/__tests__/LineNumberRenderable.scrollbox.test.ts +827 -0
- package/src/renderables/__tests__/LineNumberRenderable.test.ts +1906 -0
- package/src/renderables/__tests__/LineNumberRenderable.wrapping.test.ts +85 -0
- package/src/renderables/__tests__/Markdown.code-colors.test.ts +288 -0
- package/src/renderables/__tests__/Markdown.test.ts +4175 -0
- package/src/renderables/__tests__/MultiRenderable.selection.test.ts +87 -0
- package/src/renderables/__tests__/Textarea.buffer.test.ts +683 -0
- package/src/renderables/__tests__/Textarea.destroyed-events.test.ts +675 -0
- package/src/renderables/__tests__/Textarea.editing.test.ts +2120 -0
- package/src/renderables/__tests__/Textarea.error-handling.test.ts +35 -0
- package/src/renderables/__tests__/Textarea.events.test.ts +738 -0
- package/src/renderables/__tests__/Textarea.highlights.test.ts +590 -0
- package/src/renderables/__tests__/Textarea.keybinding.test.ts +3275 -0
- package/src/renderables/__tests__/Textarea.paste.test.ts +357 -0
- package/src/renderables/__tests__/Textarea.rendering.test.ts +1927 -0
- package/src/renderables/__tests__/Textarea.scroll.test.ts +733 -0
- package/src/renderables/__tests__/Textarea.selection.test.ts +1589 -0
- package/src/renderables/__tests__/Textarea.stress.test.ts +670 -0
- package/src/renderables/__tests__/Textarea.undo-redo.test.ts +383 -0
- package/src/renderables/__tests__/Textarea.visual-lines.test.ts +310 -0
- package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.code.test.ts.snap +221 -0
- package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.scrollbox-simple.test.ts.snap +89 -0
- package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.scrollbox.test.ts.snap +457 -0
- package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.test.ts.snap +158 -0
- package/src/renderables/__tests__/__snapshots__/Textarea.rendering.test.ts.snap +387 -0
- package/src/renderables/__tests__/markdown-parser.test.ts +241 -0
- package/src/renderables/__tests__/renderable-test-utils.ts +60 -0
- package/src/renderables/composition/README.md +8 -0
- package/src/renderables/composition/VRenderable.ts +32 -0
- package/src/renderables/composition/constructs.ts +127 -0
- package/src/renderables/composition/vnode.ts +277 -0
- package/src/renderables/index.ts +23 -0
- package/src/renderables/markdown-parser.ts +79 -0
- package/src/renderer-theme-mode.ts +199 -0
- package/src/renderer.ts +4975 -0
- package/src/runtime-plugin-support-configure.ts +63 -0
- package/src/runtime-plugin-support.ts +13 -0
- package/src/runtime-plugin.ts +626 -0
- package/src/specs/terminal-startup.md +64 -0
- package/src/syntax-style.test.ts +841 -0
- package/src/syntax-style.ts +274 -0
- package/src/testing/README.md +219 -0
- package/src/testing/bun-test-node.ts +880 -0
- package/src/testing/capture-spans.test.ts +216 -0
- package/src/testing/integration.test.ts +276 -0
- package/src/testing/manual-clock.ts +117 -0
- package/src/testing/mock-keys.test.ts +1378 -0
- package/src/testing/mock-keys.ts +457 -0
- package/src/testing/mock-mouse.test.ts +218 -0
- package/src/testing/mock-mouse.ts +247 -0
- package/src/testing/mock-tree-sitter-client.ts +81 -0
- package/src/testing/spy.ts +13 -0
- package/src/testing/terminal-capabilities.ts +47 -0
- package/src/testing/test-recorder.test.ts +410 -0
- package/src/testing/test-recorder.ts +133 -0
- package/src/testing/test-renderer.ts +375 -0
- package/src/testing/test-renderer.wait.test.ts +278 -0
- package/src/testing/test-streams.ts +31 -0
- package/src/testing.ts +9 -0
- package/src/tests/__snapshots__/absolute-positioning.snapshot.test.ts.snap +481 -0
- package/src/tests/__snapshots__/renderable.snapshot.test.ts.snap +19 -0
- package/src/tests/__snapshots__/scrollbox.test.ts.snap +29 -0
- package/src/tests/absolute-positioning.snapshot.test.ts +638 -0
- package/src/tests/allocator-stats.test.ts +53 -0
- package/src/tests/audio.test.ts +303 -0
- package/src/tests/destroy-during-render.test.ts +200 -0
- package/src/tests/destroy-on-exit.fixture.ts +36 -0
- package/src/tests/destroy-on-exit.test.ts +62 -0
- package/src/tests/ffi-borrowed-pointer-callsites.test.ts +153 -0
- package/src/tests/hover-cursor.test.ts +98 -0
- package/src/tests/native-backed-measurement-lifecycle.test.ts +133 -0
- package/src/tests/native-backed-measurement-parity.test.ts +322 -0
- package/src/tests/native-span-feed-async.test.ts +173 -0
- package/src/tests/native-span-feed-close.test.ts +120 -0
- package/src/tests/native-span-feed-coverage.test.ts +227 -0
- package/src/tests/native-span-feed-edge-cases.test.ts +384 -0
- package/src/tests/native-span-feed-use-after-free.test.ts +45 -0
- package/src/tests/opacity.test.ts +123 -0
- package/src/tests/renderable.snapshot.test.ts +524 -0
- package/src/tests/renderable.test.ts +1851 -0
- package/src/tests/renderer.clock.test.ts +270 -0
- package/src/tests/renderer.console-startup.test.ts +2151 -0
- package/src/tests/renderer.control.test.ts +458 -0
- package/src/tests/renderer.core-slot-binding.test.ts +962 -0
- package/src/tests/renderer.cursor.test.ts +26 -0
- package/src/tests/renderer.custom-stdout.test.ts +1112 -0
- package/src/tests/renderer.destroy-during-render.test.ts +147 -0
- package/src/tests/renderer.focus-restore.test.ts +257 -0
- package/src/tests/renderer.focus.test.ts +329 -0
- package/src/tests/renderer.idle.test.ts +219 -0
- package/src/tests/renderer.input.test.ts +2615 -0
- package/src/tests/renderer.kitty-flags.test.ts +195 -0
- package/src/tests/renderer.lifecycle.test.ts +34 -0
- package/src/tests/renderer.mouse.test.ts +1315 -0
- package/src/tests/renderer.notifications.test.ts +27 -0
- package/src/tests/renderer.palette.test.ts +1199 -0
- package/src/tests/renderer.remote.test.ts +247 -0
- package/src/tests/renderer.render-stats.test.ts +146 -0
- package/src/tests/renderer.scrollback-surface.test.ts +474 -0
- package/src/tests/renderer.selection.test.ts +138 -0
- package/src/tests/renderer.slot-registry.test.ts +684 -0
- package/src/tests/renderer.tracker.test.ts +202 -0
- package/src/tests/renderer.useMouse.test.ts +83 -0
- package/src/tests/runtime-plugin-node-modules-cycle.fixture.ts +76 -0
- package/src/tests/runtime-plugin-node-modules-import-like-string.fixture.ts +48 -0
- package/src/tests/runtime-plugin-node-modules-mjs.fixture.ts +43 -0
- package/src/tests/runtime-plugin-node-modules-no-bare-rewrite.fixture.ts +67 -0
- package/src/tests/runtime-plugin-node-modules-package-type-cache.fixture.ts +72 -0
- package/src/tests/runtime-plugin-node-modules-runtime-specifier.fixture.ts +44 -0
- package/src/tests/runtime-plugin-node-modules-scoped-package-bare-rewrite.fixture.ts +85 -0
- package/src/tests/runtime-plugin-path-alias.fixture.ts +43 -0
- package/src/tests/runtime-plugin-resolve-roots.fixture.ts +65 -0
- package/src/tests/runtime-plugin-support-configure.fixture.ts +31 -0
- package/src/tests/runtime-plugin-support-late-addition.fixture.ts +17 -0
- package/src/tests/runtime-plugin-support.fixture.ts +11 -0
- package/src/tests/runtime-plugin-support.test.ts +54 -0
- package/src/tests/runtime-plugin-windows-file-url.fixture.ts +30 -0
- package/src/tests/runtime-plugin.fixture.ts +40 -0
- package/src/tests/runtime-plugin.test.ts +369 -0
- package/src/tests/scrollbox-culling-bug.test.ts +114 -0
- package/src/tests/scrollbox-hitgrid-resize.test.ts +136 -0
- package/src/tests/scrollbox-hitgrid.test.ts +909 -0
- package/src/tests/scrollbox.test.ts +1895 -0
- package/src/tests/wrap-resize-perf.test.ts +276 -0
- package/src/tests/yoga-api-coverage.test.ts +409 -0
- package/src/tests/yoga-callback-stress.test.ts +122 -0
- package/src/tests/yoga-ffi.test.ts +117 -0
- package/src/tests/yoga-setters.test.ts +921 -0
- package/src/tests/yoga-upstream/YGAlignBaselineTest.test.ts +124 -0
- package/src/tests/yoga-upstream/YGComputedBorderTest.test.ts +27 -0
- package/src/tests/yoga-upstream/YGComputedMarginTest.test.ts +27 -0
- package/src/tests/yoga-upstream/YGComputedPaddingTest.test.ts +27 -0
- package/src/tests/yoga-upstream/YGDirtiedTest.test.ts +157 -0
- package/src/tests/yoga-upstream/YGErrataTest.test.ts +40 -0
- package/src/tests/yoga-upstream/YGFlexBasisAuto.test.ts +23 -0
- package/src/tests/yoga-upstream/YGHasNewLayout.test.ts +81 -0
- package/src/tests/yoga-upstream/YGMeasureCacheTest.test.ts +31 -0
- package/src/tests/yoga-upstream/YGMeasureTest.test.ts +70 -0
- package/src/tests/yoga-upstream/generated/YGAbsolutePositionTest.test.ts +1864 -0
- package/src/tests/yoga-upstream/generated/YGAlignContentTest.test.ts +5829 -0
- package/src/tests/yoga-upstream/generated/YGAlignItemsTest.test.ts +2444 -0
- package/src/tests/yoga-upstream/generated/YGAlignSelfTest.test.ts +293 -0
- package/src/tests/yoga-upstream/generated/YGAndroidNewsFeed.test.ts +315 -0
- package/src/tests/yoga-upstream/generated/YGAspectRatioTest.test.ts +231 -0
- package/src/tests/yoga-upstream/generated/YGAutoTest.test.ts +347 -0
- package/src/tests/yoga-upstream/generated/YGBorderTest.test.ts +256 -0
- package/src/tests/yoga-upstream/generated/YGBoxSizingTest.test.ts +2747 -0
- package/src/tests/yoga-upstream/generated/YGDimensionTest.test.ts +129 -0
- package/src/tests/yoga-upstream/generated/YGDisplayContentsTest.test.ts +109 -0
- package/src/tests/yoga-upstream/generated/YGDisplayTest.test.ts +1097 -0
- package/src/tests/yoga-upstream/generated/YGFlexDirectionTest.test.ts +4562 -0
- package/src/tests/yoga-upstream/generated/YGFlexTest.test.ts +677 -0
- package/src/tests/yoga-upstream/generated/YGFlexWrapTest.test.ts +2071 -0
- package/src/tests/yoga-upstream/generated/YGGapTest.test.ts +3303 -0
- package/src/tests/yoga-upstream/generated/YGIntrinsicSizeTest.test.ts +582 -0
- package/src/tests/yoga-upstream/generated/YGJustifyContentTest.test.ts +2150 -0
- package/src/tests/yoga-upstream/generated/YGMarginTest.test.ts +1963 -0
- package/src/tests/yoga-upstream/generated/YGMinMaxDimensionTest.test.ts +1446 -0
- package/src/tests/yoga-upstream/generated/YGPaddingTest.test.ts +354 -0
- package/src/tests/yoga-upstream/generated/YGPercentageTest.test.ts +1760 -0
- package/src/tests/yoga-upstream/generated/YGRoundingTest.test.ts +1161 -0
- package/src/tests/yoga-upstream/generated/YGSizeOverflowTest.test.ts +207 -0
- package/src/tests/yoga-upstream/generated/YGStaticPositionTest.test.ts +6338 -0
- package/src/tests/yoga-upstream/tools/MeasureCounter.ts +54 -0
- package/src/tests/yoga-upstream/tools/utils.ts +81 -0
- package/src/text-buffer-view.test.ts +722 -0
- package/src/text-buffer-view.ts +193 -0
- package/src/text-buffer.test.ts +512 -0
- package/src/text-buffer.ts +250 -0
- package/src/types.ts +199 -0
- package/src/utils.ts +88 -0
- package/src/yoga.ts +1146 -0
- package/src/zig/ansi.zig +502 -0
- package/src/zig/audio.zig +1206 -0
- package/src/zig/bench/README.md +50 -0
- package/src/zig/bench/buffer-color-blending_bench.zig +350 -0
- package/src/zig/bench/buffer-draw-box_bench.zig +786 -0
- package/src/zig/bench/buffer-draw-text-buffer_bench.zig +894 -0
- package/src/zig/bench/edit-buffer_bench.zig +476 -0
- package/src/zig/bench/editor-view_bench.zig +169 -0
- package/src/zig/bench/native-span-feed_bench.zig +107 -0
- package/src/zig/bench/rope-markers_bench.zig +713 -0
- package/src/zig/bench/rope_bench.zig +514 -0
- package/src/zig/bench/styled-text_bench.zig +476 -0
- package/src/zig/bench/text-buffer-coords_bench.zig +362 -0
- package/src/zig/bench/text-buffer-view_bench.zig +459 -0
- package/src/zig/bench/text-chunk-graphemes_bench.zig +272 -0
- package/src/zig/bench/utf8_bench.zig +799 -0
- package/src/zig/bench-utils.zig +431 -0
- package/src/zig/bench.zig +223 -0
- package/src/zig/buffer-methods.zig +215 -0
- package/src/zig/buffer.zig +2515 -0
- package/src/zig/build.zig +700 -0
- package/src/zig/build.zig.zon +19 -0
- package/src/zig/edit-buffer.zig +900 -0
- package/src/zig/editor-view.zig +812 -0
- package/src/zig/event-bus.zig +28 -0
- package/src/zig/event-emitter.zig +65 -0
- package/src/zig/file-logger.zig +92 -0
- package/src/zig/grapheme.zig +838 -0
- package/src/zig/handles.zig +267 -0
- package/src/zig/lib.zig +2813 -0
- package/src/zig/link.zig +349 -0
- package/src/zig/logger.zig +43 -0
- package/src/zig/mem-registry.zig +126 -0
- package/src/zig/miniaudio_shim.c +21 -0
- package/src/zig/native-renderable.zig +112 -0
- package/src/zig/native-span-feed-bench-lib.zig +7 -0
- package/src/zig/native-span-feed.zig +747 -0
- package/src/zig/renderer-output.zig +677 -0
- package/src/zig/renderer.zig +2106 -0
- package/src/zig/rope.zig +1220 -0
- package/src/zig/split-scrollback.zig +88 -0
- package/src/zig/syntax-style.zig +174 -0
- package/src/zig/terminal.zig +1652 -0
- package/src/zig/test.zig +82 -0
- package/src/zig/tests/README.md +18 -0
- package/src/zig/tests/ansi_test.zig +18 -0
- package/src/zig/tests/audio_test.zig +439 -0
- package/src/zig/tests/buffer-methods_test.zig +1111 -0
- package/src/zig/tests/buffer_test.zig +2926 -0
- package/src/zig/tests/edit-buffer-history_test.zig +299 -0
- package/src/zig/tests/edit-buffer_test.zig +1688 -0
- package/src/zig/tests/editor-view_test.zig +3454 -0
- package/src/zig/tests/event-emitter_test.zig +249 -0
- package/src/zig/tests/grapheme_test.zig +1329 -0
- package/src/zig/tests/handles_test.zig +123 -0
- package/src/zig/tests/link_test.zig +220 -0
- package/src/zig/tests/mem-registry_test.zig +473 -0
- package/src/zig/tests/memory_leak_regression_test.zig +234 -0
- package/src/zig/tests/native-renderable_test.zig +16 -0
- package/src/zig/tests/native-span-feed_test.zig +1266 -0
- package/src/zig/tests/renderer_test.zig +2604 -0
- package/src/zig/tests/rope-nested_test.zig +712 -0
- package/src/zig/tests/rope_fuzz_test.zig +238 -0
- package/src/zig/tests/rope_test.zig +2362 -0
- package/src/zig/tests/segment-merge.test.zig +148 -0
- package/src/zig/tests/split-scrollback_test.zig +70 -0
- package/src/zig/tests/syntax-style_test.zig +558 -0
- package/src/zig/tests/terminal_test.zig +1489 -0
- package/src/zig/tests/test-renderer.zig +126 -0
- package/src/zig/tests/text-buffer-drawing_test.zig +3291 -0
- package/src/zig/tests/text-buffer-highlights_test.zig +706 -0
- package/src/zig/tests/text-buffer-iterators_test.zig +776 -0
- package/src/zig/tests/text-buffer-segment_test.zig +320 -0
- package/src/zig/tests/text-buffer-selection_test.zig +1056 -0
- package/src/zig/tests/text-buffer-selection_viewport_test.zig +358 -0
- package/src/zig/tests/text-buffer-view_test.zig +3672 -0
- package/src/zig/tests/text-buffer_test.zig +2191 -0
- package/src/zig/tests/unicode-width-map.zon +3909 -0
- package/src/zig/tests/utf8_no_zwj_test.zig +260 -0
- package/src/zig/tests/utf8_test.zig +4060 -0
- package/src/zig/tests/utf8_wcwidth_cursor_test.zig +267 -0
- package/src/zig/tests/utf8_wcwidth_test.zig +357 -0
- package/src/zig/tests/word-wrap-editing_test.zig +498 -0
- package/src/zig/tests/wrap-cache-perf_test.zig +113 -0
- package/src/zig/tests/yoga_test.zig +65 -0
- package/src/zig/text-buffer-iterators.zig +496 -0
- package/src/zig/text-buffer-segment.zig +403 -0
- package/src/zig/text-buffer-view.zig +1428 -0
- package/src/zig/text-buffer.zig +1272 -0
- package/src/zig/utf8.zig +1954 -0
- package/src/zig/utils.zig +12 -0
- package/src/zig/uucode-stub.zig +76 -0
- package/src/zig/vendor/miniaudio/miniaudio.h +93468 -0
- package/src/zig/yoga.zig +658 -0
- package/src/zig-structs.ts +381 -0
- package/src/zig.ts +5260 -0
- package/tsconfig.build.json +17 -0
- package/tsconfig.json +27 -0
- package/tsconfig.node-test.json +138 -0
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BoxSizing,
|
|
3
|
+
Align,
|
|
4
|
+
Dimension,
|
|
5
|
+
Direction,
|
|
6
|
+
Display,
|
|
7
|
+
Edge,
|
|
8
|
+
FlexDirection,
|
|
9
|
+
Gutter,
|
|
10
|
+
Justify,
|
|
11
|
+
LogLevel,
|
|
12
|
+
MeasureMode,
|
|
13
|
+
Overflow,
|
|
14
|
+
PositionType,
|
|
15
|
+
Unit,
|
|
16
|
+
Wrap,
|
|
17
|
+
} from "../yoga.js"
|
|
18
|
+
|
|
19
|
+
export type AlignString =
|
|
20
|
+
| "auto"
|
|
21
|
+
| "flex-start"
|
|
22
|
+
| "center"
|
|
23
|
+
| "flex-end"
|
|
24
|
+
| "stretch"
|
|
25
|
+
| "baseline"
|
|
26
|
+
| "space-between"
|
|
27
|
+
| "space-around"
|
|
28
|
+
| "space-evenly"
|
|
29
|
+
export type BoxSizingString = "border-box" | "content-box"
|
|
30
|
+
export type DimensionString = "width" | "height"
|
|
31
|
+
export type DirectionString = "inherit" | "ltr" | "rtl"
|
|
32
|
+
export type DisplayString = "flex" | "none" | "contents"
|
|
33
|
+
export type EdgeString = "left" | "top" | "right" | "bottom" | "start" | "end" | "horizontal" | "vertical" | "all"
|
|
34
|
+
export type FlexDirectionString = "column" | "column-reverse" | "row" | "row-reverse"
|
|
35
|
+
export type GutterString = "column" | "row" | "all"
|
|
36
|
+
export type JustifyString = "flex-start" | "center" | "flex-end" | "space-between" | "space-around" | "space-evenly"
|
|
37
|
+
export type LogLevelString = "error" | "warn" | "info" | "debug" | "verbose" | "fatal"
|
|
38
|
+
export type MeasureModeString = "undefined" | "exactly" | "at-most"
|
|
39
|
+
export type OverflowString = "visible" | "hidden" | "scroll"
|
|
40
|
+
export type PositionTypeString = "static" | "relative" | "absolute"
|
|
41
|
+
export type UnitString = "undefined" | "point" | "percent" | "auto"
|
|
42
|
+
export type WrapString = "no-wrap" | "wrap" | "wrap-reverse"
|
|
43
|
+
|
|
44
|
+
export function parseAlign(value: string | null | undefined): Align {
|
|
45
|
+
if (value == null) {
|
|
46
|
+
return Align.Auto
|
|
47
|
+
}
|
|
48
|
+
switch (value.toLowerCase()) {
|
|
49
|
+
case "auto":
|
|
50
|
+
return Align.Auto
|
|
51
|
+
case "flex-start":
|
|
52
|
+
return Align.FlexStart
|
|
53
|
+
case "center":
|
|
54
|
+
return Align.Center
|
|
55
|
+
case "flex-end":
|
|
56
|
+
return Align.FlexEnd
|
|
57
|
+
case "stretch":
|
|
58
|
+
return Align.Stretch
|
|
59
|
+
case "baseline":
|
|
60
|
+
return Align.Baseline
|
|
61
|
+
case "space-between":
|
|
62
|
+
return Align.SpaceBetween
|
|
63
|
+
case "space-around":
|
|
64
|
+
return Align.SpaceAround
|
|
65
|
+
case "space-evenly":
|
|
66
|
+
return Align.SpaceEvenly
|
|
67
|
+
default:
|
|
68
|
+
return Align.Auto
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function parseAlignItems(value: string | null | undefined): Align {
|
|
73
|
+
if (value == null) {
|
|
74
|
+
return Align.Stretch
|
|
75
|
+
}
|
|
76
|
+
switch (value.toLowerCase()) {
|
|
77
|
+
case "auto":
|
|
78
|
+
return Align.Auto
|
|
79
|
+
case "flex-start":
|
|
80
|
+
return Align.FlexStart
|
|
81
|
+
case "center":
|
|
82
|
+
return Align.Center
|
|
83
|
+
case "flex-end":
|
|
84
|
+
return Align.FlexEnd
|
|
85
|
+
case "stretch":
|
|
86
|
+
return Align.Stretch
|
|
87
|
+
case "baseline":
|
|
88
|
+
return Align.Baseline
|
|
89
|
+
case "space-between":
|
|
90
|
+
return Align.SpaceBetween
|
|
91
|
+
case "space-around":
|
|
92
|
+
return Align.SpaceAround
|
|
93
|
+
case "space-evenly":
|
|
94
|
+
return Align.SpaceEvenly
|
|
95
|
+
default:
|
|
96
|
+
return Align.Stretch
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function parseBoxSizing(value: string): BoxSizing {
|
|
101
|
+
if (value == null) {
|
|
102
|
+
return BoxSizing.BorderBox
|
|
103
|
+
}
|
|
104
|
+
switch (value.toLowerCase()) {
|
|
105
|
+
case "border-box":
|
|
106
|
+
return BoxSizing.BorderBox
|
|
107
|
+
case "content-box":
|
|
108
|
+
return BoxSizing.ContentBox
|
|
109
|
+
default:
|
|
110
|
+
return BoxSizing.BorderBox
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function parseDimension(value: string): Dimension {
|
|
115
|
+
if (value == null) {
|
|
116
|
+
return Dimension.Width
|
|
117
|
+
}
|
|
118
|
+
switch (value.toLowerCase()) {
|
|
119
|
+
case "width":
|
|
120
|
+
return Dimension.Width
|
|
121
|
+
case "height":
|
|
122
|
+
return Dimension.Height
|
|
123
|
+
default:
|
|
124
|
+
return Dimension.Width
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function parseDirection(value: string): Direction {
|
|
129
|
+
if (value == null) {
|
|
130
|
+
return Direction.LTR
|
|
131
|
+
}
|
|
132
|
+
switch (value.toLowerCase()) {
|
|
133
|
+
case "inherit":
|
|
134
|
+
return Direction.Inherit
|
|
135
|
+
case "ltr":
|
|
136
|
+
return Direction.LTR
|
|
137
|
+
case "rtl":
|
|
138
|
+
return Direction.RTL
|
|
139
|
+
default:
|
|
140
|
+
return Direction.LTR
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function parseDisplay(value: string): Display {
|
|
145
|
+
if (value == null) {
|
|
146
|
+
return Display.Flex
|
|
147
|
+
}
|
|
148
|
+
switch (value.toLowerCase()) {
|
|
149
|
+
case "flex":
|
|
150
|
+
return Display.Flex
|
|
151
|
+
case "none":
|
|
152
|
+
return Display.None
|
|
153
|
+
case "contents":
|
|
154
|
+
return Display.Contents
|
|
155
|
+
default:
|
|
156
|
+
return Display.Flex
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export function parseEdge(value: string): Edge {
|
|
161
|
+
if (value == null) {
|
|
162
|
+
return Edge.All
|
|
163
|
+
}
|
|
164
|
+
switch (value.toLowerCase()) {
|
|
165
|
+
case "left":
|
|
166
|
+
return Edge.Left
|
|
167
|
+
case "top":
|
|
168
|
+
return Edge.Top
|
|
169
|
+
case "right":
|
|
170
|
+
return Edge.Right
|
|
171
|
+
case "bottom":
|
|
172
|
+
return Edge.Bottom
|
|
173
|
+
case "start":
|
|
174
|
+
return Edge.Start
|
|
175
|
+
case "end":
|
|
176
|
+
return Edge.End
|
|
177
|
+
case "horizontal":
|
|
178
|
+
return Edge.Horizontal
|
|
179
|
+
case "vertical":
|
|
180
|
+
return Edge.Vertical
|
|
181
|
+
case "all":
|
|
182
|
+
return Edge.All
|
|
183
|
+
default:
|
|
184
|
+
return Edge.All
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export function parseFlexDirection(value: string | null | undefined): FlexDirection {
|
|
189
|
+
if (value == null) {
|
|
190
|
+
return FlexDirection.Column
|
|
191
|
+
}
|
|
192
|
+
switch (value.toLowerCase()) {
|
|
193
|
+
case "column":
|
|
194
|
+
return FlexDirection.Column
|
|
195
|
+
case "column-reverse":
|
|
196
|
+
return FlexDirection.ColumnReverse
|
|
197
|
+
case "row":
|
|
198
|
+
return FlexDirection.Row
|
|
199
|
+
case "row-reverse":
|
|
200
|
+
return FlexDirection.RowReverse
|
|
201
|
+
default:
|
|
202
|
+
return FlexDirection.Column
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export function parseGutter(value: string): Gutter {
|
|
207
|
+
if (value == null) {
|
|
208
|
+
return Gutter.All
|
|
209
|
+
}
|
|
210
|
+
switch (value.toLowerCase()) {
|
|
211
|
+
case "column":
|
|
212
|
+
return Gutter.Column
|
|
213
|
+
case "row":
|
|
214
|
+
return Gutter.Row
|
|
215
|
+
case "all":
|
|
216
|
+
return Gutter.All
|
|
217
|
+
default:
|
|
218
|
+
return Gutter.All
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export function parseJustify(value: string | null | undefined): Justify {
|
|
223
|
+
if (value == null) {
|
|
224
|
+
return Justify.FlexStart
|
|
225
|
+
}
|
|
226
|
+
switch (value.toLowerCase()) {
|
|
227
|
+
case "flex-start":
|
|
228
|
+
return Justify.FlexStart
|
|
229
|
+
case "center":
|
|
230
|
+
return Justify.Center
|
|
231
|
+
case "flex-end":
|
|
232
|
+
return Justify.FlexEnd
|
|
233
|
+
case "space-between":
|
|
234
|
+
return Justify.SpaceBetween
|
|
235
|
+
case "space-around":
|
|
236
|
+
return Justify.SpaceAround
|
|
237
|
+
case "space-evenly":
|
|
238
|
+
return Justify.SpaceEvenly
|
|
239
|
+
default:
|
|
240
|
+
return Justify.FlexStart
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export function parseLogLevel(value: string): LogLevel {
|
|
245
|
+
if (value == null) {
|
|
246
|
+
return LogLevel.Info
|
|
247
|
+
}
|
|
248
|
+
switch (value.toLowerCase()) {
|
|
249
|
+
case "error":
|
|
250
|
+
return LogLevel.Error
|
|
251
|
+
case "warn":
|
|
252
|
+
return LogLevel.Warn
|
|
253
|
+
case "info":
|
|
254
|
+
return LogLevel.Info
|
|
255
|
+
case "debug":
|
|
256
|
+
return LogLevel.Debug
|
|
257
|
+
case "verbose":
|
|
258
|
+
return LogLevel.Verbose
|
|
259
|
+
case "fatal":
|
|
260
|
+
return LogLevel.Fatal
|
|
261
|
+
default:
|
|
262
|
+
return LogLevel.Info
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export function parseMeasureMode(value: string): MeasureMode {
|
|
267
|
+
if (value == null) {
|
|
268
|
+
return MeasureMode.Undefined
|
|
269
|
+
}
|
|
270
|
+
switch (value.toLowerCase()) {
|
|
271
|
+
case "undefined":
|
|
272
|
+
return MeasureMode.Undefined
|
|
273
|
+
case "exactly":
|
|
274
|
+
return MeasureMode.Exactly
|
|
275
|
+
case "at-most":
|
|
276
|
+
return MeasureMode.AtMost
|
|
277
|
+
default:
|
|
278
|
+
return MeasureMode.Undefined
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export function parseOverflow(value: string | null | undefined): Overflow {
|
|
283
|
+
if (value == null) {
|
|
284
|
+
return Overflow.Visible
|
|
285
|
+
}
|
|
286
|
+
switch (value.toLowerCase()) {
|
|
287
|
+
case "visible":
|
|
288
|
+
return Overflow.Visible
|
|
289
|
+
case "hidden":
|
|
290
|
+
return Overflow.Hidden
|
|
291
|
+
case "scroll":
|
|
292
|
+
return Overflow.Scroll
|
|
293
|
+
default:
|
|
294
|
+
return Overflow.Visible
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export function parsePositionType(value: string | null | undefined): PositionType {
|
|
299
|
+
if (value == null) {
|
|
300
|
+
return PositionType.Relative
|
|
301
|
+
}
|
|
302
|
+
switch (value.toLowerCase()) {
|
|
303
|
+
case "static":
|
|
304
|
+
return PositionType.Static
|
|
305
|
+
case "relative":
|
|
306
|
+
return PositionType.Relative
|
|
307
|
+
case "absolute":
|
|
308
|
+
return PositionType.Absolute
|
|
309
|
+
default:
|
|
310
|
+
return PositionType.Static
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export function parseUnit(value: string): Unit {
|
|
315
|
+
if (value == null) {
|
|
316
|
+
return Unit.Point
|
|
317
|
+
}
|
|
318
|
+
switch (value.toLowerCase()) {
|
|
319
|
+
case "undefined":
|
|
320
|
+
return Unit.Undefined
|
|
321
|
+
case "point":
|
|
322
|
+
return Unit.Point
|
|
323
|
+
case "percent":
|
|
324
|
+
return Unit.Percent
|
|
325
|
+
case "auto":
|
|
326
|
+
return Unit.Auto
|
|
327
|
+
default:
|
|
328
|
+
return Unit.Point
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export function parseWrap(value: string | null | undefined): Wrap {
|
|
333
|
+
if (value == null) {
|
|
334
|
+
return Wrap.NoWrap
|
|
335
|
+
}
|
|
336
|
+
switch (value.toLowerCase()) {
|
|
337
|
+
case "no-wrap":
|
|
338
|
+
return Wrap.NoWrap
|
|
339
|
+
case "wrap":
|
|
340
|
+
return Wrap.Wrap
|
|
341
|
+
case "wrap-reverse":
|
|
342
|
+
return Wrap.WrapReverse
|
|
343
|
+
default:
|
|
344
|
+
return Wrap.NoWrap
|
|
345
|
+
}
|
|
346
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test"
|
|
2
|
+
import { EditBuffer } from "./edit-buffer.js"
|
|
3
|
+
|
|
4
|
+
function waitForWorker(worker: Worker) {
|
|
5
|
+
let timeout: ReturnType<typeof setTimeout> | undefined
|
|
6
|
+
return new Promise<void>((resolve, reject) => {
|
|
7
|
+
timeout = setTimeout(() => reject(new Error("worker did not complete")), 5_000)
|
|
8
|
+
worker.addEventListener("message", () => resolve(), { once: true })
|
|
9
|
+
worker.addEventListener(
|
|
10
|
+
"error",
|
|
11
|
+
(event) => {
|
|
12
|
+
reject(event.error ?? new Error(event.message))
|
|
13
|
+
},
|
|
14
|
+
{ once: true },
|
|
15
|
+
)
|
|
16
|
+
}).finally(() => {
|
|
17
|
+
if (timeout) clearTimeout(timeout)
|
|
18
|
+
})
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
describe("native event worker callback repro", () => {
|
|
22
|
+
test("keeps native event callback valid after a worker installs and releases its callback", async () => {
|
|
23
|
+
const first = EditBuffer.create("unicode")
|
|
24
|
+
first.on("content-changed", () => {})
|
|
25
|
+
first.setText("main-before-worker")
|
|
26
|
+
await Bun.sleep(0)
|
|
27
|
+
|
|
28
|
+
const worker = new Worker(new URL("./native-event-worker-repro.worker.ts", import.meta.url), {
|
|
29
|
+
type: "module",
|
|
30
|
+
})
|
|
31
|
+
await waitForWorker(worker)
|
|
32
|
+
await worker.terminate()
|
|
33
|
+
|
|
34
|
+
let delivered = 0
|
|
35
|
+
const second = EditBuffer.create("unicode")
|
|
36
|
+
second.on("content-changed", () => {
|
|
37
|
+
delivered++
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
second.setText("main-after-worker")
|
|
41
|
+
await Bun.sleep(0)
|
|
42
|
+
|
|
43
|
+
second.destroy()
|
|
44
|
+
first.destroy()
|
|
45
|
+
|
|
46
|
+
expect(delivered).toBe(1)
|
|
47
|
+
})
|
|
48
|
+
})
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test"
|
|
2
|
+
import { OptimizedBuffer } from "./buffer.js"
|
|
3
|
+
import { RGBA } from "./lib/RGBA.js"
|
|
4
|
+
import { TextBuffer } from "./text-buffer.js"
|
|
5
|
+
import { TextBufferView } from "./text-buffer-view.js"
|
|
6
|
+
import { EditBuffer } from "./edit-buffer.js"
|
|
7
|
+
import { EditorView } from "./editor-view.js"
|
|
8
|
+
import { SyntaxStyle } from "./syntax-style.js"
|
|
9
|
+
import type { Pointer } from "./platform/ffi.js"
|
|
10
|
+
import Yoga from "./yoga.js"
|
|
11
|
+
import {
|
|
12
|
+
NativeMeasureTargetKind,
|
|
13
|
+
resolveRenderLib,
|
|
14
|
+
setRenderLibPath,
|
|
15
|
+
type OptimizedBufferHandle,
|
|
16
|
+
type RendererHandle,
|
|
17
|
+
type TextBufferHandle,
|
|
18
|
+
} from "./zig.js"
|
|
19
|
+
|
|
20
|
+
describe("native handles", () => {
|
|
21
|
+
test("render library path cannot change after native use", () => {
|
|
22
|
+
resolveRenderLib()
|
|
23
|
+
expect(() => setRenderLibPath("/tmp/opentui-unused-native-library.so")).toThrow(
|
|
24
|
+
"setRenderLibPath() must be called before resolveRenderLib()",
|
|
25
|
+
)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test("renderer calls after destroy are rejected safely", () => {
|
|
29
|
+
const lib = resolveRenderLib()
|
|
30
|
+
const renderer = lib.createRenderer(4, 3, { bufferedOutput: "memory" })
|
|
31
|
+
expect(renderer).toBeTruthy()
|
|
32
|
+
const rendererHandle = renderer as RendererHandle
|
|
33
|
+
const current = lib.getCurrentBuffer(rendererHandle)
|
|
34
|
+
const currentHandle = current.ptr
|
|
35
|
+
|
|
36
|
+
lib.destroyRenderer(rendererHandle)
|
|
37
|
+
lib.setCursorPosition(rendererHandle, 1, 1, true)
|
|
38
|
+
lib.destroyRenderer(rendererHandle)
|
|
39
|
+
|
|
40
|
+
expect(lib.getBufferWidth(currentHandle)).toBe(0)
|
|
41
|
+
|
|
42
|
+
const second = lib.createRenderer(4, 3, { bufferedOutput: "memory" }) as RendererHandle
|
|
43
|
+
expect(second).toBeTruthy()
|
|
44
|
+
const before = lib.getCursorState(second)
|
|
45
|
+
lib.setCursorPosition(rendererHandle, 2, 2, true)
|
|
46
|
+
expect(lib.getCursorState(second).x).toBe(before.x)
|
|
47
|
+
expect(lib.getCursorState(second).y).toBe(before.y)
|
|
48
|
+
lib.destroyRenderer(second)
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
test("buffer stale and wrong-kind handles are rejected", () => {
|
|
52
|
+
const lib = resolveRenderLib()
|
|
53
|
+
const buffer = OptimizedBuffer.create(4, 3, "unicode")
|
|
54
|
+
expect(buffer.buffers.char.length).toBe(12)
|
|
55
|
+
const bufferHandle = buffer.ptr
|
|
56
|
+
buffer.destroy()
|
|
57
|
+
expect(() => buffer.buffers).toThrow()
|
|
58
|
+
expect(() => buffer.fillRect(0, 0, 1, 1, RGBA.fromValues(1, 0, 0, 1))).toThrow("is destroyed")
|
|
59
|
+
|
|
60
|
+
expect(lib.getBufferWidth(bufferHandle)).toBe(0)
|
|
61
|
+
lib.destroyOptimizedBuffer(bufferHandle)
|
|
62
|
+
|
|
63
|
+
const renderer = lib.createRenderer(4, 3, { bufferedOutput: "memory" }) as RendererHandle
|
|
64
|
+
expect(lib.getBufferWidth(renderer as unknown as OptimizedBufferHandle)).toBe(0)
|
|
65
|
+
lib.destroyRenderer(renderer)
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
test("text, view, edit, editor, and syntax stale handles are rejected", () => {
|
|
69
|
+
const lib = resolveRenderLib()
|
|
70
|
+
|
|
71
|
+
const textBuffer = TextBuffer.create("unicode")
|
|
72
|
+
const textHandle = textBuffer.ptr
|
|
73
|
+
const textView = TextBufferView.create(textBuffer)
|
|
74
|
+
const textViewHandle = textView.ptr
|
|
75
|
+
textView.destroy()
|
|
76
|
+
expect(lib.textBufferViewGetVirtualLineCount(textViewHandle)).toBe(0)
|
|
77
|
+
textBuffer.destroy()
|
|
78
|
+
expect(lib.textBufferGetLength(textHandle)).toBe(0)
|
|
79
|
+
|
|
80
|
+
const editBuffer = EditBuffer.create("unicode")
|
|
81
|
+
const editHandle = editBuffer.ptr
|
|
82
|
+
const borrowedTextHandle = lib.editBufferGetTextBuffer(editHandle)
|
|
83
|
+
const editorView = EditorView.create(editBuffer, 10, 4)
|
|
84
|
+
const editorHandle = editorView.ptr
|
|
85
|
+
const borrowedViewHandle = lib.editorViewGetTextBufferView(editorHandle)
|
|
86
|
+
editorView.destroy()
|
|
87
|
+
expect(lib.textBufferViewGetVirtualLineCount(borrowedViewHandle)).toBe(0)
|
|
88
|
+
editBuffer.destroy()
|
|
89
|
+
expect(lib.editBufferGetId(editHandle)).toBe(0)
|
|
90
|
+
expect(lib.textBufferGetLength(borrowedTextHandle)).toBe(0)
|
|
91
|
+
|
|
92
|
+
const style = SyntaxStyle.create()
|
|
93
|
+
const styleHandle = style.ptr
|
|
94
|
+
style.destroy()
|
|
95
|
+
expect(lib.syntaxStyleGetStyleCount(styleHandle)).toBe(0)
|
|
96
|
+
|
|
97
|
+
expect(lib.textBufferGetLength(editHandle as unknown as TextBufferHandle)).toBe(0)
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
test("owned text buffer destroys child views", () => {
|
|
101
|
+
const lib = resolveRenderLib()
|
|
102
|
+
const textBuffer = TextBuffer.create("unicode")
|
|
103
|
+
const textView = TextBufferView.create(textBuffer)
|
|
104
|
+
const textViewHandle = textView.ptr
|
|
105
|
+
|
|
106
|
+
textBuffer.destroy()
|
|
107
|
+
|
|
108
|
+
expect(lib.textBufferViewGetVirtualLineCount(textViewHandle)).toBe(0)
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
test("borrowed edit buffer text handle cannot own text buffer views", () => {
|
|
112
|
+
const lib = resolveRenderLib()
|
|
113
|
+
const editBuffer = EditBuffer.create("unicode")
|
|
114
|
+
const editHandle = editBuffer.ptr
|
|
115
|
+
const borrowedTextHandle = lib.editBufferGetTextBuffer(editHandle)
|
|
116
|
+
|
|
117
|
+
expect(() => lib.createTextBufferView(borrowedTextHandle)).toThrow("Failed to create TextBufferView")
|
|
118
|
+
|
|
119
|
+
editBuffer.destroy()
|
|
120
|
+
expect(lib.textBufferGetLength(borrowedTextHandle)).toBe(0)
|
|
121
|
+
})
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
describe("native renderable measure target contract", () => {
|
|
125
|
+
test("rejects null nodes, unknown kinds, and stale target handles", () => {
|
|
126
|
+
const lib = resolveRenderLib()
|
|
127
|
+
const textBuffer = TextBuffer.create("unicode")
|
|
128
|
+
const textView = TextBufferView.create(textBuffer)
|
|
129
|
+
const node = Yoga.Node.createForOpenTUI()
|
|
130
|
+
const renderable = lib.createNativeRenderable()
|
|
131
|
+
|
|
132
|
+
try {
|
|
133
|
+
expect(lib.nativeRenderableAttachYogaNode(renderable, 0 as unknown as Pointer)).toBe(false)
|
|
134
|
+
expect(lib.nativeRenderableAttachYogaNode(renderable, node.ptr)).toBe(true)
|
|
135
|
+
expect(lib.yogaNodeHasMeasureFunc(node.ptr)).toBe(false)
|
|
136
|
+
|
|
137
|
+
expect(
|
|
138
|
+
lib.nativeRenderableSetMeasureTarget(renderable, NativeMeasureTargetKind.TextBufferView, textView.ptr),
|
|
139
|
+
).toBe(true)
|
|
140
|
+
expect(lib.yogaNodeHasMeasureFunc(node.ptr)).toBe(true)
|
|
141
|
+
|
|
142
|
+
// Unknown kinds are rejected and leave the current target in place.
|
|
143
|
+
expect(
|
|
144
|
+
lib.nativeRenderableSetMeasureTarget(renderable, 999 as unknown as NativeMeasureTargetKind, textView.ptr),
|
|
145
|
+
).toBe(false)
|
|
146
|
+
expect(lib.yogaNodeHasMeasureFunc(node.ptr)).toBe(true)
|
|
147
|
+
|
|
148
|
+
// Clear the target before destroying the view: a native renderable must
|
|
149
|
+
// never keep measuring a destroyed view (renderables enforce this by
|
|
150
|
+
// destroying the native renderable before their views).
|
|
151
|
+
expect(lib.nativeRenderableSetMeasureTarget(renderable, NativeMeasureTargetKind.None, 0)).toBe(true)
|
|
152
|
+
expect(lib.yogaNodeHasMeasureFunc(node.ptr)).toBe(false)
|
|
153
|
+
|
|
154
|
+
const staleViewHandle = textView.ptr
|
|
155
|
+
textView.destroy()
|
|
156
|
+
expect(
|
|
157
|
+
lib.nativeRenderableSetMeasureTarget(renderable, NativeMeasureTargetKind.TextBufferView, staleViewHandle),
|
|
158
|
+
).toBe(false)
|
|
159
|
+
expect(lib.yogaNodeHasMeasureFunc(node.ptr)).toBe(false)
|
|
160
|
+
} finally {
|
|
161
|
+
lib.destroyNativeRenderable(renderable)
|
|
162
|
+
node.free()
|
|
163
|
+
textView.destroy()
|
|
164
|
+
textBuffer.destroy()
|
|
165
|
+
}
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
test("kind None clears the measure target", () => {
|
|
169
|
+
const lib = resolveRenderLib()
|
|
170
|
+
const editBuffer = EditBuffer.create("unicode")
|
|
171
|
+
const editorView = EditorView.create(editBuffer, 10, 4)
|
|
172
|
+
const node = Yoga.Node.createForOpenTUI()
|
|
173
|
+
const renderable = lib.createNativeRenderable()
|
|
174
|
+
|
|
175
|
+
try {
|
|
176
|
+
expect(lib.nativeRenderableAttachYogaNode(renderable, node.ptr)).toBe(true)
|
|
177
|
+
expect(lib.nativeRenderableSetMeasureTarget(renderable, NativeMeasureTargetKind.EditorView, editorView.ptr)).toBe(
|
|
178
|
+
true,
|
|
179
|
+
)
|
|
180
|
+
expect(lib.yogaNodeHasMeasureFunc(node.ptr)).toBe(true)
|
|
181
|
+
|
|
182
|
+
expect(lib.nativeRenderableSetMeasureTarget(renderable, NativeMeasureTargetKind.None, 0)).toBe(true)
|
|
183
|
+
expect(lib.yogaNodeHasMeasureFunc(node.ptr)).toBe(false)
|
|
184
|
+
} finally {
|
|
185
|
+
lib.destroyNativeRenderable(renderable)
|
|
186
|
+
node.free()
|
|
187
|
+
editorView.destroy()
|
|
188
|
+
editBuffer.destroy()
|
|
189
|
+
}
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
test("destroying a native renderable clears the node measure func and invalidates the handle", () => {
|
|
193
|
+
const lib = resolveRenderLib()
|
|
194
|
+
const textBuffer = TextBuffer.create("unicode")
|
|
195
|
+
const textView = TextBufferView.create(textBuffer)
|
|
196
|
+
const node = Yoga.Node.createForOpenTUI()
|
|
197
|
+
const renderable = lib.createNativeRenderable()
|
|
198
|
+
|
|
199
|
+
try {
|
|
200
|
+
expect(lib.nativeRenderableAttachYogaNode(renderable, node.ptr)).toBe(true)
|
|
201
|
+
expect(
|
|
202
|
+
lib.nativeRenderableSetMeasureTarget(renderable, NativeMeasureTargetKind.TextBufferView, textView.ptr),
|
|
203
|
+
).toBe(true)
|
|
204
|
+
expect(lib.yogaNodeHasMeasureFunc(node.ptr)).toBe(true)
|
|
205
|
+
|
|
206
|
+
lib.destroyNativeRenderable(renderable)
|
|
207
|
+
expect(lib.yogaNodeHasMeasureFunc(node.ptr)).toBe(false)
|
|
208
|
+
|
|
209
|
+
// Stale native renderable handles are rejected safely, including double destroy.
|
|
210
|
+
lib.destroyNativeRenderable(renderable)
|
|
211
|
+
expect(lib.nativeRenderableAttachYogaNode(renderable, node.ptr)).toBe(false)
|
|
212
|
+
expect(
|
|
213
|
+
lib.nativeRenderableSetMeasureTarget(renderable, NativeMeasureTargetKind.TextBufferView, textView.ptr),
|
|
214
|
+
).toBe(false)
|
|
215
|
+
} finally {
|
|
216
|
+
node.free()
|
|
217
|
+
textView.destroy()
|
|
218
|
+
textBuffer.destroy()
|
|
219
|
+
}
|
|
220
|
+
})
|
|
221
|
+
})
|