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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
import {
closeBrackets,
closeBracketsKeymap,
autocompletion,
completionKeymap,
} from '@codemirror/autocomplete';
import {
defaultKeymap,
history,
historyKeymap,
indentWithTab,
} from '@codemirror/commands';
import {
bracketMatching,
codeFolding,
foldGutter,
foldKeymap,
indentOnInput,
syntaxHighlighting,
} from '@codemirror/language';
import { lintKeymap, lintGutter } from '@codemirror/lint';
import { search, searchKeymap } from '@codemirror/search';
import { EditorState } from '@codemirror/state';
import {
drawSelection,
highlightActiveLine,
highlightActiveLineGutter,
highlightSpecialChars,
keymap,
lineNumbers,
rectangularSelection,
} from '@codemirror/view';
import { classHighlighter } from '@lezer/highlight';
import problemLanguageSupport from '../language/problemLanguageSupport';
import type EditorStore from './EditorStore';
import SearchPanel from './SearchPanel';
import findOccurrences from './findOccurrences';
import indentationMarkerViewPlugin from './indentationMarkerViewPlugin';
import semanticHighlighting from './semanticHighlighting';
export default function createEditorState(
initialValue: string,
store: EditorStore,
): EditorState {
return EditorState.create({
doc: initialValue,
extensions: [
autocompletion({
activateOnTyping: true,
override: [(context) => store.contentAssist(context)],
}),
closeBrackets(),
bracketMatching(),
drawSelection(),
EditorState.allowMultipleSelections.of(true),
findOccurrences,
highlightActiveLine(),
highlightActiveLineGutter(),
highlightSpecialChars(),
history(),
indentOnInput(),
indentationMarkerViewPlugin(),
rectangularSelection(),
search({
createPanel(view) {
return new SearchPanel(view, store.searchPanel);
},
}),
syntaxHighlighting(classHighlighter),
semanticHighlighting,
// We add the gutters to `extensions` in the order we want them to appear.
lintGutter(),
lineNumbers(),
codeFolding({
placeholderDOM(_view, onClick) {
const button = document.createElement('button');
button.className = 'problem-editor-foldPlaceholder';
button.ariaLabel = 'Unfold lines';
const span = document.createElement('span');
span.innerText = '...';
button.appendChild(span);
button.addEventListener('click', onClick);
return button;
},
}),
foldGutter({
markerDOM(open) {
const div = document.createElement('div');
div.className = [
'problem-editor-foldMarker',
`problem-editor-foldMarker-${open ? 'open' : 'closed'}`,
].join(' ');
return div;
},
}),
keymap.of([
{ key: 'Mod-Shift-f', run: () => store.formatText() },
...closeBracketsKeymap,
...completionKeymap,
...foldKeymap,
...historyKeymap,
indentWithTab,
// Override keys in `lintKeymap` to go through the `EditorStore`.
{ key: 'Mod-Shift-m', run: () => store.lintPanel.open() },
...lintKeymap,
// Override keys in `searchKeymap` to go through the `EditorStore`.
{
key: 'Mod-f',
run: () => store.searchPanel.open(),
scope: 'editor search-panel',
},
{
key: 'Escape',
run: () => store.searchPanel.close(),
scope: 'editor search-panel',
},
...searchKeymap,
...defaultKeymap,
]),
problemLanguageSupport(),
],
});
}
|