-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Overhaul CodeBlock rendering #1328
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
🦋 Changeset detectedLatest commit: 535b37d The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Thanks for the feedback, there are a couple of UI stay in the box changes for that icon that I will make when I have a few minutes to work on that |
|
I think this is ready please test. |
|
Sorry for the delay - will have some time to test later today. |
|
rebased and tested, ready to merge if you are |
|
@cte, I think this is ready to test again |
BackgroundI was working on a fix for this PR related to problems with nested non-inline code blocks like this: ```
contains tripple-ticks
```The best way to fix that problem was to stop double-nesting markdown when rendering code blocks, and directly pass Proposal: Replace Rehype with ShikiI propose that we drop Rehype in favor of Shiki. Syntax highlight style is CodeNotice that the current syntax highlight Rehype (left) is not recognizing syntax like regular expression symbols or nested ShellShiki also provides beautiful shell markup: More examples: |
|
I had the same thought. I even went as far as re-implementing our See:
I haven't tried dropping this in as a replacement to the existing component yet though. |
|
Shiki seems to work great from a development F5 build, but I have spent a couple hours today trying to get it to package and it just will not go... the code runs and shiki executes, but it is missing all of it's language definition so there is no highlight. |
|
This PR has become pretty mature, please give it a try. Here is a good test instruction:
Summary of Features
Summary of Shiki Features
|
- Add word wrap toggle button with ⟼/⤸ symbols - Initialize word wrap state with prop defaulting to true - Style buttons consistently with same width - Add separator between adjacent code blocks - Show controls on hover when block is visible Signed-off-by: Eric Wheeler <[email protected]>
- Add window shade toggle with ⌄/⌃ symbols - Define constant collapsed height 500px - Maintain scroll position when toggling Signed-off-by: Eric Wheeler <[email protected]>
- Add semi-transparent wrapper with hover effect Signed-off-by: Eric Wheeler <[email protected]>
Signed-off-by: Eric Wheeler <[email protected]>
- Add StyledPre ref for scroll control - Use requestAnimationFrame and setTimeout for reliable content rendering - Implement immediate scrolling behavior without animation Signed-off-by: Eric Wheeler <[email protected]>
Moves the code block height check into its own useEffect hook that runs whenever highlightedCode changes, ensuring the collapse button visibility is updated whenever the rendered content changes. Signed-off-by: Eric Wheeler <[email protected]>
Replace manual scroll position tracking with scrollIntoView for more reliable visibility when toggling code blocks. This ensures collapsed/expanded blocks remain visible in the viewport regardless of surrounding content changes. - Remove lastScrollPosition state - Use scrollIntoView with smooth behavior - Simplify toggle handler code Signed-off-by: Eric Wheeler <[email protected]>
Renamed components for better semantic clarity: - CopyButton -> CodeBlockButton - CopyButtonWrapper -> CodeBlockButtonWrapper - updateCopyButtonPosition -> updateCodeBlockButtonPosition Signed-off-by: Eric Wheeler <[email protected]>
Transform static language indicator into interactive dropdown with all Shiki languages so users can change the highlighting if the default language selected by the AI is not accurate. Current language remains bold for identification. Standardize button heights and alignment for visual consistency. Signed-off-by: Eric Wheeler <[email protected]>
Check for officially supported languages before checking aliases and enable support for single character language identifiers. Signed-off-by: Eric Wheeler <[email protected]>
Add mock for shiki bundledLanguages to handle ES module imports in Jest Signed-off-by: Eric Wheeler <[email protected]>
Add minimal required CSP directives for Shiki syntax highlighting: - wasm-unsafe-eval: Required for WebAssembly compilation - strict-dynamic: Ensures script loading security These CSP changes are scoped to VSCode webview context where the code execution environment is already sandboxed. Signed-off-by: Eric Wheeler <[email protected]>
Dynamic imports of .wasm files return a module object where the binary data is under the default export. This change ensures the actual ArrayBuffer is passed to new WebAssembly.Module() rather than the module wrapper object, which is necessary for correct loading of WebAssembly modules per Vite/ESModule conventions. Appeases ellipsis-dev linter/validator. Signed-off-by: Eric Wheeler <[email protected]>
When text is parsed character by character, the detected language could be partial or incorrect (e.g., 'type' instead of 'typescript'). This change: - Prevents incorrect language display in button wrapper - Exports ExtendedLanguage type for better type safety - Uses proper state management with normalized language values - Implements React best practices with controlled state Signed-off-by: Eric Wheeler <[email protected]>
Test was failing because CSP structure changed with additional directives before the nonce. Extract script-src section with regex to verify nonce presence regardless of its position in the directive. Signed-off-by: Eric Wheeler <[email protected]>
Add test to ensure CSP includes 'wasm-unsafe-eval' directive required for Shiki syntax highlighting to function. Signed-off-by: Eric Wheeler <[email protected]>
Previously, scrolling between stacked code blocks was jarring - when reaching the bottom of one block, continued scrolling would get stuck on the outer container instead of smoothly transitioning to the next block. Implements physics-based smooth scrolling that naturally chains between nested code blocks and their container. When reaching a block's boundary, scrolling transitions to the outer container with momentum and gradual deceleration, allowing seamless flow to the next block. Signed-off-by: Eric Wheeler <[email protected]>
When selecting text in a code block, the button wrapper would remain visible and interfere with text selection, making it difficult to select text accurately. This fix adds mouseDown/mouseUp handlers to hide/show the wrapper during selection.
Fixes issue introduced in dc8a892fef8630cc0d2ccf9019463ce95b7d3fc0 where language dropdown selection would immediately revert after changing. The problem was caused by the useEffect overriding user selections when the language prop changed. This solution uses a ref to track whether the user has made a manual selection, preventing the effect from overriding user choices while still keeping the component reactive to model-streamed language updates. Signed-off-by: Eric Wheeler <[email protected]>
Prevents the CodeBlock component from automatically scrolling to the bottom when new content arrives if the user has manually scrolled away from the bottom. Uses a ref updated by a scroll listener to track the scroll state before content updates, ensuring the user's scroll position is respected. Signed-off-by: Eric Wheeler <[email protected]>
The custom wheel event handler in the CodeBlock component intercepted all wheel events, preventing the default browser behavior for horizontal scrolling when the Shift key was held. This change adds a check for `e.shiftKey` at the beginning of the `handleWheel` function. If Shift is pressed, the handler returns early, allowing the browser to handle the horizontal scroll as expected. Signed-off-by: Eric Wheeler <[email protected]>
Improve scrolling behavior for code blocks by: - Adding a consistent SCROLL_SNAP_TOLERANCE constant (20px) - Tracking outer container scroll position - Moving scrolling logic to happen immediately after Shiki highlighting completes - Ensuring both inner and outer containers scroll to bottom simultaneously when appropriate This creates a more responsive and consistent scrolling experience without relying on arbitrary timeouts. Signed-off-by: Eric Wheeler <[email protected]>
Fixes issue where language selection dropdown would display truncated language names and not properly update UI state after selection. Signed-off-by: Eric Wheeler <[email protected]>
The forceWrap prop was being passed to CodeBlock but was not defined in CodeBlockProps interface or used in the component. Removing it resolves the type error without changing behavior. Signed-off-by: Eric Wheeler <[email protected]>
- Update CodeAccordian.tsx to use @src/utils/getLanguageFromPath and @roo/shared/ExtensionMessage - Update MarkdownBlock.tsx to use @src/context/ExtensionStateContext Signed-off-by: Eric Wheeler <[email protected]>
Only apply special wheel event handling when the pre element actually has a scrollbar. Otherwise, let the browser handle default scrolling behavior. This ensures proper event bubbling when content is too small to need scrolling. Signed-off-by: Eric Wheeler <[email protected]>
|
rebased on 3.14.3 |
|
@KJ7LNW - I merged this change in a separate branch (#3019) since I don't have access to push to your branches (I think your fork predates when I got admin access to the Roo Code repository). I still have a little bit of cleanup to do related to the Thanks so much for this PR - it's really big improvement IMO. |






Overview
This is a port of cline/cline#1583 to RooCode, plus new features:
This PR has become pretty mature, please give it a try.
Summary of CodeBlock Features
Summary of Shiki Features
github-darkorgithub-lightdepending on whether the vscode theme contains the word "light" (close/reopen the Roo task if you change your VSCode theme).Testing
Latest test build:
Here is a good test instruction:
How to Test
New Screenshots
Older Screenshots
These were taken earlier in development, before the expand/collapse and word-wrap widgets were added:
Code
Notice that the current syntax highlight Rehype (left) is not recognizing syntax like regular expression symbols or nested
var = "${variables} in strings"--- but Shiki does this really well (right, this PR).Shell
Shiki also provides beautiful shell markup:
More examples:
Current Rehype (left) - Shiki (right, this PR)

Get in Touch
If you have any questions or feedback, please reach out on the Roo Code Discord.
My Discord handle is KJ7LNW.
Important
Overhaul
CodeBlockrendering with new features, Shiki integration for syntax highlighting, and build updates for WebAssembly support.CodeBlock.tsx.highlighter.ts.github-darkorgithub-lightbased on VSCode theme.vite.config.tsto include a WebAssembly plugin for Shiki.shikiand related dependencies from optimization invite.config.ts.CodeBlockinCodeBlock.test.tsx.package.jsonto includeshikiand adjust dependencies.This description was created by
for 1117500926889242a2fc63f1d102b1b9cf78e864. It will automatically update as commits are pushed.