diff --git a/desktop/src/components/chat/CodeViewer.tsx b/desktop/src/components/chat/CodeViewer.tsx index 4af18121..57abd7ed 100644 --- a/desktop/src/components/chat/CodeViewer.tsx +++ b/desktop/src/components/chat/CodeViewer.tsx @@ -1,5 +1,5 @@ -import { useMemo, useState } from 'react' -import hljs from 'highlight.js' +import { useState } from 'react' +import { Highlight, themes } from 'prism-react-renderer' import { CopyButton } from '../shared/CopyButton' type Props = { @@ -12,37 +12,14 @@ type Props = { export function CodeViewer({ code, language, maxLines = 20, showLineNumbers = true }: Props) { const [expanded, setExpanded] = useState(false) - const lines = code.split('\n') - const isTruncated = !expanded && lines.length > maxLines - const visibleCode = isTruncated ? lines.slice(0, maxLines).join('\n') : code - - // Only highlight when language is explicitly known. - // Do NOT use highlightAuto — it misdetects plain text as code. - const hasLanguage = !!language && !!hljs.getLanguage(language) - const effectiveShowLineNumbers = showLineNumbers && hasLanguage - - const highlightedLines = useMemo(() => { - return visibleCode.split('\n').map((line) => { - try { - if (hasLanguage) { - return hljs.highlight(line || ' ', { language: language!, ignoreIllegals: true }).value - } - return escapeHtml(line || ' ') - } catch { - return escapeHtml(line) - } - }) - }, [hasLanguage, language, visibleCode]) - - const startLine = 1 + const allLines = code.split('\n') + const isTruncated = !expanded && allLines.length > maxLines + const visibleCode = isTruncated ? allLines.slice(0, maxLines).join('\n') : code + const effectiveShowLineNumbers = showLineNumbers && !!language && language !== 'text' const languageLabel = language || 'code' - - const visibleLines = visibleCode.split('\n') - - const lineCountLabel = `${lines.length} ${lines.length === 1 ? 'line' : 'lines'}` - - const showExpandToggle = lines.length > maxLines + const lineCountLabel = `${allLines.length} ${allLines.length === 1 ? 'line' : 'lines'}` + const showExpandToggle = allLines.length > maxLines return (
+ {tokens.map((line, i) => {
+ const lineProps = getLineProps({ line })
+ return effectiveShowLineNumbers ? (
+
+
+ {i + 1}
+
+
+ {line.map((token, key) => (
+
+ ))}
+
+
+ ) : (
+
+
+ {line.map((token, key) => (
+
+ ))}
+
+
+ )
+ })}
+
+ )}
+