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), }); }, }; }