feat(app): syntax highlighting and copy button for chat code blocks (#1062)

Adds Lezer-based highlighting to fenced code blocks in assistant messages,
with a hover/tap copy button. Colors move into the theme as
`theme.colors.syntax`, so the chat blocks, file preview, and diff viewer
share one StyleSheet path — token color updates flow through the Unistyles
native ShadowRegistry with no React re-renders on the chat hot path.
This commit is contained in:
Mohamed Boudra
2026-05-17 16:01:08 +08:00
committed by GitHub
parent 952b58c0eb
commit f6afe0d864
7 changed files with 347 additions and 82 deletions
+9 -8
View File
@@ -74,6 +74,7 @@ import { getMarkdownListMarker, getMarkdownNextSiblingType } from "@/utils/markd
import { type AssistantFileLinkSource } from "@/utils/assistant-file-link-resolver";
import { useAssistantFileLinkResolver } from "@/hooks/use-assistant-file-link-resolver";
import type { ToastApi } from "@/components/toast-host";
import { HighlightedCodeBlock } from "@/components/highlighted-code-block";
import { splitMarkdownBlocks } from "@/utils/split-markdown-blocks";
import { formatDuration, formatMessageTimestamp } from "@/utils/time";
import {
@@ -1650,13 +1651,13 @@ export const AssistantMessage = memo(function AssistantMessage({
styles: MarkdownStyles,
inheritedStyles: TextStyle = {},
) => (
<MarkdownInheritedText
<HighlightedCodeBlock
key={node.key}
code={node.content}
language={null}
inheritedStyles={inheritedStyles}
textStyle={styles.code_block}
>
{node.content}
</MarkdownInheritedText>
/>
),
fence: (
node: ASTNode,
@@ -1665,13 +1666,13 @@ export const AssistantMessage = memo(function AssistantMessage({
styles: MarkdownStyles,
inheritedStyles: TextStyle = {},
) => (
<MarkdownInheritedText
<HighlightedCodeBlock
key={node.key}
code={node.content}
language={node.sourceInfo}
inheritedStyles={inheritedStyles}
textStyle={styles.fence}
>
{node.content}
</MarkdownInheritedText>
/>
),
code_inline: (
node: ASTNode,