Define a programming editor with syntax highlighting
HTML
<body style="padding: 1em">
<div id="editor"></div>
</body>
<script type="importmap">
{
"imports": {
"codemirror": "https://esm.sh/*codemirror@6.0.1",
"@codemirror/state": "https://esm.sh/*@codemirror/state@6.4.1",
"@codemirror/search": "https://esm.sh/*@codemirror/search@6.5.6",
"@codemirror/autocomplete": "https://esm.sh/*@codemirror/autocomplete@6.9.0",
"@codemirror/view": "https://esm.sh/*@codemirror/view@6.17.1",
"@codemirror/commands": "https://esm.sh/*@codemirror/commands@6.2.5",
"@codemirror/language": "https://esm.sh/*@codemirror/language@6.9.0",
"@codemirror/lint": "https://esm.sh/*@codemirror/lint@6.4.1",
"@lezer/lr": "https://esm.sh/*@lezer/lr@1.3.9",
"@lezer/highlight": "https://esm.sh/*@lezer/highlight@1.1.6",
"@lezer/common": "https://esm.sh/*@lezer/common@1.2.1",
"style-mod": "https://esm.sh/*style-mod@4.1.2",
"w3c-keyname": "https://esm.sh/*w3c-keyname@2.2.8",
"crelt": "https://esm.sh/*crelt@1.0.6",
"thememirror": "https://esm.sh/*thememirror@2.0.1",
"@valtzu/codemirror-lang-el": "https://esm.sh/*@valtzu/codemirror-lang-el"
}
}
</script>
CSS
body {
background: #222;
font-family: Arial, sans-serif;
}
.cm-diagnostic,
.cm-info {
padding: 0.8rem !important;
font-size: 0.85rem;
display: inline-block;
box-shadow: rgba(0, 0, 0, 0.15) 0 2px 5px;
}
.cm-completionDetail {
float: right;
opacity: 0.5;
font-style: inherit !important;
}
JavaScript
import { EditorView, basicSetup } from "codemirror";
import { acceptCompletion } from "@codemirror/autocomplete";
import { keymap } from "@codemirror/view";
import { expressionlanguage } from "@valtzu/codemirror-lang-el";
import { defaultKeymap } from "@codemirror/commands";
import { barf } from "thememirror";
let editor = new EditorView({
extensions: [
basicSetup,
keymap.of([...defaultKeymap, {key: "Tab", run: acceptCompletion}]),
barf,
expressionlanguage({
types: {
"User": {
identifiers: [
{ name: "self", type: ["User"], info: 'Self-reference for property-access demonstration purposes' },
{ name: "name", type: ["string"] },
{ name: "age", type: ["int"], info: "Years since birthday", detail: "years" },
],
functions: [
{ name: "isActive", returnType: ["bool"] },
{ name: "getGroup", args: [], returnType: ["Group"], info: 'Get the user group' },
],
},
"Group": {
identifiers: [{ name: "name", type: ["string"] }]
}
},
identifiers: [
{ name: "user", type: ["User"], info: 'This is the user' },
],
functions: [
{ name: "is_granted", args: [{ name: "subject" }, { name: "object" }], info: 'Check if subject has permission to the object', returnType: ['bool'] },
],
})
],
parent: document.getElementById('editor'),
doc: 'is_granted(user, user.self.getGroup())',
});