editor
This commit is contained in:
@@ -2,19 +2,51 @@
|
||||
|
||||
import { useEffect, useRef, forwardRef, useImperativeHandle, useState } from "react";
|
||||
import styles from "@/styles/Editor.module.css";
|
||||
import { loadRhaiWasm, initRhaiMode } from "@/utils/wasmLoader";
|
||||
|
||||
// Dynamic import for CodeMirror to avoid SSR issues
|
||||
let CodeMirror: any = null;
|
||||
let isCodeMirrorReady = false;
|
||||
|
||||
if (typeof window !== "undefined") {
|
||||
import("codemirror")
|
||||
.then(async (cm) => {
|
||||
CodeMirror = cm.default;
|
||||
await import("codemirror/mode/javascript/javascript");
|
||||
await import("codemirror/addon/edit/matchbrackets");
|
||||
await import("codemirror/addon/edit/closebrackets");
|
||||
await import("codemirror/addon/selection/active-line");
|
||||
await import("codemirror/lib/codemirror.css");
|
||||
await import("codemirror/theme/monokai.css");
|
||||
await import("codemirror/addon/comment/comment");
|
||||
// @ts-ignore - CodeMirror addon type issues
|
||||
await import("codemirror/addon/fold/brace-fold");
|
||||
// @ts-ignore - CodeMirror addon type issues
|
||||
await import("codemirror/addon/fold/foldgutter");
|
||||
// @ts-ignore - CodeMirror addon type issues
|
||||
await import("codemirror/addon/search/match-highlighter");
|
||||
require("codemirror/lib/codemirror.css");
|
||||
require("codemirror/theme/monokai.css");
|
||||
require("codemirror/addon/fold/foldgutter.css");
|
||||
|
||||
try {
|
||||
await loadRhaiWasm();
|
||||
initRhaiMode(CodeMirror);
|
||||
console.log('✅ WASM-based Rhai mode initialized successfully');
|
||||
} catch (error) {
|
||||
console.warn('⚠️ Failed to load WASM Rhai mode, falling back to JavaScript mode:', error);
|
||||
// Fallback to JavaScript mode if WASM fails
|
||||
CodeMirror.defineMode("rhai", (config: any) => {
|
||||
const jsMode = CodeMirror.getMode(config, "javascript");
|
||||
return {
|
||||
...jsMode,
|
||||
name: "rhai",
|
||||
helperType: "rhai"
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
isCodeMirrorReady = true;
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Failed to load CodeMirror:', error);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -26,7 +58,7 @@ interface EditorProps {
|
||||
}
|
||||
|
||||
export const Editor = forwardRef<any, EditorProps>(function Editor(
|
||||
{ initialValue = "", onChange, onRequestRun, onReady },
|
||||
{ initialValue = "", onChange, onReady },
|
||||
ref,
|
||||
) {
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||
@@ -37,19 +69,30 @@ export const Editor = forwardRef<any, EditorProps>(function Editor(
|
||||
|
||||
// Initialize editor only once
|
||||
useEffect(() => {
|
||||
if (!CodeMirror || !textareaRef.current || editorRef.current) return;
|
||||
if (!isCodeMirrorReady || !CodeMirror || !textareaRef.current || editorRef.current) return;
|
||||
|
||||
const editor = CodeMirror.fromTextArea(textareaRef.current, {
|
||||
lineNumbers: true,
|
||||
mode: "javascript", // Placeholder mode, will be 'rhai' when WASM is integrated
|
||||
mode: "rhai",
|
||||
theme: "monokai",
|
||||
indentUnit: 4,
|
||||
matchBrackets: true,
|
||||
autoCloseBrackets: true,
|
||||
foldGutter: {
|
||||
rangeFinder: CodeMirror.fold.brace,
|
||||
},
|
||||
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
|
||||
styleActiveLine: true,
|
||||
extraKeys: {
|
||||
"Ctrl-Enter": () => {
|
||||
onRequestRun?.();
|
||||
},
|
||||
highlightSelectionMatches: {
|
||||
minChars: 3,
|
||||
showToken: true,
|
||||
annotateScrollbar: true,
|
||||
},
|
||||
rulers: [],
|
||||
autoCloseBrackets: {
|
||||
pairs: `()[]{}''""`,
|
||||
closeBefore: `)]}'":;,`,
|
||||
triples: "",
|
||||
explode: "()[]{}",
|
||||
},
|
||||
});
|
||||
|
||||
@@ -70,25 +113,14 @@ export const Editor = forwardRef<any, EditorProps>(function Editor(
|
||||
editorRef.current = null;
|
||||
}
|
||||
};
|
||||
}, []); // Empty dependency array - only initialize once
|
||||
|
||||
// Update keyboard shortcut when onRequestRun changes
|
||||
useEffect(() => {
|
||||
if (editorRef.current && onRequestRun) {
|
||||
editorRef.current.setOption("extraKeys", {
|
||||
"Ctrl-Enter": () => {
|
||||
onRequestRun();
|
||||
},
|
||||
});
|
||||
}
|
||||
}, [onRequestRun]);
|
||||
}, []); // Only run once
|
||||
|
||||
return (
|
||||
<div className={styles.editorContainer}>
|
||||
<textarea
|
||||
ref={textareaRef}
|
||||
defaultValue={initialValue}
|
||||
placeholder="Enter your Rhai code here..."
|
||||
placeholder="Code goes here"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -210,7 +210,7 @@ export default function Playground() {
|
||||
className={styles.result}
|
||||
readOnly
|
||||
autoComplete="off"
|
||||
placeholder="Script output will appear here..."
|
||||
placeholder="Use print() to produce output"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -66,7 +66,7 @@ export const Terminal = forwardRef<TerminalRef, {}>(function Terminal(_props, re
|
||||
});
|
||||
|
||||
term.open(terminalRef.current);
|
||||
term.write('Terminal ready...\r\n');
|
||||
term.write('Terminal ready.\r\n');
|
||||
|
||||
xtermRef.current = term;
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user