-
-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathcopy-inline-code-view-plugin.ts
More file actions
102 lines (94 loc) · 2.19 KB
/
copy-inline-code-view-plugin.ts
File metadata and controls
102 lines (94 loc) · 2.19 KB
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
import { syntaxTree } from "@codemirror/language";
import { RangeSetBuilder } from "@codemirror/state";
import {
Decoration,
DecorationSet,
EditorView,
PluginValue,
ViewPlugin,
ViewUpdate,
} from "@codemirror/view";
import { CopyWidget } from "./copy-code-widget";
import { RegexFilters, shouldExclude } from "./regex-exclude";
class CopyInlineCodeViewPlugin implements PluginValue {
decorations: DecorationSet;
showOnHover: boolean;
filters: RegexFilters;
iconName: string;
useLegacyIcon: boolean;
constructor(
view: EditorView,
showOnHover: boolean,
filters: RegexFilters,
iconName: string,
useLegacyIcon: boolean
) {
this.showOnHover = showOnHover;
this.filters = filters;
this.iconName = iconName;
this.useLegacyIcon = useLegacyIcon;
this.decorations = this.buildDecorations(view);
}
update(update: ViewUpdate) {
if (update.docChanged || update.viewportChanged) {
this.decorations = this.buildDecorations(update.view);
}
}
destroy() {}
buildDecorations(view: EditorView): DecorationSet {
const builder = new RangeSetBuilder<Decoration>();
const showOnHover = this.showOnHover;
const filters = this.filters;
const iconName = this.iconName;
const useLegacyIcon = this.useLegacyIcon;
for (const { from, to } of view.visibleRanges) {
syntaxTree(view.state).iterate({
from,
to,
enter(node) {
if (node.type.name.startsWith("inline-code")) {
const codeText = view.state.doc.sliceString(
node.from,
node.to
);
if (shouldExclude(codeText, filters) || node.to + 1 > view.state.doc.length) {
return;
}
builder.add(
node.to + 1,
node.to + 1,
Decoration.widget({
widget: new CopyWidget(
showOnHover,
iconName,
useLegacyIcon
),
})
);
}
},
});
}
return builder.finish();
}
}
export const createCopyPlugin = (
showOnHover: boolean,
filters: RegexFilters,
iconName: string,
useLegacyIcon: boolean
) => {
return ViewPlugin.define(
(view: EditorView) =>
new CopyInlineCodeViewPlugin(
view,
showOnHover,
filters,
iconName,
useLegacyIcon
),
{
decorations: (p) => p.decorations,
}
);
};