first commit

This commit is contained in:
Christian Lawson-Perfect 2025-02-12 10:55:23 +00:00
commit 6c637e42c8
7 changed files with 165 additions and 0 deletions

5
.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
.make.*
node_modules/
.watchmakerc
code-editor.bundle.mjs
package-lock.json

13
Makefile Normal file
View file

@ -0,0 +1,13 @@
NODE_BIN=node_modules/.bin
DEST=../better-think-editor/dist
$(DEST)/code-editor.mjs: code-editor.bundle.mjs
cp $< $@
code-editor.terser.mjs: code-editor.bundle.mjs
$(NODE_BIN)/terser --compress --mangle -- $< > $@
code-editor.bundle.mjs: code-editor.mjs
$(NODE_BIN)/rollup $< -f es -p @rollup/plugin-node-resolve -o $@

81
code-editor.mjs Normal file
View file

@ -0,0 +1,81 @@
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);

38
index.html Normal file
View file

@ -0,0 +1,38 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>A thing made by CLP</title>
<script type="module" src="script.js"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<h1>A thing made by CLP</h1>
</header>
<main>
<h2>Elm</h2>
<code-editor language="elm">
module Poo
type alias Poo
= Arg Int
| Poo Float
a : Poo -> Poo
a plop = case plop of
Arg i -> Poo (toFloat i)
Poo f -> Arg (floor f)
</code-editor>
<h2>JavaScript</h2>
<code-editor language="javascript">
const x = 1;
function a() {
return x%2;
}
</code-editor>
</main>
</body>
</html>

22
package.json Normal file
View file

@ -0,0 +1,22 @@
{
"name": "codemirror-element",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"@codemirror/lang-javascript": "^6.2.2",
"@codemirror/lang-python": "^6.1.2",
"@codemirror/legacy-modes": "^6.4.3",
"@replit/codemirror-vim": "^6.2.0",
"@rollup/plugin-node-resolve": "^15.0.2",
"codemirror": "^6.0.1",
"codemirror-lang-r": "^0.1.0-2",
"rollup": "^3.20.6",
"terser": "^5.17.1"
}
}

1
script.js Normal file
View file

@ -0,0 +1 @@
import './code-editor.bundle.mjs';

5
style.css Normal file
View file

@ -0,0 +1,5 @@
:root {
--spacing: 1em;
color-scheme: light dark;
}