@fairyhunter13/opentui-core 0.1.114 → 0.1.116
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/3d/SpriteResourceManager.d.ts +74 -0
- package/3d/SpriteUtils.d.ts +13 -0
- package/3d/TextureUtils.d.ts +24 -0
- package/3d/ThreeRenderable.d.ts +40 -0
- package/3d/WGPURenderer.d.ts +61 -0
- package/3d/animation/ExplodingSpriteEffect.d.ts +71 -0
- package/3d/animation/PhysicsExplodingSpriteEffect.d.ts +76 -0
- package/3d/animation/SpriteAnimator.d.ts +124 -0
- package/3d/animation/SpriteParticleGenerator.d.ts +62 -0
- package/3d/canvas.d.ts +44 -0
- package/3d/index.d.ts +12 -0
- package/3d/physics/PlanckPhysicsAdapter.d.ts +19 -0
- package/3d/physics/RapierPhysicsAdapter.d.ts +19 -0
- package/3d/physics/physics-interface.d.ts +27 -0
- package/3d.d.ts +2 -0
- package/3d.js +34041 -0
- package/3d.js.map +155 -0
- package/LICENSE +21 -0
- package/NativeSpanFeed.d.ts +41 -0
- package/Renderable.d.ts +334 -0
- package/animation/Timeline.d.ts +126 -0
- package/ansi.d.ts +13 -0
- package/buffer.d.ts +111 -0
- package/console.d.ts +144 -0
- package/edit-buffer.d.ts +98 -0
- package/editor-view.d.ts +73 -0
- package/index-dcj62y8t.js +20614 -0
- package/index-dcj62y8t.js.map +67 -0
- package/index-jyrhjc34.js +411 -0
- package/index-jyrhjc34.js.map +10 -0
- package/index-wc7ae60z.js +12299 -0
- package/index-wc7ae60z.js.map +42 -0
- package/index.d.ts +23 -0
- package/index.js +478 -0
- package/index.js.map +9 -0
- package/lib/KeyHandler.d.ts +61 -0
- package/lib/RGBA.d.ts +25 -0
- package/lib/ascii.font.d.ts +508 -0
- package/lib/border.d.ts +51 -0
- package/lib/bunfs.d.ts +7 -0
- package/lib/clipboard.d.ts +17 -0
- package/lib/clock.d.ts +15 -0
- package/lib/data-paths.d.ts +26 -0
- package/lib/debounce.d.ts +42 -0
- package/lib/detect-links.d.ts +6 -0
- package/lib/env.d.ts +42 -0
- package/lib/extmarks-history.d.ts +17 -0
- package/lib/extmarks.d.ts +89 -0
- package/lib/hast-styled-text.d.ts +17 -0
- package/lib/index.d.ts +21 -0
- package/lib/keymapping.d.ts +25 -0
- package/lib/objects-in-viewport.d.ts +24 -0
- package/lib/output.capture.d.ts +24 -0
- package/lib/parse.keypress-kitty.d.ts +2 -0
- package/lib/parse.keypress.d.ts +26 -0
- package/lib/parse.mouse.d.ts +30 -0
- package/lib/paste.d.ts +7 -0
- package/lib/queue.d.ts +15 -0
- package/lib/renderable.validations.d.ts +12 -0
- package/lib/scroll-acceleration.d.ts +43 -0
- package/lib/selection.d.ts +63 -0
- package/lib/singleton.d.ts +7 -0
- package/lib/stdin-parser.d.ts +87 -0
- package/lib/styled-text.d.ts +63 -0
- package/lib/terminal-capability-detection.d.ts +30 -0
- package/lib/terminal-palette.d.ts +50 -0
- package/lib/tree-sitter/assets/update.d.ts +11 -0
- package/lib/tree-sitter/client.d.ts +47 -0
- package/lib/tree-sitter/default-parsers.d.ts +2 -0
- package/lib/tree-sitter/download-utils.d.ts +21 -0
- package/lib/tree-sitter/index.d.ts +8 -0
- package/lib/tree-sitter/parser.worker.d.ts +1 -0
- package/lib/tree-sitter/parsers-config.d.ts +53 -0
- package/lib/tree-sitter/resolve-ft.d.ts +5 -0
- package/lib/tree-sitter/types.d.ts +82 -0
- package/lib/tree-sitter-styled-text.d.ts +14 -0
- package/lib/validate-dir-name.d.ts +1 -0
- package/lib/yoga.options.d.ts +32 -0
- package/package.json +53 -62
- package/parser.worker.js +899 -0
- package/parser.worker.js.map +12 -0
- package/plugins/core-slot.d.ts +72 -0
- package/plugins/registry.d.ts +42 -0
- package/plugins/types.d.ts +34 -0
- package/post/effects.d.ts +147 -0
- package/post/filters.d.ts +65 -0
- package/post/matrices.d.ts +20 -0
- package/renderables/ASCIIFont.d.ts +52 -0
- package/renderables/Box.d.ts +81 -0
- package/renderables/Code.d.ts +78 -0
- package/renderables/Diff.d.ts +142 -0
- package/renderables/EditBufferRenderable.d.ts +237 -0
- package/renderables/FrameBuffer.d.ts +16 -0
- package/renderables/Input.d.ts +67 -0
- package/renderables/LineNumberRenderable.d.ts +78 -0
- package/renderables/Markdown.d.ts +185 -0
- package/renderables/ScrollBar.d.ts +77 -0
- package/renderables/ScrollBox.d.ts +124 -0
- package/renderables/Select.d.ts +115 -0
- package/renderables/Slider.d.ts +47 -0
- package/renderables/TabSelect.d.ts +96 -0
- package/renderables/Text.d.ts +36 -0
- package/renderables/TextBufferRenderable.d.ts +105 -0
- package/renderables/TextNode.d.ts +91 -0
- package/renderables/TextTable.d.ts +140 -0
- package/renderables/Textarea.d.ts +63 -0
- package/renderables/TimeToFirstDraw.d.ts +24 -0
- package/renderables/__tests__/renderable-test-utils.d.ts +12 -0
- package/renderables/composition/VRenderable.d.ts +16 -0
- package/renderables/composition/constructs.d.ts +35 -0
- package/renderables/composition/vnode.d.ts +46 -0
- package/renderables/index.d.ts +23 -0
- package/renderables/markdown-parser.d.ts +10 -0
- package/renderer.d.ts +419 -0
- package/runtime-plugin-support.d.ts +3 -0
- package/runtime-plugin-support.js +29 -0
- package/runtime-plugin-support.js.map +10 -0
- package/runtime-plugin.d.ts +16 -0
- package/runtime-plugin.js +16 -0
- package/runtime-plugin.js.map +9 -0
- package/syntax-style.d.ts +54 -0
- package/testing/manual-clock.d.ts +17 -0
- package/testing/mock-keys.d.ts +81 -0
- package/testing/mock-mouse.d.ts +38 -0
- package/testing/mock-tree-sitter-client.d.ts +23 -0
- package/testing/spy.d.ts +7 -0
- package/testing/test-recorder.d.ts +61 -0
- package/testing/test-renderer.d.ts +23 -0
- package/testing.d.ts +6 -0
- package/testing.js +697 -0
- package/testing.js.map +15 -0
- package/text-buffer-view.d.ts +42 -0
- package/text-buffer.d.ts +67 -0
- package/types.d.ts +139 -0
- package/utils.d.ts +14 -0
- package/zig-structs.d.ts +155 -0
- package/zig.d.ts +353 -0
- package/dev/keypress-debug-renderer.ts +0 -148
- package/dev/keypress-debug.ts +0 -43
- package/dev/print-env-vars.ts +0 -32
- package/dev/test-tmux-graphics-334.sh +0 -68
- package/dev/thai-debug-test.ts +0 -68
- package/docs/development.md +0 -144
- package/scripts/build.ts +0 -400
- package/scripts/publish.ts +0 -60
- package/src/3d/SpriteResourceManager.ts +0 -286
- package/src/3d/SpriteUtils.ts +0 -70
- package/src/3d/TextureUtils.ts +0 -196
- package/src/3d/ThreeRenderable.ts +0 -197
- package/src/3d/WGPURenderer.ts +0 -294
- package/src/3d/animation/ExplodingSpriteEffect.ts +0 -513
- package/src/3d/animation/PhysicsExplodingSpriteEffect.ts +0 -429
- package/src/3d/animation/SpriteAnimator.ts +0 -633
- package/src/3d/animation/SpriteParticleGenerator.ts +0 -435
- package/src/3d/canvas.ts +0 -464
- package/src/3d/index.ts +0 -12
- package/src/3d/physics/PlanckPhysicsAdapter.ts +0 -72
- package/src/3d/physics/RapierPhysicsAdapter.ts +0 -66
- package/src/3d/physics/physics-interface.ts +0 -31
- package/src/3d/shaders/supersampling.wgsl +0 -201
- package/src/3d.ts +0 -3
- package/src/NativeSpanFeed.ts +0 -300
- package/src/Renderable.ts +0 -1704
- package/src/__snapshots__/buffer.test.ts.snap +0 -28
- package/src/animation/Timeline.test.ts +0 -2709
- package/src/animation/Timeline.ts +0 -598
- package/src/ansi.ts +0 -18
- package/src/benchmark/attenuation-benchmark.ts +0 -81
- package/src/benchmark/colormatrix-benchmark.ts +0 -128
- package/src/benchmark/gain-benchmark.ts +0 -80
- package/src/benchmark/latest-all-bench-run.json +0 -707
- package/src/benchmark/latest-async-bench-run.json +0 -336
- package/src/benchmark/latest-default-bench-run.json +0 -657
- package/src/benchmark/latest-large-bench-run.json +0 -707
- package/src/benchmark/latest-quick-bench-run.json +0 -207
- package/src/benchmark/markdown-benchmark.ts +0 -1796
- package/src/benchmark/native-span-feed-async-benchmark.ts +0 -355
- package/src/benchmark/native-span-feed-benchmark.md +0 -56
- package/src/benchmark/native-span-feed-benchmark.ts +0 -596
- package/src/benchmark/native-span-feed-compare.ts +0 -280
- package/src/benchmark/renderer-benchmark.ts +0 -754
- package/src/benchmark/text-table-benchmark.ts +0 -948
- package/src/buffer.test.ts +0 -291
- package/src/buffer.ts +0 -554
- package/src/console.test.ts +0 -612
- package/src/console.ts +0 -1254
- package/src/edit-buffer.test.ts +0 -1769
- package/src/edit-buffer.ts +0 -411
- package/src/editor-view.test.ts +0 -1032
- package/src/editor-view.ts +0 -284
- package/src/examples/ascii-font-selection-demo.ts +0 -245
- package/src/examples/assets/Water_2_M_Normal.jpg +0 -0
- package/src/examples/assets/concrete.png +0 -0
- package/src/examples/assets/crate.png +0 -0
- package/src/examples/assets/crate_emissive.png +0 -0
- package/src/examples/assets/forrest_background.png +0 -0
- package/src/examples/assets/hast-example.json +0 -1018
- package/src/examples/assets/heart.png +0 -0
- package/src/examples/assets/main_char_heavy_attack.png +0 -0
- package/src/examples/assets/main_char_idle.png +0 -0
- package/src/examples/assets/main_char_jump_end.png +0 -0
- package/src/examples/assets/main_char_jump_landing.png +0 -0
- package/src/examples/assets/main_char_jump_start.png +0 -0
- package/src/examples/assets/main_char_run_loop.png +0 -0
- package/src/examples/assets/roughness_map.jpg +0 -0
- package/src/examples/build.ts +0 -115
- package/src/examples/code-demo.ts +0 -924
- package/src/examples/console-demo.ts +0 -358
- package/src/examples/core-plugin-slots-demo.ts +0 -759
- package/src/examples/diff-demo.ts +0 -701
- package/src/examples/draggable-three-demo.ts +0 -259
- package/src/examples/editor-demo.ts +0 -322
- package/src/examples/extmarks-demo.ts +0 -196
- package/src/examples/focus-restore-demo.ts +0 -310
- package/src/examples/fonts.ts +0 -245
- package/src/examples/fractal-shader-demo.ts +0 -268
- package/src/examples/framebuffer-demo.ts +0 -674
- package/src/examples/full-unicode-demo.ts +0 -241
- package/src/examples/golden-star-demo.ts +0 -933
- package/src/examples/grayscale-buffer-demo.ts +0 -249
- package/src/examples/hast-syntax-highlighting-demo.ts +0 -129
- package/src/examples/index.ts +0 -926
- package/src/examples/input-demo.ts +0 -377
- package/src/examples/input-select-layout-demo.ts +0 -425
- package/src/examples/install.sh +0 -143
- package/src/examples/keypress-debug-demo.ts +0 -452
- package/src/examples/lib/HexList.ts +0 -122
- package/src/examples/lib/PaletteGrid.ts +0 -125
- package/src/examples/lib/standalone-keys.ts +0 -25
- package/src/examples/lib/tab-controller.ts +0 -243
- package/src/examples/lights-phong-demo.ts +0 -290
- package/src/examples/link-demo.ts +0 -220
- package/src/examples/live-state-demo.ts +0 -480
- package/src/examples/markdown-demo.ts +0 -725
- package/src/examples/mouse-interaction-demo.ts +0 -428
- package/src/examples/nested-zindex-demo.ts +0 -357
- package/src/examples/opacity-example.ts +0 -235
- package/src/examples/opentui-demo.ts +0 -1057
- package/src/examples/physx-planck-2d-demo.ts +0 -623
- package/src/examples/physx-rapier-2d-demo.ts +0 -655
- package/src/examples/relative-positioning-demo.ts +0 -323
- package/src/examples/scroll-example.ts +0 -214
- package/src/examples/scrollbox-mouse-test.ts +0 -112
- package/src/examples/scrollbox-overlay-hit-test.ts +0 -206
- package/src/examples/select-demo.ts +0 -237
- package/src/examples/shader-cube-demo.ts +0 -1015
- package/src/examples/simple-layout-example.ts +0 -591
- package/src/examples/slider-demo.ts +0 -617
- package/src/examples/split-mode-demo.ts +0 -453
- package/src/examples/sprite-animation-demo.ts +0 -443
- package/src/examples/sprite-particle-generator-demo.ts +0 -486
- package/src/examples/static-sprite-demo.ts +0 -193
- package/src/examples/sticky-scroll-example.ts +0 -308
- package/src/examples/styled-text-demo.ts +0 -282
- package/src/examples/tab-select-demo.ts +0 -219
- package/src/examples/terminal-title.ts +0 -29
- package/src/examples/terminal.ts +0 -305
- package/src/examples/text-node-demo.ts +0 -416
- package/src/examples/text-selection-demo.ts +0 -377
- package/src/examples/text-table-demo.ts +0 -503
- package/src/examples/text-truncation-demo.ts +0 -481
- package/src/examples/text-wrap.ts +0 -757
- package/src/examples/texture-loading-demo.ts +0 -259
- package/src/examples/timeline-example.ts +0 -670
- package/src/examples/transparency-demo.ts +0 -400
- package/src/examples/vnode-composition-demo.ts +0 -404
- package/src/examples/wide-grapheme-overlay-demo.ts +0 -280
- package/src/index.ts +0 -24
- package/src/lib/KeyHandler.integration.test.ts +0 -292
- package/src/lib/KeyHandler.stopPropagation.test.ts +0 -289
- package/src/lib/KeyHandler.test.ts +0 -662
- package/src/lib/KeyHandler.ts +0 -222
- package/src/lib/RGBA.test.ts +0 -984
- package/src/lib/RGBA.ts +0 -204
- package/src/lib/ascii.font.ts +0 -330
- package/src/lib/border.test.ts +0 -83
- package/src/lib/border.ts +0 -170
- package/src/lib/bunfs.test.ts +0 -27
- package/src/lib/bunfs.ts +0 -18
- package/src/lib/clipboard.test.ts +0 -41
- package/src/lib/clipboard.ts +0 -47
- package/src/lib/clock.ts +0 -35
- package/src/lib/data-paths.test.ts +0 -133
- package/src/lib/data-paths.ts +0 -109
- package/src/lib/debounce.ts +0 -106
- package/src/lib/detect-links.test.ts +0 -98
- package/src/lib/detect-links.ts +0 -56
- package/src/lib/env.test.ts +0 -228
- package/src/lib/env.ts +0 -209
- package/src/lib/extmarks-history.ts +0 -51
- package/src/lib/extmarks-multiwidth.test.ts +0 -322
- package/src/lib/extmarks.test.ts +0 -3457
- package/src/lib/extmarks.ts +0 -843
- package/src/lib/fonts/block.json +0 -405
- package/src/lib/fonts/grid.json +0 -265
- package/src/lib/fonts/huge.json +0 -741
- package/src/lib/fonts/pallet.json +0 -314
- package/src/lib/fonts/shade.json +0 -591
- package/src/lib/fonts/slick.json +0 -321
- package/src/lib/fonts/tiny.json +0 -69
- package/src/lib/hast-styled-text.ts +0 -59
- package/src/lib/index.ts +0 -21
- package/src/lib/keymapping.test.ts +0 -317
- package/src/lib/keymapping.ts +0 -115
- package/src/lib/objects-in-viewport.test.ts +0 -787
- package/src/lib/objects-in-viewport.ts +0 -153
- package/src/lib/output.capture.ts +0 -58
- package/src/lib/parse.keypress-kitty.protocol.test.ts +0 -340
- package/src/lib/parse.keypress-kitty.test.ts +0 -663
- package/src/lib/parse.keypress-kitty.ts +0 -439
- package/src/lib/parse.keypress.test.ts +0 -1849
- package/src/lib/parse.keypress.ts +0 -397
- package/src/lib/parse.mouse.test.ts +0 -552
- package/src/lib/parse.mouse.ts +0 -232
- package/src/lib/paste.ts +0 -16
- package/src/lib/queue.ts +0 -65
- package/src/lib/renderable.validations.test.ts +0 -87
- package/src/lib/renderable.validations.ts +0 -83
- package/src/lib/scroll-acceleration.ts +0 -98
- package/src/lib/selection.ts +0 -240
- package/src/lib/singleton.ts +0 -28
- package/src/lib/stdin-parser.test.ts +0 -2290
- package/src/lib/stdin-parser.ts +0 -1810
- package/src/lib/styled-text.ts +0 -178
- package/src/lib/terminal-capability-detection.test.ts +0 -202
- package/src/lib/terminal-capability-detection.ts +0 -79
- package/src/lib/terminal-palette.test.ts +0 -878
- package/src/lib/terminal-palette.ts +0 -383
- package/src/lib/tree-sitter/assets/README.md +0 -118
- package/src/lib/tree-sitter/assets/update.ts +0 -334
- package/src/lib/tree-sitter/assets.d.ts +0 -9
- package/src/lib/tree-sitter/cache.test.ts +0 -273
- package/src/lib/tree-sitter/client.test.ts +0 -1165
- package/src/lib/tree-sitter/client.ts +0 -607
- package/src/lib/tree-sitter/default-parsers.ts +0 -86
- package/src/lib/tree-sitter/download-utils.ts +0 -148
- package/src/lib/tree-sitter/index.ts +0 -28
- package/src/lib/tree-sitter/parser.worker.ts +0 -1042
- package/src/lib/tree-sitter/parsers-config.ts +0 -81
- package/src/lib/tree-sitter/resolve-ft.test.ts +0 -55
- package/src/lib/tree-sitter/resolve-ft.ts +0 -189
- package/src/lib/tree-sitter/types.ts +0 -82
- package/src/lib/tree-sitter-styled-text.test.ts +0 -1253
- package/src/lib/tree-sitter-styled-text.ts +0 -306
- package/src/lib/validate-dir-name.ts +0 -55
- package/src/lib/yoga.options.test.ts +0 -628
- package/src/lib/yoga.options.ts +0 -346
- package/src/plugins/core-slot.ts +0 -579
- package/src/plugins/registry.ts +0 -402
- package/src/plugins/types.ts +0 -46
- package/src/post/effects.ts +0 -930
- package/src/post/filters.ts +0 -489
- package/src/post/matrices.ts +0 -288
- package/src/renderables/ASCIIFont.ts +0 -219
- package/src/renderables/Box.test.ts +0 -205
- package/src/renderables/Box.ts +0 -326
- package/src/renderables/Code.test.ts +0 -2062
- package/src/renderables/Code.ts +0 -357
- package/src/renderables/Diff.regression.test.ts +0 -226
- package/src/renderables/Diff.test.ts +0 -3101
- package/src/renderables/Diff.ts +0 -1211
- package/src/renderables/EditBufferRenderable.test.ts +0 -288
- package/src/renderables/EditBufferRenderable.ts +0 -1166
- package/src/renderables/FrameBuffer.ts +0 -47
- package/src/renderables/Input.test.ts +0 -1228
- package/src/renderables/Input.ts +0 -247
- package/src/renderables/LineNumberRenderable.ts +0 -724
- package/src/renderables/Markdown.ts +0 -1393
- package/src/renderables/ScrollBar.ts +0 -422
- package/src/renderables/ScrollBox.ts +0 -883
- package/src/renderables/Select.test.ts +0 -1033
- package/src/renderables/Select.ts +0 -524
- package/src/renderables/Slider.test.ts +0 -456
- package/src/renderables/Slider.ts +0 -342
- package/src/renderables/TabSelect.test.ts +0 -197
- package/src/renderables/TabSelect.ts +0 -455
- package/src/renderables/Text.selection-buffer.test.ts +0 -123
- package/src/renderables/Text.test.ts +0 -2660
- package/src/renderables/Text.ts +0 -147
- package/src/renderables/TextBufferRenderable.ts +0 -518
- package/src/renderables/TextNode.test.ts +0 -1058
- package/src/renderables/TextNode.ts +0 -325
- package/src/renderables/TextTable.test.ts +0 -1421
- package/src/renderables/TextTable.ts +0 -1344
- package/src/renderables/Textarea.ts +0 -430
- package/src/renderables/TimeToFirstDraw.ts +0 -89
- package/src/renderables/__snapshots__/Code.test.ts.snap +0 -13
- package/src/renderables/__snapshots__/Diff.test.ts.snap +0 -785
- package/src/renderables/__snapshots__/Text.test.ts.snap +0 -421
- package/src/renderables/__snapshots__/TextTable.test.ts.snap +0 -215
- package/src/renderables/__tests__/LineNumberRenderable.scrollbox-simple.test.ts +0 -144
- package/src/renderables/__tests__/LineNumberRenderable.scrollbox.test.ts +0 -816
- package/src/renderables/__tests__/LineNumberRenderable.test.ts +0 -1865
- package/src/renderables/__tests__/LineNumberRenderable.wrapping.test.ts +0 -85
- package/src/renderables/__tests__/Markdown.code-colors.test.ts +0 -242
- package/src/renderables/__tests__/Markdown.test.ts +0 -2518
- package/src/renderables/__tests__/MultiRenderable.selection.test.ts +0 -87
- package/src/renderables/__tests__/Textarea.buffer.test.ts +0 -682
- package/src/renderables/__tests__/Textarea.destroyed-events.test.ts +0 -675
- package/src/renderables/__tests__/Textarea.editing.test.ts +0 -2041
- package/src/renderables/__tests__/Textarea.error-handling.test.ts +0 -35
- package/src/renderables/__tests__/Textarea.events.test.ts +0 -738
- package/src/renderables/__tests__/Textarea.highlights.test.ts +0 -590
- package/src/renderables/__tests__/Textarea.keybinding.test.ts +0 -3149
- package/src/renderables/__tests__/Textarea.paste.test.ts +0 -357
- package/src/renderables/__tests__/Textarea.rendering.test.ts +0 -1866
- package/src/renderables/__tests__/Textarea.scroll.test.ts +0 -733
- package/src/renderables/__tests__/Textarea.selection.test.ts +0 -1590
- package/src/renderables/__tests__/Textarea.stress.test.ts +0 -670
- package/src/renderables/__tests__/Textarea.undo-redo.test.ts +0 -383
- package/src/renderables/__tests__/Textarea.visual-lines.test.ts +0 -310
- package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.code.test.ts.snap +0 -221
- package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.scrollbox-simple.test.ts.snap +0 -89
- package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.scrollbox.test.ts.snap +0 -457
- package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.test.ts.snap +0 -158
- package/src/renderables/__tests__/__snapshots__/Textarea.rendering.test.ts.snap +0 -387
- package/src/renderables/__tests__/markdown-parser.test.ts +0 -217
- package/src/renderables/__tests__/renderable-test-utils.ts +0 -60
- package/src/renderables/composition/README.md +0 -8
- package/src/renderables/composition/VRenderable.ts +0 -32
- package/src/renderables/composition/constructs.ts +0 -127
- package/src/renderables/composition/vnode.ts +0 -289
- package/src/renderables/index.ts +0 -23
- package/src/renderables/markdown-parser.ts +0 -66
- package/src/renderer.ts +0 -2681
- package/src/runtime-plugin-support.ts +0 -39
- package/src/runtime-plugin.ts +0 -615
- package/src/syntax-style.test.ts +0 -841
- package/src/syntax-style.ts +0 -257
- package/src/testing/README.md +0 -210
- package/src/testing/capture-spans.test.ts +0 -194
- package/src/testing/integration.test.ts +0 -276
- package/src/testing/manual-clock.ts +0 -117
- package/src/testing/mock-keys.test.ts +0 -1378
- package/src/testing/mock-keys.ts +0 -457
- package/src/testing/mock-mouse.test.ts +0 -218
- package/src/testing/mock-mouse.ts +0 -247
- package/src/testing/mock-tree-sitter-client.ts +0 -73
- package/src/testing/spy.ts +0 -13
- package/src/testing/test-recorder.test.ts +0 -415
- package/src/testing/test-recorder.ts +0 -145
- package/src/testing/test-renderer.ts +0 -132
- package/src/testing.ts +0 -7
- package/src/tests/__snapshots__/absolute-positioning.snapshot.test.ts.snap +0 -481
- package/src/tests/__snapshots__/renderable.snapshot.test.ts.snap +0 -19
- package/src/tests/__snapshots__/scrollbox.test.ts.snap +0 -29
- package/src/tests/absolute-positioning.snapshot.test.ts +0 -638
- package/src/tests/allocator-stats.test.ts +0 -38
- package/src/tests/destroy-during-render.test.ts +0 -200
- package/src/tests/destroy-on-exit.fixture.ts +0 -36
- package/src/tests/destroy-on-exit.test.ts +0 -41
- package/src/tests/hover-cursor.test.ts +0 -98
- package/src/tests/native-span-feed-async.test.ts +0 -173
- package/src/tests/native-span-feed-close.test.ts +0 -120
- package/src/tests/native-span-feed-coverage.test.ts +0 -227
- package/src/tests/native-span-feed-edge-cases.test.ts +0 -352
- package/src/tests/native-span-feed-use-after-free.test.ts +0 -45
- package/src/tests/opacity.test.ts +0 -123
- package/src/tests/renderable.snapshot.test.ts +0 -524
- package/src/tests/renderable.test.ts +0 -1281
- package/src/tests/renderer.clock.test.ts +0 -158
- package/src/tests/renderer.console-startup.test.ts +0 -185
- package/src/tests/renderer.control.test.ts +0 -425
- package/src/tests/renderer.core-slot-binding.test.ts +0 -952
- package/src/tests/renderer.cursor.test.ts +0 -26
- package/src/tests/renderer.destroy-during-render.test.ts +0 -147
- package/src/tests/renderer.focus-restore.test.ts +0 -257
- package/src/tests/renderer.focus.test.ts +0 -294
- package/src/tests/renderer.idle.test.ts +0 -219
- package/src/tests/renderer.input.test.ts +0 -2237
- package/src/tests/renderer.kitty-flags.test.ts +0 -195
- package/src/tests/renderer.mouse.test.ts +0 -1274
- package/src/tests/renderer.palette.test.ts +0 -629
- package/src/tests/renderer.selection.test.ts +0 -49
- package/src/tests/renderer.slot-registry.test.ts +0 -684
- package/src/tests/renderer.useMouse.test.ts +0 -47
- package/src/tests/runtime-plugin-node-modules-cycle.fixture.ts +0 -76
- package/src/tests/runtime-plugin-node-modules-mjs.fixture.ts +0 -43
- package/src/tests/runtime-plugin-node-modules-no-bare-rewrite.fixture.ts +0 -67
- package/src/tests/runtime-plugin-node-modules-package-type-cache.fixture.ts +0 -72
- package/src/tests/runtime-plugin-node-modules-runtime-specifier.fixture.ts +0 -44
- package/src/tests/runtime-plugin-node-modules-scoped-package-bare-rewrite.fixture.ts +0 -85
- package/src/tests/runtime-plugin-path-alias.fixture.ts +0 -43
- package/src/tests/runtime-plugin-resolve-roots.fixture.ts +0 -65
- package/src/tests/runtime-plugin-support.fixture.ts +0 -11
- package/src/tests/runtime-plugin-support.test.ts +0 -19
- package/src/tests/runtime-plugin-windows-file-url.fixture.ts +0 -30
- package/src/tests/runtime-plugin.fixture.ts +0 -40
- package/src/tests/runtime-plugin.test.ts +0 -354
- package/src/tests/scrollbox-culling-bug.test.ts +0 -114
- package/src/tests/scrollbox-hitgrid-resize.test.ts +0 -136
- package/src/tests/scrollbox-hitgrid.test.ts +0 -909
- package/src/tests/scrollbox.test.ts +0 -1530
- package/src/tests/wrap-resize-perf.test.ts +0 -276
- package/src/tests/yoga-setters.test.ts +0 -921
- package/src/text-buffer-view.test.ts +0 -705
- package/src/text-buffer-view.ts +0 -189
- package/src/text-buffer.test.ts +0 -347
- package/src/text-buffer.ts +0 -250
- package/src/types.ts +0 -161
- package/src/utils.ts +0 -88
- package/src/zig/ansi.zig +0 -268
- package/src/zig/bench/README.md +0 -50
- package/src/zig/bench/buffer-draw-text-buffer_bench.zig +0 -887
- package/src/zig/bench/edit-buffer_bench.zig +0 -476
- package/src/zig/bench/native-span-feed_bench.zig +0 -100
- package/src/zig/bench/rope-markers_bench.zig +0 -713
- package/src/zig/bench/rope_bench.zig +0 -514
- package/src/zig/bench/styled-text_bench.zig +0 -470
- package/src/zig/bench/text-buffer-coords_bench.zig +0 -362
- package/src/zig/bench/text-buffer-view_bench.zig +0 -459
- package/src/zig/bench/text-chunk-graphemes_bench.zig +0 -273
- package/src/zig/bench/utf8_bench.zig +0 -799
- package/src/zig/bench-utils.zig +0 -431
- package/src/zig/bench.zig +0 -217
- package/src/zig/buffer-methods.zig +0 -211
- package/src/zig/buffer.zig +0 -2281
- package/src/zig/build.zig +0 -289
- package/src/zig/build.zig.zon +0 -16
- package/src/zig/edit-buffer.zig +0 -825
- package/src/zig/editor-view.zig +0 -802
- package/src/zig/event-bus.zig +0 -13
- package/src/zig/event-emitter.zig +0 -65
- package/src/zig/file-logger.zig +0 -92
- package/src/zig/grapheme.zig +0 -599
- package/src/zig/lib.zig +0 -1854
- package/src/zig/link.zig +0 -333
- package/src/zig/logger.zig +0 -43
- package/src/zig/mem-registry.zig +0 -125
- package/src/zig/native-span-feed-bench-lib.zig +0 -7
- package/src/zig/native-span-feed.zig +0 -708
- package/src/zig/renderer.zig +0 -1393
- package/src/zig/rope.zig +0 -1220
- package/src/zig/syntax-style.zig +0 -161
- package/src/zig/terminal.zig +0 -987
- package/src/zig/test.zig +0 -72
- package/src/zig/tests/README.md +0 -18
- package/src/zig/tests/buffer-methods_test.zig +0 -1109
- package/src/zig/tests/buffer_test.zig +0 -2557
- package/src/zig/tests/edit-buffer-history_test.zig +0 -271
- package/src/zig/tests/edit-buffer_test.zig +0 -1689
- package/src/zig/tests/editor-view_test.zig +0 -3299
- package/src/zig/tests/event-emitter_test.zig +0 -249
- package/src/zig/tests/grapheme_test.zig +0 -1304
- package/src/zig/tests/link_test.zig +0 -190
- package/src/zig/tests/mem-registry_test.zig +0 -473
- package/src/zig/tests/memory_leak_regression_test.zig +0 -159
- package/src/zig/tests/native-span-feed_test.zig +0 -1264
- package/src/zig/tests/renderer_test.zig +0 -1017
- package/src/zig/tests/rope-nested_test.zig +0 -712
- package/src/zig/tests/rope_fuzz_test.zig +0 -238
- package/src/zig/tests/rope_test.zig +0 -2362
- package/src/zig/tests/segment-merge.test.zig +0 -148
- package/src/zig/tests/syntax-style_test.zig +0 -557
- package/src/zig/tests/terminal_test.zig +0 -754
- package/src/zig/tests/text-buffer-drawing_test.zig +0 -3237
- package/src/zig/tests/text-buffer-highlights_test.zig +0 -666
- package/src/zig/tests/text-buffer-iterators_test.zig +0 -776
- package/src/zig/tests/text-buffer-segment_test.zig +0 -320
- package/src/zig/tests/text-buffer-selection_test.zig +0 -1035
- package/src/zig/tests/text-buffer-selection_viewport_test.zig +0 -358
- package/src/zig/tests/text-buffer-view_test.zig +0 -3649
- package/src/zig/tests/text-buffer_test.zig +0 -2191
- package/src/zig/tests/unicode-width-map.zon +0 -3909
- package/src/zig/tests/utf8_no_zwj_test.zig +0 -260
- package/src/zig/tests/utf8_test.zig +0 -4057
- package/src/zig/tests/utf8_wcwidth_cursor_test.zig +0 -267
- package/src/zig/tests/utf8_wcwidth_test.zig +0 -357
- package/src/zig/tests/word-wrap-editing_test.zig +0 -498
- package/src/zig/tests/wrap-cache-perf_test.zig +0 -113
- package/src/zig/text-buffer-iterators.zig +0 -499
- package/src/zig/text-buffer-segment.zig +0 -404
- package/src/zig/text-buffer-view.zig +0 -1371
- package/src/zig/text-buffer.zig +0 -1180
- package/src/zig/utf8.zig +0 -1948
- package/src/zig/utils.zig +0 -9
- package/src/zig-structs.ts +0 -261
- package/src/zig.ts +0 -3884
- package/tsconfig.build.json +0 -24
- package/tsconfig.json +0 -27
- /package/{src/lib/tree-sitter/assets → assets}/javascript/highlights.scm +0 -0
- /package/{src/lib/tree-sitter/assets → assets}/javascript/tree-sitter-javascript.wasm +0 -0
- /package/{src/lib/tree-sitter/assets → assets}/markdown/highlights.scm +0 -0
- /package/{src/lib/tree-sitter/assets → assets}/markdown/injections.scm +0 -0
- /package/{src/lib/tree-sitter/assets → assets}/markdown/tree-sitter-markdown.wasm +0 -0
- /package/{src/lib/tree-sitter/assets → assets}/markdown_inline/highlights.scm +0 -0
- /package/{src/lib/tree-sitter/assets → assets}/markdown_inline/tree-sitter-markdown_inline.wasm +0 -0
- /package/{src/lib/tree-sitter/assets → assets}/typescript/highlights.scm +0 -0
- /package/{src/lib/tree-sitter/assets → assets}/typescript/tree-sitter-typescript.wasm +0 -0
- /package/{src/lib/tree-sitter/assets → assets}/zig/highlights.scm +0 -0
- /package/{src/lib/tree-sitter/assets → assets}/zig/tree-sitter-zig.wasm +0 -0
|
@@ -1,1393 +0,0 @@
|
|
|
1
|
-
import { Renderable, type RenderableOptions } from "../Renderable.js"
|
|
2
|
-
import { type RenderContext } from "../types.js"
|
|
3
|
-
import { SyntaxStyle, type StyleDefinition } from "../syntax-style.js"
|
|
4
|
-
import type { TextChunk } from "../text-buffer.js"
|
|
5
|
-
import { createTextAttributes } from "../utils.js"
|
|
6
|
-
import type { BorderStyle } from "../lib/border.js"
|
|
7
|
-
import { RGBA, parseColor, type ColorInput } from "../lib/RGBA.js"
|
|
8
|
-
import { type MarkedToken, type Token, type Tokens } from "marked"
|
|
9
|
-
import { CodeRenderable, type OnChunksCallback } from "./Code.js"
|
|
10
|
-
import {
|
|
11
|
-
TextTableRenderable,
|
|
12
|
-
type TextTableCellContent,
|
|
13
|
-
type TextTableColumnFitter,
|
|
14
|
-
type TextTableColumnWidthMode,
|
|
15
|
-
type TextTableContent,
|
|
16
|
-
} from "./TextTable.js"
|
|
17
|
-
import type { TreeSitterClient } from "../lib/tree-sitter/index.js"
|
|
18
|
-
import { infoStringToFiletype } from "../lib/tree-sitter/resolve-ft.js"
|
|
19
|
-
import { parseMarkdownIncremental, type ParseState } from "./markdown-parser.js"
|
|
20
|
-
import type { OptimizedBuffer } from "../buffer.js"
|
|
21
|
-
import { detectLinks } from "../lib/detect-links.js"
|
|
22
|
-
|
|
23
|
-
export interface MarkdownTableOptions {
|
|
24
|
-
/**
|
|
25
|
-
* Strategy for sizing table columns.
|
|
26
|
-
* - "content": columns fit to intrinsic content width.
|
|
27
|
-
* - "full": columns expand to fill available width.
|
|
28
|
-
*/
|
|
29
|
-
widthMode?: TextTableColumnWidthMode
|
|
30
|
-
/**
|
|
31
|
-
* Column fitting method when shrinking constrained tables.
|
|
32
|
-
*/
|
|
33
|
-
columnFitter?: TextTableColumnFitter
|
|
34
|
-
/**
|
|
35
|
-
* Wrapping strategy for table cell content.
|
|
36
|
-
*/
|
|
37
|
-
wrapMode?: "none" | "char" | "word"
|
|
38
|
-
/**
|
|
39
|
-
* Padding applied on all sides of each table cell.
|
|
40
|
-
*/
|
|
41
|
-
cellPadding?: number
|
|
42
|
-
/**
|
|
43
|
-
* Enables/disables table border rendering.
|
|
44
|
-
*/
|
|
45
|
-
borders?: boolean
|
|
46
|
-
/**
|
|
47
|
-
* Overrides outer border visibility. Defaults to `borders`.
|
|
48
|
-
*/
|
|
49
|
-
outerBorder?: boolean
|
|
50
|
-
/**
|
|
51
|
-
* Border style for markdown tables.
|
|
52
|
-
*/
|
|
53
|
-
borderStyle?: BorderStyle
|
|
54
|
-
/**
|
|
55
|
-
* Border color for markdown tables. Defaults to conceal style color.
|
|
56
|
-
*/
|
|
57
|
-
borderColor?: ColorInput
|
|
58
|
-
/**
|
|
59
|
-
* Enables/disables selection support on markdown tables.
|
|
60
|
-
*/
|
|
61
|
-
selectable?: boolean
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export interface MarkdownOptions extends RenderableOptions<MarkdownRenderable> {
|
|
65
|
-
content?: string
|
|
66
|
-
syntaxStyle: SyntaxStyle
|
|
67
|
-
fg?: ColorInput
|
|
68
|
-
bg?: ColorInput
|
|
69
|
-
/** Controls concealment for markdown syntax markers in markdown text blocks. */
|
|
70
|
-
conceal?: boolean
|
|
71
|
-
/** Controls concealment inside fenced code blocks rendered by CodeRenderable. */
|
|
72
|
-
concealCode?: boolean
|
|
73
|
-
treeSitterClient?: TreeSitterClient
|
|
74
|
-
/**
|
|
75
|
-
* Enable streaming mode for incremental content updates.
|
|
76
|
-
*
|
|
77
|
-
* Semantics:
|
|
78
|
-
* - The trailing markdown block stays unstable while streaming is enabled.
|
|
79
|
-
* - Tables render all rows produced by the markdown parser (including trailing rows).
|
|
80
|
-
* - Incomplete table rows are normalized by the parser and rendered with empty cells
|
|
81
|
-
* where data is missing.
|
|
82
|
-
*
|
|
83
|
-
* Expectations:
|
|
84
|
-
* - Keep this true while chunks are still being appended.
|
|
85
|
-
* - Set this to false once streaming is complete to finalize trailing token parsing.
|
|
86
|
-
*/
|
|
87
|
-
streaming?: boolean
|
|
88
|
-
/**
|
|
89
|
-
* Options for internally rendered markdown tables.
|
|
90
|
-
*/
|
|
91
|
-
tableOptions?: MarkdownTableOptions
|
|
92
|
-
/**
|
|
93
|
-
* Custom node renderer. Return a Renderable to override default rendering,
|
|
94
|
-
* or undefined/null to use default rendering.
|
|
95
|
-
*/
|
|
96
|
-
renderNode?: (token: Token, context: RenderNodeContext) => Renderable | undefined | null
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export interface RenderNodeContext {
|
|
100
|
-
syntaxStyle: SyntaxStyle
|
|
101
|
-
conceal: boolean
|
|
102
|
-
concealCode: boolean
|
|
103
|
-
treeSitterClient?: TreeSitterClient
|
|
104
|
-
/** Creates default renderable for this token */
|
|
105
|
-
defaultRender: () => Renderable | null
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
interface TableContentCache {
|
|
109
|
-
content: TextTableContent
|
|
110
|
-
cellKeys: Uint32Array[]
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
interface ResolvedTableRenderableOptions {
|
|
114
|
-
columnWidthMode: TextTableColumnWidthMode
|
|
115
|
-
columnFitter: TextTableColumnFitter
|
|
116
|
-
wrapMode: "none" | "char" | "word"
|
|
117
|
-
cellPadding: number
|
|
118
|
-
border: boolean
|
|
119
|
-
outerBorder: boolean
|
|
120
|
-
showBorders: boolean
|
|
121
|
-
borderStyle: BorderStyle
|
|
122
|
-
borderColor: ColorInput
|
|
123
|
-
selectable: boolean
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const TRAILING_MARKDOWN_BLOCK_BREAKS_RE = /(?:\r?\n)+$/
|
|
127
|
-
|
|
128
|
-
function colorsEqual(left?: RGBA, right?: RGBA): boolean {
|
|
129
|
-
if (!left || !right) return left === right
|
|
130
|
-
return left.equals(right)
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export interface BlockState {
|
|
134
|
-
token: MarkedToken
|
|
135
|
-
tokenRaw: string // Cache raw for comparison
|
|
136
|
-
renderable: Renderable
|
|
137
|
-
tableContentCache?: TableContentCache
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
export type { ParseState }
|
|
141
|
-
|
|
142
|
-
export class MarkdownRenderable extends Renderable {
|
|
143
|
-
private _content: string = ""
|
|
144
|
-
private _syntaxStyle: SyntaxStyle
|
|
145
|
-
private _fg?: RGBA
|
|
146
|
-
private _bg?: RGBA
|
|
147
|
-
private _conceal: boolean
|
|
148
|
-
private _concealCode: boolean
|
|
149
|
-
private _treeSitterClient?: TreeSitterClient
|
|
150
|
-
private _tableOptions?: MarkdownTableOptions
|
|
151
|
-
private _renderNode?: MarkdownOptions["renderNode"]
|
|
152
|
-
|
|
153
|
-
_parseState: ParseState | null = null
|
|
154
|
-
private _streaming: boolean = false
|
|
155
|
-
_blockStates: BlockState[] = []
|
|
156
|
-
private _styleDirty: boolean = false
|
|
157
|
-
private _linkifyMarkdownChunks: OnChunksCallback = (chunks, context) =>
|
|
158
|
-
detectLinks(chunks, {
|
|
159
|
-
content: context.content,
|
|
160
|
-
highlights: context.highlights,
|
|
161
|
-
})
|
|
162
|
-
|
|
163
|
-
private _inlineConcealChunks: OnChunksCallback = (chunks, context) => {
|
|
164
|
-
return this.buildInlineConcealChunks(chunks, context)
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
protected _contentDefaultOptions = {
|
|
168
|
-
content: "",
|
|
169
|
-
conceal: true,
|
|
170
|
-
concealCode: false,
|
|
171
|
-
streaming: false,
|
|
172
|
-
} satisfies Partial<MarkdownOptions>
|
|
173
|
-
|
|
174
|
-
constructor(ctx: RenderContext, options: MarkdownOptions) {
|
|
175
|
-
super(ctx, {
|
|
176
|
-
...options,
|
|
177
|
-
flexDirection: "column",
|
|
178
|
-
flexShrink: options.flexShrink ?? 0,
|
|
179
|
-
})
|
|
180
|
-
|
|
181
|
-
this._syntaxStyle = options.syntaxStyle
|
|
182
|
-
this._fg = options.fg ? parseColor(options.fg) : undefined
|
|
183
|
-
this._bg = options.bg ? parseColor(options.bg) : undefined
|
|
184
|
-
this._conceal = options.conceal ?? this._contentDefaultOptions.conceal
|
|
185
|
-
this._concealCode = options.concealCode ?? this._contentDefaultOptions.concealCode
|
|
186
|
-
this._content = options.content ?? this._contentDefaultOptions.content
|
|
187
|
-
this._treeSitterClient = options.treeSitterClient
|
|
188
|
-
this._tableOptions = options.tableOptions
|
|
189
|
-
this._renderNode = options.renderNode
|
|
190
|
-
this._streaming = options.streaming ?? this._contentDefaultOptions.streaming
|
|
191
|
-
|
|
192
|
-
this.updateBlocks()
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
get content(): string {
|
|
196
|
-
return this._content
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
set content(value: string) {
|
|
200
|
-
if (this.isDestroyed) return
|
|
201
|
-
if (this._content !== value) {
|
|
202
|
-
this._content = value
|
|
203
|
-
this.updateBlocks()
|
|
204
|
-
this.requestRender()
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
get syntaxStyle(): SyntaxStyle {
|
|
209
|
-
return this._syntaxStyle
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
set syntaxStyle(value: SyntaxStyle) {
|
|
213
|
-
if (this._syntaxStyle !== value) {
|
|
214
|
-
this._syntaxStyle = value
|
|
215
|
-
// Mark dirty - actual re-render happens in renderSelf
|
|
216
|
-
this._styleDirty = true
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
get fg(): RGBA | undefined {
|
|
221
|
-
return this._fg
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
set fg(value: ColorInput | undefined) {
|
|
225
|
-
const next = value ? parseColor(value) : undefined
|
|
226
|
-
if (!colorsEqual(this._fg, next)) {
|
|
227
|
-
this._fg = next
|
|
228
|
-
this._styleDirty = true
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
get bg(): RGBA | undefined {
|
|
233
|
-
return this._bg
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
set bg(value: ColorInput | undefined) {
|
|
237
|
-
const next = value ? parseColor(value) : undefined
|
|
238
|
-
if (!colorsEqual(this._bg, next)) {
|
|
239
|
-
this._bg = next
|
|
240
|
-
this._styleDirty = true
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
get conceal(): boolean {
|
|
245
|
-
return this._conceal
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
set conceal(value: boolean) {
|
|
249
|
-
if (this._conceal !== value) {
|
|
250
|
-
this._conceal = value
|
|
251
|
-
// Mark dirty - actual re-render happens in renderSelf
|
|
252
|
-
this._styleDirty = true
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
get concealCode(): boolean {
|
|
257
|
-
return this._concealCode
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
set concealCode(value: boolean) {
|
|
261
|
-
if (this._concealCode !== value) {
|
|
262
|
-
this._concealCode = value
|
|
263
|
-
// Mark dirty - actual re-render happens in renderSelf
|
|
264
|
-
this._styleDirty = true
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
get streaming(): boolean {
|
|
269
|
-
return this._streaming
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
set streaming(value: boolean) {
|
|
273
|
-
if (this.isDestroyed) return
|
|
274
|
-
if (this._streaming !== value) {
|
|
275
|
-
this._streaming = value
|
|
276
|
-
this.updateBlocks(true)
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
get tableOptions(): MarkdownTableOptions | undefined {
|
|
281
|
-
return this._tableOptions
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
set tableOptions(value: MarkdownTableOptions | undefined) {
|
|
285
|
-
this._tableOptions = value
|
|
286
|
-
this.applyTableOptionsToBlocks()
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
private getStyle(group: string): StyleDefinition | undefined {
|
|
290
|
-
// The solid reconciler applies props via setters in JSX declaration order.
|
|
291
|
-
// If `content` is set before `syntaxStyle`, updateBlocks() runs before
|
|
292
|
-
// _syntaxStyle is initialized.
|
|
293
|
-
if (!this._syntaxStyle) return undefined
|
|
294
|
-
let style = this._syntaxStyle.getStyle(group)
|
|
295
|
-
if (!style && group.includes(".")) {
|
|
296
|
-
const baseName = group.split(".")[0]
|
|
297
|
-
style = this._syntaxStyle.getStyle(baseName)
|
|
298
|
-
}
|
|
299
|
-
return style
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
private createChunk(text: string, group: string, link?: { url: string }): TextChunk {
|
|
303
|
-
const style = this.getStyle(group) || this.getStyle("default")
|
|
304
|
-
return {
|
|
305
|
-
__isChunk: true,
|
|
306
|
-
text,
|
|
307
|
-
fg: style?.fg,
|
|
308
|
-
bg: style?.bg,
|
|
309
|
-
attributes: style
|
|
310
|
-
? createTextAttributes({
|
|
311
|
-
bold: style.bold,
|
|
312
|
-
italic: style.italic,
|
|
313
|
-
underline: style.underline,
|
|
314
|
-
dim: style.dim,
|
|
315
|
-
})
|
|
316
|
-
: 0,
|
|
317
|
-
link,
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
private createDefaultChunk(text: string): TextChunk {
|
|
322
|
-
return this.createChunk(text, "default")
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
private renderInlineContent(tokens: Token[], chunks: TextChunk[]): void {
|
|
326
|
-
for (const token of tokens) {
|
|
327
|
-
this.renderInlineToken(token as MarkedToken, chunks)
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
private renderInlineToken(token: MarkedToken, chunks: TextChunk[]): void {
|
|
332
|
-
switch (token.type) {
|
|
333
|
-
case "text":
|
|
334
|
-
chunks.push(this.createDefaultChunk(token.text))
|
|
335
|
-
break
|
|
336
|
-
|
|
337
|
-
case "escape":
|
|
338
|
-
chunks.push(this.createDefaultChunk(token.text))
|
|
339
|
-
break
|
|
340
|
-
|
|
341
|
-
case "codespan":
|
|
342
|
-
if (this._conceal) {
|
|
343
|
-
chunks.push(this.createChunk(token.text, "markup.raw"))
|
|
344
|
-
} else {
|
|
345
|
-
chunks.push(this.createChunk("`", "markup.raw"))
|
|
346
|
-
chunks.push(this.createChunk(token.text, "markup.raw"))
|
|
347
|
-
chunks.push(this.createChunk("`", "markup.raw"))
|
|
348
|
-
}
|
|
349
|
-
break
|
|
350
|
-
|
|
351
|
-
case "strong":
|
|
352
|
-
if (!this._conceal) {
|
|
353
|
-
chunks.push(this.createChunk("**", "markup.strong"))
|
|
354
|
-
}
|
|
355
|
-
for (const child of token.tokens) {
|
|
356
|
-
this.renderInlineTokenWithStyle(child as MarkedToken, chunks, "markup.strong")
|
|
357
|
-
}
|
|
358
|
-
if (!this._conceal) {
|
|
359
|
-
chunks.push(this.createChunk("**", "markup.strong"))
|
|
360
|
-
}
|
|
361
|
-
break
|
|
362
|
-
|
|
363
|
-
case "em":
|
|
364
|
-
if (!this._conceal) {
|
|
365
|
-
chunks.push(this.createChunk("*", "markup.italic"))
|
|
366
|
-
}
|
|
367
|
-
for (const child of token.tokens) {
|
|
368
|
-
this.renderInlineTokenWithStyle(child as MarkedToken, chunks, "markup.italic")
|
|
369
|
-
}
|
|
370
|
-
if (!this._conceal) {
|
|
371
|
-
chunks.push(this.createChunk("*", "markup.italic"))
|
|
372
|
-
}
|
|
373
|
-
break
|
|
374
|
-
|
|
375
|
-
case "del":
|
|
376
|
-
if (!this._conceal) {
|
|
377
|
-
chunks.push(this.createChunk("~~", "markup.strikethrough"))
|
|
378
|
-
}
|
|
379
|
-
for (const child of token.tokens) {
|
|
380
|
-
this.renderInlineTokenWithStyle(child as MarkedToken, chunks, "markup.strikethrough")
|
|
381
|
-
}
|
|
382
|
-
if (!this._conceal) {
|
|
383
|
-
chunks.push(this.createChunk("~~", "markup.strikethrough"))
|
|
384
|
-
}
|
|
385
|
-
break
|
|
386
|
-
|
|
387
|
-
case "link": {
|
|
388
|
-
const linkHref = { url: token.href }
|
|
389
|
-
if (this._conceal) {
|
|
390
|
-
for (const child of token.tokens) {
|
|
391
|
-
this.renderInlineTokenWithStyle(child as MarkedToken, chunks, "markup.link.label", linkHref)
|
|
392
|
-
}
|
|
393
|
-
chunks.push(this.createChunk(" (", "markup.link", linkHref))
|
|
394
|
-
chunks.push(this.createChunk(token.href, "markup.link.url", linkHref))
|
|
395
|
-
chunks.push(this.createChunk(")", "markup.link", linkHref))
|
|
396
|
-
} else {
|
|
397
|
-
chunks.push(this.createChunk("[", "markup.link", linkHref))
|
|
398
|
-
for (const child of token.tokens) {
|
|
399
|
-
this.renderInlineTokenWithStyle(child as MarkedToken, chunks, "markup.link.label", linkHref)
|
|
400
|
-
}
|
|
401
|
-
chunks.push(this.createChunk("](", "markup.link", linkHref))
|
|
402
|
-
chunks.push(this.createChunk(token.href, "markup.link.url", linkHref))
|
|
403
|
-
chunks.push(this.createChunk(")", "markup.link", linkHref))
|
|
404
|
-
}
|
|
405
|
-
break
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
case "image": {
|
|
409
|
-
const imageHref = { url: token.href }
|
|
410
|
-
if (this._conceal) {
|
|
411
|
-
chunks.push(this.createChunk(token.text || "image", "markup.link.label", imageHref))
|
|
412
|
-
} else {
|
|
413
|
-
chunks.push(this.createChunk(")
|
|
416
|
-
chunks.push(this.createChunk(token.href, "markup.link.url", imageHref))
|
|
417
|
-
chunks.push(this.createChunk(")", "markup.link", imageHref))
|
|
418
|
-
}
|
|
419
|
-
break
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
case "br":
|
|
423
|
-
chunks.push(this.createDefaultChunk("\n"))
|
|
424
|
-
break
|
|
425
|
-
|
|
426
|
-
default:
|
|
427
|
-
if ("tokens" in token && Array.isArray(token.tokens)) {
|
|
428
|
-
this.renderInlineContent(token.tokens, chunks)
|
|
429
|
-
} else if ("text" in token && typeof token.text === "string") {
|
|
430
|
-
chunks.push(this.createDefaultChunk(token.text))
|
|
431
|
-
}
|
|
432
|
-
break
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
private renderInlineTokenWithStyle(
|
|
437
|
-
token: MarkedToken,
|
|
438
|
-
chunks: TextChunk[],
|
|
439
|
-
styleGroup: string,
|
|
440
|
-
link?: { url: string },
|
|
441
|
-
): void {
|
|
442
|
-
switch (token.type) {
|
|
443
|
-
case "text":
|
|
444
|
-
chunks.push(this.createChunk(token.text, styleGroup, link))
|
|
445
|
-
break
|
|
446
|
-
|
|
447
|
-
case "escape":
|
|
448
|
-
chunks.push(this.createChunk(token.text, styleGroup, link))
|
|
449
|
-
break
|
|
450
|
-
|
|
451
|
-
case "codespan":
|
|
452
|
-
if (this._conceal) {
|
|
453
|
-
chunks.push(this.createChunk(token.text, "markup.raw", link))
|
|
454
|
-
} else {
|
|
455
|
-
chunks.push(this.createChunk("`", "markup.raw", link))
|
|
456
|
-
chunks.push(this.createChunk(token.text, "markup.raw", link))
|
|
457
|
-
chunks.push(this.createChunk("`", "markup.raw", link))
|
|
458
|
-
}
|
|
459
|
-
break
|
|
460
|
-
|
|
461
|
-
default:
|
|
462
|
-
this.renderInlineToken(token, chunks)
|
|
463
|
-
break
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
private buildInlineConcealChunks(chunks: TextChunk[], context: { content: string; highlights: any[] }): TextChunk[] {
|
|
468
|
-
// Re-parse with marked to get inline tokens, then render with concealment.
|
|
469
|
-
// Falls back to original chunks if inline rendering produces nothing.
|
|
470
|
-
const result: TextChunk[] = []
|
|
471
|
-
try {
|
|
472
|
-
const parsed = parseMarkdownIncremental(context.content, null, 0)
|
|
473
|
-
const tokens = parsed.tokens
|
|
474
|
-
for (const token of tokens) {
|
|
475
|
-
this.renderBlockTokenInline(token, result)
|
|
476
|
-
}
|
|
477
|
-
} catch {
|
|
478
|
-
return chunks
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
// Remove trailing newline added by renderBlockTokenInline
|
|
482
|
-
if (result.length > 0 && result[result.length - 1].text === "\n") {
|
|
483
|
-
result.pop()
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
if (result.length === 0) return chunks
|
|
487
|
-
|
|
488
|
-
// Apply linkification on top of inline-rendered chunks
|
|
489
|
-
const linked = this._linkifyMarkdownChunks(result, context as any)
|
|
490
|
-
if (Array.isArray(linked)) return linked
|
|
491
|
-
return result
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
private renderBlockTokenInline(token: MarkedToken, chunks: TextChunk[]): void {
|
|
495
|
-
switch (token.type) {
|
|
496
|
-
case "heading": {
|
|
497
|
-
const headingToken = token as Tokens.Heading
|
|
498
|
-
const style = `markup.heading.${headingToken.depth}`
|
|
499
|
-
for (const child of headingToken.tokens) {
|
|
500
|
-
this.renderInlineTokenWithStyle(child as MarkedToken, chunks, style)
|
|
501
|
-
}
|
|
502
|
-
chunks.push(this.createDefaultChunk("\n"))
|
|
503
|
-
break
|
|
504
|
-
}
|
|
505
|
-
case "paragraph": {
|
|
506
|
-
const paragraphToken = token as Tokens.Paragraph
|
|
507
|
-
this.renderInlineContent(paragraphToken.tokens, chunks)
|
|
508
|
-
chunks.push(this.createDefaultChunk("\n"))
|
|
509
|
-
break
|
|
510
|
-
}
|
|
511
|
-
case "list": {
|
|
512
|
-
this.renderListInline(token as Tokens.List, chunks, 0)
|
|
513
|
-
break
|
|
514
|
-
}
|
|
515
|
-
case "blockquote": {
|
|
516
|
-
const quoteToken = token as Tokens.Blockquote
|
|
517
|
-
for (const child of quoteToken.tokens) {
|
|
518
|
-
const markedChild = child as MarkedToken
|
|
519
|
-
if (markedChild.type === "paragraph" && "tokens" in markedChild) {
|
|
520
|
-
chunks.push(this.createChunk("▎ ", "markup.quote"))
|
|
521
|
-
for (const inline of (markedChild as Tokens.Paragraph).tokens) {
|
|
522
|
-
this.renderInlineTokenWithStyle(inline as MarkedToken, chunks, "markup.quote")
|
|
523
|
-
}
|
|
524
|
-
chunks.push(this.createDefaultChunk("\n"))
|
|
525
|
-
} else if (markedChild.type === "table") {
|
|
526
|
-
// Reconstruct pipe table from structured token data so every row
|
|
527
|
-
// gets the blockquote ▎ prefix (tbl.raw may only have > on first line)
|
|
528
|
-
const tbl = markedChild as Tokens.Table
|
|
529
|
-
const headerCells = tbl.header.map((h) => h.text || " ").join(" | ")
|
|
530
|
-
const sepCells = tbl.header.map(() => "---").join(" | ")
|
|
531
|
-
const tableLines = [
|
|
532
|
-
`| ${headerCells} |`,
|
|
533
|
-
`| ${sepCells} |`,
|
|
534
|
-
...tbl.rows.map((row) => `| ${row.map((c) => c.text || " ").join(" | ")} |`),
|
|
535
|
-
]
|
|
536
|
-
for (const line of tableLines) {
|
|
537
|
-
chunks.push(this.createChunk("▎ ", "markup.quote"))
|
|
538
|
-
chunks.push(this.createDefaultChunk(line + "\n"))
|
|
539
|
-
}
|
|
540
|
-
} else {
|
|
541
|
-
chunks.push(this.createChunk("▎ ", "markup.quote"))
|
|
542
|
-
this.renderBlockTokenInline(markedChild, chunks)
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
break
|
|
546
|
-
}
|
|
547
|
-
case "code": {
|
|
548
|
-
// Fenced code blocks that ended up in the inline path (rare — normally
|
|
549
|
-
// handled separately by createCodeRenderable). Render as raw block.
|
|
550
|
-
const codeToken = token as Tokens.Code
|
|
551
|
-
const rawStyle = this.getStyle("markup.raw.block")
|
|
552
|
-
const codeText = codeToken.text
|
|
553
|
-
for (const line of codeText.split("\n")) {
|
|
554
|
-
chunks.push({
|
|
555
|
-
__isChunk: true,
|
|
556
|
-
text: " " + line,
|
|
557
|
-
fg: rawStyle?.fg,
|
|
558
|
-
bg: rawStyle?.bg,
|
|
559
|
-
attributes: rawStyle
|
|
560
|
-
? createTextAttributes({
|
|
561
|
-
bold: rawStyle.bold,
|
|
562
|
-
italic: rawStyle.italic,
|
|
563
|
-
underline: rawStyle.underline,
|
|
564
|
-
dim: rawStyle.dim,
|
|
565
|
-
})
|
|
566
|
-
: 0,
|
|
567
|
-
})
|
|
568
|
-
chunks.push(this.createDefaultChunk("\n"))
|
|
569
|
-
}
|
|
570
|
-
break
|
|
571
|
-
}
|
|
572
|
-
case "html": {
|
|
573
|
-
// Inline/block HTML — render as raw text
|
|
574
|
-
chunks.push(this.createDefaultChunk(token.text))
|
|
575
|
-
chunks.push(this.createDefaultChunk("\n"))
|
|
576
|
-
break
|
|
577
|
-
}
|
|
578
|
-
case "hr": {
|
|
579
|
-
const hrStyle = this.getStyle("punctuation.special")
|
|
580
|
-
chunks.push({
|
|
581
|
-
__isChunk: true,
|
|
582
|
-
text: "─".repeat(40),
|
|
583
|
-
fg: hrStyle?.fg,
|
|
584
|
-
bg: hrStyle?.bg,
|
|
585
|
-
attributes: hrStyle
|
|
586
|
-
? createTextAttributes({
|
|
587
|
-
bold: hrStyle.bold,
|
|
588
|
-
italic: hrStyle.italic,
|
|
589
|
-
underline: hrStyle.underline,
|
|
590
|
-
dim: hrStyle.dim,
|
|
591
|
-
})
|
|
592
|
-
: 0,
|
|
593
|
-
})
|
|
594
|
-
chunks.push(this.createDefaultChunk("\n"))
|
|
595
|
-
break
|
|
596
|
-
}
|
|
597
|
-
case "table": {
|
|
598
|
-
// Tables that ended up in the inline path (rare — normally handled
|
|
599
|
-
// separately by createTextTableRenderable). Render as raw text.
|
|
600
|
-
chunks.push(this.createDefaultChunk((token as any).raw ?? ""))
|
|
601
|
-
chunks.push(this.createDefaultChunk("\n"))
|
|
602
|
-
break
|
|
603
|
-
}
|
|
604
|
-
case "def":
|
|
605
|
-
// Link reference definitions — not rendered visually
|
|
606
|
-
break
|
|
607
|
-
case "space":
|
|
608
|
-
chunks.push(this.createDefaultChunk("\n"))
|
|
609
|
-
break
|
|
610
|
-
default:
|
|
611
|
-
if ("tokens" in token && Array.isArray(token.tokens)) {
|
|
612
|
-
this.renderInlineContent(token.tokens, chunks)
|
|
613
|
-
} else {
|
|
614
|
-
chunks.push(this.createDefaultChunk((token as any).raw ?? ""))
|
|
615
|
-
}
|
|
616
|
-
chunks.push(this.createDefaultChunk("\n"))
|
|
617
|
-
break
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
private renderListInline(list: Tokens.List, chunks: TextChunk[], depth: number): void {
|
|
622
|
-
const listStyle = this.getStyle("markup.list")
|
|
623
|
-
const checkedStyle = this.getStyle("markup.list.checked")
|
|
624
|
-
const uncheckedStyle = this.getStyle("markup.list.unchecked")
|
|
625
|
-
for (let i = 0; i < list.items.length; i++) {
|
|
626
|
-
const item = list.items[i]
|
|
627
|
-
const indent = " ".repeat(depth)
|
|
628
|
-
const start = typeof list.start === "number" ? list.start : 1
|
|
629
|
-
|
|
630
|
-
// Task list items: show checkbox
|
|
631
|
-
if (item.task) {
|
|
632
|
-
const checkmark = item.checked ? "☑ " : "☐ "
|
|
633
|
-
const checkStyle = item.checked ? checkedStyle : uncheckedStyle
|
|
634
|
-
chunks.push({
|
|
635
|
-
__isChunk: true,
|
|
636
|
-
text: indent + checkmark,
|
|
637
|
-
fg: checkStyle?.fg ?? listStyle?.fg,
|
|
638
|
-
bg: checkStyle?.bg ?? listStyle?.bg,
|
|
639
|
-
attributes: checkStyle
|
|
640
|
-
? createTextAttributes({
|
|
641
|
-
bold: checkStyle.bold,
|
|
642
|
-
italic: checkStyle.italic,
|
|
643
|
-
underline: checkStyle.underline,
|
|
644
|
-
dim: checkStyle.dim,
|
|
645
|
-
})
|
|
646
|
-
: 0,
|
|
647
|
-
})
|
|
648
|
-
} else {
|
|
649
|
-
const bullet = list.ordered ? `${start + i}. ` : "• "
|
|
650
|
-
chunks.push({
|
|
651
|
-
__isChunk: true,
|
|
652
|
-
text: indent + bullet,
|
|
653
|
-
fg: listStyle?.fg,
|
|
654
|
-
bg: listStyle?.bg,
|
|
655
|
-
attributes: listStyle
|
|
656
|
-
? createTextAttributes({
|
|
657
|
-
bold: listStyle.bold,
|
|
658
|
-
italic: listStyle.italic,
|
|
659
|
-
underline: listStyle.underline,
|
|
660
|
-
dim: listStyle.dim,
|
|
661
|
-
})
|
|
662
|
-
: 0,
|
|
663
|
-
})
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
for (const subToken of item.tokens) {
|
|
667
|
-
const markedSub = subToken as MarkedToken
|
|
668
|
-
if (markedSub.type === "text" && "tokens" in markedSub && Array.isArray(markedSub.tokens)) {
|
|
669
|
-
this.renderInlineContent(markedSub.tokens, chunks)
|
|
670
|
-
} else if (markedSub.type === "list") {
|
|
671
|
-
chunks.push(this.createDefaultChunk("\n"))
|
|
672
|
-
this.renderListInline(markedSub as Tokens.List, chunks, depth + 1)
|
|
673
|
-
continue
|
|
674
|
-
} else if (markedSub.type === "paragraph" && "tokens" in markedSub) {
|
|
675
|
-
this.renderInlineContent((markedSub as Tokens.Paragraph).tokens, chunks)
|
|
676
|
-
} else if (markedSub.type === "code") {
|
|
677
|
-
// Render fenced code blocks inside list items on their own indented lines
|
|
678
|
-
if (chunks.length > 0 && !chunks[chunks.length - 1].text.endsWith("\n")) {
|
|
679
|
-
chunks[chunks.length - 1] = { ...chunks[chunks.length - 1], text: chunks[chunks.length - 1].text + "\n" }
|
|
680
|
-
} else {
|
|
681
|
-
chunks.push(this.createDefaultChunk("\n"))
|
|
682
|
-
}
|
|
683
|
-
const codeLines = (markedSub as Tokens.Code).text.split("\n")
|
|
684
|
-
const codeStyle = this.getStyle("markup.raw") || this.getStyle("default")
|
|
685
|
-
for (const codeLine of codeLines) {
|
|
686
|
-
chunks.push(this.createDefaultChunk(indent + " "))
|
|
687
|
-
chunks.push({
|
|
688
|
-
__isChunk: true,
|
|
689
|
-
text: codeLine,
|
|
690
|
-
fg: codeStyle?.fg,
|
|
691
|
-
bg: codeStyle?.bg,
|
|
692
|
-
attributes: 0,
|
|
693
|
-
})
|
|
694
|
-
chunks.push(this.createDefaultChunk("\n"))
|
|
695
|
-
}
|
|
696
|
-
continue
|
|
697
|
-
} else {
|
|
698
|
-
this.renderInlineToken(markedSub, chunks)
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
chunks.push(this.createDefaultChunk("\n"))
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
|
|
705
|
-
private createMarkdownCodeRenderable(content: string, id: string, marginBottom: number = 0): CodeRenderable {
|
|
706
|
-
return new CodeRenderable(this.ctx, {
|
|
707
|
-
id,
|
|
708
|
-
content,
|
|
709
|
-
filetype: "markdown",
|
|
710
|
-
syntaxStyle: this._syntaxStyle,
|
|
711
|
-
fg: this._fg,
|
|
712
|
-
bg: this._bg,
|
|
713
|
-
conceal: this._conceal,
|
|
714
|
-
drawUnstyledText: true,
|
|
715
|
-
streaming: true,
|
|
716
|
-
onChunks: this._conceal ? this._inlineConcealChunks : this._linkifyMarkdownChunks,
|
|
717
|
-
treeSitterClient: this._treeSitterClient,
|
|
718
|
-
width: "100%",
|
|
719
|
-
marginBottom,
|
|
720
|
-
})
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
private createCodeRenderable(token: Tokens.Code, id: string, marginBottom: number = 0): Renderable {
|
|
724
|
-
return new CodeRenderable(this.ctx, {
|
|
725
|
-
id,
|
|
726
|
-
content: token.text,
|
|
727
|
-
filetype: infoStringToFiletype(token.lang ?? ""),
|
|
728
|
-
syntaxStyle: this._syntaxStyle,
|
|
729
|
-
fg: this._fg,
|
|
730
|
-
bg: this._bg,
|
|
731
|
-
conceal: this._concealCode,
|
|
732
|
-
drawUnstyledText: !(this._streaming && this._concealCode),
|
|
733
|
-
streaming: this._streaming,
|
|
734
|
-
treeSitterClient: this._treeSitterClient,
|
|
735
|
-
width: "100%",
|
|
736
|
-
marginBottom,
|
|
737
|
-
})
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
private applyMarkdownCodeRenderable(renderable: CodeRenderable, content: string, marginBottom: number): void {
|
|
741
|
-
renderable.content = content
|
|
742
|
-
renderable.filetype = "markdown"
|
|
743
|
-
renderable.syntaxStyle = this._syntaxStyle
|
|
744
|
-
renderable.fg = this._fg
|
|
745
|
-
renderable.bg = this._bg
|
|
746
|
-
renderable.conceal = this._conceal
|
|
747
|
-
renderable.drawUnstyledText = true
|
|
748
|
-
renderable.streaming = true
|
|
749
|
-
renderable.onChunks = this._conceal ? this._inlineConcealChunks : this._linkifyMarkdownChunks
|
|
750
|
-
renderable.marginBottom = marginBottom
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
private applyCodeBlockRenderable(renderable: CodeRenderable, token: Tokens.Code, marginBottom: number): void {
|
|
754
|
-
renderable.content = token.text
|
|
755
|
-
renderable.filetype = infoStringToFiletype(token.lang ?? "")
|
|
756
|
-
renderable.syntaxStyle = this._syntaxStyle
|
|
757
|
-
renderable.fg = this._fg
|
|
758
|
-
renderable.bg = this._bg
|
|
759
|
-
renderable.conceal = this._concealCode
|
|
760
|
-
renderable.drawUnstyledText = !(this._streaming && this._concealCode)
|
|
761
|
-
renderable.streaming = this._streaming
|
|
762
|
-
renderable.marginBottom = marginBottom
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
private shouldRenderSeparately(token: MarkedToken): boolean {
|
|
766
|
-
return token.type === "code" || token.type === "table" || token.type === "blockquote"
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
private getInterBlockMargin(token: MarkedToken, hasNextToken: boolean): number {
|
|
770
|
-
if (!hasNextToken) return 0
|
|
771
|
-
return this.shouldRenderSeparately(token) ? 1 : 0
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
private createMarkdownBlockToken(raw: string): MarkedToken {
|
|
775
|
-
return {
|
|
776
|
-
type: "paragraph",
|
|
777
|
-
raw,
|
|
778
|
-
text: raw,
|
|
779
|
-
tokens: [],
|
|
780
|
-
} as MarkedToken
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
private normalizeMarkdownBlockRaw(raw: string): string {
|
|
784
|
-
return raw.replace(TRAILING_MARKDOWN_BLOCK_BREAKS_RE, "")
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
private buildRenderableTokens(tokens: MarkedToken[]): MarkedToken[] {
|
|
788
|
-
if (this._renderNode) {
|
|
789
|
-
return tokens.filter((token) => token.type !== "space")
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
const renderTokens: MarkedToken[] = []
|
|
793
|
-
let markdownRaw = ""
|
|
794
|
-
|
|
795
|
-
const flushMarkdownRaw = (): void => {
|
|
796
|
-
if (markdownRaw.length === 0) return
|
|
797
|
-
const normalizedRaw = this.normalizeMarkdownBlockRaw(markdownRaw)
|
|
798
|
-
if (normalizedRaw.length > 0) {
|
|
799
|
-
renderTokens.push(this.createMarkdownBlockToken(normalizedRaw))
|
|
800
|
-
}
|
|
801
|
-
markdownRaw = ""
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
for (let i = 0; i < tokens.length; i += 1) {
|
|
805
|
-
const token = tokens[i]
|
|
806
|
-
|
|
807
|
-
if (token.type === "space") {
|
|
808
|
-
if (markdownRaw.length === 0) {
|
|
809
|
-
continue
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
let nextIndex = i + 1
|
|
813
|
-
while (nextIndex < tokens.length && tokens[nextIndex].type === "space") {
|
|
814
|
-
nextIndex += 1
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
const nextToken = tokens[nextIndex]
|
|
818
|
-
if (nextToken && !this.shouldRenderSeparately(nextToken)) {
|
|
819
|
-
markdownRaw += token.raw
|
|
820
|
-
}
|
|
821
|
-
continue
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
if (this.shouldRenderSeparately(token)) {
|
|
825
|
-
flushMarkdownRaw()
|
|
826
|
-
renderTokens.push(token)
|
|
827
|
-
continue
|
|
828
|
-
}
|
|
829
|
-
|
|
830
|
-
markdownRaw += token.raw
|
|
831
|
-
}
|
|
832
|
-
|
|
833
|
-
flushMarkdownRaw()
|
|
834
|
-
|
|
835
|
-
return renderTokens
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
private getTableRowsToRender(table: Tokens.Table): Tokens.TableCell[][] {
|
|
839
|
-
return table.rows
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
private hashString(value: string, seed: number): number {
|
|
843
|
-
let hash = seed >>> 0
|
|
844
|
-
for (let i = 0; i < value.length; i += 1) {
|
|
845
|
-
hash ^= value.charCodeAt(i)
|
|
846
|
-
hash = Math.imul(hash, 16777619)
|
|
847
|
-
}
|
|
848
|
-
return hash >>> 0
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
private hashTableToken(token: MarkedToken, seed: number, depth: number = 0): number {
|
|
852
|
-
let hash = this.hashString(token.type, seed)
|
|
853
|
-
|
|
854
|
-
if ("raw" in token && typeof token.raw === "string") {
|
|
855
|
-
return this.hashString(token.raw, hash)
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
if ("text" in token && typeof token.text === "string") {
|
|
859
|
-
hash = this.hashString(token.text, hash)
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
if (depth < 2 && "tokens" in token && Array.isArray(token.tokens)) {
|
|
863
|
-
for (const child of token.tokens) {
|
|
864
|
-
hash = this.hashTableToken(child as MarkedToken, hash, depth + 1)
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
return hash >>> 0
|
|
869
|
-
}
|
|
870
|
-
|
|
871
|
-
private getTableCellKey(cell: Tokens.TableCell | undefined, isHeader: boolean): number {
|
|
872
|
-
const seed = isHeader ? 2902232141 : 1371922141
|
|
873
|
-
if (!cell) {
|
|
874
|
-
return seed
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
if (typeof cell.text === "string") {
|
|
878
|
-
return this.hashString(cell.text, seed)
|
|
879
|
-
}
|
|
880
|
-
|
|
881
|
-
if (Array.isArray(cell.tokens) && cell.tokens.length > 0) {
|
|
882
|
-
let hash = seed ^ cell.tokens.length
|
|
883
|
-
for (const token of cell.tokens) {
|
|
884
|
-
hash = this.hashTableToken(token as MarkedToken, hash)
|
|
885
|
-
}
|
|
886
|
-
return hash >>> 0
|
|
887
|
-
}
|
|
888
|
-
|
|
889
|
-
return (seed ^ 2654435769) >>> 0
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
private createTableDataCellChunks(cell: Tokens.TableCell | undefined): TextChunk[] {
|
|
893
|
-
const chunks: TextChunk[] = []
|
|
894
|
-
if (cell) {
|
|
895
|
-
this.renderInlineContent(cell.tokens, chunks)
|
|
896
|
-
}
|
|
897
|
-
return chunks.length > 0 ? chunks : [this.createDefaultChunk(" ")]
|
|
898
|
-
}
|
|
899
|
-
|
|
900
|
-
private createTableHeaderCellChunks(cell: Tokens.TableCell): TextChunk[] {
|
|
901
|
-
const chunks: TextChunk[] = []
|
|
902
|
-
this.renderInlineContent(cell.tokens, chunks)
|
|
903
|
-
|
|
904
|
-
const baseChunks = chunks.length > 0 ? chunks : [this.createDefaultChunk(" ")]
|
|
905
|
-
const headingStyle = this.getStyle("markup.heading") || this.getStyle("default")
|
|
906
|
-
if (!headingStyle) {
|
|
907
|
-
return baseChunks
|
|
908
|
-
}
|
|
909
|
-
|
|
910
|
-
const headingAttributes = createTextAttributes({
|
|
911
|
-
bold: headingStyle.bold,
|
|
912
|
-
italic: headingStyle.italic,
|
|
913
|
-
underline: headingStyle.underline,
|
|
914
|
-
dim: headingStyle.dim,
|
|
915
|
-
})
|
|
916
|
-
|
|
917
|
-
return baseChunks.map((chunk) => ({
|
|
918
|
-
...chunk,
|
|
919
|
-
fg: headingStyle.fg ?? chunk.fg,
|
|
920
|
-
bg: headingStyle.bg ?? chunk.bg,
|
|
921
|
-
attributes: headingAttributes,
|
|
922
|
-
}))
|
|
923
|
-
}
|
|
924
|
-
|
|
925
|
-
private buildTableContentCache(
|
|
926
|
-
table: Tokens.Table,
|
|
927
|
-
previous?: TableContentCache,
|
|
928
|
-
forceRegenerate: boolean = false,
|
|
929
|
-
): { cache: TableContentCache | null; changed: boolean } {
|
|
930
|
-
const colCount = table.header.length
|
|
931
|
-
const rowsToRender = this.getTableRowsToRender(table)
|
|
932
|
-
if (colCount === 0 || rowsToRender.length === 0) {
|
|
933
|
-
return { cache: null, changed: previous !== undefined }
|
|
934
|
-
}
|
|
935
|
-
|
|
936
|
-
const content: TextTableContent = []
|
|
937
|
-
const cellKeys: Uint32Array[] = []
|
|
938
|
-
const totalRows = rowsToRender.length + 1
|
|
939
|
-
|
|
940
|
-
let changed = forceRegenerate || !previous
|
|
941
|
-
|
|
942
|
-
for (let rowIndex = 0; rowIndex < totalRows; rowIndex += 1) {
|
|
943
|
-
const rowContent: TextTableCellContent[] = []
|
|
944
|
-
const rowKeys = new Uint32Array(colCount)
|
|
945
|
-
|
|
946
|
-
for (let colIndex = 0; colIndex < colCount; colIndex += 1) {
|
|
947
|
-
const isHeader = rowIndex === 0
|
|
948
|
-
const cell = isHeader ? table.header[colIndex] : rowsToRender[rowIndex - 1]?.[colIndex]
|
|
949
|
-
const cellKey = this.getTableCellKey(cell, isHeader)
|
|
950
|
-
rowKeys[colIndex] = cellKey
|
|
951
|
-
|
|
952
|
-
const previousCellKey = previous?.cellKeys[rowIndex]?.[colIndex]
|
|
953
|
-
const previousCellContent = previous?.content[rowIndex]?.[colIndex]
|
|
954
|
-
|
|
955
|
-
if (!forceRegenerate && previousCellKey === cellKey && Array.isArray(previousCellContent)) {
|
|
956
|
-
rowContent.push(previousCellContent)
|
|
957
|
-
continue
|
|
958
|
-
}
|
|
959
|
-
|
|
960
|
-
changed = true
|
|
961
|
-
rowContent.push(
|
|
962
|
-
isHeader ? this.createTableHeaderCellChunks(table.header[colIndex]) : this.createTableDataCellChunks(cell),
|
|
963
|
-
)
|
|
964
|
-
}
|
|
965
|
-
|
|
966
|
-
content.push(rowContent)
|
|
967
|
-
cellKeys.push(rowKeys)
|
|
968
|
-
}
|
|
969
|
-
|
|
970
|
-
if (previous && !changed) {
|
|
971
|
-
if (previous.content.length !== content.length) {
|
|
972
|
-
changed = true
|
|
973
|
-
} else {
|
|
974
|
-
for (let rowIndex = 0; rowIndex < content.length; rowIndex += 1) {
|
|
975
|
-
if ((previous.content[rowIndex]?.length ?? 0) !== content[rowIndex].length) {
|
|
976
|
-
changed = true
|
|
977
|
-
break
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
}
|
|
982
|
-
|
|
983
|
-
return {
|
|
984
|
-
cache: {
|
|
985
|
-
content,
|
|
986
|
-
cellKeys,
|
|
987
|
-
},
|
|
988
|
-
changed,
|
|
989
|
-
}
|
|
990
|
-
}
|
|
991
|
-
|
|
992
|
-
private resolveTableRenderableOptions(): ResolvedTableRenderableOptions {
|
|
993
|
-
const borders = this._tableOptions?.borders ?? true
|
|
994
|
-
|
|
995
|
-
return {
|
|
996
|
-
columnWidthMode: this._tableOptions?.widthMode ?? "full",
|
|
997
|
-
columnFitter: this._tableOptions?.columnFitter ?? "proportional",
|
|
998
|
-
wrapMode: this._tableOptions?.wrapMode ?? "word",
|
|
999
|
-
cellPadding: this._tableOptions?.cellPadding ?? 0,
|
|
1000
|
-
border: borders,
|
|
1001
|
-
outerBorder: this._tableOptions?.outerBorder ?? borders,
|
|
1002
|
-
showBorders: borders,
|
|
1003
|
-
borderStyle: this._tableOptions?.borderStyle ?? "single",
|
|
1004
|
-
borderColor: this._tableOptions?.borderColor ?? this.getStyle("conceal")?.fg ?? "#888888",
|
|
1005
|
-
selectable: this._tableOptions?.selectable ?? true,
|
|
1006
|
-
}
|
|
1007
|
-
}
|
|
1008
|
-
|
|
1009
|
-
private applyTableRenderableOptions(
|
|
1010
|
-
tableRenderable: TextTableRenderable,
|
|
1011
|
-
options: ResolvedTableRenderableOptions,
|
|
1012
|
-
): void {
|
|
1013
|
-
tableRenderable.columnWidthMode = options.columnWidthMode
|
|
1014
|
-
tableRenderable.columnFitter = options.columnFitter
|
|
1015
|
-
tableRenderable.wrapMode = options.wrapMode
|
|
1016
|
-
tableRenderable.cellPadding = options.cellPadding
|
|
1017
|
-
tableRenderable.border = options.border
|
|
1018
|
-
tableRenderable.outerBorder = options.outerBorder
|
|
1019
|
-
tableRenderable.showBorders = options.showBorders
|
|
1020
|
-
tableRenderable.borderStyle = options.borderStyle
|
|
1021
|
-
tableRenderable.borderColor = options.borderColor
|
|
1022
|
-
tableRenderable.selectable = options.selectable
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
private applyTableOptionsToBlocks(): void {
|
|
1026
|
-
const options = this.resolveTableRenderableOptions()
|
|
1027
|
-
let updated = false
|
|
1028
|
-
|
|
1029
|
-
for (const state of this._blockStates) {
|
|
1030
|
-
if (state.renderable instanceof TextTableRenderable) {
|
|
1031
|
-
this.applyTableRenderableOptions(state.renderable, options)
|
|
1032
|
-
updated = true
|
|
1033
|
-
}
|
|
1034
|
-
}
|
|
1035
|
-
|
|
1036
|
-
if (updated) {
|
|
1037
|
-
this.requestRender()
|
|
1038
|
-
}
|
|
1039
|
-
}
|
|
1040
|
-
|
|
1041
|
-
private createTextTableRenderable(
|
|
1042
|
-
content: TextTableContent,
|
|
1043
|
-
id: string,
|
|
1044
|
-
marginBottom: number = 0,
|
|
1045
|
-
): TextTableRenderable {
|
|
1046
|
-
const options = this.resolveTableRenderableOptions()
|
|
1047
|
-
return new TextTableRenderable(this.ctx, {
|
|
1048
|
-
id,
|
|
1049
|
-
content,
|
|
1050
|
-
width: "100%",
|
|
1051
|
-
marginBottom,
|
|
1052
|
-
columnWidthMode: options.columnWidthMode,
|
|
1053
|
-
columnFitter: options.columnFitter,
|
|
1054
|
-
wrapMode: options.wrapMode,
|
|
1055
|
-
cellPadding: options.cellPadding,
|
|
1056
|
-
border: options.border,
|
|
1057
|
-
outerBorder: options.outerBorder,
|
|
1058
|
-
showBorders: options.showBorders,
|
|
1059
|
-
borderStyle: options.borderStyle,
|
|
1060
|
-
borderColor: options.borderColor,
|
|
1061
|
-
selectable: options.selectable,
|
|
1062
|
-
})
|
|
1063
|
-
}
|
|
1064
|
-
|
|
1065
|
-
private createTableBlock(
|
|
1066
|
-
table: Tokens.Table,
|
|
1067
|
-
id: string,
|
|
1068
|
-
marginBottom: number = 0,
|
|
1069
|
-
previousCache?: TableContentCache,
|
|
1070
|
-
forceRegenerate: boolean = false,
|
|
1071
|
-
): { renderable: Renderable; tableContentCache?: TableContentCache } {
|
|
1072
|
-
const { cache } = this.buildTableContentCache(table, previousCache, forceRegenerate)
|
|
1073
|
-
|
|
1074
|
-
if (!cache) {
|
|
1075
|
-
return {
|
|
1076
|
-
renderable: this.createMarkdownCodeRenderable(table.raw, id, marginBottom),
|
|
1077
|
-
}
|
|
1078
|
-
}
|
|
1079
|
-
|
|
1080
|
-
return {
|
|
1081
|
-
renderable: this.createTextTableRenderable(cache.content, id, marginBottom),
|
|
1082
|
-
tableContentCache: cache,
|
|
1083
|
-
}
|
|
1084
|
-
}
|
|
1085
|
-
|
|
1086
|
-
private createDefaultRenderable(token: MarkedToken, index: number, hasNextToken: boolean = false): Renderable | null {
|
|
1087
|
-
const id = `${this.id}-block-${index}`
|
|
1088
|
-
const marginBottom = this.getInterBlockMargin(token, hasNextToken)
|
|
1089
|
-
|
|
1090
|
-
if (token.type === "code") {
|
|
1091
|
-
return this.createCodeRenderable(token, id, marginBottom)
|
|
1092
|
-
}
|
|
1093
|
-
|
|
1094
|
-
if (token.type === "table") {
|
|
1095
|
-
return this.createTableBlock(token, id, marginBottom).renderable
|
|
1096
|
-
}
|
|
1097
|
-
|
|
1098
|
-
if (token.type === "space") {
|
|
1099
|
-
return null
|
|
1100
|
-
}
|
|
1101
|
-
|
|
1102
|
-
if (!token.raw) {
|
|
1103
|
-
return null
|
|
1104
|
-
}
|
|
1105
|
-
|
|
1106
|
-
return this.createMarkdownCodeRenderable(token.raw, id, marginBottom)
|
|
1107
|
-
}
|
|
1108
|
-
|
|
1109
|
-
private updateBlockRenderable(state: BlockState, token: MarkedToken, index: number, hasNextToken: boolean): void {
|
|
1110
|
-
const marginBottom = this.getInterBlockMargin(token, hasNextToken)
|
|
1111
|
-
|
|
1112
|
-
if (token.type === "code") {
|
|
1113
|
-
this.applyCodeBlockRenderable(state.renderable as CodeRenderable, token as Tokens.Code, marginBottom)
|
|
1114
|
-
return
|
|
1115
|
-
}
|
|
1116
|
-
|
|
1117
|
-
if (token.type === "table") {
|
|
1118
|
-
const tableToken = token as Tokens.Table
|
|
1119
|
-
const { cache, changed } = this.buildTableContentCache(tableToken, state.tableContentCache)
|
|
1120
|
-
|
|
1121
|
-
if (!cache) {
|
|
1122
|
-
if (state.renderable instanceof CodeRenderable) {
|
|
1123
|
-
this.applyMarkdownCodeRenderable(state.renderable, tableToken.raw, marginBottom)
|
|
1124
|
-
state.tableContentCache = undefined
|
|
1125
|
-
return
|
|
1126
|
-
}
|
|
1127
|
-
|
|
1128
|
-
state.renderable.destroyRecursively()
|
|
1129
|
-
const fallbackRenderable = this.createMarkdownCodeRenderable(
|
|
1130
|
-
tableToken.raw,
|
|
1131
|
-
`${this.id}-block-${index}`,
|
|
1132
|
-
marginBottom,
|
|
1133
|
-
)
|
|
1134
|
-
this.add(fallbackRenderable)
|
|
1135
|
-
state.renderable = fallbackRenderable
|
|
1136
|
-
state.tableContentCache = undefined
|
|
1137
|
-
return
|
|
1138
|
-
}
|
|
1139
|
-
|
|
1140
|
-
if (state.renderable instanceof TextTableRenderable) {
|
|
1141
|
-
if (changed) {
|
|
1142
|
-
state.renderable.content = cache.content
|
|
1143
|
-
}
|
|
1144
|
-
this.applyTableRenderableOptions(state.renderable, this.resolveTableRenderableOptions())
|
|
1145
|
-
state.renderable.marginBottom = marginBottom
|
|
1146
|
-
state.tableContentCache = cache
|
|
1147
|
-
return
|
|
1148
|
-
}
|
|
1149
|
-
|
|
1150
|
-
state.renderable.destroyRecursively()
|
|
1151
|
-
const tableRenderable = this.createTextTableRenderable(cache.content, `${this.id}-block-${index}`, marginBottom)
|
|
1152
|
-
this.add(tableRenderable)
|
|
1153
|
-
state.renderable = tableRenderable
|
|
1154
|
-
state.tableContentCache = cache
|
|
1155
|
-
return
|
|
1156
|
-
}
|
|
1157
|
-
|
|
1158
|
-
if (state.renderable instanceof CodeRenderable) {
|
|
1159
|
-
this.applyMarkdownCodeRenderable(state.renderable, token.raw, marginBottom)
|
|
1160
|
-
return
|
|
1161
|
-
}
|
|
1162
|
-
|
|
1163
|
-
state.renderable.destroyRecursively()
|
|
1164
|
-
const markdownRenderable = this.createMarkdownCodeRenderable(token.raw, `${this.id}-block-${index}`, marginBottom)
|
|
1165
|
-
this.add(markdownRenderable)
|
|
1166
|
-
state.renderable = markdownRenderable
|
|
1167
|
-
}
|
|
1168
|
-
|
|
1169
|
-
private updateBlocks(forceTableRefresh: boolean = false): void {
|
|
1170
|
-
if (this.isDestroyed) return
|
|
1171
|
-
if (!this._content) {
|
|
1172
|
-
this.clearBlockStates()
|
|
1173
|
-
this._parseState = null
|
|
1174
|
-
return
|
|
1175
|
-
}
|
|
1176
|
-
|
|
1177
|
-
const trailingUnstable = this._streaming ? 2 : 0
|
|
1178
|
-
this._parseState = parseMarkdownIncremental(this._content, this._parseState, trailingUnstable)
|
|
1179
|
-
|
|
1180
|
-
const tokens = this._parseState.tokens
|
|
1181
|
-
|
|
1182
|
-
// Parse failure fallback
|
|
1183
|
-
if (tokens.length === 0 && this._content.length > 0) {
|
|
1184
|
-
this.clearBlockStates()
|
|
1185
|
-
const fallback = this.createMarkdownCodeRenderable(this._content, `${this.id}-fallback`)
|
|
1186
|
-
this.add(fallback)
|
|
1187
|
-
this._blockStates = [
|
|
1188
|
-
{
|
|
1189
|
-
token: { type: "text", raw: this._content, text: this._content } as MarkedToken,
|
|
1190
|
-
tokenRaw: this._content,
|
|
1191
|
-
renderable: fallback,
|
|
1192
|
-
},
|
|
1193
|
-
]
|
|
1194
|
-
return
|
|
1195
|
-
}
|
|
1196
|
-
|
|
1197
|
-
const blockTokens = this.buildRenderableTokens(tokens)
|
|
1198
|
-
const lastBlockIndex = blockTokens.length - 1
|
|
1199
|
-
|
|
1200
|
-
let blockIndex = 0
|
|
1201
|
-
for (let i = 0; i < blockTokens.length; i++) {
|
|
1202
|
-
const token = blockTokens[i]
|
|
1203
|
-
const hasNextToken = i < lastBlockIndex
|
|
1204
|
-
const existing = this._blockStates[blockIndex]
|
|
1205
|
-
|
|
1206
|
-
const shouldForceRefresh = forceTableRefresh
|
|
1207
|
-
|
|
1208
|
-
// Same token object reference means unchanged
|
|
1209
|
-
if (existing && existing.token === token) {
|
|
1210
|
-
if (shouldForceRefresh) {
|
|
1211
|
-
this.updateBlockRenderable(existing, token, blockIndex, hasNextToken)
|
|
1212
|
-
existing.tokenRaw = token.raw
|
|
1213
|
-
}
|
|
1214
|
-
blockIndex++
|
|
1215
|
-
continue
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1218
|
-
// Same content, update reference
|
|
1219
|
-
if (existing && existing.tokenRaw === token.raw && existing.token.type === token.type) {
|
|
1220
|
-
existing.token = token
|
|
1221
|
-
if (shouldForceRefresh) {
|
|
1222
|
-
this.updateBlockRenderable(existing, token, blockIndex, hasNextToken)
|
|
1223
|
-
existing.tokenRaw = token.raw
|
|
1224
|
-
}
|
|
1225
|
-
blockIndex++
|
|
1226
|
-
continue
|
|
1227
|
-
}
|
|
1228
|
-
|
|
1229
|
-
// Same type, different content - update in place
|
|
1230
|
-
if (existing && existing.token.type === token.type) {
|
|
1231
|
-
this.updateBlockRenderable(existing, token, blockIndex, hasNextToken)
|
|
1232
|
-
existing.token = token
|
|
1233
|
-
existing.tokenRaw = token.raw
|
|
1234
|
-
blockIndex++
|
|
1235
|
-
continue
|
|
1236
|
-
}
|
|
1237
|
-
|
|
1238
|
-
// Different type or new block
|
|
1239
|
-
if (existing) {
|
|
1240
|
-
existing.renderable.destroyRecursively()
|
|
1241
|
-
}
|
|
1242
|
-
|
|
1243
|
-
let renderable: Renderable | undefined
|
|
1244
|
-
let tableContentCache: TableContentCache | undefined
|
|
1245
|
-
|
|
1246
|
-
if (this._renderNode) {
|
|
1247
|
-
const context: RenderNodeContext = {
|
|
1248
|
-
syntaxStyle: this._syntaxStyle,
|
|
1249
|
-
conceal: this._conceal,
|
|
1250
|
-
concealCode: this._concealCode,
|
|
1251
|
-
treeSitterClient: this._treeSitterClient,
|
|
1252
|
-
defaultRender: () => this.createDefaultRenderable(token, blockIndex, hasNextToken),
|
|
1253
|
-
}
|
|
1254
|
-
const custom = this._renderNode(token, context)
|
|
1255
|
-
if (custom) {
|
|
1256
|
-
renderable = custom
|
|
1257
|
-
}
|
|
1258
|
-
}
|
|
1259
|
-
|
|
1260
|
-
if (!renderable) {
|
|
1261
|
-
if (token.type === "table") {
|
|
1262
|
-
const tableBlock = this.createTableBlock(
|
|
1263
|
-
token,
|
|
1264
|
-
`${this.id}-block-${blockIndex}`,
|
|
1265
|
-
this.getInterBlockMargin(token, hasNextToken),
|
|
1266
|
-
)
|
|
1267
|
-
renderable = tableBlock.renderable
|
|
1268
|
-
tableContentCache = tableBlock.tableContentCache
|
|
1269
|
-
} else {
|
|
1270
|
-
renderable = this.createDefaultRenderable(token, blockIndex, hasNextToken) ?? undefined
|
|
1271
|
-
}
|
|
1272
|
-
}
|
|
1273
|
-
|
|
1274
|
-
if (token.type === "table" && !tableContentCache && renderable instanceof TextTableRenderable) {
|
|
1275
|
-
const { cache } = this.buildTableContentCache(token as Tokens.Table)
|
|
1276
|
-
tableContentCache = cache ?? undefined
|
|
1277
|
-
}
|
|
1278
|
-
|
|
1279
|
-
if (renderable) {
|
|
1280
|
-
this.add(renderable)
|
|
1281
|
-
this._blockStates[blockIndex] = {
|
|
1282
|
-
token,
|
|
1283
|
-
tokenRaw: token.raw,
|
|
1284
|
-
renderable,
|
|
1285
|
-
tableContentCache,
|
|
1286
|
-
}
|
|
1287
|
-
}
|
|
1288
|
-
blockIndex++
|
|
1289
|
-
}
|
|
1290
|
-
|
|
1291
|
-
while (this._blockStates.length > blockIndex) {
|
|
1292
|
-
const removed = this._blockStates.pop()!
|
|
1293
|
-
removed.renderable.destroyRecursively()
|
|
1294
|
-
}
|
|
1295
|
-
}
|
|
1296
|
-
|
|
1297
|
-
private clearBlockStates(): void {
|
|
1298
|
-
for (const state of this._blockStates) {
|
|
1299
|
-
state.renderable.destroyRecursively()
|
|
1300
|
-
}
|
|
1301
|
-
this._blockStates = []
|
|
1302
|
-
}
|
|
1303
|
-
|
|
1304
|
-
/**
|
|
1305
|
-
* Re-render existing blocks without rebuilding the parse state or block structure.
|
|
1306
|
-
* Used when only style/conceal changes - much faster than full rebuild.
|
|
1307
|
-
*/
|
|
1308
|
-
private rerenderBlocks(): void {
|
|
1309
|
-
for (let i = 0; i < this._blockStates.length; i++) {
|
|
1310
|
-
const state = this._blockStates[i]
|
|
1311
|
-
const hasNextToken = i < this._blockStates.length - 1
|
|
1312
|
-
const marginBottom = this.getInterBlockMargin(state.token, hasNextToken)
|
|
1313
|
-
|
|
1314
|
-
if (state.token.type === "code") {
|
|
1315
|
-
this.applyCodeBlockRenderable(state.renderable as CodeRenderable, state.token as Tokens.Code, marginBottom)
|
|
1316
|
-
continue
|
|
1317
|
-
}
|
|
1318
|
-
|
|
1319
|
-
if (state.token.type === "table") {
|
|
1320
|
-
const tableToken = state.token as Tokens.Table
|
|
1321
|
-
const { cache } = this.buildTableContentCache(tableToken, state.tableContentCache, true)
|
|
1322
|
-
|
|
1323
|
-
if (!cache) {
|
|
1324
|
-
if (state.renderable instanceof CodeRenderable) {
|
|
1325
|
-
this.applyMarkdownCodeRenderable(state.renderable, tableToken.raw, marginBottom)
|
|
1326
|
-
} else {
|
|
1327
|
-
state.renderable.destroyRecursively()
|
|
1328
|
-
const fallbackRenderable = this.createMarkdownCodeRenderable(
|
|
1329
|
-
tableToken.raw,
|
|
1330
|
-
`${this.id}-block-${i}`,
|
|
1331
|
-
marginBottom,
|
|
1332
|
-
)
|
|
1333
|
-
this.add(fallbackRenderable)
|
|
1334
|
-
state.renderable = fallbackRenderable
|
|
1335
|
-
}
|
|
1336
|
-
state.tableContentCache = undefined
|
|
1337
|
-
continue
|
|
1338
|
-
}
|
|
1339
|
-
|
|
1340
|
-
if (state.renderable instanceof TextTableRenderable) {
|
|
1341
|
-
state.renderable.content = cache.content
|
|
1342
|
-
this.applyTableRenderableOptions(state.renderable, this.resolveTableRenderableOptions())
|
|
1343
|
-
state.renderable.marginBottom = marginBottom
|
|
1344
|
-
state.tableContentCache = cache
|
|
1345
|
-
continue
|
|
1346
|
-
}
|
|
1347
|
-
|
|
1348
|
-
state.renderable.destroyRecursively()
|
|
1349
|
-
const tableRenderable = this.createTextTableRenderable(cache.content, `${this.id}-block-${i}`, marginBottom)
|
|
1350
|
-
this.add(tableRenderable)
|
|
1351
|
-
state.renderable = tableRenderable
|
|
1352
|
-
state.tableContentCache = cache
|
|
1353
|
-
continue
|
|
1354
|
-
}
|
|
1355
|
-
|
|
1356
|
-
if (state.renderable instanceof CodeRenderable) {
|
|
1357
|
-
this.applyMarkdownCodeRenderable(state.renderable, state.token.raw, marginBottom)
|
|
1358
|
-
continue
|
|
1359
|
-
}
|
|
1360
|
-
|
|
1361
|
-
state.renderable.destroyRecursively()
|
|
1362
|
-
const markdownRenderable = this.createMarkdownCodeRenderable(
|
|
1363
|
-
state.token.raw,
|
|
1364
|
-
`${this.id}-block-${i}`,
|
|
1365
|
-
marginBottom,
|
|
1366
|
-
)
|
|
1367
|
-
this.add(markdownRenderable)
|
|
1368
|
-
state.renderable = markdownRenderable
|
|
1369
|
-
}
|
|
1370
|
-
}
|
|
1371
|
-
|
|
1372
|
-
public clearCache(): void {
|
|
1373
|
-
this._parseState = null
|
|
1374
|
-
this.clearBlockStates()
|
|
1375
|
-
this.updateBlocks()
|
|
1376
|
-
this.requestRender()
|
|
1377
|
-
}
|
|
1378
|
-
|
|
1379
|
-
public refreshStyles(): void {
|
|
1380
|
-
this._styleDirty = false
|
|
1381
|
-
this.rerenderBlocks()
|
|
1382
|
-
this.requestRender()
|
|
1383
|
-
}
|
|
1384
|
-
|
|
1385
|
-
protected override renderSelf(buffer: OptimizedBuffer, deltaTime: number): void {
|
|
1386
|
-
// Check if style/conceal changed - re-render blocks before rendering
|
|
1387
|
-
if (this._styleDirty) {
|
|
1388
|
-
this._styleDirty = false
|
|
1389
|
-
this.rerenderBlocks()
|
|
1390
|
-
}
|
|
1391
|
-
super.renderSelf(buffer, deltaTime)
|
|
1392
|
-
}
|
|
1393
|
-
}
|