@codemirror/lint 0.18.3 → 0.18.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 CHANGED
@@ -1,3 +1,11 @@
1
+ ## 0.18.4 (2021-06-07)
2
+
3
+ ### Bug fixes
4
+
5
+ Multiple `linter` extensions can now be added to an editor without disrupting each other.
6
+
7
+ Fix poor layout on lint tooltips due to changes in @codemirror/tooltip.
8
+
1
9
  ## 0.18.3 (2021-05-10)
2
10
 
3
11
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -36,7 +36,7 @@ class LintState {
36
36
  widget: new DiagnosticWidget(d),
37
37
  diagnostic: d
38
38
  }).range(d.from);
39
- }));
39
+ }), true);
40
40
  return new LintState(ranges, panel, findDiagnostic(ranges));
41
41
  }
42
42
  }
@@ -175,6 +175,53 @@ const lintKeymap = [
175
175
  { key: "Mod-Shift-m", run: openLintPanel },
176
176
  { key: "F8", run: nextDiagnostic }
177
177
  ];
178
+ const lintPlugin = view.ViewPlugin.fromClass(class {
179
+ constructor(view) {
180
+ this.view = view;
181
+ this.timeout = -1;
182
+ this.set = true;
183
+ let { delay } = view.state.facet(lintSource);
184
+ this.lintTime = Date.now() + delay;
185
+ this.run = this.run.bind(this);
186
+ this.timeout = setTimeout(this.run, delay);
187
+ }
188
+ run() {
189
+ let now = Date.now();
190
+ if (now < this.lintTime - 10) {
191
+ setTimeout(this.run, this.lintTime - now);
192
+ }
193
+ else {
194
+ this.set = false;
195
+ let { state } = this.view, { sources } = state.facet(lintSource);
196
+ Promise.all(sources.map(source => Promise.resolve(source(this.view)))).then(annotations => {
197
+ var _a, _b;
198
+ let all = annotations.reduce((a, b) => a.concat(b));
199
+ if (this.view.state.doc == state.doc &&
200
+ (all.length || ((_b = (_a = this.view.state.field(lintState, false)) === null || _a === void 0 ? void 0 : _a.diagnostics) === null || _b === void 0 ? void 0 : _b.size)))
201
+ this.view.dispatch(setDiagnostics(this.view.state, all));
202
+ }, error => { view.logException(this.view.state, error); });
203
+ }
204
+ }
205
+ update(update) {
206
+ if (update.docChanged) {
207
+ let { delay } = update.state.facet(lintSource);
208
+ this.lintTime = Date.now() + delay;
209
+ if (!this.set) {
210
+ this.set = true;
211
+ this.timeout = setTimeout(this.run, delay);
212
+ }
213
+ }
214
+ }
215
+ destroy() {
216
+ clearTimeout(this.timeout);
217
+ }
218
+ });
219
+ const lintSource = state.Facet.define({
220
+ combine(input) {
221
+ return { sources: input.map(i => i.source), delay: input.length ? Math.max(...input.map(i => i.delay)) : 750 };
222
+ },
223
+ enables: lintPlugin
224
+ });
178
225
  /**
179
226
  Given a diagnostic source, this function returns an extension that
180
227
  enables linting with that source. It will be called whenever the
@@ -182,41 +229,7 @@ editor is idle (after its content changed).
182
229
  */
