feat(CodeEditor): add support for multiple programming languages in CodeMirror

This commit is contained in:
Jaime Idolpx 2026-06-09 06:22:46 -04:00
parent 58f85ff88f
commit 8d5de3f92f
2 changed files with 34 additions and 3 deletions

View File

@ -8,7 +8,14 @@
"dev": "vite" "dev": "vite"
}, },
"dependencies": { "dependencies": {
"@codemirror/lang-cpp": "^6.0.3",
"@codemirror/lang-css": "^6.3.1",
"@codemirror/lang-javascript": "^6.2.5",
"@codemirror/lang-json": "^6.0.2", "@codemirror/lang-json": "^6.0.2",
"@codemirror/lang-php": "^6.0.2",
"@codemirror/lang-python": "^6.2.1",
"@codemirror/lang-rust": "^6.0.2",
"@codemirror/lang-sql": "^6.10.0",
"@codemirror/lang-xml": "^6.1.0", "@codemirror/lang-xml": "^6.1.0",
"@codemirror/theme-one-dark": "^6.1.3", "@codemirror/theme-one-dark": "^6.1.3",
"@emotion/react": "11.14.0", "@emotion/react": "11.14.0",

View File

@ -2,6 +2,13 @@ import { useRef, useState } from 'react';
import CodeMirror, { EditorView } from '@uiw/react-codemirror'; import CodeMirror, { EditorView } from '@uiw/react-codemirror';
import { json } from '@codemirror/lang-json'; import { json } from '@codemirror/lang-json';
import { xml } from '@codemirror/lang-xml'; import { xml } from '@codemirror/lang-xml';
import { javascript } from '@codemirror/lang-javascript';
import { python } from '@codemirror/lang-python';
import { cpp } from '@codemirror/lang-cpp';
import { css } from '@codemirror/lang-css';
import { rust } from '@codemirror/lang-rust';
import { php } from '@codemirror/lang-php';
import { sql } from '@codemirror/lang-sql';
import { oneDark } from '@codemirror/theme-one-dark'; import { oneDark } from '@codemirror/theme-one-dark';
import { Eye, Pencil, Save } from 'lucide-react'; import { Eye, Pencil, Save } from 'lucide-react';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
@ -25,13 +32,30 @@ const cmTheme = EditorView.theme({
'.cm-focused': { outline: 'none' }, '.cm-focused': { outline: 'none' },
}); });
const langExt: Record<CodeMode, any> = { const langExt: Record<Exclude<CodeMode, 'code'>, any> = {
json: json(), json: json(),
xml: xml(), xml: xml(),
text: [], text: [],
code: [], // no CM lang pack needed; SyntaxHighlighter handles view-mode
}; };
function cmLangExt(prismLang: string | undefined): any {
switch (prismLang) {
case 'javascript': return javascript();
case 'typescript': return javascript({ typescript: true });
case 'jsx': return javascript({ jsx: true });
case 'tsx': return javascript({ jsx: true, typescript: true });
case 'python': return python();
case 'c':
case 'cpp': return cpp();
case 'css':
case 'scss': return css();
case 'rust': return rust();
case 'php': return php();
case 'sql': return sql();
default: return [];
}
}
const syntaxLang: Record<CodeMode, string> = { const syntaxLang: Record<CodeMode, string> = {
text: 'text', json: 'json', xml: 'xml', code: 'text', text: 'text', json: 'json', xml: 'xml', code: 'text',
}; };
@ -50,7 +74,7 @@ export default function CodeEditor({ text, mode, syntaxHighlightLang, readOnly =
const editorViewRef = useRef<EditorView | null>(null); const editorViewRef = useRef<EditorView | null>(null);
const displayText = prettify(text, mode); const displayText = prettify(text, mode);
const extensions = [langExt[mode], cmTheme].flat(); const extensions = [mode === 'code' ? cmLangExt(syntaxHighlightLang) : langExt[mode], cmTheme].flat();
const handleSave = async () => { const handleSave = async () => {
if (!editorViewRef.current || !onSave) return; if (!editorViewRef.current || !onSave) return;