-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathextension.ts
92 lines (82 loc) · 2.31 KB
/
extension.ts
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
import { Facet, Extension, RangeSet } from '@codemirror/state';
import {
WidgetType,
EditorView,
Decoration,
ViewPlugin,
DecorationSet,
ViewUpdate,
MatchDecorator,
} from '@codemirror/view';
interface MorgenPluginSettings {
decorateIDs: 'show' | 'hide' | 'replace_with_emoji';
}
const DEFAULT_SETTINGS: MorgenPluginSettings = {
decorateIDs: 'show',
};
class IDWidget extends WidgetType {
constructor(readonly id: string) {
super();
}
toDOM() {
const wrap = document.createElement('span');
wrap.setAttribute('aria-label', `ID: ${this.id}`);
const box = wrap.appendChild(document.createElement('span'));
box.innerText = '▫️';
box.style.opacity = '0.7';
box.style.filter = 'grayscale()';
return wrap;
}
}
const settingsFacet = Facet.define<MorgenPluginSettings, MorgenPluginSettings>({
combine: (allSettings) => allSettings[0] ?? DEFAULT_SETTINGS,
});
function hideIdsDeco(view: EditorView): DecorationSet {
return new MatchDecorator({
regexp: /🆔 ([A-Za-z0-9]+)/g,
decoration: (match) => {
return Decoration.replace({
widget:
view.state.facet(settingsFacet).decorateIDs === 'hide'
? undefined
: new IDWidget(match[1]),
});
},
}).createDeco(view);
}
const hideIDsPlugin = ViewPlugin.fromClass(
class {
decorations: DecorationSet;
placeholderMatcher: MatchDecorator;
previousSettingsHash: string;
constructor(view: EditorView) {
this.previousSettingsHash = JSON.stringify(view.state.facet(settingsFacet));
this.decorations =
view.state.facet(settingsFacet).decorateIDs === 'show'
? RangeSet.empty
: hideIdsDeco(view);
}
update(update: ViewUpdate) {
if (
update.docChanged ||
this.previousSettingsHash !== JSON.stringify(update.view.state.facet(settingsFacet))
) {
this.previousSettingsHash = JSON.stringify(update.view.state.facet(settingsFacet));
this.decorations =
update.view.state.facet(settingsFacet).decorateIDs === 'show'
? RangeSet.empty
: hideIdsDeco(update.view);
}
}
},
{
decorations: (v) => v.decorations,
provide: (plugin) =>
EditorView.atomicRanges.of(
(view) => view.plugin(plugin)?.decorations || Decoration.none,
),
},
);
export function hideIDsExtension(settings: MorgenPluginSettings = DEFAULT_SETTINGS): Extension {
return [settingsFacet.of(settings), hideIDsPlugin];
}