import { StreamLanguage } from "@codemirror/language"; import { octave } from "@codemirror/legacy-modes/mode/octave"; import { EditorState } from "@codemirror/state"; import { keymap } from "@codemirror/view"; import { basicSetup, EditorView } from "codemirror"; import { useEffect, useRef } from "react"; export function Editor({ value, onChange, onRun }: { value: string; onChange: (s: string) => void; onRun: () => void }) { const host = useRef(null); const view = useRef(null); const cb = useRef({ onChange, onRun }); cb.current = { onChange, onRun }; useEffect(() => { const v = new EditorView({ parent: host.current!, state: EditorState.create({ doc: value, extensions: [ keymap.of([{ key: "Mod-Enter", run: () => (cb.current.onRun(), true) }]), basicSetup, StreamLanguage.define(octave), EditorView.updateListener.of(u => { if (u.docChanged) cb.current.onChange(u.state.doc.toString()); }), ], }), }); view.current = v; return () => v.destroy(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { const v = view.current; if (v && v.state.doc.toString() !== value) { v.dispatch({ changes: { from: 0, to: v.state.doc.length, insert: value } }); } }, [value]); return
; }