183
230
  function linter(source, config = {}) {
184
231
  var _a;
185
- let delay = (_a = config.delay) !== null && _a !== void 0 ? _a : 750;
186
- return view.ViewPlugin.fromClass(class {
187
- constructor(view) {
188
- this.view = view;
189
- this.lintTime = Date.now() + delay;
190
- this.set = true;
191
- this.run = this.run.bind(this);
192
- setTimeout(this.run, delay);
193
- }
194
- run() {
195
- let now = Date.now();
196
- if (now < this.lintTime - 10) {
197
- setTimeout(this.run, this.lintTime - now);
198
- }
199
- else {
200
- this.set = false;
201
- let { state } = this.view;
202
- Promise.resolve(source(this.view)).then(annotations => {
203
- var _a, _b;
204
- if (this.view.state.doc == state.doc &&
205
- (annotations.length || ((_b = (_a = this.view.state.field(lintState, false)) === null || _a === void 0 ? void 0 : _a.diagnostics) === null || _b === void 0 ? void 0 : _b.size)))
206
- this.view.dispatch(setDiagnostics(this.view.state, annotations));
207
- }, error => { view.logException(this.view.state, error); });
208
- }
209
- }
210
- update(update) {
211
- if (update.docChanged) {
212
- this.lintTime = Date.now() + delay;
213
- if (!this.set) {
214
- this.set = true;
215
- setTimeout(this.run, delay);
216
- }
217
- }
218
- }
219
- });
232
+ return lintSource.of({ source, delay: (_a = config.delay) !== null && _a !== void 0 ? _a : 750 });
220
233
  }
