codemirror-element/code-editor.mjs
Christian Lawson-Perfect 6c637e42c8 first commit
2025-02-12 10:55:30 +00:00

81 lines
No EOL
2.1 KiB
JavaScript

import {basicSetup} from "codemirror";
import {EditorView, keymap} from "@codemirror/view";
import {EditorState} from "@codemirror/state";
import {python} from "@codemirror/lang-python";
import {r} from "codemirror-lang-r";
import {javascript} from "@codemirror/lang-javascript";
import {elm} from "@codemirror/legacy-modes/mode/elm";
import {StreamLanguage} from "@codemirror/language"
import {vim} from "@replit/codemirror-vim";
import {indentWithTab} from "@codemirror/commands";
window.EditorView = EditorView;
const languages = {
'python': python,
'r': r,
'javascript': javascript,
'elm': () => StreamLanguage.define(elm),
}
export function codemirror_editor(language, options) {
const language_plugin = languages[language];
options = Object.assign({
extensions: [
vim(),
basicSetup,
keymap.of([indentWithTab]),
EditorView.updateListener.of(update => {
if(!options?.onChange || update.changes.desc.empty) {
return;
}
options.onChange(update);
})
]
}, options);
if(language_plugin) {
options.extensions.push(language_plugin());
}
let editor = new EditorView(options);
return editor;
}
export class CodeEditorElement extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({mode: 'open'});
}
connectedCallback() {
this.init_editor();
}
init_editor() {
const code = this.textContent;
const code_tag = this.shadowRoot;
const language = this.getAttribute('language') || '';
this.codeMirror = codemirror_editor(
language,
{
doc: code,
parent: code_tag,
root: this.shadowRoot,
onChange: update => this.onChange(update)
}
);
}
onChange() {
const code = this.codeMirror.state.doc.toString();
this.value = code;
this.dispatchEvent(new CustomEvent('change'));
}
}
customElements.define("code-editor", CodeEditorElement);