@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
package/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# OpenTUI Core
|
|
2
|
+
|
|
3
|
+
OpenTUI is a native terminal UI core written in Zig with TypeScript bindings. The native core exposes a C ABI and can be used from any language. OpenTUI powers OpenCode in production today and will also power terminal.shop. It is an extensible core with a focus on correctness, stability, and high performance. It provides a component-based architecture with flexible layout capabilities, allowing you to create complex terminal applications.
|
|
4
|
+
|
|
5
|
+
## Documentation
|
|
6
|
+
|
|
7
|
+
- [Getting Started](docs/getting-started.md) - API and usage guide
|
|
8
|
+
- [Development Guide](docs/development.md) - Building, testing, and contributing
|
|
9
|
+
- [Tree-Sitter](docs/tree-sitter.md) - Syntax highlighting integration
|
|
10
|
+
- [Renderables vs Constructs](docs/renderables-vs-constructs.md) - Understanding the component model
|
|
11
|
+
- [Environment Variables](docs/env-vars.md) - Configuration options
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
bun install @opentui/core
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Build
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
bun run build
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
This creates platform-specific libraries that are automatically loaded by the TypeScript layer.
|
|
26
|
+
|
|
27
|
+
## Examples
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
bun install
|
|
31
|
+
cd ../examples
|
|
32
|
+
bun run dev
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Benchmarks
|
|
36
|
+
|
|
37
|
+
Run native performance benchmarks:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
bun run bench:native
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
See [src/zig/bench.zig](src/zig/bench.zig) for available options like `--filter` and `--mem`.
|
|
44
|
+
|
|
45
|
+
NativeSpanFeed TypeScript benchmarks:
|
|
46
|
+
|
|
47
|
+
- [src/benchmark/native-span-feed-benchmark.md](src/benchmark/native-span-feed-benchmark.md)
|
|
48
|
+
|
|
49
|
+
## CLI Renderer
|
|
50
|
+
|
|
51
|
+
### Renderables
|
|
52
|
+
|
|
53
|
+
Renderables are hierarchical objects that can be positioned, nested, styled and rendered to the terminal:
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { createCliRenderer, TextRenderable } from "@opentui/core"
|
|
57
|
+
|
|
58
|
+
const renderer = await createCliRenderer()
|
|
59
|
+
|
|
60
|
+
const obj = new TextRenderable(renderer, { id: "my-obj", content: "Hello, world!" })
|
|
61
|
+
|
|
62
|
+
renderer.root.add(obj)
|
|
63
|
+
```
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { BoxRenderable, type CliRenderer, createCliRenderer, CodeRenderable, addDefaultParsers } from "../src/index.js"
|
|
3
|
+
import { ScrollBoxRenderable } from "../src/renderables/ScrollBox.js"
|
|
4
|
+
import { SyntaxStyle } from "../src/syntax-style.js"
|
|
5
|
+
import { parseColor } from "../src/lib/RGBA.js"
|
|
6
|
+
|
|
7
|
+
const parsers = [
|
|
8
|
+
{
|
|
9
|
+
filetype: "json",
|
|
10
|
+
wasm: "https://github.com/tree-sitter/tree-sitter-json/releases/download/v0.24.8/tree-sitter-json.wasm",
|
|
11
|
+
queries: {
|
|
12
|
+
highlights: [
|
|
13
|
+
"https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/json/highlights.scm",
|
|
14
|
+
],
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
]
|
|
18
|
+
addDefaultParsers(parsers)
|
|
19
|
+
let scrollBox: ScrollBoxRenderable | null = null
|
|
20
|
+
let renderer: CliRenderer | null = null
|
|
21
|
+
let syntaxStyle: SyntaxStyle | null = null
|
|
22
|
+
let eventCount = 0
|
|
23
|
+
|
|
24
|
+
function addEvent(eventType: string, event: object) {
|
|
25
|
+
if (!renderer || !scrollBox || !syntaxStyle) return
|
|
26
|
+
|
|
27
|
+
eventCount++
|
|
28
|
+
|
|
29
|
+
const eventData = {
|
|
30
|
+
type: eventType,
|
|
31
|
+
timestamp: new Date().toISOString(),
|
|
32
|
+
...event,
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const eventBox = new BoxRenderable(renderer, {
|
|
36
|
+
id: `event-${eventCount}`,
|
|
37
|
+
width: "auto",
|
|
38
|
+
marginBottom: 1,
|
|
39
|
+
padding: 1,
|
|
40
|
+
backgroundColor: "#1f2937",
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
const codeDisplay = new CodeRenderable(renderer, {
|
|
44
|
+
id: `event-code-${eventCount}`,
|
|
45
|
+
content: JSON.stringify(eventData, null, 2),
|
|
46
|
+
filetype: "json",
|
|
47
|
+
conceal: false,
|
|
48
|
+
syntaxStyle,
|
|
49
|
+
bg: "#1f2937",
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
eventBox.add(codeDisplay)
|
|
53
|
+
scrollBox.add(eventBox)
|
|
54
|
+
|
|
55
|
+
const children = scrollBox.getChildren()
|
|
56
|
+
if (children.length > 50) {
|
|
57
|
+
const oldest = children[0]
|
|
58
|
+
if (oldest) {
|
|
59
|
+
scrollBox.remove(oldest)
|
|
60
|
+
oldest.destroyRecursively()
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async function main() {
|
|
66
|
+
const usePrepend = process.argv.includes("--prepend")
|
|
67
|
+
const prependInputHandlers = usePrepend
|
|
68
|
+
? [
|
|
69
|
+
(sequence: string) => {
|
|
70
|
+
addEvent("raw-input-before", { sequence })
|
|
71
|
+
return false
|
|
72
|
+
},
|
|
73
|
+
]
|
|
74
|
+
: []
|
|
75
|
+
renderer = await createCliRenderer({
|
|
76
|
+
exitOnCtrlC: true,
|
|
77
|
+
targetFps: 60,
|
|
78
|
+
useKittyKeyboard: { events: true },
|
|
79
|
+
prependInputHandlers,
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
renderer.setBackgroundColor("#0D1117")
|
|
83
|
+
|
|
84
|
+
const mainContainer = new BoxRenderable(renderer, {
|
|
85
|
+
id: "main-container",
|
|
86
|
+
flexGrow: 1,
|
|
87
|
+
flexDirection: "column",
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
renderer.root.add(mainContainer)
|
|
91
|
+
|
|
92
|
+
scrollBox = new ScrollBoxRenderable(renderer, {
|
|
93
|
+
id: "event-scroll-box",
|
|
94
|
+
stickyScroll: true,
|
|
95
|
+
stickyStart: "bottom",
|
|
96
|
+
border: true,
|
|
97
|
+
borderColor: "#6BCF7F",
|
|
98
|
+
title: `Keypress Debug${usePrepend ? " (prepend mode)" : ""} (Ctrl+C to exit)`,
|
|
99
|
+
titleAlignment: "center",
|
|
100
|
+
contentOptions: {
|
|
101
|
+
paddingLeft: 1,
|
|
102
|
+
paddingRight: 1,
|
|
103
|
+
paddingTop: 1,
|
|
104
|
+
},
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
mainContainer.add(scrollBox)
|
|
108
|
+
|
|
109
|
+
syntaxStyle = SyntaxStyle.fromStyles({
|
|
110
|
+
string: { fg: parseColor("#A5D6FF") },
|
|
111
|
+
number: { fg: parseColor("#79C0FF") },
|
|
112
|
+
boolean: { fg: parseColor("#79C0FF") },
|
|
113
|
+
keyword: { fg: parseColor("#FF7B72") },
|
|
114
|
+
default: { fg: parseColor("#E6EDF3") },
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
addEvent("capabilities", renderer.capabilities)
|
|
118
|
+
|
|
119
|
+
renderer.addInputHandler((sequence) => {
|
|
120
|
+
addEvent("raw-input-after", { sequence })
|
|
121
|
+
return true
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
renderer.keyInput.on("keypress", (event) => {
|
|
125
|
+
addEvent("keypress", event)
|
|
126
|
+
|
|
127
|
+
if (event.name === "c" && event.shift) {
|
|
128
|
+
if (renderer) {
|
|
129
|
+
addEvent("capabilities", renderer.capabilities)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
renderer.keyInput.on("keyrelease", (event) => {
|
|
135
|
+
addEvent("keyrelease", event)
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
renderer.keyInput.on("paste", (event) => {
|
|
139
|
+
addEvent("paste", event)
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
renderer.requestRender()
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
main().catch((err) => {
|
|
146
|
+
console.error("Error:", err)
|
|
147
|
+
process.exit(1)
|
|
148
|
+
})
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { parseKeypress } from "../src/lib/parse.keypress.ts"
|
|
3
|
+
|
|
4
|
+
console.log("Keypress Debug Tool")
|
|
5
|
+
console.log("Press keys to see their parsed output. Press Ctrl+C to exit.\n")
|
|
6
|
+
|
|
7
|
+
// Set stdin to raw mode to capture individual keypresses
|
|
8
|
+
process.stdin.setRawMode(true)
|
|
9
|
+
process.stdin.resume()
|
|
10
|
+
|
|
11
|
+
// Listen for keypress data
|
|
12
|
+
process.stdin.on("data", (data: Buffer) => {
|
|
13
|
+
// Check for Ctrl+C to exit
|
|
14
|
+
if (data.toString() === "\x03") {
|
|
15
|
+
console.log("\nExiting keypress debug tool...")
|
|
16
|
+
process.stdin.setRawMode(false)
|
|
17
|
+
process.exit(0)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const parsed = parseKeypress(data)
|
|
21
|
+
|
|
22
|
+
console.log("Input data:", JSON.stringify(data.toString()))
|
|
23
|
+
console.log("Raw:", JSON.stringify(parsed?.raw))
|
|
24
|
+
console.log("Parsed:", {
|
|
25
|
+
name: parsed?.name,
|
|
26
|
+
ctrl: parsed?.ctrl,
|
|
27
|
+
meta: parsed?.meta,
|
|
28
|
+
shift: parsed?.shift,
|
|
29
|
+
option: parsed?.option,
|
|
30
|
+
number: parsed?.number,
|
|
31
|
+
sequence: parsed?.sequence,
|
|
32
|
+
code: parsed?.code,
|
|
33
|
+
buffer: data,
|
|
34
|
+
})
|
|
35
|
+
console.log("---")
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
// Handle Ctrl+C gracefully
|
|
39
|
+
process.on("SIGINT", () => {
|
|
40
|
+
console.log("\nExiting keypress debug tool...")
|
|
41
|
+
process.stdin.setRawMode(false)
|
|
42
|
+
process.exit(0)
|
|
43
|
+
})
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Development script to print all registered environment variables
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* bun dev/print-env-vars.ts # Colored output (default)
|
|
8
|
+
* bun dev/print-env-vars.ts --markdown # Markdown output
|
|
9
|
+
* bun dev/print-env-vars.ts --update # Update docs/env-vars.md
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { generateEnvColored, generateEnvMarkdown } from "../src/index.js"
|
|
13
|
+
import { join } from "path"
|
|
14
|
+
|
|
15
|
+
const args = process.argv.slice(2)
|
|
16
|
+
const useMarkdown = args.includes("--markdown")
|
|
17
|
+
const updateDocs = args.includes("--update")
|
|
18
|
+
|
|
19
|
+
const generateMarkdownContent = () => {
|
|
20
|
+
return `# Environment Variables\n\n${generateEnvMarkdown()}---\n\n_generated via packages/core/dev/print-env-vars.ts_\n`
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (updateDocs) {
|
|
24
|
+
const docsPath = join(import.meta.dir, "../docs/env-vars.md")
|
|
25
|
+
const content = generateMarkdownContent()
|
|
26
|
+
await Bun.write(docsPath, content)
|
|
27
|
+
console.log(`✓ Updated ${docsPath}`)
|
|
28
|
+
} else if (useMarkdown) {
|
|
29
|
+
console.log(`${generateEnvMarkdown()}\n---\n_generated via packages/core/dev/print-env-vars.ts_`)
|
|
30
|
+
} else {
|
|
31
|
+
console.log(generateEnvColored())
|
|
32
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Test script for issue #334: Kitty Graphics Protocol query leaks into tmux pane title
|
|
3
|
+
#
|
|
4
|
+
# This script verifies that the kitty graphics query doesn't corrupt tmux pane titles.
|
|
5
|
+
# Run this inside tmux to test.
|
|
6
|
+
#
|
|
7
|
+
# Usage: ./test-tmux-graphics-334.sh
|
|
8
|
+
#
|
|
9
|
+
# Expected results:
|
|
10
|
+
# - Test 1 (Direct query): FAIL - demonstrates the bug
|
|
11
|
+
# - Test 2 (DCS passthrough): PASS - demonstrates the fix
|
|
12
|
+
# - Test 3 (No query): PASS - control test
|
|
13
|
+
|
|
14
|
+
set -e
|
|
15
|
+
|
|
16
|
+
SESSION_NAME="opentui-test-334-$$"
|
|
17
|
+
EXPECTED_TITLE="test-title"
|
|
18
|
+
|
|
19
|
+
cleanup() {
|
|
20
|
+
tmux kill-session -t "$SESSION_NAME" 2>/dev/null || true
|
|
21
|
+
}
|
|
22
|
+
trap cleanup EXIT
|
|
23
|
+
|
|
24
|
+
run_test() {
|
|
25
|
+
local test_name="$1"
|
|
26
|
+
local query_cmd="$2"
|
|
27
|
+
|
|
28
|
+
cleanup
|
|
29
|
+
tmux new-session -d -s "$SESSION_NAME" -x 80 -y 24
|
|
30
|
+
tmux select-pane -t "$SESSION_NAME" -T "$EXPECTED_TITLE"
|
|
31
|
+
|
|
32
|
+
if [ -n "$query_cmd" ]; then
|
|
33
|
+
tmux send-keys -t "$SESSION_NAME" "$query_cmd" Enter
|
|
34
|
+
sleep 0.5
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
local after_title
|
|
38
|
+
after_title=$(tmux display-message -t "$SESSION_NAME" -p '#{pane_title}')
|
|
39
|
+
|
|
40
|
+
if [[ "$after_title" == *"Gi=31337"* ]] || [[ "$after_title" == *"i=31337"* ]]; then
|
|
41
|
+
echo "FAIL: $test_name - pane title corrupted: '$after_title'"
|
|
42
|
+
return 1
|
|
43
|
+
elif [[ "$after_title" != "$EXPECTED_TITLE" ]]; then
|
|
44
|
+
echo "WARN: $test_name - pane title changed: '$after_title'"
|
|
45
|
+
return 1
|
|
46
|
+
else
|
|
47
|
+
echo "PASS: $test_name"
|
|
48
|
+
return 0
|
|
49
|
+
fi
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
echo "=== Issue #334 Test: Kitty Graphics Query in tmux ==="
|
|
53
|
+
echo "tmux version: $(tmux -V)"
|
|
54
|
+
echo ""
|
|
55
|
+
|
|
56
|
+
echo "Test 1: Direct query (demonstrates bug)"
|
|
57
|
+
run_test "Direct kitty graphics query" \
|
|
58
|
+
"printf '\\x1b_Gi=31337,s=1,v=1,a=q,t=d,f=24;AAAA\\x1b\\\\\\x1b[c'" || true
|
|
59
|
+
|
|
60
|
+
echo "Test 2: DCS passthrough wrapped query (demonstrates fix)"
|
|
61
|
+
run_test "DCS passthrough wrapped" \
|
|
62
|
+
"printf '\\x1bPtmux;\\x1b\\x1b_Gi=31337,s=1,v=1,a=q,t=d,f=24;AAAA\\x1b\\x1b\\\\\\x1b\\x1b[c\\x1b\\\\'"
|
|
63
|
+
|
|
64
|
+
echo "Test 3: No query (control)"
|
|
65
|
+
run_test "No query" ""
|
|
66
|
+
|
|
67
|
+
echo ""
|
|
68
|
+
echo "If Test 1 fails and Test 2 passes, the fix is working correctly."
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Probe theme-related terminal queries inside and outside tmux.
|
|
3
|
+
#
|
|
4
|
+
# Run this in the pane you want to test. It writes queries directly to /dev/tty,
|
|
5
|
+
# captures any replies, and prints both an escaped representation and raw hex.
|
|
6
|
+
#
|
|
7
|
+
# Usage:
|
|
8
|
+
# ./packages/core/dev/test-tmux-theme-queries.sh
|
|
9
|
+
|
|
10
|
+
set -u
|
|
11
|
+
set -o pipefail
|
|
12
|
+
|
|
13
|
+
LC_ALL=C
|
|
14
|
+
|
|
15
|
+
ESC=$'\033'
|
|
16
|
+
BEL=$'\a'
|
|
17
|
+
ST="${ESC}\\"
|
|
18
|
+
LOG_FILE="${LOG_FILE:-./_tmux_theme_query_$(date +%s).log}"
|
|
19
|
+
|
|
20
|
+
exec 3<> /dev/tty
|
|
21
|
+
|
|
22
|
+
ORIGINAL_STTY="$(stty -g <&3)"
|
|
23
|
+
|
|
24
|
+
cleanup() {
|
|
25
|
+
stty "$ORIGINAL_STTY" <&3 2>/dev/null || true
|
|
26
|
+
exec 3>&- 3<&-
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interrupt() {
|
|
30
|
+
cleanup
|
|
31
|
+
exit 130
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
trap cleanup EXIT
|
|
35
|
+
trap interrupt INT TERM
|
|
36
|
+
|
|
37
|
+
READ_GAP_TENTHS="${READ_GAP_TENTHS:-4}"
|
|
38
|
+
|
|
39
|
+
stty -echo -icanon min 0 time "$READ_GAP_TENTHS" <&3
|
|
40
|
+
|
|
41
|
+
tmux_wrap() {
|
|
42
|
+
local payload="$1"
|
|
43
|
+
payload=${payload//$ESC/$ESC$ESC}
|
|
44
|
+
printf '%s' "${ESC}Ptmux;${payload}${ST}"
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
escape_for_display() {
|
|
48
|
+
local value="$1"
|
|
49
|
+
value=${value//$ESC/\\e}
|
|
50
|
+
value=${value//$BEL/\\a}
|
|
51
|
+
value=${value//$'\r'/\\r}
|
|
52
|
+
value=${value//$'\n'/\\n$'\n'}
|
|
53
|
+
value=${value//$'\t'/\\t}
|
|
54
|
+
printf '%s' "$value"
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
hex_dump() {
|
|
58
|
+
if [ -z "$1" ]; then
|
|
59
|
+
printf '(none)\n'
|
|
60
|
+
return
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
printf '%s' "$1" | od -An -tx1 -v | tr -s ' ' | sed 's/^ //'
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
read_until_gap() {
|
|
67
|
+
local response=""
|
|
68
|
+
local chunk=""
|
|
69
|
+
|
|
70
|
+
while true; do
|
|
71
|
+
chunk="$(dd bs=1 count=1 2>/dev/null <&3)"
|
|
72
|
+
if [ -z "$chunk" ]; then
|
|
73
|
+
break
|
|
74
|
+
fi
|
|
75
|
+
response+="$chunk"
|
|
76
|
+
done
|
|
77
|
+
|
|
78
|
+
printf '%s' "$response"
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
drain_input() {
|
|
82
|
+
local drained=""
|
|
83
|
+
drained="$(read_until_gap)"
|
|
84
|
+
if [ -n "$drained" ]; then
|
|
85
|
+
printf 'Drained pending input before next test.\n' | tee -a "$LOG_FILE"
|
|
86
|
+
printf ' escaped: %s\n' "$(escape_for_display "$drained")" | tee -a "$LOG_FILE"
|
|
87
|
+
printf ' hex: %s\n' "$(hex_dump "$drained")" | tee -a "$LOG_FILE"
|
|
88
|
+
fi
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
run_case() {
|
|
92
|
+
local name="$1"
|
|
93
|
+
local payload="$2"
|
|
94
|
+
local response=""
|
|
95
|
+
|
|
96
|
+
drain_input
|
|
97
|
+
|
|
98
|
+
{
|
|
99
|
+
printf '\n=== %s ===\n' "$name"
|
|
100
|
+
printf 'query escaped: %s\n' "$(escape_for_display "$payload")"
|
|
101
|
+
printf 'query hex: %s\n' "$(hex_dump "$payload")"
|
|
102
|
+
} | tee -a "$LOG_FILE"
|
|
103
|
+
|
|
104
|
+
printf '%s' "$payload" >&3
|
|
105
|
+
response="$(read_until_gap)"
|
|
106
|
+
|
|
107
|
+
if [ -z "$response" ]; then
|
|
108
|
+
printf 'response: (none)\n' | tee -a "$LOG_FILE"
|
|
109
|
+
return
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
{
|
|
113
|
+
printf 'response escaped: %s\n' "$(escape_for_display "$response")"
|
|
114
|
+
printf 'response hex: %s\n' "$(hex_dump "$response")"
|
|
115
|
+
} | tee -a "$LOG_FILE"
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
OSC10_BEL="${ESC}]10;?${BEL}"
|
|
119
|
+
OSC11_BEL="${ESC}]11;?${BEL}"
|
|
120
|
+
OSC10_ST="${ESC}]10;?${ST}"
|
|
121
|
+
OSC11_ST="${ESC}]11;?${ST}"
|
|
122
|
+
OSC10_11_BEL="${OSC10_BEL}${OSC11_BEL}"
|
|
123
|
+
OSC10_11_ST="${OSC10_ST}${OSC11_ST}"
|
|
124
|
+
CPR_QUERY="${ESC}[6n"
|
|
125
|
+
XTVERSION_QUERY="${ESC}[>0q"
|
|
126
|
+
COLOR_SCHEME_REQUEST="${ESC}[?996n"
|
|
127
|
+
|
|
128
|
+
{
|
|
129
|
+
printf 'tmux theme query probe\n'
|
|
130
|
+
printf 'log file: %s\n' "$LOG_FILE"
|
|
131
|
+
printf 'tmux env: %s\n' "${TMUX:-<not set>}"
|
|
132
|
+
printf 'TERM: %s\n' "${TERM:-<not set>}"
|
|
133
|
+
printf 'TERM_PROGRAM: %s\n' "${TERM_PROGRAM:-<not set>}"
|
|
134
|
+
printf 'read gap tenths: %s\n' "$READ_GAP_TENTHS"
|
|
135
|
+
printf '\n'
|
|
136
|
+
printf 'Recommended: run this inside tmux in the same pane where theme-mode.ts fails.\n'
|
|
137
|
+
} | tee "$LOG_FILE"
|
|
138
|
+
|
|
139
|
+
run_case 'Control: plain CPR (CSI 6n)' "$CPR_QUERY"
|
|
140
|
+
run_case 'Control: plain xtversion (CSI > 0q)' "$XTVERSION_QUERY"
|
|
141
|
+
run_case 'Plain OSC 10/11 combined with BEL terminators' "$OSC10_11_BEL"
|
|
142
|
+
run_case 'Plain OSC 10/11 combined with ST terminators' "$OSC10_11_ST"
|
|
143
|
+
run_case 'tmux wrapped OSC 10/11 combined in one DCS wrapper (BEL)' "$(tmux_wrap "$OSC10_11_BEL")"
|
|
144
|
+
run_case 'tmux wrapped OSC 10/11 combined in one DCS wrapper (ST)' "$(tmux_wrap "$OSC10_11_ST")"
|
|
145
|
+
run_case 'tmux wrapped OSC 10 only (BEL)' "$(tmux_wrap "$OSC10_BEL")"
|
|
146
|
+
run_case 'tmux wrapped OSC 11 only (BEL)' "$(tmux_wrap "$OSC11_BEL")"
|
|
147
|
+
run_case 'tmux wrapped OSC 10 then OSC 11 as separate DCS wrappers (BEL)' "$(tmux_wrap "$OSC10_BEL")$(tmux_wrap "$OSC11_BEL")"
|
|
148
|
+
run_case 'Plain color scheme request (CSI ?996n)' "$COLOR_SCHEME_REQUEST"
|
|
149
|
+
run_case 'tmux wrapped color scheme request (CSI ?996n)' "$(tmux_wrap "$COLOR_SCHEME_REQUEST")"
|
|
150
|
+
|
|
151
|
+
printf '\nDone. If you want, paste the generated log file and I will compare which query forms tmux answers.\n' | tee -a "$LOG_FILE"
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { TextRenderable, createCliRenderer } from "../src/index.js"
|
|
3
|
+
import { ScrollBoxRenderable } from "../src/renderables/ScrollBox.js"
|
|
4
|
+
async function main() {
|
|
5
|
+
const renderer = await createCliRenderer({ exitOnCtrlC: true })
|
|
6
|
+
console.log("capabilities:", renderer.capabilities)
|
|
7
|
+
const scrollBox = new ScrollBoxRenderable(renderer, {
|
|
8
|
+
id: "scroll-box",
|
|
9
|
+
border: true,
|
|
10
|
+
height: 20,
|
|
11
|
+
title: "Thai Render Debug (Up/Down to scroll, Ctrl+C to exit)",
|
|
12
|
+
titleAlignment: "center",
|
|
13
|
+
})
|
|
14
|
+
const thaiLorem = `ภาษาไทยเป็นภาษาที่มีความสวยงามและซับซ้อนมาก มีพยัญชนะ 44 ตัว สระ 32 รูป และวรรณยุกต์ 4 รูป
|
|
15
|
+
มอญเป็นชนชาติที่มีอิทธิพลต่อภาษาไทยมาก คำว่า "มอ" เป็นพยัญชนะที่ใช้บ่อยในภาษาไทย
|
|
16
|
+
ตัวอย่างคำที่มี มอ: มา มี มือ มอง มัว มอบ มวย มอม มอด มอก
|
|
17
|
+
การเขียนภาษาไทยต้องใส่ใจเรื่องวรรณยุกต์ เช่น ม่า ม้า หม่า หม้า
|
|
18
|
+
สระลอยและสระเปลี่ยนรูปทำให้ภาษาไทยมีความพิเศษ เช่น เมือง แมว ไม้ ใหม่
|
|
19
|
+
คำผสมที่น่าสนใจ: มอมแมม มอดมอด มอมเมา มืดมอม มอมดำ
|
|
20
|
+
ภาษาไทยมีระบบการเขียนที่ไม่เว้นวรรคระหว่างคำ ทำให้การอ่านต้องอาศัยความเข้าใจ
|
|
21
|
+
ตัวอักษรไทยมีสามระดับ: บน กลาง ล่าง เช่น ก็ ปี่ ฎุ ฏู ญ ฐ ฑ
|
|
22
|
+
วรรณยุกต์ไทยมี 5 เสียง: สามัญ เอก โท ตรี จัตวา
|
|
23
|
+
ตัวอย่างเสียงวรรณยุกต์: มา ม่า ม้า หมา หม่า หม้า
|
|
24
|
+
การสะกดคำในภาษาไทยมีกฎเกณฑ์ที่ซับซ้อน มีทั้งตัวสะกดมาตราแม่ ก กา และตัวสะกดไม่ตรงมาตรา
|
|
25
|
+
คำยืมจากภาษาบาลีสันสกฤต: กรรม ธรรม สงฆ์ ศาสนา พระ มหา
|
|
26
|
+
คำยืมจากภาษาเขมร: ถนน เสวย ขนม ตำรวจ ทหาร
|
|
27
|
+
คำยืมจากภาษาจีน: ก๋วยเตี๋ยว เต้าหู้ บะหมี่ เกี๊ยว ซาลาเปา
|
|
28
|
+
ภาษาไทยถิ่นมีหลายภาษา: ภาษาเหนือ ภาษาอีสาน ภาษาใต้ ภาษากลาง
|
|
29
|
+
มอญกับไทยมีความสัมพันธ์ทางวัฒนธรรมมายาวนาน
|
|
30
|
+
ตัวเลขไทย: ๐ ๑ ๒ ๓ ๔ ๕ ๖ ๗ ๘ ๙
|
|
31
|
+
เครื่องหมายวรรคตอน: ฯ ๆ ฯลฯ « » ๏
|
|
32
|
+
อักษรไทยมีต้นกำเนิดจากอักษรเขมร ซึ่งมาจากอักษรปัลลวะของอินเดียใต้
|
|
33
|
+
พ่อขุนรามคำแหงมหาราชทรงประดิษฐ์อักษรไทยเมื่อ พ.ศ. 1826
|
|
34
|
+
ภาษาไทยเป็นภาษาที่มีวรรณยุกต์ การออกเสียงผิดวรรณยุกต์ทำให้ความหมายเปลี่ยน
|
|
35
|
+
ตัวอย่าง: ขาว (สีขาว) ข่าว (news) ข้าว (rice) เข้า (enter)
|
|
36
|
+
มอเตอร์ไซค์ มอนิเตอร์ มอลต์ มอร์ฟีน เป็นคำทับศัพท์ที่มี มอ
|
|
37
|
+
สำนวนไทยที่มี มอ: มอมเมา หมอมหมาม มืดมอม มอดไหม้
|
|
38
|
+
คำกริยาที่มี มอ: มอง มอบ มอม มอด มอก
|
|
39
|
+
คำนามที่มี มอ: มอญ มอด หมอ มอเตอร์
|
|
40
|
+
การผันวรรณยุกต์ของ มอ: มอ ม่อ ม้อ หมอ หม่อ หม้อ
|
|
41
|
+
ภาษาไทยมีคำควบกล้ำ: กร กล กว ขร ขล ขว คร คล คว
|
|
42
|
+
ตัวอย่างคำควบกล้ำ: กราบ กลาง กวาง ครู คลอง ความ
|
|
43
|
+
อักษรสูง กลาง ต่ำ มีผลต่อการผันวรรณยุกต์
|
|
44
|
+
อักษรสูง: ข ฃ ฉ ฐ ถ ผ ฝ ศ ษ ส ห
|
|
45
|
+
อักษรกลาง: ก จ ฎ ฏ ด ต บ ป อ
|
|
46
|
+
อักษรต่ำ: ค ฅ ฆ ง ช ซ ฌ ญ ฑ ฒ ณ ท ธ น พ ฟ ภ ม ย ร ล ว ฬ ฮ`
|
|
47
|
+
const text = new TextRenderable(renderer, {
|
|
48
|
+
id: "thai-text",
|
|
49
|
+
content: thaiLorem,
|
|
50
|
+
})
|
|
51
|
+
scrollBox.add(text)
|
|
52
|
+
renderer.root.add(scrollBox)
|
|
53
|
+
renderer.keyInput.on("keypress", (event) => {
|
|
54
|
+
if (event.name === "down") scrollBox.scrollDown()
|
|
55
|
+
if (event.name === "up") scrollBox.scrollUp()
|
|
56
|
+
})
|
|
57
|
+
renderer.requestRender()
|
|
58
|
+
|
|
59
|
+
renderer.keyInput.on("keypress", (event) => {
|
|
60
|
+
if (event.name === "`") {
|
|
61
|
+
renderer.console.toggle()
|
|
62
|
+
}
|
|
63
|
+
})
|
|
64
|
+
}
|
|
65
|
+
main().catch((err) => {
|
|
66
|
+
console.error("Error:", err)
|
|
67
|
+
process.exit(1)
|
|
68
|
+
})
|