221
234
  function assignKeys(actions) {
222
235
  let assigned = [];
@@ -479,6 +492,10 @@ const baseTheme = view.EditorView.baseTheme({
479
492
  ".cm-lintRange-warning": { backgroundImage: underline("orange") },
480
493
  ".cm-lintRange-info": { backgroundImage: underline("#999") },
481
494
  ".cm-lintRange-active": { backgroundColor: "#ffdd9980" },
495
+ ".cm-tooltip-lint": {
496
+ padding: 0,
497
+ margin: 0
498
+ },
482
499
  ".cm-lintPoint": {
483
500
  position: "relative",
484
501
  "&:after": {
package/dist/index.d.ts CHANGED
@@ -74,12 +74,13 @@ A set of default key bindings for the lint functionality.
74
74
  - F8: [`nextDiagnostic`](https://codemirror.net/6/docs/ref/#lint.nextDiagnostic)
75
75
  */
76
76
  declare const lintKeymap: readonly KeyBinding[];
77
+ declare type LintSource = (view: EditorView) => readonly Diagnostic[] | Promise<readonly Diagnostic[]>;
77
78
  /**
78
79
  Given a diagnostic source, this function returns an extension that
79
80
  enables linting with that source. It will be called whenever the
80
81
  editor is idle (after its content changed).
81
82
  */
82
- declare function linter(source: (view: EditorView) => readonly Diagnostic[] | Promise<readonly Diagnostic[]>, config?: {
83
+ declare function linter(source: LintSource, config?: {
83
84
  /**
84
85
  Time to wait (in milliseconds) after a change before running
85
86
  the linter. Defaults to 750ms.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { EditorView, Decoration, ViewPlugin, logException, WidgetType } from '@codemirror/view';
2
- import { StateEffect, StateField } from '@codemirror/state';
2
+ import { StateEffect, StateField, Facet } from '@codemirror/state';
3
3
  import { hoverTooltip } from '@codemirror/tooltip';
4
4
  import { showPanel, getPanel } from '@codemirror/panel';
5
5
  import elt from 'crelt';
@@ -28,7 +28,7 @@ class LintState {
28
28
  widget: new DiagnosticWidget(d),
29
29
  diagnostic: d
30
30
  }).range(d.from);
31
- }));
31
+ }), true);
32
32
  return new LintState(ranges, panel, findDiagnostic(ranges));
33
33
  }
34
34
  }
@@ -167,6 +167,53 @@ const lintKeymap = [
167
167
  { key: "Mod-Shift-m", run: openLintPanel },
168
168
  { key: "F8", run: nextDiagnostic }
169
169
  ];
170
+ const lintPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
171
+ constructor(view) {
172
+ this.view = view;
173
+ this.timeout = -1;
174
+ this.set = true;
175
+ let { delay } = view.state.facet(lintSource);
176
+ this.lintTime = Date.now() + delay;
177
+ this.run = this.run.bind(this);
178
+ this.timeout = setTimeout(this.run, delay);
179
+ }
180
+ run() {
181
+ let now = Date.now();
182
+ if (now < this.lintTime - 10) {
183
+ setTimeout(this.run, this.lintTime - now);
184
+ }
185
+ else {
186
+ this.set = false;
187
+ let { state } = this.view, { sources } = state.facet(lintSource);
188
+ Promise.all(sources.map(source => Promise.resolve(source(this.view)))).then(annotations => {
189
+ var _a, _b;
190
+ let all = annotations.reduce((a, b) => a.concat(b));
191
+ if (this.view.state.doc == state.doc &&
192
+ (all.length || ((_b = (_a = this.view.state.field(lintState, false)) === null || _a === void 0 ? void 0 : _a.diagnostics) === null || _b === void 0 ? void 0 : _b.size)))
193
+ this.view.dispatch(setDiagnostics(this.view.state, all));
194
+ }, error => { logException(this.view.state, error); });
195
+ }
196
+ }
197
+ update(update) {
198
+ if (update.docChanged) {
199
+ let { delay } = update.state.facet(lintSource);
200
+ this.lintTime = Date.now() + delay;
201
+ if (!this.set) {
202
+ this.set = true;
203
+ this.timeout = setTimeout(this.run, delay);
204
+ }
205
+ }
206
+ }
207
+ destroy() {
208
+ clearTimeout(this.timeout);
209
+ }
210
+ });
211
+ const lintSource = /*@__PURE__*/Facet.define({
212
+ combine(input) {
213
+ return { sources: input.map(i => i.source), delay: input.length ? Math.max(...input.map(i => i.delay)) : 750 };
214
+ },
215
+ enables: lintPlugin
216
+ });
170
217
  /**
171
218
  Given a diagnostic source, this function returns an extension that
172
219
  enables linting with that source. It will be called whenever the
@@ -174,41 +221,7 @@ editor is idle (after its content changed).
174
221
  */
175
222
  function linter(source, config = {}) {
176
223
  var _a;
177
- let delay = (_a = config.delay) !== null && _a !== void 0 ? _a : 750;
178
- return ViewPlugin.fromClass(class {
179
- constructor(view) {
180
- this.view = view;
181
- this.lintTime = Date.now() + delay;
182
- this.set = true;
183
- this.run = this.run.bind(this);
184
- setTimeout(this.run, delay);
185
- }
186
- run() {
187
- let now = Date.now();
188
- if (now < this.lintTime - 10) {
189
- setTimeout(this.run, this.lintTime - now);
190
- }
191
- else {
192
- this.set = false;
193
- let { state } = this.view;
194
- Promise.resolve(source(this.view)).then(annotations => {
195
- var _a, _b;
196
- if (this.view.state.doc == state.doc &&
197
- (annotations.length || ((_b = (_a = this.view.state.field(lintState, false)) === null || _a === void 0 ? void 0 : _a.diagnostics) === null || _b === void 0 ? void 0 : _b.size)))
198
- this.view.dispatch(setDiagnostics(this.view.state, annotations));
199
- }, error => { logException(this.view.state, error); });
200
- }
201
- }
202
- update(update) {
203
- if (update.docChanged) {
204
- this.lintTime = Date.now() + delay;
205
- if (!this.set) {
206
- this.set = true;
207
- setTimeout(this.run, delay);
208
- }
209
- }
210
- }
211
- });
224
+ return lintSource.of({ source, delay: (_a = config.delay) !== null && _a !== void 0 ? _a : 750 });
212
225
  }
213
226
  function assignKeys(actions) {
214
227
  let assigned = [];
@@ -471,6 +484,10 @@ const baseTheme = /*@__PURE__*/EditorView.baseTheme({
471
484
  ".cm-lintRange-warning": { backgroundImage: /*@__PURE__*/underline("orange") },
472
485
  ".cm-lintRange-info": { backgroundImage: /*@__PURE__*/underline("#999") },
473
486
  ".cm-lintRange-active": { backgroundColor: "#ffdd9980" },
487
+ ".cm-tooltip-lint": {
488
+ padding: 0,
489
+ margin: 0
490
+ },
474
491
  ".cm-lintPoint": {
475
492
  position: "relative",
476
493
  "&:after": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/lint",
3
- "version": "0.18.3",
3
+ "version": "0.18.4",
4
4
  "description": "Linting support for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",