diff --git a/modules/home/code-line.tsx b/modules/home/code-line.tsx index 06da7478..bbc4742d 100644 --- a/modules/home/code-line.tsx +++ b/modules/home/code-line.tsx @@ -2,39 +2,33 @@ "use client"; import React from 'react'; -export const CodeLine = ({ line }: { line: string }) => { - // Basic replacements to simulate syntax highlighting - // Note: This is a very simplistic implementation and should be replaced with a proper library like prismjs or shiki in production - - const highlight = (text: string) => { - // We use a series of replacements. Order matters to avoid replacing inside already replaced spans. - // A better approach for robust highlighting is tokenization. - - const highlighted = text; - - // Comments (simple // for now) - if (highlighted.includes('//')) { - const parts = highlighted.split('//'); - return <>{'//' + parts[1]}; - } +const escapeHtml = (text: string) => { + return text + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); +}; - return ; - }; +const highlightCode = (code: string) => { + const escaped = escapeHtml(code); + return escaped + .replace(/import|from|export|default|return|const|new/g, '$&') + .replace(/'[^']*'/g, '$&') + .replace(/"[^"]*"/g, '$&') + .replace(/Editron|console|editor/g, '$&'); +}; - const highlightCode = (code: string) => { - return code - .replace(/import|from|export|default|return|const|new/g, '$&') - .replace(/'[^']*'/g, '$&') - .replace(/"[^"]*"/g, '$&') - .replace(/Editron|console|editor/g, '$&'); +const highlight = (text: string) => { + if (text.includes('//')) { + const parts = text.split('//'); + return <>{'//' + parts[1]}; } + return ; +}; - const [highlighted, setHighlighted] = React.useState(line); - - React.useEffect(() => { - setHighlighted(highlight(line)); -// eslint-disable-next-line react-hooks/exhaustive-deps - }, [line]); - +export const CodeLine = ({ line }: { line: string }) => { + const highlighted = React.useMemo(() => highlight(line), [line]); return highlighted; }; diff --git a/modules/playground/components/playground-editor.tsx b/modules/playground/components/playground-editor.tsx index 1434060a..c70601e1 100644 --- a/modules/playground/components/playground-editor.tsx +++ b/modules/playground/components/playground-editor.tsx @@ -1,7 +1,7 @@ "use client"; import { EDITOR_CONFIG } from "@/lib/constants/config"; -import { useRef, useEffect, useState } from "react"; +import { useRef, useEffect, useState, useCallback } from "react"; import Editor, { type Monaco } from "@monaco-editor/react"; import type { editor as MonacoEditor } from "monaco-editor"; import { @@ -253,7 +253,7 @@ const PlaygroundEditor = ({ ); }; - const updateEditorLanguage = () => { + const updateEditorLanguage = useCallback(() => { if (!activeFile || !monacoRef.current || !editorRef.current) return; const model = editorRef.current.getModel(); if (!model) return; @@ -264,12 +264,11 @@ const PlaygroundEditor = ({ } catch (error) { console.warn("Failed to set editor language:", error); } - }; + }, [activeFile]); useEffect(() => { updateEditorLanguage(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [activeFile]); + }, [activeFile, updateEditorLanguage]); // Bind Yjs to Monaco useEffect(() => { diff --git a/modules/webcontainers/components/terminal.tsx b/modules/webcontainers/components/terminal.tsx index 743a32fd..4154e015 100644 --- a/modules/webcontainers/components/terminal.tsx +++ b/modules/webcontainers/components/terminal.tsx @@ -325,7 +325,6 @@ const writePrompt(); return terminal; -// eslint-disable-next-line react-hooks/exhaustive-deps }, [theme, handleTerminalInput, writePrompt]); const connectToWebContainer = useCallback(async () => { @@ -420,7 +419,6 @@ const currentProcess.current.kill(); } if (shellProcess.current) { -// eslint-disable-next-line react-hooks/exhaustive-deps shellProcess.current.kill(); } if (term.current) {