resources/editors/codemirror.js (39 lines of code) (raw):
// https://codemirror.net/examples/bundle/
import { EditorView, basicSetup } from "codemirror";
import { StateEffect } from "@codemirror/state";
import { javascript } from "@codemirror/lang-javascript";
let lang = javascript();
let extensions = [basicSetup, EditorView.lineWrapping];
export default function (element, value) {
let view = new EditorView({
extensions,
parent: element,
doc: value,
wordWrapColumn: 80,
});
return {
editor: view,
// Anything before this promise resolves will happen before timing starts
ready: Promise.resolve(),
getScrollHeight() {
return element.scrollHeight;
},
getScrollTop() {
return element.scrollTop;
},
setScrollTop(value) {
element.scrollTop = value;
},
setValue: (value) =>
view.dispatch({
changes: { from: 0, to: view.state.doc.length, insert: value },
}),
format(on) {
// https://codemirror.net/examples/config/
// https://discuss.codemirror.net/t/cm6-dynamically-switching-syntax-theme-w-reconfigure/2858/6
if (on && extensions.length === 2)
extensions.push(lang);
else if (!on && extensions.length === 3)
extensions.pop();
view.dispatch({
effects: StateEffect.reconfigure.of(extensions),
});
},
};
}