-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.js
100 lines (88 loc) · 3.01 KB
/
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import './style.css'
import { EditorView, basicSetup } from 'codemirror'
import { EditorState } from '@codemirror/state'
import { parser, props } from "@nextjournal/lezer-clojure"
import { styleTags, tags } from "@lezer/highlight"
import { indentNodeProp, foldNodeProp, foldInside, LRLanguage, LanguageSupport } from "@codemirror/language"
import { evalExtension } from "./eval-region"
const { coll } = props
export const clojureLanguage = LRLanguage.define({
parser: parser.configure({
props: [styleTags({
NS: tags.keyword,
DefLike: tags.keyword,
"Operator/Symbol": tags.keyword,
"VarName/Symbol": tags.definition(tags.variableName),
// Symbol: tags.keyword,
// "'": tags.keyword, // quote
Boolean: tags.atom,
"DocString/...": tags.emphasis,
"Discard!": tags.comment,
Number: tags.number,
StringContent: tags.string,
"\"\\\"\"": tags.string, // need to pass something, that returns " when being parsed as JSON
Keyword: tags.atom,
Nil: tags.null,
LineComment: tags.lineComment,
RegExp: tags.regexp
}),
indentNodeProp.add((nodeType) => {
return (context) => {
let { pos, unit, node, state, baseIndent, textAfter } = context
if (nodeType.prop(coll)) {
// same behaviour as in clojure-mode: args after operator are always 2-units indented
let parentBase = context.column(node.firstChild.to) // column at the right of parent opening-(
if ("List" == nodeType.name && ["NS", "DefLike", "Operator"].includes(node.firstChild.nextSibling.type.name)) {
return parentBase + 1
} else {
return parentBase
}
} else {
return 0
}
}
}),
foldNodeProp.add({ ["Vector Map List"]: foldInside })]
}),
languageData: { commentTokens: { line: ";;" } }
})
export function clojure() {
return new LanguageSupport(clojureLanguage)
}
let editorState = EditorState.create({
doc: `(map inc (range 5))`,
extensions: [basicSetup.slice(0, 15).concat(basicSetup.slice(16)), clojure(), evalExtension()]
})
function isLinux() {
if (navigator.userAgent.match(/(Linux)|(X11)/g) === null) {
return false
}
return true
}
function isMac() {
if (!isLinux &&
navigator.userAgent.match(/(Mac)|(iPhone)|(iPad)|(iPod)/g) != null) {
return true
}
return false
}
function modifier() {
if (isMac()) {
return "Cmd"
} else {
return "Ctrl"
}
}
new EditorView({
state: editorState,
parent: document.querySelector('#app')
}).focus()
let topLevelText = "Alt+Enter = Eval top-level form"
let keyBindings = "<strong>Key bindings:</strong>,Shift+Enter = Eval cell," +
topLevelText + "," + modifier() +
"+Enter = Eval at cursor, Esc/Arrows = Clear result";
keyBindings = keyBindings.split(',');
for ( let i = 0; i < keyBindings.length; i++ )
keyBindings[i] = "" + keyBindings[i] + "<br>";
keyBindings = keyBindings.join('');
document.getElementById("keymap").innerHTML = keyBindings;