@coze-editor/extension-lint 0.1.0-alpha.09ffeb
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/esm/index.js +1011 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/index.d.mts +48 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.js +1038 -0
- package/dist/index.js.map +1 -0
- package/package.json +46 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1038 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
|
|
29
|
+
// src/index.ts
|
|
30
|
+
var index_exports = {};
|
|
31
|
+
__export(index_exports, {
|
|
32
|
+
closeLintPanel: () => closeLintPanel,
|
|
33
|
+
diagnosticCount: () => diagnosticCount,
|
|
34
|
+
forEachDiagnostic: () => forEachDiagnostic,
|
|
35
|
+
forceLinting: () => forceLinting,
|
|
36
|
+
lintGutter: () => lintGutter,
|
|
37
|
+
lintKeymap: () => lintKeymap,
|
|
38
|
+
linter: () => linter,
|
|
39
|
+
nextDiagnostic: () => nextDiagnostic,
|
|
40
|
+
openLintPanel: () => openLintPanel,
|
|
41
|
+
previousDiagnostic: () => previousDiagnostic,
|
|
42
|
+
setDiagnostics: () => setDiagnostics,
|
|
43
|
+
setDiagnosticsEffect: () => setDiagnosticsEffect
|
|
44
|
+
});
|
|
45
|
+
module.exports = __toCommonJS(index_exports);
|
|
46
|
+
var import_crelt = __toESM(require("crelt"));
|
|
47
|
+
var import_view2 = require("@codemirror/view");
|
|
48
|
+
var import_state = require("@codemirror/state");
|
|
49
|
+
|
|
50
|
+
// src/merge-decorations.ts
|
|
51
|
+
var import_view = require("@codemirror/view");
|
|
52
|
+
var splitDiagnosticBySeverity = (decorations) => {
|
|
53
|
+
const diagnosticMap = /* @__PURE__ */ new Map();
|
|
54
|
+
const decoration = decorations.iter();
|
|
55
|
+
while (decoration.value) {
|
|
56
|
+
const { severity } = decoration.value.spec.diagnostic;
|
|
57
|
+
if (!diagnosticMap.has(severity)) {
|
|
58
|
+
diagnosticMap.set(severity, []);
|
|
59
|
+
}
|
|
60
|
+
diagnosticMap.get(severity).push(decoration.value.spec.diagnostic);
|
|
61
|
+
decoration.next();
|
|
62
|
+
}
|
|
63
|
+
return diagnosticMap;
|
|
64
|
+
};
|
|
65
|
+
var createDecoration = (from, to, severity, diagnostics) => {
|
|
66
|
+
const last = diagnostics[diagnostics.length - 1];
|
|
67
|
+
return import_view.Decoration.mark({
|
|
68
|
+
attributes: {
|
|
69
|
+
class: `cm-lintRange cm-lintRange-${severity}${last.markClass ? ` ${last.markClass}` : ""}`
|
|
70
|
+
},
|
|
71
|
+
sourceDiagnostics: diagnostics
|
|
72
|
+
}).range(from, to);
|
|
73
|
+
};
|
|
74
|
+
var mergeDecoration = (diagnostics) => {
|
|
75
|
+
const cloned = diagnostics.map((e) => ({
|
|
76
|
+
from: e.from,
|
|
77
|
+
to: e.to
|
|
78
|
+
}));
|
|
79
|
+
const merged = [];
|
|
80
|
+
cloned.sort((a, b) => a.from - b.from);
|
|
81
|
+
let current = cloned[0];
|
|
82
|
+
let currentSourceDiagnostics = [diagnostics[0]];
|
|
83
|
+
for (let i = 1; i < cloned.length; i++) {
|
|
84
|
+
const next = cloned[i];
|
|
85
|
+
if (next.from <= current.to) {
|
|
86
|
+
currentSourceDiagnostics.push(diagnostics[i]);
|
|
87
|
+
current.to = Math.max(current.to, next.to);
|
|
88
|
+
} else {
|
|
89
|
+
merged.push({ ...current, sourceDiagnostics: currentSourceDiagnostics });
|
|
90
|
+
current = next;
|
|
91
|
+
currentSourceDiagnostics = [diagnostics[i]];
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
merged.push({ ...current, sourceDiagnostics: currentSourceDiagnostics });
|
|
95
|
+
return merged;
|
|
96
|
+
};
|
|
97
|
+
var mergeDecorations = (decorations) => {
|
|
98
|
+
try {
|
|
99
|
+
const diagnosticMap = splitDiagnosticBySeverity(decorations);
|
|
100
|
+
const merge = [];
|
|
101
|
+
diagnosticMap.forEach((value, key) => {
|
|
102
|
+
mergeDecoration(value).forEach((diagnostic) => {
|
|
103
|
+
if (typeof diagnostic.from !== "number" || typeof diagnostic.to !== "number") {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (diagnostic.from < diagnostic.to) {
|
|
107
|
+
merge.push(
|
|
108
|
+
createDecoration(
|
|
109
|
+
diagnostic.from,
|
|
110
|
+
diagnostic.to,
|
|
111
|
+
key,
|
|
112
|
+
diagnostic.sourceDiagnostics
|
|
113
|
+
)
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
merge.sort((a, b) => {
|
|
119
|
+
if (a.from !== b.from) {
|
|
120
|
+
return a.from - b.from;
|
|
121
|
+
}
|
|
122
|
+
return a.value.startSide - b.value.startSide;
|
|
123
|
+
});
|
|
124
|
+
return import_view.Decoration.set(merge);
|
|
125
|
+
} catch (e) {
|
|
126
|
+
console.error("linter mergeDecorations error", e);
|
|
127
|
+
return decorations;
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
// src/index.ts
|
|
132
|
+
var SelectedDiagnostic = class {
|
|
133
|
+
constructor(from, to, diagnostic) {
|
|
134
|
+
this.from = from;
|
|
135
|
+
this.to = to;
|
|
136
|
+
this.diagnostic = diagnostic;
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
var LintState = class _LintState {
|
|
140
|
+
constructor(diagnostics, panel, selected) {
|
|
141
|
+
this.diagnostics = diagnostics;
|
|
142
|
+
this.panel = panel;
|
|
143
|
+
this.selected = selected;
|
|
144
|
+
}
|
|
145
|
+
static init(diagnostics, panel, state) {
|
|
146
|
+
let markedDiagnostics = diagnostics;
|
|
147
|
+
const diagnosticFilter = state.facet(lintConfig).markerFilter;
|
|
148
|
+
if (diagnosticFilter) {
|
|
149
|
+
markedDiagnostics = diagnosticFilter(markedDiagnostics, state);
|
|
150
|
+
}
|
|
151
|
+
const ranges = import_view2.Decoration.set(
|
|
152
|
+
markedDiagnostics.map((d) => {
|
|
153
|
+
if (d.from == d.to || d.from == d.to - 1 && state.doc.lineAt(d.from).to == d.from) {
|
|
154
|
+
return import_view2.Decoration.widget({
|
|
155
|
+
widget: new DiagnosticWidget(d),
|
|
156
|
+
diagnostic: d
|
|
157
|
+
}).range(d.from);
|
|
158
|
+
}
|
|
159
|
+
return import_view2.Decoration.mark({
|
|
160
|
+
attributes: {
|
|
161
|
+
class: `cm-lintRange cm-lintRange-${d.severity}${d.markClass ? ` ${d.markClass}` : ""}`
|
|
162
|
+
},
|
|
163
|
+
diagnostic: d
|
|
164
|
+
}).range(d.from, d.to);
|
|
165
|
+
}),
|
|
166
|
+
true
|
|
167
|
+
);
|
|
168
|
+
return new _LintState(ranges, panel, findDiagnostic(ranges));
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
function findDiagnostic(diagnostics, diagnostic = null, after = 0) {
|
|
172
|
+
let found = null;
|
|
173
|
+
diagnostics.between(after, 1e9, (from, to, { spec }) => {
|
|
174
|
+
if (diagnostic && spec.diagnostic != diagnostic) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
found = new SelectedDiagnostic(from, to, spec.diagnostic);
|
|
178
|
+
return false;
|
|
179
|
+
});
|
|
180
|
+
return found;
|
|
181
|
+
}
|
|
182
|
+
function hideTooltip(tr, tooltip) {
|
|
183
|
+
const from = tooltip.pos, to = tooltip.end || from;
|
|
184
|
+
const result = tr.state.facet(lintConfig).hideOn(tr, from, to);
|
|
185
|
+
if (result != null) {
|
|
186
|
+
return result;
|
|
187
|
+
}
|
|
188
|
+
const line = tr.startState.doc.lineAt(tooltip.pos);
|
|
189
|
+
return !!(tr.effects.some((e) => e.is(setDiagnosticsEffect)) || tr.changes.touchesRange(line.from, Math.max(line.to, to)));
|
|
190
|
+
}
|
|
191
|
+
function maybeEnableLint(state, effects) {
|
|
192
|
+
return state.field(lintState, false) ? effects : effects.concat(import_state.StateEffect.appendConfig.of(lintExtensions));
|
|
193
|
+
}
|
|
194
|
+
function setDiagnostics(state, diagnostics) {
|
|
195
|
+
return {
|
|
196
|
+
effects: maybeEnableLint(state, [setDiagnosticsEffect.of(diagnostics)])
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
var setDiagnosticsEffect = import_state.StateEffect.define();
|
|
200
|
+
var togglePanel = import_state.StateEffect.define();
|
|
201
|
+
var movePanelSelection = import_state.StateEffect.define();
|
|
202
|
+
var lintState = import_state.StateField.define({
|
|
203
|
+
create() {
|
|
204
|
+
return new LintState(import_view2.Decoration.none, null, null);
|
|
205
|
+
},
|
|
206
|
+
update(value, tr) {
|
|
207
|
+
if (tr.docChanged && value.diagnostics.size) {
|
|
208
|
+
const mapped = value.diagnostics.map(tr.changes);
|
|
209
|
+
let selected = null, { panel } = value;
|
|
210
|
+
if (value.selected) {
|
|
211
|
+
const selPos = tr.changes.mapPos(value.selected.from, 1);
|
|
212
|
+
selected = findDiagnostic(mapped, value.selected.diagnostic, selPos) || findDiagnostic(mapped, null, selPos);
|
|
213
|
+
}
|
|
214
|
+
if (!mapped.size && panel && tr.state.facet(lintConfig).autoPanel) {
|
|
215
|
+
panel = null;
|
|
216
|
+
}
|
|
217
|
+
value = new LintState(mapped, panel, selected);
|
|
218
|
+
}
|
|
219
|
+
for (const effect of tr.effects) {
|
|
220
|
+
if (effect.is(setDiagnosticsEffect)) {
|
|
221
|
+
const panel = !tr.state.facet(lintConfig).autoPanel ? value.panel : effect.value.length ? LintPanel.open : null;
|
|
222
|
+
value = LintState.init(effect.value, panel, tr.state);
|
|
223
|
+
} else if (effect.is(togglePanel)) {
|
|
224
|
+
value = new LintState(
|
|
225
|
+
value.diagnostics,
|
|
226
|
+
effect.value ? LintPanel.open : null,
|
|
227
|
+
value.selected
|
|
228
|
+
);
|
|
229
|
+
} else if (effect.is(movePanelSelection)) {
|
|
230
|
+
value = new LintState(value.diagnostics, value.panel, effect.value);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return value;
|
|
234
|
+
},
|
|
235
|
+
provide: (f) => [
|
|
236
|
+
import_view2.showPanel.from(f, (val) => val.panel),
|
|
237
|
+
// mergeDecorations 中合并了相同 severity 的 diagnostic 在编辑器中的下划线样式,以前会重复绘制下划线,现在只会绘制一次。
|
|
238
|
+
import_view2.EditorView.decorations.from(f, (s) => mergeDecorations(s.diagnostics))
|
|
239
|
+
]
|
|
240
|
+
});
|
|
241
|
+
function diagnosticCount(state) {
|
|
242
|
+
const lint = state.field(lintState, false);
|
|
243
|
+
return lint ? lint.diagnostics.size : 0;
|
|
244
|
+
}
|
|
245
|
+
var activeMark = import_view2.Decoration.mark({
|
|
246
|
+
class: "cm-lintRange cm-lintRange-active"
|
|
247
|
+
});
|
|
248
|
+
function lintTooltip(view, pos, side) {
|
|
249
|
+
const { diagnostics } = view.state.field(lintState);
|
|
250
|
+
let found = [], stackStart = 2e8, stackEnd = 0;
|
|
251
|
+
diagnostics.between(
|
|
252
|
+
pos - (side < 0 ? 1 : 0),
|
|
253
|
+
pos + (side > 0 ? 1 : 0),
|
|
254
|
+
(from, to, { spec }) => {
|
|
255
|
+
if (pos >= from && pos <= to && (from == to || (pos > from || side > 0) && (pos < to || side < 0))) {
|
|
256
|
+
found.push(spec.diagnostic);
|
|
257
|
+
stackStart = Math.min(from, stackStart);
|
|
258
|
+
stackEnd = Math.max(to, stackEnd);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
);
|
|
262
|
+
const diagnosticFilter = view.state.facet(lintConfig).tooltipFilter;
|
|
263
|
+
if (diagnosticFilter) {
|
|
264
|
+
found = diagnosticFilter(found, view.state);
|
|
265
|
+
}
|
|
266
|
+
if (!found.length) {
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
return {
|
|
270
|
+
pos: stackStart,
|
|
271
|
+
end: stackEnd,
|
|
272
|
+
above: view.state.doc.lineAt(stackStart).to < stackEnd,
|
|
273
|
+
create() {
|
|
274
|
+
return { dom: diagnosticsTooltip(view, found) };
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
function diagnosticsTooltip(view, diagnostics) {
|
|
279
|
+
return (0, import_crelt.default)(
|
|
280
|
+
"ul",
|
|
281
|
+
{ class: "cm-tooltip-lint" },
|
|
282
|
+
diagnostics.map((d) => renderDiagnostic(view, d, false))
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
var openLintPanel = (view) => {
|
|
286
|
+
const field = view.state.field(lintState, false);
|
|
287
|
+
if (!field || !field.panel) {
|
|
288
|
+
view.dispatch({
|
|
289
|
+
effects: maybeEnableLint(view.state, [togglePanel.of(true)])
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
const panel = (0, import_view2.getPanel)(view, LintPanel.open);
|
|
293
|
+
if (panel) {
|
|
294
|
+
panel.dom.querySelector(".cm-panel-lint ul").focus();
|
|
295
|
+
}
|
|
296
|
+
return true;
|
|
297
|
+
};
|
|
298
|
+
var closeLintPanel = (view) => {
|
|
299
|
+
const field = view.state.field(lintState, false);
|
|
300
|
+
if (!field || !field.panel) {
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
view.dispatch({ effects: togglePanel.of(false) });
|
|
304
|
+
return true;
|
|
305
|
+
};
|
|
306
|
+
var nextDiagnostic = (view) => {
|
|
307
|
+
const field = view.state.field(lintState, false);
|
|
308
|
+
if (!field) {
|
|
309
|
+
return false;
|
|
310
|
+
}
|
|
311
|
+
const sel = view.state.selection.main;
|
|
312
|
+
let next = field.diagnostics.iter(sel.to + 1);
|
|
313
|
+
if (!next.value) {
|
|
314
|
+
next = field.diagnostics.iter(0);
|
|
315
|
+
if (!next.value || next.from == sel.from && next.to == sel.to) {
|
|
316
|
+
return false;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
view.dispatch({
|
|
320
|
+
selection: { anchor: next.from, head: next.to },
|
|
321
|
+
scrollIntoView: true
|
|
322
|
+
});
|
|
323
|
+
return true;
|
|
324
|
+
};
|
|
325
|
+
var previousDiagnostic = (view) => {
|
|
326
|
+
const { state } = view, field = state.field(lintState, false);
|
|
327
|
+
if (!field) {
|
|
328
|
+
return false;
|
|
329
|
+
}
|
|
330
|
+
const sel = state.selection.main;
|
|
331
|
+
let prevFrom, prevTo, lastFrom, lastTo;
|
|
332
|
+
field.diagnostics.between(0, state.doc.length, (from, to) => {
|
|
333
|
+
if (to < sel.to && (prevFrom == null || prevFrom < from)) {
|
|
334
|
+
prevFrom = from;
|
|
335
|
+
prevTo = to;
|
|
336
|
+
}
|
|
337
|
+
if (lastFrom == null || from > lastFrom) {
|
|
338
|
+
lastFrom = from;
|
|
339
|
+
lastTo = to;
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
if (lastFrom == null || prevFrom == null && lastFrom == sel.from) {
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
view.dispatch({
|
|
346
|
+
selection: { anchor: prevFrom ?? lastFrom, head: prevTo ?? lastTo },
|
|
347
|
+
scrollIntoView: true
|
|
348
|
+
});
|
|
349
|
+
return true;
|
|
350
|
+
};
|
|
351
|
+
var lintKeymap = [
|
|
352
|
+
{ key: "Mod-Shift-m", run: openLintPanel, preventDefault: true },
|
|
353
|
+
{ key: "F8", run: nextDiagnostic }
|
|
354
|
+
];
|
|
355
|
+
var lintPlugin = import_view2.ViewPlugin.fromClass(
|
|
356
|
+
class {
|
|
357
|
+
constructor(view) {
|
|
358
|
+
this.view = view;
|
|
359
|
+
const { delay } = view.state.facet(lintConfig);
|
|
360
|
+
this.lintTime = Date.now() + delay;
|
|
361
|
+
this.run = this.run.bind(this);
|
|
362
|
+
this.timeout = window.setTimeout(this.run, delay);
|
|
363
|
+
}
|
|
364
|
+
lintTime;
|
|
365
|
+
timeout = -1;
|
|
366
|
+
set = true;
|
|
367
|
+
run() {
|
|
368
|
+
clearTimeout(this.timeout);
|
|
369
|
+
const now = Date.now();
|
|
370
|
+
if (now < this.lintTime - 10) {
|
|
371
|
+
this.timeout = window.setTimeout(this.run, this.lintTime - now);
|
|
372
|
+
} else {
|
|
373
|
+
this.set = false;
|
|
374
|
+
const { state } = this.view, { sources } = state.facet(lintConfig);
|
|
375
|
+
if (sources.length) {
|
|
376
|
+
Promise.all(
|
|
377
|
+
sources.map((source) => Promise.resolve(source(this.view)))
|
|
378
|
+
).then(
|
|
379
|
+
(annotations) => {
|
|
380
|
+
const all = annotations.reduce((a, b) => a.concat(b));
|
|
381
|
+
if (this.view.state.doc == state.doc) {
|
|
382
|
+
this.view.dispatch(setDiagnostics(this.view.state, all));
|
|
383
|
+
}
|
|
384
|
+
},
|
|
385
|
+
(error) => {
|
|
386
|
+
(0, import_view2.logException)(this.view.state, error);
|
|
387
|
+
}
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
update(update) {
|
|
393
|
+
const config = update.state.facet(lintConfig);
|
|
394
|
+
if (update.docChanged || config != update.startState.facet(lintConfig) || config.needsRefresh && config.needsRefresh(update)) {
|
|
395
|
+
this.lintTime = Date.now() + config.delay;
|
|
396
|
+
if (!this.set) {
|
|
397
|
+
this.set = true;
|
|
398
|
+
this.timeout = window.setTimeout(this.run, config.delay);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
force() {
|
|
403
|
+
if (this.set) {
|
|
404
|
+
this.lintTime = Date.now();
|
|
405
|
+
this.run();
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
destroy() {
|
|
409
|
+
clearTimeout(this.timeout);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
);
|
|
413
|
+
var lintConfig = import_state.Facet.define({
|
|
414
|
+
combine(input) {
|
|
415
|
+
return {
|
|
416
|
+
sources: input.map((i) => i.source).filter((x) => x != null),
|
|
417
|
+
...(0, import_state.combineConfig)(
|
|
418
|
+
input.map((i) => i.config),
|
|
419
|
+
{
|
|
420
|
+
delay: 750,
|
|
421
|
+
markerFilter: null,
|
|
422
|
+
tooltipFilter: null,
|
|
423
|
+
needsRefresh: null,
|
|
424
|
+
hideOn: () => null
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
needsRefresh: (a, b) => !a ? b : !b ? a : (u) => a(u) || b(u)
|
|
428
|
+
}
|
|
429
|
+
)
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
function linter(source, config = {}) {
|
|
434
|
+
return [lintConfig.of({ source, config }), lintPlugin, lintExtensions];
|
|
435
|
+
}
|
|
436
|
+
function forceLinting(view) {
|
|
437
|
+
const plugin = view.plugin(lintPlugin);
|
|
438
|
+
if (plugin) {
|
|
439
|
+
plugin.force();
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
function assignKeys(actions) {
|
|
443
|
+
const assigned = [];
|
|
444
|
+
if (actions) {
|
|
445
|
+
actions: for (const { name } of actions) {
|
|
446
|
+
for (let i = 0; i < name.length; i++) {
|
|
447
|
+
const ch = name[i];
|
|
448
|
+
if (/[a-zA-Z]/.test(ch) && !assigned.some((c) => c.toLowerCase() == ch.toLowerCase())) {
|
|
449
|
+
assigned.push(ch);
|
|
450
|
+
continue actions;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
assigned.push("");
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
return assigned;
|
|
457
|
+
}
|
|
458
|
+
function renderDiagnostic(view, diagnostic, inPanel) {
|
|
459
|
+
var _a;
|
|
460
|
+
const keys = inPanel ? assignKeys(diagnostic.actions) : [];
|
|
461
|
+
return (0, import_crelt.default)(
|
|
462
|
+
"li",
|
|
463
|
+
{ class: `cm-diagnostic cm-diagnostic-${diagnostic.severity}` },
|
|
464
|
+
(0, import_crelt.default)(
|
|
465
|
+
"span",
|
|
466
|
+
{ class: "cm-diagnosticText" },
|
|
467
|
+
diagnostic.renderMessage ? diagnostic.renderMessage(view) : diagnostic.message
|
|
468
|
+
),
|
|
469
|
+
(_a = diagnostic.actions) == null ? void 0 : _a.map((action, i) => {
|
|
470
|
+
let fired = false;
|
|
471
|
+
const click = (e) => {
|
|
472
|
+
e.preventDefault();
|
|
473
|
+
if (fired) {
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
fired = true;
|
|
477
|
+
const found = findDiagnostic(
|
|
478
|
+
view.state.field(lintState).diagnostics,
|
|
479
|
+
diagnostic
|
|
480
|
+
);
|
|
481
|
+
if (found) {
|
|
482
|
+
action.apply(view, found.from, found.to);
|
|
483
|
+
}
|
|
484
|
+
};
|
|
485
|
+
const { name } = action, keyIndex = keys[i] ? name.indexOf(keys[i]) : -1;
|
|
486
|
+
const nameElt = keyIndex < 0 ? name : [
|
|
487
|
+
name.slice(0, keyIndex),
|
|
488
|
+
(0, import_crelt.default)("u", name.slice(keyIndex, keyIndex + 1)),
|
|
489
|
+
name.slice(keyIndex + 1)
|
|
490
|
+
];
|
|
491
|
+
return (0, import_crelt.default)(
|
|
492
|
+
"button",
|
|
493
|
+
{
|
|
494
|
+
type: "button",
|
|
495
|
+
class: "cm-diagnosticAction",
|
|
496
|
+
onclick: click,
|
|
497
|
+
onmousedown: click,
|
|
498
|
+
"aria-label": ` Action: ${name}${keyIndex < 0 ? "" : ` (access key "${keys[i]})"`}.`
|
|
499
|
+
},
|
|
500
|
+
nameElt
|
|
501
|
+
);
|
|
502
|
+
}),
|
|
503
|
+
diagnostic.source && (0, import_crelt.default)("div", { class: "cm-diagnosticSource" }, diagnostic.source)
|
|
504
|
+
);
|
|
505
|
+
}
|
|
506
|
+
var DiagnosticWidget = class extends import_view2.WidgetType {
|
|
507
|
+
constructor(diagnostic) {
|
|
508
|
+
super();
|
|
509
|
+
this.diagnostic = diagnostic;
|
|
510
|
+
}
|
|
511
|
+
eq(other) {
|
|
512
|
+
return other.diagnostic == this.diagnostic;
|
|
513
|
+
}
|
|
514
|
+
toDOM() {
|
|
515
|
+
return (0, import_crelt.default)("span", {
|
|
516
|
+
class: `cm-lintPoint cm-lintPoint-${this.diagnostic.severity}`
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
};
|
|
520
|
+
var PanelItem = class {
|
|
521
|
+
constructor(view, diagnostic) {
|
|
522
|
+
this.diagnostic = diagnostic;
|
|
523
|
+
this.dom = renderDiagnostic(view, diagnostic, true);
|
|
524
|
+
this.dom.id = this.id;
|
|
525
|
+
this.dom.setAttribute("role", "option");
|
|
526
|
+
}
|
|
527
|
+
id = `item_${Math.floor(Math.random() * 4294967295).toString(16)}`;
|
|
528
|
+
dom;
|
|
529
|
+
};
|
|
530
|
+
var LintPanel = class _LintPanel {
|
|
531
|
+
constructor(view) {
|
|
532
|
+
this.view = view;
|
|
533
|
+
const onkeydown = (event) => {
|
|
534
|
+
if (event.keyCode == 27) {
|
|
535
|
+
closeLintPanel(this.view);
|
|
536
|
+
this.view.focus();
|
|
537
|
+
} else if (event.keyCode == 38 || event.keyCode == 33) {
|
|
538
|
+
this.moveSelection(
|
|
539
|
+
(this.selectedIndex - 1 + this.items.length) % this.items.length
|
|
540
|
+
);
|
|
541
|
+
} else if (event.keyCode == 40 || event.keyCode == 34) {
|
|
542
|
+
this.moveSelection((this.selectedIndex + 1) % this.items.length);
|
|
543
|
+
} else if (event.keyCode == 36) {
|
|
544
|
+
this.moveSelection(0);
|
|
545
|
+
} else if (event.keyCode == 35) {
|
|
546
|
+
this.moveSelection(this.items.length - 1);
|
|
547
|
+
} else if (event.keyCode == 13) {
|
|
548
|
+
this.view.focus();
|
|
549
|
+
} else if (event.keyCode >= 65 && event.keyCode <= 90 && this.selectedIndex >= 0) {
|
|
550
|
+
const { diagnostic } = this.items[this.selectedIndex], keys = assignKeys(diagnostic.actions);
|
|
551
|
+
for (let i = 0; i < keys.length; i++) {
|
|
552
|
+
if (keys[i].toUpperCase().charCodeAt(0) == event.keyCode) {
|
|
553
|
+
const found = findDiagnostic(
|
|
554
|
+
this.view.state.field(lintState).diagnostics,
|
|
555
|
+
diagnostic
|
|
556
|
+
);
|
|
557
|
+
if (found) {
|
|
558
|
+
diagnostic.actions[i].apply(view, found.from, found.to);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
} else {
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
565
|
+
event.preventDefault();
|
|
566
|
+
};
|
|
567
|
+
const onclick = (event) => {
|
|
568
|
+
for (let i = 0; i < this.items.length; i++) {
|
|
569
|
+
if (this.items[i].dom.contains(event.target)) {
|
|
570
|
+
this.moveSelection(i);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
};
|
|
574
|
+
this.list = (0, import_crelt.default)("ul", {
|
|
575
|
+
tabIndex: 0,
|
|
576
|
+
role: "listbox",
|
|
577
|
+
"aria-label": this.view.state.phrase("Diagnostics"),
|
|
578
|
+
onkeydown,
|
|
579
|
+
onclick
|
|
580
|
+
});
|
|
581
|
+
this.dom = (0, import_crelt.default)(
|
|
582
|
+
"div",
|
|
583
|
+
{ class: "cm-panel-lint" },
|
|
584
|
+
this.list,
|
|
585
|
+
(0, import_crelt.default)(
|
|
586
|
+
"button",
|
|
587
|
+
{
|
|
588
|
+
type: "button",
|
|
589
|
+
name: "close",
|
|
590
|
+
"aria-label": this.view.state.phrase("close"),
|
|
591
|
+
onclick: () => closeLintPanel(this.view)
|
|
592
|
+
},
|
|
593
|
+
"\xD7"
|
|
594
|
+
)
|
|
595
|
+
);
|
|
596
|
+
this.update();
|
|
597
|
+
}
|
|
598
|
+
items = [];
|
|
599
|
+
dom;
|
|
600
|
+
list;
|
|
601
|
+
get selectedIndex() {
|
|
602
|
+
const { selected } = this.view.state.field(lintState);
|
|
603
|
+
if (!selected) {
|
|
604
|
+
return -1;
|
|
605
|
+
}
|
|
606
|
+
for (let i = 0; i < this.items.length; i++) {
|
|
607
|
+
if (this.items[i].diagnostic == selected.diagnostic) {
|
|
608
|
+
return i;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
return -1;
|
|
612
|
+
}
|
|
613
|
+
update() {
|
|
614
|
+
const { diagnostics, selected } = this.view.state.field(lintState);
|
|
615
|
+
let i = 0, needsSync = false, newSelectedItem = null;
|
|
616
|
+
diagnostics.between(
|
|
617
|
+
0,
|
|
618
|
+
this.view.state.doc.length,
|
|
619
|
+
(_start, _end, { spec }) => {
|
|
620
|
+
let found = -1, item;
|
|
621
|
+
for (let j = i; j < this.items.length; j++) {
|
|
622
|
+
if (this.items[j].diagnostic == spec.diagnostic) {
|
|
623
|
+
found = j;
|
|
624
|
+
break;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
if (found < 0) {
|
|
628
|
+
item = new PanelItem(this.view, spec.diagnostic);
|
|
629
|
+
this.items.splice(i, 0, item);
|
|
630
|
+
needsSync = true;
|
|
631
|
+
} else {
|
|
632
|
+
item = this.items[found];
|
|
633
|
+
if (found > i) {
|
|
634
|
+
this.items.splice(i, found - i);
|
|
635
|
+
needsSync = true;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
if (selected && item.diagnostic == selected.diagnostic) {
|
|
639
|
+
if (!item.dom.hasAttribute("aria-selected")) {
|
|
640
|
+
item.dom.setAttribute("aria-selected", "true");
|
|
641
|
+
newSelectedItem = item;
|
|
642
|
+
}
|
|
643
|
+
} else if (item.dom.hasAttribute("aria-selected")) {
|
|
644
|
+
item.dom.removeAttribute("aria-selected");
|
|
645
|
+
}
|
|
646
|
+
i++;
|
|
647
|
+
}
|
|
648
|
+
);
|
|
649
|
+
while (i < this.items.length && !(this.items.length == 1 && this.items[0].diagnostic.from < 0)) {
|
|
650
|
+
needsSync = true;
|
|
651
|
+
this.items.pop();
|
|
652
|
+
}
|
|
653
|
+
if (this.items.length == 0) {
|
|
654
|
+
this.items.push(
|
|
655
|
+
new PanelItem(this.view, {
|
|
656
|
+
from: -1,
|
|
657
|
+
to: -1,
|
|
658
|
+
severity: "info",
|
|
659
|
+
message: this.view.state.phrase("No diagnostics")
|
|
660
|
+
})
|
|
661
|
+
);
|
|
662
|
+
needsSync = true;
|
|
663
|
+
}
|
|
664
|
+
if (newSelectedItem) {
|
|
665
|
+
this.list.setAttribute("aria-activedescendant", newSelectedItem.id);
|
|
666
|
+
this.view.requestMeasure({
|
|
667
|
+
key: this,
|
|
668
|
+
read: () => ({
|
|
669
|
+
sel: newSelectedItem.dom.getBoundingClientRect(),
|
|
670
|
+
panel: this.list.getBoundingClientRect()
|
|
671
|
+
}),
|
|
672
|
+
write: ({ sel, panel }) => {
|
|
673
|
+
const scaleY = panel.height / this.list.offsetHeight;
|
|
674
|
+
if (sel.top < panel.top) {
|
|
675
|
+
this.list.scrollTop -= (panel.top - sel.top) / scaleY;
|
|
676
|
+
} else if (sel.bottom > panel.bottom) {
|
|
677
|
+
this.list.scrollTop += (sel.bottom - panel.bottom) / scaleY;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
});
|
|
681
|
+
} else if (this.selectedIndex < 0) {
|
|
682
|
+
this.list.removeAttribute("aria-activedescendant");
|
|
683
|
+
}
|
|
684
|
+
if (needsSync) {
|
|
685
|
+
this.sync();
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
sync() {
|
|
689
|
+
let domPos = this.list.firstChild;
|
|
690
|
+
function rm() {
|
|
691
|
+
const prev = domPos;
|
|
692
|
+
domPos = prev.nextSibling;
|
|
693
|
+
prev.remove();
|
|
694
|
+
}
|
|
695
|
+
for (const item of this.items) {
|
|
696
|
+
if (item.dom.parentNode == this.list) {
|
|
697
|
+
while (domPos != item.dom) {
|
|
698
|
+
rm();
|
|
699
|
+
}
|
|
700
|
+
domPos = item.dom.nextSibling;
|
|
701
|
+
} else {
|
|
702
|
+
this.list.insertBefore(item.dom, domPos);
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
while (domPos) {
|
|
706
|
+
rm();
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
moveSelection(selectedIndex) {
|
|
710
|
+
if (this.selectedIndex < 0) {
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
713
|
+
const field = this.view.state.field(lintState);
|
|
714
|
+
const selection = findDiagnostic(
|
|
715
|
+
field.diagnostics,
|
|
716
|
+
this.items[selectedIndex].diagnostic
|
|
717
|
+
);
|
|
718
|
+
if (!selection) {
|
|
719
|
+
return;
|
|
720
|
+
}
|
|
721
|
+
this.view.dispatch({
|
|
722
|
+
selection: { anchor: selection.from, head: selection.to },
|
|
723
|
+
scrollIntoView: true,
|
|
724
|
+
effects: movePanelSelection.of(selection)
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
static open(view) {
|
|
728
|
+
return new _LintPanel(view);
|
|
729
|
+
}
|
|
730
|
+
};
|
|
731
|
+
function svg(content, attrs = 'viewBox="0 0 40 40"') {
|
|
732
|
+
return `url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" ${attrs}>${encodeURIComponent(content)}</svg>')`;
|
|
733
|
+
}
|
|
734
|
+
function underline(color) {
|
|
735
|
+
return svg(
|
|
736
|
+
`<path d="m0 2.5 l2 -1.5 l1 0 l2 1.5 l1 0" stroke="${color}" fill="none" stroke-width=".7"/>`,
|
|
737
|
+
'width="6" height="3"'
|
|
738
|
+
);
|
|
739
|
+
}
|
|
740
|
+
var baseTheme = import_view2.EditorView.baseTheme({
|
|
741
|
+
".cm-diagnostic": {
|
|
742
|
+
padding: "3px 6px 3px 8px",
|
|
743
|
+
marginLeft: "-1px",
|
|
744
|
+
display: "block",
|
|
745
|
+
whiteSpace: "pre-wrap"
|
|
746
|
+
},
|
|
747
|
+
".cm-diagnostic-error": { borderLeft: "5px solid #d11" },
|
|
748
|
+
".cm-diagnostic-warning": { borderLeft: "5px solid orange" },
|
|
749
|
+
".cm-diagnostic-info": { borderLeft: "5px solid #999" },
|
|
750
|
+
".cm-diagnostic-hint": { borderLeft: "5px solid #66d" },
|
|
751
|
+
".cm-diagnosticAction": {
|
|
752
|
+
font: "inherit",
|
|
753
|
+
border: "none",
|
|
754
|
+
padding: "2px 4px",
|
|
755
|
+
backgroundColor: "#444",
|
|
756
|
+
color: "white",
|
|
757
|
+
borderRadius: "3px",
|
|
758
|
+
marginLeft: "8px",
|
|
759
|
+
cursor: "pointer"
|
|
760
|
+
},
|
|
761
|
+
".cm-diagnosticSource": {
|
|
762
|
+
fontSize: "70%",
|
|
763
|
+
opacity: 0.7
|
|
764
|
+
},
|
|
765
|
+
".cm-lintRange": {
|
|
766
|
+
backgroundPosition: "left bottom",
|
|
767
|
+
backgroundRepeat: "repeat-x",
|
|
768
|
+
paddingBottom: "0.7px"
|
|
769
|
+
},
|
|
770
|
+
".cm-lintRange-error": { backgroundImage: underline("#d11") },
|
|
771
|
+
".cm-lintRange-warning": { backgroundImage: underline("orange") },
|
|
772
|
+
".cm-lintRange-info": { backgroundImage: underline("#999") },
|
|
773
|
+
".cm-lintRange-hint": { backgroundImage: underline("#66d") },
|
|
774
|
+
".cm-lintRange-active": { backgroundColor: "#ffdd9980" },
|
|
775
|
+
".cm-tooltip-lint": {
|
|
776
|
+
padding: 0,
|
|
777
|
+
margin: 0
|
|
778
|
+
},
|
|
779
|
+
".cm-lintPoint": {
|
|
780
|
+
position: "relative",
|
|
781
|
+
"&:after": {
|
|
782
|
+
content: '""',
|
|
783
|
+
position: "absolute",
|
|
784
|
+
bottom: 0,
|
|
785
|
+
left: "-2px",
|
|
786
|
+
borderLeft: "3px solid transparent",
|
|
787
|
+
borderRight: "3px solid transparent",
|
|
788
|
+
borderBottom: "4px solid #d11"
|
|
789
|
+
}
|
|
790
|
+
},
|
|
791
|
+
".cm-lintPoint-warning": {
|
|
792
|
+
"&:after": { borderBottomColor: "orange" }
|
|
793
|
+
},
|
|
794
|
+
".cm-lintPoint-info": {
|
|
795
|
+
"&:after": { borderBottomColor: "#999" }
|
|
796
|
+
},
|
|
797
|
+
".cm-lintPoint-hint": {
|
|
798
|
+
"&:after": { borderBottomColor: "#66d" }
|
|
799
|
+
},
|
|
800
|
+
".cm-panel.cm-panel-lint": {
|
|
801
|
+
position: "relative",
|
|
802
|
+
"& ul": {
|
|
803
|
+
maxHeight: "100px",
|
|
804
|
+
overflowY: "auto",
|
|
805
|
+
"& [aria-selected]": {
|
|
806
|
+
backgroundColor: "#ddd",
|
|
807
|
+
"& u": { textDecoration: "underline" }
|
|
808
|
+
},
|
|
809
|
+
"&:focus [aria-selected]": {
|
|
810
|
+
background_fallback: "#bdf",
|
|
811
|
+
backgroundColor: "Highlight",
|
|
812
|
+
color_fallback: "white",
|
|
813
|
+
color: "HighlightText"
|
|
814
|
+
},
|
|
815
|
+
"& u": { textDecoration: "none" },
|
|
816
|
+
padding: 0,
|
|
817
|
+
margin: 0
|
|
818
|
+
},
|
|
819
|
+
"& [name=close]": {
|
|
820
|
+
position: "absolute",
|
|
821
|
+
top: "0",
|
|
822
|
+
right: "2px",
|
|
823
|
+
background: "inherit",
|
|
824
|
+
border: "none",
|
|
825
|
+
font: "inherit",
|
|
826
|
+
padding: 0,
|
|
827
|
+
margin: 0
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
});
|
|
831
|
+
function severityWeight(sev) {
|
|
832
|
+
return sev == "error" ? 4 : sev == "warning" ? 3 : sev == "info" ? 2 : 1;
|
|
833
|
+
}
|
|
834
|
+
var LintGutterMarker = class extends import_view2.GutterMarker {
|
|
835
|
+
constructor(diagnostics) {
|
|
836
|
+
super();
|
|
837
|
+
this.diagnostics = diagnostics;
|
|
838
|
+
this.severity = diagnostics.reduce(
|
|
839
|
+
(max, d) => severityWeight(max) < severityWeight(d.severity) ? d.severity : max,
|
|
840
|
+
"hint"
|
|
841
|
+
);
|
|
842
|
+
}
|
|
843
|
+
severity;
|
|
844
|
+
toDOM(view) {
|
|
845
|
+
const elt2 = document.createElement("div");
|
|
846
|
+
elt2.className = `cm-lint-marker cm-lint-marker-${this.severity}`;
|
|
847
|
+
let { diagnostics } = this;
|
|
848
|
+
const diagnosticsFilter = view.state.facet(lintGutterConfig).tooltipFilter;
|
|
849
|
+
if (diagnosticsFilter) {
|
|
850
|
+
diagnostics = diagnosticsFilter(diagnostics, view.state);
|
|
851
|
+
}
|
|
852
|
+
if (diagnostics.length) {
|
|
853
|
+
elt2.onmouseover = () => gutterMarkerMouseOver(view, elt2, diagnostics);
|
|
854
|
+
}
|
|
855
|
+
return elt2;
|
|
856
|
+
}
|
|
857
|
+
};
|
|
858
|
+
function trackHoverOn(view, marker) {
|
|
859
|
+
const mousemove = (event) => {
|
|
860
|
+
const rect = marker.getBoundingClientRect();
|
|
861
|
+
if (event.clientX > rect.left - 10 /* Margin */ && event.clientX < rect.right + 10 /* Margin */ && event.clientY > rect.top - 10 /* Margin */ && event.clientY < rect.bottom + 10 /* Margin */) {
|
|
862
|
+
return;
|
|
863
|
+
}
|
|
864
|
+
for (let target = event.target; target; target = target.parentNode) {
|
|
865
|
+
if (target.nodeType == 1 && target.classList.contains("cm-tooltip-lint")) {
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
window.removeEventListener("mousemove", mousemove);
|
|
870
|
+
if (view.state.field(lintGutterTooltip)) {
|
|
871
|
+
view.dispatch({ effects: setLintGutterTooltip.of(null) });
|
|
872
|
+
}
|
|
873
|
+
};
|
|
874
|
+
window.addEventListener("mousemove", mousemove);
|
|
875
|
+
}
|
|
876
|
+
function gutterMarkerMouseOver(view, marker, diagnostics) {
|
|
877
|
+
function hovered() {
|
|
878
|
+
const line = view.elementAtHeight(
|
|
879
|
+
marker.getBoundingClientRect().top + 5 - view.documentTop
|
|
880
|
+
);
|
|
881
|
+
const linePos = view.coordsAtPos(line.from);
|
|
882
|
+
if (linePos) {
|
|
883
|
+
view.dispatch({
|
|
884
|
+
effects: setLintGutterTooltip.of({
|
|
885
|
+
pos: line.from,
|
|
886
|
+
above: false,
|
|
887
|
+
create() {
|
|
888
|
+
return {
|
|
889
|
+
dom: diagnosticsTooltip(view, diagnostics),
|
|
890
|
+
getCoords: () => marker.getBoundingClientRect()
|
|
891
|
+
};
|
|
892
|
+
}
|
|
893
|
+
})
|
|
894
|
+
});
|
|
895
|
+
}
|
|
896
|
+
marker.onmouseout = marker.onmousemove = null;
|
|
897
|
+
trackHoverOn(view, marker);
|
|
898
|
+
}
|
|
899
|
+
const { hoverTime } = view.state.facet(lintGutterConfig);
|
|
900
|
+
let hoverTimeout = setTimeout(hovered, hoverTime);
|
|
901
|
+
marker.onmouseout = () => {
|
|
902
|
+
clearTimeout(hoverTimeout);
|
|
903
|
+
marker.onmouseout = marker.onmousemove = null;
|
|
904
|
+
};
|
|
905
|
+
marker.onmousemove = () => {
|
|
906
|
+
clearTimeout(hoverTimeout);
|
|
907
|
+
hoverTimeout = setTimeout(hovered, hoverTime);
|
|
908
|
+
};
|
|
909
|
+
}
|
|
910
|
+
function markersForDiagnostics(doc, diagnostics) {
|
|
911
|
+
const byLine = /* @__PURE__ */ Object.create(null);
|
|
912
|
+
for (const diagnostic of diagnostics) {
|
|
913
|
+
const line = doc.lineAt(diagnostic.from);
|
|
914
|
+
(byLine[line.from] || (byLine[line.from] = [])).push(diagnostic);
|
|
915
|
+
}
|
|
916
|
+
const markers = [];
|
|
917
|
+
for (const line in byLine) {
|
|
918
|
+
markers.push(new LintGutterMarker(byLine[line]).range(+line));
|
|
919
|
+
}
|
|
920
|
+
return import_state.RangeSet.of(markers, true);
|
|
921
|
+
}
|
|
922
|
+
var lintGutterExtension = (0, import_view2.gutter)({
|
|
923
|
+
class: "cm-gutter-lint",
|
|
924
|
+
markers: (view) => view.state.field(lintGutterMarkers)
|
|
925
|
+
});
|
|
926
|
+
var lintGutterMarkers = import_state.StateField.define({
|
|
927
|
+
create() {
|
|
928
|
+
return import_state.RangeSet.empty;
|
|
929
|
+
},
|
|
930
|
+
update(markers, tr) {
|
|
931
|
+
markers = markers.map(tr.changes);
|
|
932
|
+
const diagnosticFilter = tr.state.facet(lintGutterConfig).markerFilter;
|
|
933
|
+
for (const effect of tr.effects) {
|
|
934
|
+
if (effect.is(setDiagnosticsEffect)) {
|
|
935
|
+
let diagnostics = effect.value;
|
|
936
|
+
if (diagnosticFilter) {
|
|
937
|
+
diagnostics = diagnosticFilter(diagnostics || [], tr.state);
|
|
938
|
+
}
|
|
939
|
+
markers = markersForDiagnostics(tr.state.doc, diagnostics.slice(0));
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
return markers;
|
|
943
|
+
}
|
|
944
|
+
});
|
|
945
|
+
var setLintGutterTooltip = import_state.StateEffect.define();
|
|
946
|
+
var lintGutterTooltip = import_state.StateField.define({
|
|
947
|
+
create() {
|
|
948
|
+
return null;
|
|
949
|
+
},
|
|
950
|
+
update(tooltip, tr) {
|
|
951
|
+
if (tooltip && tr.docChanged) {
|
|
952
|
+
tooltip = hideTooltip(tr, tooltip) ? null : { ...tooltip, pos: tr.changes.mapPos(tooltip.pos) };
|
|
953
|
+
}
|
|
954
|
+
return tr.effects.reduce(
|
|
955
|
+
(t, e) => e.is(setLintGutterTooltip) ? e.value : t,
|
|
956
|
+
tooltip
|
|
957
|
+
);
|
|
958
|
+
},
|
|
959
|
+
provide: (field) => import_view2.showTooltip.from(field)
|
|
960
|
+
});
|
|
961
|
+
var lintGutterTheme = import_view2.EditorView.baseTheme({
|
|
962
|
+
".cm-gutter-lint": {
|
|
963
|
+
width: "1.4em",
|
|
964
|
+
"& .cm-gutterElement": {
|
|
965
|
+
padding: ".2em"
|
|
966
|
+
}
|
|
967
|
+
},
|
|
968
|
+
".cm-lint-marker": {
|
|
969
|
+
width: "1em",
|
|
970
|
+
height: "1em"
|
|
971
|
+
},
|
|
972
|
+
".cm-lint-marker-info": {
|
|
973
|
+
content: svg(
|
|
974
|
+
'<path fill="#aaf" stroke="#77e" stroke-width="6" stroke-linejoin="round" d="M5 5L35 5L35 35L5 35Z"/>'
|
|
975
|
+
)
|
|
976
|
+
},
|
|
977
|
+
".cm-lint-marker-warning": {
|
|
978
|
+
content: svg(
|
|
979
|
+
'<path fill="#fe8" stroke="#fd7" stroke-width="6" stroke-linejoin="round" d="M20 6L37 35L3 35Z"/>'
|
|
980
|
+
)
|
|
981
|
+
},
|
|
982
|
+
".cm-lint-marker-error": {
|
|
983
|
+
content: svg(
|
|
984
|
+
'<circle cx="20" cy="20" r="15" fill="#f87" stroke="#f43" stroke-width="6"/>'
|
|
985
|
+
)
|
|
986
|
+
}
|
|
987
|
+
});
|
|
988
|
+
var lintExtensions = [
|
|
989
|
+
lintState,
|
|
990
|
+
import_view2.EditorView.decorations.compute([lintState], (state) => {
|
|
991
|
+
const { selected, panel } = state.field(lintState);
|
|
992
|
+
return !selected || !panel || selected.from == selected.to ? import_view2.Decoration.none : import_view2.Decoration.set([activeMark.range(selected.from, selected.to)]);
|
|
993
|
+
}),
|
|
994
|
+
(0, import_view2.hoverTooltip)(lintTooltip, { hideOn: hideTooltip }),
|
|
995
|
+
baseTheme
|
|
996
|
+
];
|
|
997
|
+
var lintGutterConfig = import_state.Facet.define({
|
|
998
|
+
combine(configs) {
|
|
999
|
+
return (0, import_state.combineConfig)(configs, {
|
|
1000
|
+
hoverTime: 300 /* Time */,
|
|
1001
|
+
markerFilter: null,
|
|
1002
|
+
tooltipFilter: null
|
|
1003
|
+
});
|
|
1004
|
+
}
|
|
1005
|
+
});
|
|
1006
|
+
function lintGutter(config = {}) {
|
|
1007
|
+
return [
|
|
1008
|
+
lintGutterConfig.of(config),
|
|
1009
|
+
lintGutterMarkers,
|
|
1010
|
+
lintGutterExtension,
|
|
1011
|
+
lintGutterTheme,
|
|
1012
|
+
lintGutterTooltip
|
|
1013
|
+
];
|
|
1014
|
+
}
|
|
1015
|
+
function forEachDiagnostic(state, f) {
|
|
1016
|
+
const lState = state.field(lintState, false);
|
|
1017
|
+
if (lState && lState.diagnostics.size) {
|
|
1018
|
+
for (let iter = import_state.RangeSet.iter([lState.diagnostics]); iter.value; iter.next()) {
|
|
1019
|
+
f(iter.value.spec.diagnostic, iter.from, iter.to);
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1024
|
+
0 && (module.exports = {
|
|
1025
|
+
closeLintPanel,
|
|
1026
|
+
diagnosticCount,
|
|
1027
|
+
forEachDiagnostic,
|
|
1028
|
+
forceLinting,
|
|
1029
|
+
lintGutter,
|
|
1030
|
+
lintKeymap,
|
|
1031
|
+
linter,
|
|
1032
|
+
nextDiagnostic,
|
|
1033
|
+
openLintPanel,
|
|
1034
|
+
previousDiagnostic,
|
|
1035
|
+
setDiagnostics,
|
|
1036
|
+
setDiagnosticsEffect
|
|
1037
|
+
});
|
|
1038
|
+
//# sourceMappingURL=index.js.map
|