@codemirror/lint 6.8.3 → 6.8.4
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/CHANGELOG.md +8 -0
- package/dist/index.cjs +139 -62
- package/dist/index.js +137 -60
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -17,34 +17,76 @@ class LintState {
|
|
|
17
17
|
this.panel = panel;
|
|
18
18
|
this.selected = selected;
|
|
19
19
|
}
|
|
20
|
-
static init(diagnostics, panel, state) {
|
|
20
|
+
static init(diagnostics, panel, state$1) {
|
|
21
21
|
// Filter the list of diagnostics for which to create markers
|
|
22
22
|
let markedDiagnostics = diagnostics;
|
|
23
|
-
let diagnosticFilter = state.facet(lintConfig).markerFilter;
|
|
23
|
+
let diagnosticFilter = state$1.facet(lintConfig).markerFilter;
|
|
24
24
|
if (diagnosticFilter)
|
|
25
|
-
markedDiagnostics = diagnosticFilter(markedDiagnostics, state);
|
|
26
|
-
let
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
25
|
+
markedDiagnostics = diagnosticFilter(markedDiagnostics, state$1);
|
|
26
|
+
let sorted = diagnostics.slice().sort((a, b) => a.from - b.from || a.to - b.to);
|
|
27
|
+
let deco = new state.RangeSetBuilder(), active = [], pos = 0;
|
|
28
|
+
for (let i = 0;;) {
|
|
29
|
+
let next = i == sorted.length ? null : sorted[i];
|
|
30
|
+
if (!next && !active.length)
|
|
31
|
+
break;
|
|
32
|
+
let from, to;
|
|
33
|
+
if (active.length) {
|
|
34
|
+
from = pos;
|
|
35
|
+
to = active.reduce((p, d) => Math.min(p, d.to), next && next.from > from ? next.from : 1e8);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
from = next.from;
|
|
39
|
+
to = next.to;
|
|
40
|
+
active.push(next);
|
|
41
|
+
i++;
|
|
42
|
+
}
|
|
43
|
+
while (i < sorted.length) {
|
|
44
|
+
let next = sorted[i];
|
|
45
|
+
if (next.from == from && (next.to > next.from || next.to == from)) {
|
|
46
|
+
active.push(next);
|
|
47
|
+
i++;
|
|
48
|
+
to = Math.min(next.to, to);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
to = Math.min(next.from, to);
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
let sev = maxSeverity(active);
|
|
56
|
+
if (active.some(d => d.from == d.to || (d.from == d.to - 1 && state$1.doc.lineAt(d.from).to == d.from))) {
|
|
57
|
+
deco.add(from, from, view.Decoration.widget({
|
|
58
|
+
widget: new DiagnosticWidget(sev),
|
|
59
|
+
diagnostics: active.slice()
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
let markClass = active.reduce((c, d) => d.markClass ? c + " " + d.markClass : c, "");
|
|
64
|
+
deco.add(from, to, view.Decoration.mark({
|
|
65
|
+
class: "cm-lintRange cm-lintRange-" + sev + markClass,
|
|
66
|
+
diagnostics: active.slice(),
|
|
67
|
+
inclusiveEnd: active.some(a => a.to > to)
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
pos = to;
|
|
71
|
+
for (let i = 0; i < active.length; i++)
|
|
72
|
+
if (active[i].to <= pos)
|
|
73
|
+
active.splice(i--, 1);
|
|
74
|
+
}
|
|
75
|
+
let set = deco.finish();
|
|
76
|
+
return new LintState(set, panel, findDiagnostic(set));
|
|
39
77
|
}
|
|
40
78
|
}
|
|
41
79
|
function findDiagnostic(diagnostics, diagnostic = null, after = 0) {
|
|
42
80
|
let found = null;
|
|
43
81
|
diagnostics.between(after, 1e9, (from, to, { spec }) => {
|
|
44
|
-
if (diagnostic && spec.diagnostic
|
|
82
|
+
if (diagnostic && spec.diagnostics.indexOf(diagnostic) < 0)
|
|
45
83
|
return;
|
|
46
|
-
|
|
47
|
-
|
|
84
|
+
if (!found)
|
|
85
|
+
found = new SelectedDiagnostic(from, to, diagnostic || spec.diagnostics[0]);
|
|
86
|
+
else if (spec.diagnostics.indexOf(found.diagnostic) < 0)
|
|
87
|
+
return false;
|
|
88
|
+
else
|
|
89
|
+
found = new SelectedDiagnostic(found.from, to, found.diagnostic);
|
|
48
90
|
});
|
|
49
91
|
return found;
|
|
50
92
|
}
|
|
@@ -118,24 +160,25 @@ function diagnosticCount(state) {
|
|
|
118
160
|
const activeMark = view.Decoration.mark({ class: "cm-lintRange cm-lintRange-active" });
|
|
119
161
|
function lintTooltip(view, pos, side) {
|
|
120
162
|
let { diagnostics } = view.state.field(lintState);
|
|
121
|
-
let found
|
|
163
|
+
let found, start = -1, end = -1;
|
|
122
164
|
diagnostics.between(pos - (side < 0 ? 1 : 0), pos + (side > 0 ? 1 : 0), (from, to, { spec }) => {
|
|
123
165
|
if (pos >= from && pos <= to &&
|
|
124
166
|
(from == to || ((pos > from || side > 0) && (pos < to || side < 0)))) {
|
|
125
|
-
found
|
|
126
|
-
|
|
127
|
-
|
|
167
|
+
found = spec.diagnostics;
|
|
168
|
+
start = from;
|
|
169
|
+
end = to;
|
|
170
|
+
return false;
|
|
128
171
|
}
|
|
129
172
|
});
|
|
130
173
|
let diagnosticFilter = view.state.facet(lintConfig).tooltipFilter;
|
|
131
|
-
if (diagnosticFilter)
|
|
174
|
+
if (found && diagnosticFilter)
|
|
132
175
|
found = diagnosticFilter(found, view.state);
|
|
133
|
-
if (!found
|
|
176
|
+
if (!found)
|
|
134
177
|
return null;
|
|
135
178
|
return {
|
|
136
|
-
pos:
|
|
137
|
-
end:
|
|
138
|
-
above: view.state.doc.lineAt(
|
|
179
|
+
pos: start,
|
|
180
|
+
end: end,
|
|
181
|
+
above: view.state.doc.lineAt(start).to < end,
|
|
139
182
|
create() {
|
|
140
183
|
return { dom: diagnosticsTooltip(view, found) };
|
|
141
184
|
}
|
|
@@ -272,7 +315,7 @@ function batchResults(promises, sink, error) {
|
|
|
272
315
|
if (collected.length == promises.length)
|
|
273
316
|
sink(collected);
|
|
274
317
|
else
|
|
275
|
-
setTimeout(() => sink(collected), 200);
|
|
318
|
+
timeout = setTimeout(() => sink(collected), 200);
|
|
276
319
|
}, error);
|
|
277
320
|
}
|
|
278
321
|
const lintConfig = state.Facet.define({
|
|
@@ -352,13 +395,13 @@ function renderDiagnostic(view, diagnostic, inPanel) {
|
|
|
352
395
|
}), diagnostic.source && elt("div", { class: "cm-diagnosticSource" }, diagnostic.source));
|
|
353
396
|
}
|
|
354
397
|
class DiagnosticWidget extends view.WidgetType {
|
|
355
|
-
constructor(
|
|
398
|
+
constructor(sev) {
|
|
356
399
|
super();
|
|
357
|
-
this.
|
|
400
|
+
this.sev = sev;
|
|
358
401
|
}
|
|
359
|
-
eq(other) { return other.
|
|
402
|
+
eq(other) { return other.sev == this.sev; }
|
|
360
403
|
toDOM() {
|
|
361
|
-
return elt("span", { class: "cm-lintPoint cm-lintPoint-" + this.
|
|
404
|
+
return elt("span", { class: "cm-lintPoint cm-lintPoint-" + this.sev });
|
|
362
405
|
}
|
|
363
406
|
}
|
|
364
407
|
class PanelItem {
|
|
@@ -441,35 +484,41 @@ class LintPanel {
|
|
|
441
484
|
update() {
|
|
442
485
|
let { diagnostics, selected } = this.view.state.field(lintState);
|
|
443
486
|
let i = 0, needsSync = false, newSelectedItem = null;
|
|
487
|
+
let seen = new Set();
|
|
444
488
|
diagnostics.between(0, this.view.state.doc.length, (_start, _end, { spec }) => {
|
|
445
|
-
let
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
if (found > i) {
|
|
459
|
-
this.items.splice(i, found - i);
|
|
489
|
+
for (let diagnostic of spec.diagnostics) {
|
|
490
|
+
if (seen.has(diagnostic))
|
|
491
|
+
continue;
|
|
492
|
+
seen.add(diagnostic);
|
|
493
|
+
let found = -1, item;
|
|
494
|
+
for (let j = i; j < this.items.length; j++)
|
|
495
|
+
if (this.items[j].diagnostic == diagnostic) {
|
|
496
|
+
found = j;
|
|
497
|
+
break;
|
|
498
|
+
}
|
|
499
|
+
if (found < 0) {
|
|
500
|
+
item = new PanelItem(this.view, diagnostic);
|
|
501
|
+
this.items.splice(i, 0, item);
|
|
460
502
|
needsSync = true;
|
|
461
503
|
}
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
504
|
+
else {
|
|
505
|
+
item = this.items[found];
|
|
506
|
+
if (found > i) {
|
|
507
|
+
this.items.splice(i, found - i);
|
|
508
|
+
needsSync = true;
|
|
509
|
+
}
|
|
467
510
|
}
|
|
511
|
+
if (selected && item.diagnostic == selected.diagnostic) {
|
|
512
|
+
if (!item.dom.hasAttribute("aria-selected")) {
|
|
513
|
+
item.dom.setAttribute("aria-selected", "true");
|
|
514
|
+
newSelectedItem = item;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
else if (item.dom.hasAttribute("aria-selected")) {
|
|
518
|
+
item.dom.removeAttribute("aria-selected");
|
|
519
|
+
}
|
|
520
|
+
i++;
|
|
468
521
|
}
|
|
469
|
-
else if (item.dom.hasAttribute("aria-selected")) {
|
|
470
|
-
item.dom.removeAttribute("aria-selected");
|
|
471
|
-
}
|
|
472
|
-
i++;
|
|
473
522
|
});
|
|
474
523
|
while (i < this.items.length && !(this.items.length == 1 && this.items[0].diagnostic.from < 0)) {
|
|
475
524
|
needsSync = true;
|
|
@@ -638,11 +687,22 @@ const baseTheme = view.EditorView.baseTheme({
|
|
|
638
687
|
function severityWeight(sev) {
|
|
639
688
|
return sev == "error" ? 4 : sev == "warning" ? 3 : sev == "info" ? 2 : 1;
|
|
640
689
|
}
|
|
690
|
+
function maxSeverity(diagnostics) {
|
|
691
|
+
let sev = "hint", weight = 1;
|
|
692
|
+
for (let d of diagnostics) {
|
|
693
|
+
let w = severityWeight(d.severity);
|
|
694
|
+
if (w > weight) {
|
|
695
|
+
weight = w;
|
|
696
|
+
sev = d.severity;
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
return sev;
|
|
700
|
+
}
|
|
641
701
|
class LintGutterMarker extends view.GutterMarker {
|
|
642
702
|
constructor(diagnostics) {
|
|
643
703
|
super();
|
|
644
704
|
this.diagnostics = diagnostics;
|
|
645
|
-
this.severity = diagnostics
|
|
705
|
+
this.severity = maxSeverity(diagnostics);
|
|
646
706
|
}
|
|
647
707
|
toDOM(view) {
|
|
648
708
|
let elt = document.createElement("div");
|
|
@@ -721,7 +781,8 @@ const lintGutterExtension = view.gutter({
|
|
|
721
781
|
widgetMarker: (view, widget, block) => {
|
|
722
782
|
let diagnostics = [];
|
|
723
783
|
view.state.field(lintGutterMarkers).between(block.from, block.to, (from, to, value) => {
|
|
724
|
-
|
|
784
|
+
if (from > block.from && from < block.to)
|
|
785
|
+
diagnostics.push(...value.diagnostics);
|
|
725
786
|
});
|
|
726
787
|
return diagnostics.length ? new LintGutterMarker(diagnostics) : null;
|
|
727
788
|
}
|
|
@@ -812,9 +873,25 @@ arguments hold the diagnostic's current position.
|
|
|
812
873
|
*/
|
|
813
874
|
function forEachDiagnostic(state$1, f) {
|
|
814
875
|
let lState = state$1.field(lintState, false);
|
|
815
|
-
if (lState && lState.diagnostics.size)
|
|
816
|
-
|
|
817
|
-
|
|
876
|
+
if (lState && lState.diagnostics.size) {
|
|
877
|
+
let pending = [], pendingStart = [], lastEnd = -1;
|
|
878
|
+
for (let iter = state.RangeSet.iter([lState.diagnostics]);; iter.next()) {
|
|
879
|
+
for (let i = 0; i < pending.length; i++)
|
|
880
|
+
if (!iter.value || iter.value.spec.diagnostics.indexOf(pending[i]) < 0) {
|
|
881
|
+
f(pending[i], pendingStart[i], lastEnd);
|
|
882
|
+
pending.splice(i, 1);
|
|
883
|
+
pendingStart.splice(i--, 1);
|
|
884
|
+
}
|
|
885
|
+
if (!iter.value)
|
|
886
|
+
break;
|
|
887
|
+
for (let d of iter.value.spec.diagnostics)
|
|
888
|
+
if (pending.indexOf(d) < 0) {
|
|
889
|
+
pending.push(d);
|
|
890
|
+
pendingStart.push(iter.from);
|
|
891
|
+
}
|
|
892
|
+
lastEnd = iter.to;
|
|
893
|
+
}
|
|
894
|
+
}
|
|
818
895
|
}
|
|
819
896
|
|
|
820
897
|
exports.closeLintPanel = closeLintPanel;
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Decoration, showPanel, EditorView, ViewPlugin, gutter, showTooltip, hoverTooltip, getPanel, logException, WidgetType, GutterMarker } from '@codemirror/view';
|
|
2
|
-
import { StateEffect, StateField, Facet, combineConfig, RangeSet } from '@codemirror/state';
|
|
2
|
+
import { StateEffect, StateField, Facet, combineConfig, RangeSet, RangeSetBuilder } from '@codemirror/state';
|
|
3
3
|
import elt from 'crelt';
|
|
4
4
|
|
|
5
5
|
class SelectedDiagnostic {
|
|
@@ -21,28 +21,70 @@ class LintState {
|
|
|
21
21
|
let diagnosticFilter = state.facet(lintConfig).markerFilter;
|
|
22
22
|
if (diagnosticFilter)
|
|
23
23
|
markedDiagnostics = diagnosticFilter(markedDiagnostics, state);
|
|
24
|
-
let
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
24
|
+
let sorted = diagnostics.slice().sort((a, b) => a.from - b.from || a.to - b.to);
|
|
25
|
+
let deco = new RangeSetBuilder(), active = [], pos = 0;
|
|
26
|
+
for (let i = 0;;) {
|
|
27
|
+
let next = i == sorted.length ? null : sorted[i];
|
|
28
|
+
if (!next && !active.length)
|
|
29
|
+
break;
|
|
30
|
+
let from, to;
|
|
31
|
+
if (active.length) {
|
|
32
|
+
from = pos;
|
|
33
|
+
to = active.reduce((p, d) => Math.min(p, d.to), next && next.from > from ? next.from : 1e8);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
from = next.from;
|
|
37
|
+
to = next.to;
|
|
38
|
+
active.push(next);
|
|
39
|
+
i++;
|
|
40
|
+
}
|
|
41
|
+
while (i < sorted.length) {
|
|
42
|
+
let next = sorted[i];
|
|
43
|
+
if (next.from == from && (next.to > next.from || next.to == from)) {
|
|
44
|
+
active.push(next);
|
|
45
|
+
i++;
|
|
46
|
+
to = Math.min(next.to, to);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
to = Math.min(next.from, to);
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
let sev = maxSeverity(active);
|
|
54
|
+
if (active.some(d => d.from == d.to || (d.from == d.to - 1 && state.doc.lineAt(d.from).to == d.from))) {
|
|
55
|
+
deco.add(from, from, Decoration.widget({
|
|
56
|
+
widget: new DiagnosticWidget(sev),
|
|
57
|
+
diagnostics: active.slice()
|
|
58
|
+
}));
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
let markClass = active.reduce((c, d) => d.markClass ? c + " " + d.markClass : c, "");
|
|
62
|
+
deco.add(from, to, Decoration.mark({
|
|
63
|
+
class: "cm-lintRange cm-lintRange-" + sev + markClass,
|
|
64
|
+
diagnostics: active.slice(),
|
|
65
|
+
inclusiveEnd: active.some(a => a.to > to)
|
|
66
|
+
}));
|
|
67
|
+
}
|
|
68
|
+
pos = to;
|
|
69
|
+
for (let i = 0; i < active.length; i++)
|
|
70
|
+
if (active[i].to <= pos)
|
|
71
|
+
active.splice(i--, 1);
|
|
72
|
+
}
|
|
73
|
+
let set = deco.finish();
|
|
74
|
+
return new LintState(set, panel, findDiagnostic(set));
|
|
37
75
|
}
|
|
38
76
|
}
|
|
39
77
|
function findDiagnostic(diagnostics, diagnostic = null, after = 0) {
|
|
40
78
|
let found = null;
|
|
41
79
|
diagnostics.between(after, 1e9, (from, to, { spec }) => {
|
|
42
|
-
if (diagnostic && spec.diagnostic
|
|
80
|
+
if (diagnostic && spec.diagnostics.indexOf(diagnostic) < 0)
|
|
43
81
|
return;
|
|
44
|
-
|
|
45
|
-
|
|
82
|
+
if (!found)
|
|
83
|
+
found = new SelectedDiagnostic(from, to, diagnostic || spec.diagnostics[0]);
|
|
84
|
+
else if (spec.diagnostics.indexOf(found.diagnostic) < 0)
|
|
85
|
+
return false;
|
|
86
|
+
else
|
|
87
|
+
found = new SelectedDiagnostic(found.from, to, found.diagnostic);
|
|
46
88
|
});
|
|
47
89
|
return found;
|
|
48
90
|
}
|
|
@@ -116,24 +158,25 @@ function diagnosticCount(state) {
|
|
|
116
158
|
const activeMark = /*@__PURE__*/Decoration.mark({ class: "cm-lintRange cm-lintRange-active" });
|
|
117
159
|
function lintTooltip(view, pos, side) {
|
|
118
160
|
let { diagnostics } = view.state.field(lintState);
|
|
119
|
-
let found
|
|
161
|
+
let found, start = -1, end = -1;
|
|
120
162
|
diagnostics.between(pos - (side < 0 ? 1 : 0), pos + (side > 0 ? 1 : 0), (from, to, { spec }) => {
|
|
121
163
|
if (pos >= from && pos <= to &&
|
|
122
164
|
(from == to || ((pos > from || side > 0) && (pos < to || side < 0)))) {
|
|
123
|
-
found
|
|
124
|
-
|
|
125
|
-
|
|
165
|
+
found = spec.diagnostics;
|
|
166
|
+
start = from;
|
|
167
|
+
end = to;
|
|
168
|
+
return false;
|
|
126
169
|
}
|
|
127
170
|
});
|
|
128
171
|
let diagnosticFilter = view.state.facet(lintConfig).tooltipFilter;
|
|
129
|
-
if (diagnosticFilter)
|
|
172
|
+
if (found && diagnosticFilter)
|
|
130
173
|
found = diagnosticFilter(found, view.state);
|
|
131
|
-
if (!found
|
|
174
|
+
if (!found)
|
|
132
175
|
return null;
|
|
133
176
|
return {
|
|
134
|
-
pos:
|
|
135
|
-
end:
|
|
136
|
-
above: view.state.doc.lineAt(
|
|
177
|
+
pos: start,
|
|
178
|
+
end: end,
|
|
179
|
+
above: view.state.doc.lineAt(start).to < end,
|
|
137
180
|
create() {
|
|
138
181
|
return { dom: diagnosticsTooltip(view, found) };
|
|
139
182
|
}
|
|
@@ -270,7 +313,7 @@ function batchResults(promises, sink, error) {
|
|
|
270
313
|
if (collected.length == promises.length)
|
|
271
314
|
sink(collected);
|
|
272
315
|
else
|
|
273
|
-
setTimeout(() => sink(collected), 200);
|
|
316
|
+
timeout = setTimeout(() => sink(collected), 200);
|
|
274
317
|
}, error);
|
|
275
318
|
}
|
|
276
319
|
const lintConfig = /*@__PURE__*/Facet.define({
|
|
@@ -350,13 +393,13 @@ function renderDiagnostic(view, diagnostic, inPanel) {
|
|
|
350
393
|
}), diagnostic.source && elt("div", { class: "cm-diagnosticSource" }, diagnostic.source));
|
|
351
394
|
}
|
|
352
395
|
class DiagnosticWidget extends WidgetType {
|
|
353
|
-
constructor(
|
|
396
|
+
constructor(sev) {
|
|
354
397
|
super();
|
|
355
|
-
this.
|
|
398
|
+
this.sev = sev;
|
|
356
399
|
}
|
|
357
|
-
eq(other) { return other.
|
|
400
|
+
eq(other) { return other.sev == this.sev; }
|
|
358
401
|
toDOM() {
|
|
359
|
-
return elt("span", { class: "cm-lintPoint cm-lintPoint-" + this.
|
|
402
|
+
return elt("span", { class: "cm-lintPoint cm-lintPoint-" + this.sev });
|
|
360
403
|
}
|
|
361
404
|
}
|
|
362
405
|
class PanelItem {
|
|
@@ -439,35 +482,41 @@ class LintPanel {
|
|
|
439
482
|
update() {
|
|
440
483
|
let { diagnostics, selected } = this.view.state.field(lintState);
|
|
441
484
|
let i = 0, needsSync = false, newSelectedItem = null;
|
|
485
|
+
let seen = new Set();
|
|
442
486
|
diagnostics.between(0, this.view.state.doc.length, (_start, _end, { spec }) => {
|
|
443
|
-
let
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
if (found > i) {
|
|
457
|
-
this.items.splice(i, found - i);
|
|
487
|
+
for (let diagnostic of spec.diagnostics) {
|
|
488
|
+
if (seen.has(diagnostic))
|
|
489
|
+
continue;
|
|
490
|
+
seen.add(diagnostic);
|
|
491
|
+
let found = -1, item;
|
|
492
|
+
for (let j = i; j < this.items.length; j++)
|
|
493
|
+
if (this.items[j].diagnostic == diagnostic) {
|
|
494
|
+
found = j;
|
|
495
|
+
break;
|
|
496
|
+
}
|
|
497
|
+
if (found < 0) {
|
|
498
|
+
item = new PanelItem(this.view, diagnostic);
|
|
499
|
+
this.items.splice(i, 0, item);
|
|
458
500
|
needsSync = true;
|
|
459
501
|
}
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
502
|
+
else {
|
|
503
|
+
item = this.items[found];
|
|
504
|
+
if (found > i) {
|
|
505
|
+
this.items.splice(i, found - i);
|
|
506
|
+
needsSync = true;
|
|
507
|
+
}
|
|
465
508
|
}
|
|
509
|
+
if (selected && item.diagnostic == selected.diagnostic) {
|
|
510
|
+
if (!item.dom.hasAttribute("aria-selected")) {
|
|
511
|
+
item.dom.setAttribute("aria-selected", "true");
|
|
512
|
+
newSelectedItem = item;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
else if (item.dom.hasAttribute("aria-selected")) {
|
|
516
|
+
item.dom.removeAttribute("aria-selected");
|
|
517
|
+
}
|
|
518
|
+
i++;
|
|
466
519
|
}
|
|
467
|
-
else if (item.dom.hasAttribute("aria-selected")) {
|
|
468
|
-
item.dom.removeAttribute("aria-selected");
|
|
469
|
-
}
|
|
470
|
-
i++;
|
|
471
520
|
});
|
|
472
521
|
while (i < this.items.length && !(this.items.length == 1 && this.items[0].diagnostic.from < 0)) {
|
|
473
522
|
needsSync = true;
|
|
@@ -636,11 +685,22 @@ const baseTheme = /*@__PURE__*/EditorView.baseTheme({
|
|
|
636
685
|
function severityWeight(sev) {
|
|
637
686
|
return sev == "error" ? 4 : sev == "warning" ? 3 : sev == "info" ? 2 : 1;
|
|
638
687
|
}
|
|
688
|
+
function maxSeverity(diagnostics) {
|
|
689
|
+
let sev = "hint", weight = 1;
|
|
690
|
+
for (let d of diagnostics) {
|
|
691
|
+
let w = severityWeight(d.severity);
|
|
692
|
+
if (w > weight) {
|
|
693
|
+
weight = w;
|
|
694
|
+
sev = d.severity;
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
return sev;
|
|
698
|
+
}
|
|
639
699
|
class LintGutterMarker extends GutterMarker {
|
|
640
700
|
constructor(diagnostics) {
|
|
641
701
|
super();
|
|
642
702
|
this.diagnostics = diagnostics;
|
|
643
|
-
this.severity = diagnostics
|
|
703
|
+
this.severity = maxSeverity(diagnostics);
|
|
644
704
|
}
|
|
645
705
|
toDOM(view) {
|
|
646
706
|
let elt = document.createElement("div");
|
|
@@ -719,7 +779,8 @@ const lintGutterExtension = /*@__PURE__*/gutter({
|
|
|
719
779
|
widgetMarker: (view, widget, block) => {
|
|
720
780
|
let diagnostics = [];
|
|
721
781
|
view.state.field(lintGutterMarkers).between(block.from, block.to, (from, to, value) => {
|
|
722
|
-
|
|
782
|
+
if (from > block.from && from < block.to)
|
|
783
|
+
diagnostics.push(...value.diagnostics);
|
|
723
784
|
});
|
|
724
785
|
return diagnostics.length ? new LintGutterMarker(diagnostics) : null;
|
|
725
786
|
}
|
|
@@ -810,9 +871,25 @@ arguments hold the diagnostic's current position.
|
|
|
810
871
|
*/
|
|
811
872
|
function forEachDiagnostic(state, f) {
|
|
812
873
|
let lState = state.field(lintState, false);
|
|
813
|
-
if (lState && lState.diagnostics.size)
|
|
814
|
-
|
|
815
|
-
|
|
874
|
+
if (lState && lState.diagnostics.size) {
|
|
875
|
+
let pending = [], pendingStart = [], lastEnd = -1;
|
|
876
|
+
for (let iter = RangeSet.iter([lState.diagnostics]);; iter.next()) {
|
|
877
|
+
for (let i = 0; i < pending.length; i++)
|
|
878
|
+
if (!iter.value || iter.value.spec.diagnostics.indexOf(pending[i]) < 0) {
|
|
879
|
+
f(pending[i], pendingStart[i], lastEnd);
|
|
880
|
+
pending.splice(i, 1);
|
|
881
|
+
pendingStart.splice(i--, 1);
|
|
882
|
+
}
|
|
883
|
+
if (!iter.value)
|
|
884
|
+
break;
|
|
885
|
+
for (let d of iter.value.spec.diagnostics)
|
|
886
|
+
if (pending.indexOf(d) < 0) {
|
|
887
|
+
pending.push(d);
|
|
888
|
+
pendingStart.push(iter.from);
|
|
889
|
+
}
|
|
890
|
+
lastEnd = iter.to;
|
|
891
|
+
}
|
|
892
|
+
}
|
|
816
893
|
}
|
|
817
894
|
|
|
818
895
|
export { closeLintPanel, diagnosticCount, forEachDiagnostic, forceLinting, lintGutter, lintKeymap, linter, nextDiagnostic, openLintPanel, previousDiagnostic, setDiagnostics, setDiagnosticsEffect };
|