diff --git a/package.json b/package.json index 92bdeced82..875515bbf9 100644 --- a/package.json +++ b/package.json @@ -129,7 +129,7 @@ "@opentelemetry/sdk-trace-web": "^2.0.0", "@playwright/test": "^1.52.0", "@reduxjs/toolkit": "^2.2.5", - "@shikijs/markdown-it": "^3.7.0", + "@shikijs/markdown-it": "^3.9.1", "@swc/plugin-styled-components": "^7.1.5", "@tanstack/react-query": "^5.27.0", "@tanstack/react-virtual": "^3.13.12", @@ -249,7 +249,7 @@ "remove-markdown": "^0.6.2", "rollup-plugin-visualizer": "^5.12.0", "sass": "^1.88.0", - "shiki": "^3.7.0", + "shiki": "^3.9.1", "strict-url-sanitise": "^0.0.1", "string-width": "^7.2.0", "styled-components": "^6.1.11", diff --git a/src/renderer/src/components/CodeBlockView/CodePreview.tsx b/src/renderer/src/components/CodeBlockView/CodePreview.tsx index c78b4af99c..9e08dab5ae 100644 --- a/src/renderer/src/components/CodeBlockView/CodePreview.tsx +++ b/src/renderer/src/components/CodeBlockView/CodePreview.tsx @@ -189,44 +189,12 @@ const CodePreview = ({ children, language, setTools }: CodePreviewProps) => { CodePreview.displayName = 'CodePreview' -/** - * 补全代码行 tokens,把原始内容拼接到高亮内容之后,确保渲染出整行来。 - */ -function completeLineTokens(themedTokens: ThemedToken[], rawLine: string): ThemedToken[] { - // 如果出现空行,补一个空格保证行高 - if (rawLine.length === 0) { - return [ - { - content: ' ', - offset: 0, - color: 'inherit', - bgColor: 'inherit', - htmlStyle: { - opacity: '0.35' - } - } - ] +const plainTokenStyle = { + color: 'inherit', + bgColor: 'inherit', + htmlStyle: { + opacity: '0.35' } - - const themedContent = themedTokens.map((token) => token.content).join('') - const extraContent = rawLine.slice(themedContent.length) - - // 已有内容已经全部高亮,直接返回 - if (!extraContent) return themedTokens - - // 补全剩余内容 - return [ - ...themedTokens, - { - content: extraContent, - offset: themedContent.length, - color: 'inherit', - bgColor: 'inherit', - htmlStyle: { - opacity: '0.35' - } - } - ] } interface VirtualizedRowData { @@ -240,11 +208,43 @@ interface VirtualizedRowData { */ const VirtualizedRow = memo( ({ rawLine, tokenLine, showLineNumbers, index }: VirtualizedRowData & { index: number }) => { + // 补全代码行 tokens,把原始内容拼接到高亮内容之后,确保渲染出整行来。 + const completeTokenLine = useMemo(() => { + // 如果出现空行,补一个空元素保证行高 + if (rawLine.length === 0) { + return [ + { + content: '', + offset: 0, + ...plainTokenStyle + } + ] + } + + const currentTokens = tokenLine ?? [] + const themedContentLength = currentTokens.reduce((acc, token) => acc + token.content.length, 0) + + // 已有内容已经全部高亮,直接返回 + if (themedContentLength >= rawLine.length) { + return currentTokens + } + + // 补全剩余内容 + return [ + ...currentTokens, + { + content: rawLine.slice(themedContentLength), + offset: themedContentLength, + ...plainTokenStyle + } + ] + }, [rawLine, tokenLine]) + return (
{showLineNumbers && {index + 1}} - {completeLineTokens(tokenLine ?? [], rawLine).map((token, tokenIndex) => ( + {completeTokenLine.map((token, tokenIndex) => ( {token.content} @@ -272,6 +272,7 @@ const ScrollContainer = styled.div<{ align-items: flex-start; width: 100%; line-height: ${(props) => props.$lineHeight}px; + contain: content; .line-number { width: var(--gutter-width, 1.2ch); diff --git a/yarn.lock b/yarn.lock index b7eb2b98f8..a1643ab873 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4923,79 +4923,79 @@ __metadata: languageName: node linkType: hard -"@shikijs/core@npm:3.7.0": - version: 3.7.0 - resolution: "@shikijs/core@npm:3.7.0" +"@shikijs/core@npm:3.9.1": + version: 3.9.1 + resolution: "@shikijs/core@npm:3.9.1" dependencies: - "@shikijs/types": "npm:3.7.0" + "@shikijs/types": "npm:3.9.1" "@shikijs/vscode-textmate": "npm:^10.0.2" "@types/hast": "npm:^3.0.4" hast-util-to-html: "npm:^9.0.5" - checksum: 10c0/885c9d00712d350ab0aac0d239b26d8ba045f075abbaee5eda33c4a39fe841a1a2b0ca34391a3704cde0edcf1468ca583bea25fcbd37b7b8d6189b7afcf2a55d + checksum: 10c0/2267cb9b056f29d93d60b5591340161db614719f1cee8e0050af8ca048eb8ee32bac51fcfe536de65dcaeadae8697fba1157c178803daae33771a2baf6bf9672 languageName: node linkType: hard -"@shikijs/engine-javascript@npm:3.7.0": - version: 3.7.0 - resolution: "@shikijs/engine-javascript@npm:3.7.0" +"@shikijs/engine-javascript@npm:3.9.1": + version: 3.9.1 + resolution: "@shikijs/engine-javascript@npm:3.9.1" dependencies: - "@shikijs/types": "npm:3.7.0" + "@shikijs/types": "npm:3.9.1" "@shikijs/vscode-textmate": "npm:^10.0.2" oniguruma-to-es: "npm:^4.3.3" - checksum: 10c0/ac792fe99a2007ab076856d32d4934e191d3b03f8bd416e96f461821580c223da73de8abc199e5eceb8b56fd47e992824b2571270e7c3d55efa6b9a6d87fec80 + checksum: 10c0/9d5e5e0fde46c9fc3813363f61b75cee9b06df10a676609b2006df344123993af94444f7564e44adb877c8299a33fa144c0bf35688370d0a70077249c2a5836b languageName: node linkType: hard -"@shikijs/engine-oniguruma@npm:3.7.0": - version: 3.7.0 - resolution: "@shikijs/engine-oniguruma@npm:3.7.0" +"@shikijs/engine-oniguruma@npm:3.9.1": + version: 3.9.1 + resolution: "@shikijs/engine-oniguruma@npm:3.9.1" dependencies: - "@shikijs/types": "npm:3.7.0" + "@shikijs/types": "npm:3.9.1" "@shikijs/vscode-textmate": "npm:^10.0.2" - checksum: 10c0/e1ec52ec2255e3330812084d62bde8853d20162b1cd285dbb63440d63d0b16c03b6ce6983982e41ac2fc2eceb3e2f6b2bc1c627d093482c4c3836c4fbb9567b0 + checksum: 10c0/70eb64cccb043d01f82804a0c630ce1861ab9cb0f79eca31ea550c1f9c6e7de2f37094c4c28f0fca81b26d78b77287d11c110809e7f76a59829c443abd88ef2c languageName: node linkType: hard -"@shikijs/langs@npm:3.7.0": - version: 3.7.0 - resolution: "@shikijs/langs@npm:3.7.0" +"@shikijs/langs@npm:3.9.1": + version: 3.9.1 + resolution: "@shikijs/langs@npm:3.9.1" dependencies: - "@shikijs/types": "npm:3.7.0" - checksum: 10c0/326e8b014e74d25ce84a63bf7fdd47d5582f85c8404d4c48d6bdacf2f32ab92ddb39b41710ee7eff3daaecbbea7ee96a6c49d427344ee8375551597c74010a81 + "@shikijs/types": "npm:3.9.1" + checksum: 10c0/94351ef82e0a7a26351eaf70e33a5c0a48727ef052b907cb3c09ebbd3bb8fb1ef7825ae27c0ff2829888d5fb9da24eeca86c914178c354754eefd7fab70a613f languageName: node linkType: hard -"@shikijs/markdown-it@npm:^3.7.0": - version: 3.7.0 - resolution: "@shikijs/markdown-it@npm:3.7.0" +"@shikijs/markdown-it@npm:^3.9.1": + version: 3.9.1 + resolution: "@shikijs/markdown-it@npm:3.9.1" dependencies: markdown-it: "npm:^14.1.0" - shiki: "npm:3.7.0" + shiki: "npm:3.9.1" peerDependencies: markdown-it-async: ^2.2.0 peerDependenciesMeta: markdown-it-async: optional: true - checksum: 10c0/28d7ccacf241ef9b60080f232ac352694e9f29556e27c4c874226cf222b2deac3edb6f27813f46cb6316fbcaaf1b7880a76fdd6acd6f40a36cde3b3392107449 + checksum: 10c0/54b7acbf1e12b8686a71fe22b988e1a1475d70bdca5434824f2cb75efc5fc929d9be793c7118e3d9a112589d39197e954b8d47dddbfc1e6981b05b5b1a28d98a languageName: node linkType: hard -"@shikijs/themes@npm:3.7.0": - version: 3.7.0 - resolution: "@shikijs/themes@npm:3.7.0" +"@shikijs/themes@npm:3.9.1": + version: 3.9.1 + resolution: "@shikijs/themes@npm:3.9.1" dependencies: - "@shikijs/types": "npm:3.7.0" - checksum: 10c0/6887eb99b55439988edab21a1af00302eaed6ba0dd7e2bea6c844ff4dfb8879a0c6c2178ba3fcfe2dbf3fd9f3ab6105572c57ae871e147aaceaf53bcc345d0cd + "@shikijs/types": "npm:3.9.1" + checksum: 10c0/a061eec4d9dd147d83cda9c41b296263fab92d6113146279a244751b9f016f8af543f91c37dcefe33f47cff9f1a1d7898f78a80169947ac119617b32d16766d4 languageName: node linkType: hard -"@shikijs/types@npm:3.7.0": - version: 3.7.0 - resolution: "@shikijs/types@npm:3.7.0" +"@shikijs/types@npm:3.9.1": + version: 3.9.1 + resolution: "@shikijs/types@npm:3.9.1" dependencies: "@shikijs/vscode-textmate": "npm:^10.0.2" "@types/hast": "npm:^3.0.4" - checksum: 10c0/d7c4fcca358c0585602090e2b4ed0a3f6742b55bea340030c115cb7aa643eac79836baa095517a538d695415458bb48c08b7be7f3c8d1cf1c1c7749a58913a3f + checksum: 10c0/c726478ae36ca078a8b9d61a9b51b83fe32b7af2cfe7ae597828b2ffccbd24858d955c49d0786af13ebd04cfbb9d192067499c410a05c41eb38da57928424076 languageName: node linkType: hard @@ -7677,7 +7677,7 @@ __metadata: "@opentelemetry/sdk-trace-web": "npm:^2.0.0" "@playwright/test": "npm:^1.52.0" "@reduxjs/toolkit": "npm:^2.2.5" - "@shikijs/markdown-it": "npm:^3.7.0" + "@shikijs/markdown-it": "npm:^3.9.1" "@strongtz/win32-arm64-msvc": "npm:^0.4.7" "@swc/plugin-styled-components": "npm:^7.1.5" "@tanstack/react-query": "npm:^5.27.0" @@ -7804,7 +7804,7 @@ __metadata: rollup-plugin-visualizer: "npm:^5.12.0" sass: "npm:^1.88.0" selection-hook: "npm:^1.0.8" - shiki: "npm:^3.7.0" + shiki: "npm:^3.9.1" strict-url-sanitise: "npm:^0.0.1" string-width: "npm:^7.2.0" styled-components: "npm:^6.1.11" @@ -19300,19 +19300,19 @@ __metadata: languageName: node linkType: hard -"shiki@npm:3.7.0, shiki@npm:^3.7.0": - version: 3.7.0 - resolution: "shiki@npm:3.7.0" +"shiki@npm:3.9.1, shiki@npm:^3.9.1": + version: 3.9.1 + resolution: "shiki@npm:3.9.1" dependencies: - "@shikijs/core": "npm:3.7.0" - "@shikijs/engine-javascript": "npm:3.7.0" - "@shikijs/engine-oniguruma": "npm:3.7.0" - "@shikijs/langs": "npm:3.7.0" - "@shikijs/themes": "npm:3.7.0" - "@shikijs/types": "npm:3.7.0" + "@shikijs/core": "npm:3.9.1" + "@shikijs/engine-javascript": "npm:3.9.1" + "@shikijs/engine-oniguruma": "npm:3.9.1" + "@shikijs/langs": "npm:3.9.1" + "@shikijs/themes": "npm:3.9.1" + "@shikijs/types": "npm:3.9.1" "@shikijs/vscode-textmate": "npm:^10.0.2" "@types/hast": "npm:^3.0.4" - checksum: 10c0/a458d06cc0487da5916e10ab9daaf314e3c3c92024664c545bcacb58fad9bd3aa18cde90a200afe4f6632a2487014def57eb6f10f38ab6269e90f3420b724105 + checksum: 10c0/383ca4b91b0ade1df7ce8889c4abeb9bfabead53a808f11de749e44f8400b3967d8bad7aad99a8ecf7991a2e1d1c42a71b73154d12baca6deeb979b9929376cb languageName: node linkType: hard