@codemirror/lint 6.4.1 → 6.5.0
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 +18 -0
- package/dist/index.cjs +19 -15
- package/dist/index.d.cts +5 -4
- package/dist/index.d.ts +5 -4
- package/dist/index.js +19 -15
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
## 6.5.0 (2024-01-30)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Make lint mark decorations inclusive, so that they are applied even if the marked content is replaced by a widget decoration.
|
|
6
|
+
|
|
7
|
+
### New features
|
|
8
|
+
|
|
9
|
+
`linter` can now be called with null as source to only provide a configuration.
|
|
10
|
+
|
|
11
|
+
`markerFilter` and `tooltipFilter` function now get passed the current editor state.
|
|
12
|
+
|
|
13
|
+
## 6.4.2 (2023-09-14)
|
|
14
|
+
|
|
15
|
+
### Bug fixes
|
|
16
|
+
|
|
17
|
+
Make sure scrolling diagnostic into view in the panel works when the editor is scaled.
|
|
18
|
+
|
|
1
19
|
## 6.4.1 (2023-08-26)
|
|
2
20
|
|
|
3
21
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -22,7 +22,7 @@ class LintState {
|
|
|
22
22
|
let markedDiagnostics = diagnostics;
|
|
23
23
|
let diagnosticFilter = state.facet(lintConfig).markerFilter;
|
|
24
24
|
if (diagnosticFilter)
|
|
25
|
-
markedDiagnostics = diagnosticFilter(markedDiagnostics);
|
|
25
|
+
markedDiagnostics = diagnosticFilter(markedDiagnostics, state);
|
|
26
26
|
let ranges = view.Decoration.set(markedDiagnostics.map((d) => {
|
|
27
27
|
// For zero-length ranges or ranges covering only a line break, create a widget
|
|
28
28
|
return d.from == d.to || (d.from == d.to - 1 && state.doc.lineAt(d.from).to == d.from)
|
|
@@ -32,7 +32,8 @@ class LintState {
|
|
|
32
32
|
}).range(d.from)
|
|
33
33
|
: view.Decoration.mark({
|
|
34
34
|
attributes: { class: "cm-lintRange cm-lintRange-" + d.severity + (d.markClass ? " " + d.markClass : "") },
|
|
35
|
-
diagnostic: d
|
|
35
|
+
diagnostic: d,
|
|
36
|
+
inclusive: true
|
|
36
37
|
}).range(d.from, d.to);
|
|
37
38
|
}), true);
|
|
38
39
|
return new LintState(ranges, panel, findDiagnostic(ranges));
|
|
@@ -108,7 +109,7 @@ function diagnosticCount(state) {
|
|
|
108
109
|
let lint = state.field(lintState, false);
|
|
109
110
|
return lint ? lint.diagnostics.size : 0;
|
|
110
111
|
}
|
|
111
|
-
const activeMark = view.Decoration.mark({ class: "cm-lintRange cm-lintRange-active" });
|
|
112
|
+
const activeMark = view.Decoration.mark({ class: "cm-lintRange cm-lintRange-active", inclusive: true });
|
|
112
113
|
function lintTooltip(view, pos, side) {
|
|
113
114
|
let { diagnostics } = view.state.field(lintState);
|
|
114
115
|
let found = [], stackStart = 2e8, stackEnd = 0;
|
|
@@ -122,7 +123,7 @@ function lintTooltip(view, pos, side) {
|
|
|
122
123
|
});
|
|
123
124
|
let diagnosticFilter = view.state.facet(lintConfig).tooltipFilter;
|
|
124
125
|
if (diagnosticFilter)
|
|
125
|
-
found = diagnosticFilter(found);
|
|
126
|
+
found = diagnosticFilter(found, view.state);
|
|
126
127
|
if (!found.length)
|
|
127
128
|
return null;
|
|
128
129
|
return {
|
|
@@ -227,11 +228,12 @@ const lintPlugin = view.ViewPlugin.fromClass(class {
|
|
|
227
228
|
else {
|
|
228
229
|
this.set = false;
|
|
229
230
|
let { state } = this.view, { sources } = state.facet(lintConfig);
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
231
|
+
if (sources.length)
|
|
232
|
+
Promise.all(sources.map(source => Promise.resolve(source(this.view)))).then(annotations => {
|
|
233
|
+
let all = annotations.reduce((a, b) => a.concat(b));
|
|
234
|
+
if (this.view.state.doc == state.doc)
|
|
235
|
+
this.view.dispatch(setDiagnostics(this.view.state, all));
|
|
236
|
+
}, error => { view.logException(this.view.state, error); });
|
|
235
237
|
}
|
|
236
238
|
}
|
|
237
239
|
update(update) {
|
|
@@ -257,7 +259,7 @@ const lintPlugin = view.ViewPlugin.fromClass(class {
|
|
|
257
259
|
});
|
|
258
260
|
const lintConfig = state.Facet.define({
|
|
259
261
|
combine(input) {
|
|
260
|
-
return Object.assign({ sources: input.map(i => i.source) }, state.combineConfig(input.map(i => i.config), {
|
|
262
|
+
return Object.assign({ sources: input.map(i => i.source).filter(x => x != null) }, state.combineConfig(input.map(i => i.config), {
|
|
261
263
|
delay: 750,
|
|
262
264
|
markerFilter: null,
|
|
263
265
|
tooltipFilter: null,
|
|
@@ -270,7 +272,8 @@ const lintConfig = state.Facet.define({
|
|
|
270
272
|
/**
|
|
271
273
|
Given a diagnostic source, this function returns an extension that
|
|
272
274
|
enables linting with that source. It will be called whenever the
|
|
273
|
-
editor is idle (after its content changed).
|
|
275
|
+
editor is idle (after its content changed). If `null` is given as
|
|
276
|
+
source, this only configures the lint extension.
|
|
274
277
|
*/
|
|
275
278
|
function linter(source, config = {}) {
|
|
276
279
|
return [
|
|
@@ -467,10 +470,11 @@ class LintPanel {
|
|
|
467
470
|
key: this,
|
|
468
471
|
read: () => ({ sel: newSelectedItem.dom.getBoundingClientRect(), panel: this.list.getBoundingClientRect() }),
|
|
469
472
|
write: ({ sel, panel }) => {
|
|
473
|
+
let scaleY = panel.height / this.list.offsetHeight;
|
|
470
474
|
if (sel.top < panel.top)
|
|
471
|
-
this.list.scrollTop -= panel.top - sel.top;
|
|
475
|
+
this.list.scrollTop -= (panel.top - sel.top) / scaleY;
|
|
472
476
|
else if (sel.bottom > panel.bottom)
|
|
473
|
-
this.list.scrollTop += sel.bottom - panel.bottom;
|
|
477
|
+
this.list.scrollTop += (sel.bottom - panel.bottom) / scaleY;
|
|
474
478
|
}
|
|
475
479
|
});
|
|
476
480
|
}
|
|
@@ -627,7 +631,7 @@ class LintGutterMarker extends view.GutterMarker {
|
|
|
627
631
|
let diagnostics = this.diagnostics;
|
|
628
632
|
let diagnosticsFilter = view.state.facet(lintGutterConfig).tooltipFilter;
|
|
629
633
|
if (diagnosticsFilter)
|
|
630
|
-
diagnostics = diagnosticsFilter(diagnostics);
|
|
634
|
+
diagnostics = diagnosticsFilter(diagnostics, view.state);
|
|
631
635
|
if (diagnostics.length)
|
|
632
636
|
elt.onmouseover = () => gutterMarkerMouseOver(view, elt, diagnostics);
|
|
633
637
|
return elt;
|
|
@@ -706,7 +710,7 @@ const lintGutterMarkers = state.StateField.define({
|
|
|
706
710
|
if (effect.is(setDiagnosticsEffect)) {
|
|
707
711
|
let diagnostics = effect.value;
|
|
708
712
|
if (diagnosticFilter)
|
|
709
|
-
diagnostics = diagnosticFilter(diagnostics || []);
|
|
713
|
+
diagnostics = diagnosticFilter(diagnostics || [], tr.state);
|
|
710
714
|
markers = markersForDiagnostics(tr.state.doc, diagnostics.slice(0));
|
|
711
715
|
}
|
|
712
716
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -62,7 +62,7 @@ interface Action {
|
|
|
62
62
|
*/
|
|
63
63
|
apply: (view: EditorView, from: number, to: number) => void;
|
|
64
64
|
}
|
|
65
|
-
type DiagnosticFilter = (diagnostics: readonly Diagnostic[]) => Diagnostic[];
|
|
65
|
+
type DiagnosticFilter = (diagnostics: readonly Diagnostic[], state: EditorState) => Diagnostic[];
|
|
66
66
|
interface LintConfig {
|
|
67
67
|
/**
|
|
68
68
|
Time to wait (in milliseconds) after a change before running
|
|
@@ -147,9 +147,10 @@ type LintSource = (view: EditorView) => readonly Diagnostic[] | Promise<readonly
|
|
|
147
147
|
/**
|
|
148
148
|
Given a diagnostic source, this function returns an extension that
|
|
149
149
|
enables linting with that source. It will be called whenever the
|
|
150
|
-
editor is idle (after its content changed).
|
|
150
|
+
editor is idle (after its content changed). If `null` is given as
|
|
151
|
+
source, this only configures the lint extension.
|
|
151
152
|
*/
|
|
152
|
-
declare function linter(source: LintSource, config?: LintConfig): Extension;
|
|
153
|
+
declare function linter(source: LintSource | null, config?: LintConfig): Extension;
|
|
153
154
|
/**
|
|
154
155
|
Forces any linters [configured](https://codemirror.net/6/docs/ref/#lint.linter) to run when the
|
|
155
156
|
editor is idle to run right away.
|
|
@@ -170,4 +171,4 @@ arguments hold the diagnostic's current position.
|
|
|
170
171
|
*/
|
|
171
172
|
declare function forEachDiagnostic(state: EditorState, f: (d: Diagnostic, from: number, to: number) => void): void;
|
|
172
173
|
|
|
173
|
-
export { Action, Diagnostic, LintSource, closeLintPanel, diagnosticCount, forEachDiagnostic, forceLinting, lintGutter, lintKeymap, linter, nextDiagnostic, openLintPanel, previousDiagnostic, setDiagnostics, setDiagnosticsEffect };
|
|
174
|
+
export { type Action, type Diagnostic, type LintSource, closeLintPanel, diagnosticCount, forEachDiagnostic, forceLinting, lintGutter, lintKeymap, linter, nextDiagnostic, openLintPanel, previousDiagnostic, setDiagnostics, setDiagnosticsEffect };
|
package/dist/index.d.ts
CHANGED
|
@@ -62,7 +62,7 @@ interface Action {
|
|
|
62
62
|
*/
|
|
63
63
|
apply: (view: EditorView, from: number, to: number) => void;
|
|
64
64
|
}
|
|
65
|
-
type DiagnosticFilter = (diagnostics: readonly Diagnostic[]) => Diagnostic[];
|
|
65
|
+
type DiagnosticFilter = (diagnostics: readonly Diagnostic[], state: EditorState) => Diagnostic[];
|
|
66
66
|
interface LintConfig {
|
|
67
67
|
/**
|
|
68
68
|
Time to wait (in milliseconds) after a change before running
|
|
@@ -147,9 +147,10 @@ type LintSource = (view: EditorView) => readonly Diagnostic[] | Promise<readonly
|
|
|
147
147
|
/**
|
|
148
148
|
Given a diagnostic source, this function returns an extension that
|
|
149
149
|
enables linting with that source. It will be called whenever the
|
|
150
|
-
editor is idle (after its content changed).
|
|
150
|
+
editor is idle (after its content changed). If `null` is given as
|
|
151
|
+
source, this only configures the lint extension.
|
|
151
152
|
*/
|
|
152
|
-
declare function linter(source: LintSource, config?: LintConfig): Extension;
|
|
153
|
+
declare function linter(source: LintSource | null, config?: LintConfig): Extension;
|
|
153
154
|
/**
|
|
154
155
|
Forces any linters [configured](https://codemirror.net/6/docs/ref/#lint.linter) to run when the
|
|
155
156
|
editor is idle to run right away.
|
|
@@ -170,4 +171,4 @@ arguments hold the diagnostic's current position.
|
|
|
170
171
|
*/
|
|
171
172
|
declare function forEachDiagnostic(state: EditorState, f: (d: Diagnostic, from: number, to: number) => void): void;
|
|
172
173
|
|
|
173
|
-
export { Action, Diagnostic, LintSource, closeLintPanel, diagnosticCount, forEachDiagnostic, forceLinting, lintGutter, lintKeymap, linter, nextDiagnostic, openLintPanel, previousDiagnostic, setDiagnostics, setDiagnosticsEffect };
|
|
174
|
+
export { type Action, type Diagnostic, type LintSource, closeLintPanel, diagnosticCount, forEachDiagnostic, forceLinting, lintGutter, lintKeymap, linter, nextDiagnostic, openLintPanel, previousDiagnostic, setDiagnostics, setDiagnosticsEffect };
|
package/dist/index.js
CHANGED
|
@@ -20,7 +20,7 @@ class LintState {
|
|
|
20
20
|
let markedDiagnostics = diagnostics;
|
|
21
21
|
let diagnosticFilter = state.facet(lintConfig).markerFilter;
|
|
22
22
|
if (diagnosticFilter)
|
|
23
|
-
markedDiagnostics = diagnosticFilter(markedDiagnostics);
|
|
23
|
+
markedDiagnostics = diagnosticFilter(markedDiagnostics, state);
|
|
24
24
|
let ranges = Decoration.set(markedDiagnostics.map((d) => {
|
|
25
25
|
// For zero-length ranges or ranges covering only a line break, create a widget
|
|
26
26
|
return d.from == d.to || (d.from == d.to - 1 && state.doc.lineAt(d.from).to == d.from)
|
|
@@ -30,7 +30,8 @@ class LintState {
|
|
|
30
30
|
}).range(d.from)
|
|
31
31
|
: Decoration.mark({
|
|
32
32
|
attributes: { class: "cm-lintRange cm-lintRange-" + d.severity + (d.markClass ? " " + d.markClass : "") },
|
|
33
|
-
diagnostic: d
|
|
33
|
+
diagnostic: d,
|
|
34
|
+
inclusive: true
|
|
34
35
|
}).range(d.from, d.to);
|
|
35
36
|
}), true);
|
|
36
37
|
return new LintState(ranges, panel, findDiagnostic(ranges));
|
|
@@ -106,7 +107,7 @@ function diagnosticCount(state) {
|
|
|
106
107
|
let lint = state.field(lintState, false);
|
|
107
108
|
return lint ? lint.diagnostics.size : 0;
|
|
108
109
|
}
|
|
109
|
-
const activeMark = /*@__PURE__*/Decoration.mark({ class: "cm-lintRange cm-lintRange-active" });
|
|
110
|
+
const activeMark = /*@__PURE__*/Decoration.mark({ class: "cm-lintRange cm-lintRange-active", inclusive: true });
|
|
110
111
|
function lintTooltip(view, pos, side) {
|
|
111
112
|
let { diagnostics } = view.state.field(lintState);
|
|
112
113
|
let found = [], stackStart = 2e8, stackEnd = 0;
|
|
@@ -120,7 +121,7 @@ function lintTooltip(view, pos, side) {
|
|
|
120
121
|
});
|
|
121
122
|
let diagnosticFilter = view.state.facet(lintConfig).tooltipFilter;
|
|
122
123
|
if (diagnosticFilter)
|
|
123
|
-
found = diagnosticFilter(found);
|
|
124
|
+
found = diagnosticFilter(found, view.state);
|
|
124
125
|
if (!found.length)
|
|
125
126
|
return null;
|
|
126
127
|
return {
|
|
@@ -225,11 +226,12 @@ const lintPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
225
226
|
else {
|
|
226
227
|
this.set = false;
|
|
227
228
|
let { state } = this.view, { sources } = state.facet(lintConfig);
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
229
|
+
if (sources.length)
|
|
230
|
+
Promise.all(sources.map(source => Promise.resolve(source(this.view)))).then(annotations => {
|
|
231
|
+
let all = annotations.reduce((a, b) => a.concat(b));
|
|
232
|
+
if (this.view.state.doc == state.doc)
|
|
233
|
+
this.view.dispatch(setDiagnostics(this.view.state, all));
|
|
234
|
+
}, error => { logException(this.view.state, error); });
|
|
233
235
|
}
|
|
234
236
|
}
|
|
235
237
|
update(update) {
|
|
@@ -255,7 +257,7 @@ const lintPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
255
257
|
});
|
|
256
258
|
const lintConfig = /*@__PURE__*/Facet.define({
|
|
257
259
|
combine(input) {
|
|
258
|
-
return Object.assign({ sources: input.map(i => i.source) }, combineConfig(input.map(i => i.config), {
|
|
260
|
+
return Object.assign({ sources: input.map(i => i.source).filter(x => x != null) }, combineConfig(input.map(i => i.config), {
|
|
259
261
|
delay: 750,
|
|
260
262
|
markerFilter: null,
|
|
261
263
|
tooltipFilter: null,
|
|
@@ -268,7 +270,8 @@ const lintConfig = /*@__PURE__*/Facet.define({
|
|
|
268
270
|
/**
|
|
269
271
|
Given a diagnostic source, this function returns an extension that
|
|
270
272
|
enables linting with that source. It will be called whenever the
|
|
271
|
-
editor is idle (after its content changed).
|
|
273
|
+
editor is idle (after its content changed). If `null` is given as
|
|
274
|
+
source, this only configures the lint extension.
|
|
272
275
|
*/
|
|
273
276
|
function linter(source, config = {}) {
|
|
274
277
|
return [
|
|
@@ -465,10 +468,11 @@ class LintPanel {
|
|
|
465
468
|
key: this,
|
|
466
469
|
read: () => ({ sel: newSelectedItem.dom.getBoundingClientRect(), panel: this.list.getBoundingClientRect() }),
|
|
467
470
|
write: ({ sel, panel }) => {
|
|
471
|
+
let scaleY = panel.height / this.list.offsetHeight;
|
|
468
472
|
if (sel.top < panel.top)
|
|
469
|
-
this.list.scrollTop -= panel.top - sel.top;
|
|
473
|
+
this.list.scrollTop -= (panel.top - sel.top) / scaleY;
|
|
470
474
|
else if (sel.bottom > panel.bottom)
|
|
471
|
-
this.list.scrollTop += sel.bottom - panel.bottom;
|
|
475
|
+
this.list.scrollTop += (sel.bottom - panel.bottom) / scaleY;
|
|
472
476
|
}
|
|
473
477
|
});
|
|
474
478
|
}
|
|
@@ -625,7 +629,7 @@ class LintGutterMarker extends GutterMarker {
|
|
|
625
629
|
let diagnostics = this.diagnostics;
|
|
626
630
|
let diagnosticsFilter = view.state.facet(lintGutterConfig).tooltipFilter;
|
|
627
631
|
if (diagnosticsFilter)
|
|
628
|
-
diagnostics = diagnosticsFilter(diagnostics);
|
|
632
|
+
diagnostics = diagnosticsFilter(diagnostics, view.state);
|
|
629
633
|
if (diagnostics.length)
|
|
630
634
|
elt.onmouseover = () => gutterMarkerMouseOver(view, elt, diagnostics);
|
|
631
635
|
return elt;
|
|
@@ -704,7 +708,7 @@ const lintGutterMarkers = /*@__PURE__*/StateField.define({
|
|
|
704
708
|
if (effect.is(setDiagnosticsEffect)) {
|
|
705
709
|
let diagnostics = effect.value;
|
|
706
710
|
if (diagnosticFilter)
|
|
707
|
-
diagnostics = diagnosticFilter(diagnostics || []);
|
|
711
|
+
diagnostics = diagnosticFilter(diagnostics || [], tr.state);
|
|
708
712
|
markers = markersForDiagnostics(tr.state.doc, diagnostics.slice(0));
|
|
709
713
|
}
|
|
710
714
|
}
|