@codemirror/language 0.19.8 → 0.19.9
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 +20 -8
- package/dist/index.d.ts +1 -1
- package/dist/index.js +20 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## 0.19.9 (2022-03-30)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Make sure nodes that end at the end of a partial parse aren't treated as valid fold targets.
|
|
6
|
+
|
|
7
|
+
Fix an issue where the parser sometimes wouldn't reuse parsing work done in the background on transactions.
|
|
8
|
+
|
|
1
9
|
## 0.19.8 (2022-03-03)
|
|
2
10
|
|
|
3
11
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -7,6 +7,7 @@ var state = require('@codemirror/state');
|
|
|
7
7
|
var view = require('@codemirror/view');
|
|
8
8
|
var text = require('@codemirror/text');
|
|
9
9
|
|
|
10
|
+
var _a;
|
|
10
11
|
/**
|
|
11
12
|
Node prop stored in a grammar's top syntax node to provide the
|
|
12
13
|
facet that stores language data for that language.
|
|
@@ -292,7 +293,7 @@ class ParseContext {
|
|
|
292
293
|
/**
|
|
293
294
|
@internal
|
|
294
295
|
*/
|
|
295
|
-
work(
|
|
296
|
+
work(until, upto) {
|
|
296
297
|
if (upto != null && upto >= this.state.doc.length)
|
|
297
298
|
upto = undefined;
|
|
298
299
|
if (this.tree != common.Tree.empty && this.isDone(upto !== null && upto !== void 0 ? upto : this.state.doc.length)) {
|
|
@@ -301,7 +302,10 @@ class ParseContext {
|
|
|
301
302
|
}
|
|
302
303
|
return this.withContext(() => {
|
|
303
304
|
var _a;
|
|
304
|
-
|
|
305
|
+
if (typeof until == "number") {
|
|
306
|
+
let endTime = Date.now() + until;
|
|
307
|
+
until = () => Date.now() > endTime;
|
|
308
|
+
}
|
|
305
309
|
if (!this.parse)
|
|
306
310
|
this.parse = this.startParse();
|
|
307
311
|
if (upto != null && (this.parse.stoppedAt == null || this.parse.stoppedAt > upto) &&
|
|
@@ -319,7 +323,7 @@ class ParseContext {
|
|
|
319
323
|
else
|
|
320
324
|
return true;
|
|
321
325
|
}
|
|
322
|
-
if (
|
|
326
|
+
if (until())
|
|
323
327
|
return false;
|
|
324
328
|
}
|
|
325
329
|
});
|
|
@@ -474,7 +478,7 @@ class LanguageState {
|
|
|
474
478
|
this.tree = context.tree;
|
|
475
479
|
}
|
|
476
480
|
apply(tr) {
|
|
477
|
-
if (!tr.docChanged)
|
|
481
|
+
if (!tr.docChanged && this.tree == this.context.tree)
|
|
478
482
|
return this;
|
|
479
483
|
let newCx = this.context.changes(tr.changes, tr.state);
|
|
480
484
|
// If the previous parse wasn't done, go forward only up to its
|
|
@@ -516,6 +520,8 @@ if (typeof requestIdleCallback != "undefined")
|
|
|
516
520
|
}, 100 /* MinPause */);
|
|
517
521
|
return () => idle < 0 ? clearTimeout(timeout) : cancelIdleCallback(idle);
|
|
518
522
|
};
|
|
523
|
+
const isInputPending = typeof navigator != "undefined" && ((_a = navigator.scheduling) === null || _a === void 0 ? void 0 : _a.isInputPending)
|
|
524
|
+
? () => navigator.scheduling.isInputPending() : null;
|
|
519
525
|
const parseWorker = view.ViewPlugin.fromClass(class ParseWorker {
|
|
520
526
|
constructor(view) {
|
|
521
527
|
this.view = view;
|
|
@@ -558,9 +564,11 @@ const parseWorker = view.ViewPlugin.fromClass(class ParseWorker {
|
|
|
558
564
|
let { state, viewport: { to: vpTo } } = this.view, field = state.field(Language.state);
|
|
559
565
|
if (field.tree == field.context.tree && field.context.isDone(vpTo + 100000 /* MaxParseAhead */))
|
|
560
566
|
return;
|
|
561
|
-
let
|
|
567
|
+
let endTime = Date.now() + Math.min(this.chunkBudget, 100 /* Slice */, deadline && !isInputPending ? Math.max(25 /* MinSlice */, deadline.timeRemaining() - 5) : 1e9);
|
|
562
568
|
let viewportFirst = field.context.treeLen < vpTo && state.doc.length > vpTo + 1000;
|
|
563
|
-
let done = field.context.work(
|
|
569
|
+
let done = field.context.work(() => {
|
|
570
|
+
return isInputPending && isInputPending() || Date.now() > endTime;
|
|
571
|
+
}, vpTo + (viewportFirst ? 0 : 100000 /* MaxParseAhead */));
|
|
564
572
|
this.chunkBudget -= Date.now() - now;
|
|
565
573
|
if (done || this.chunkBudget <= 0) {
|
|
566
574
|
field.context.takeTree();
|
|
@@ -585,7 +593,7 @@ const parseWorker = view.ViewPlugin.fromClass(class ParseWorker {
|
|
|
585
593
|
this.working();
|
|
586
594
|
}
|
|
587
595
|
isWorking() {
|
|
588
|
-
return this.working || this.workScheduled > 0;
|
|
596
|
+
return !!(this.working || this.workScheduled > 0);
|
|
589
597
|
}
|
|
590
598
|
}, {
|
|
591
599
|
eventHandlers: { focus() { this.scheduleWork(); } }
|
|
@@ -1123,7 +1131,7 @@ function syntaxFolding(state, start, end) {
|
|
|
1123
1131
|
if (found && cur.from < start)
|
|
1124
1132
|
break;
|
|
1125
1133
|
let prop = cur.type.prop(foldNodeProp);
|
|
1126
|
-
if (prop) {
|
|
1134
|
+
if (prop && (cur.to < tree.length - 50 || tree.length == state.doc.length || !isUnfinished(cur))) {
|
|
1127
1135
|
let value = prop(cur, state);
|
|
1128
1136
|
if (value && value.from <= end && value.from >= start && value.to > end)
|
|
1129
1137
|
found = value;
|
|
@@ -1131,6 +1139,10 @@ function syntaxFolding(state, start, end) {
|
|
|
1131
1139
|
}
|
|
1132
1140
|
return found;
|
|
1133
1141
|
}
|
|
1142
|
+
function isUnfinished(node) {
|
|
1143
|
+
let ch = node.lastChild;
|
|
1144
|
+
return ch && ch.to == node.to && ch.type.isError;
|
|
1145
|
+
}
|
|
1134
1146
|
/**
|
|
1135
1147
|
Check whether the given line is foldable. First asks any fold
|
|
1136
1148
|
services registered through
|
package/dist/index.d.ts
CHANGED
|
@@ -156,7 +156,7 @@ stopped running, either because it parsed the entire document,
|
|
|
156
156
|
because it spent too much time and was cut off, or because there
|
|
157
157
|
is no language parser enabled.
|
|
158
158
|
*/
|
|
159
|
-
declare function syntaxParserRunning(view: EditorView): boolean
|
|
159
|
+
declare function syntaxParserRunning(view: EditorView): boolean;
|
|
160
160
|
/**
|
|
161
161
|
A parse context provided to parsers working on the editor content.
|
|
162
162
|
*/
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { StateEffect, StateField, Facet, EditorState } from '@codemirror/state';
|
|
|
3
3
|
import { ViewPlugin, logException } from '@codemirror/view';
|
|
4
4
|
import { countColumn } from '@codemirror/text';
|
|
5
5
|
|
|
6
|
+
var _a;
|
|
6
7
|
/**
|
|
7
8
|
Node prop stored in a grammar's top syntax node to provide the
|
|
8
9
|
facet that stores language data for that language.
|
|
@@ -288,7 +289,7 @@ class ParseContext {
|
|
|
288
289
|
/**
|
|
289
290
|
@internal
|
|
290
291
|
*/
|
|
291
|
-
work(
|
|
292
|
+
work(until, upto) {
|
|
292
293
|
if (upto != null && upto >= this.state.doc.length)
|
|
293
294
|
upto = undefined;
|
|
294
295
|
if (this.tree != Tree.empty && this.isDone(upto !== null && upto !== void 0 ? upto : this.state.doc.length)) {
|
|
@@ -297,7 +298,10 @@ class ParseContext {
|
|
|
297
298
|
}
|
|
298
299
|
return this.withContext(() => {
|
|
299
300
|
var _a;
|
|
300
|
-
|
|
301
|
+
if (typeof until == "number") {
|
|
302
|
+
let endTime = Date.now() + until;
|
|
303
|
+
until = () => Date.now() > endTime;
|
|
304
|
+
}
|
|
301
305
|
if (!this.parse)
|
|
302
306
|
this.parse = this.startParse();
|
|
303
307
|
if (upto != null && (this.parse.stoppedAt == null || this.parse.stoppedAt > upto) &&
|
|
@@ -315,7 +319,7 @@ class ParseContext {
|
|
|
315
319
|
else
|
|
316
320
|
return true;
|
|
317
321
|
}
|
|
318
|
-
if (
|
|
322
|
+
if (until())
|
|
319
323
|
return false;
|
|
320
324
|
}
|
|
321
325
|
});
|
|
@@ -470,7 +474,7 @@ class LanguageState {
|
|
|
470
474
|
this.tree = context.tree;
|
|
471
475
|
}
|
|
472
476
|
apply(tr) {
|
|
473
|
-
if (!tr.docChanged)
|
|
477
|
+
if (!tr.docChanged && this.tree == this.context.tree)
|
|
474
478
|
return this;
|
|
475
479
|
let newCx = this.context.changes(tr.changes, tr.state);
|
|
476
480
|
// If the previous parse wasn't done, go forward only up to its
|
|
@@ -512,6 +516,8 @@ if (typeof requestIdleCallback != "undefined")
|
|
|
512
516
|
}, 100 /* MinPause */);
|
|
513
517
|
return () => idle < 0 ? clearTimeout(timeout) : cancelIdleCallback(idle);
|
|
514
518
|
};
|
|
519
|
+
const isInputPending = typeof navigator != "undefined" && ((_a = navigator.scheduling) === null || _a === void 0 ? void 0 : _a.isInputPending)
|
|
520
|
+
? () => navigator.scheduling.isInputPending() : null;
|
|
515
521
|
const parseWorker = /*@__PURE__*/ViewPlugin.fromClass(class ParseWorker {
|
|
516
522
|
constructor(view) {
|
|
517
523
|
this.view = view;
|
|
@@ -554,9 +560,11 @@ const parseWorker = /*@__PURE__*/ViewPlugin.fromClass(class ParseWorker {
|
|
|
554
560
|
let { state, viewport: { to: vpTo } } = this.view, field = state.field(Language.state);
|
|
555
561
|
if (field.tree == field.context.tree && field.context.isDone(vpTo + 100000 /* MaxParseAhead */))
|
|
556
562
|
return;
|
|
557
|
-
let
|
|
563
|
+
let endTime = Date.now() + Math.min(this.chunkBudget, 100 /* Slice */, deadline && !isInputPending ? Math.max(25 /* MinSlice */, deadline.timeRemaining() - 5) : 1e9);
|
|
558
564
|
let viewportFirst = field.context.treeLen < vpTo && state.doc.length > vpTo + 1000;
|
|
559
|
-
let done = field.context.work(
|
|
565
|
+
let done = field.context.work(() => {
|
|
566
|
+
return isInputPending && isInputPending() || Date.now() > endTime;
|
|
567
|
+
}, vpTo + (viewportFirst ? 0 : 100000 /* MaxParseAhead */));
|
|
560
568
|
this.chunkBudget -= Date.now() - now;
|
|
561
569
|
if (done || this.chunkBudget <= 0) {
|
|
562
570
|
field.context.takeTree();
|
|
@@ -581,7 +589,7 @@ const parseWorker = /*@__PURE__*/ViewPlugin.fromClass(class ParseWorker {
|
|
|
581
589
|
this.working();
|
|
582
590
|
}
|
|
583
591
|
isWorking() {
|
|
584
|
-
return this.working || this.workScheduled > 0;
|
|
592
|
+
return !!(this.working || this.workScheduled > 0);
|
|
585
593
|
}
|
|
586
594
|
}, {
|
|
587
595
|
eventHandlers: { focus() { this.scheduleWork(); } }
|
|
@@ -1119,7 +1127,7 @@ function syntaxFolding(state, start, end) {
|
|
|
1119
1127
|
if (found && cur.from < start)
|
|
1120
1128
|
break;
|
|
1121
1129
|
let prop = cur.type.prop(foldNodeProp);
|
|
1122
|
-
if (prop) {
|
|
1130
|
+
if (prop && (cur.to < tree.length - 50 || tree.length == state.doc.length || !isUnfinished(cur))) {
|
|
1123
1131
|
let value = prop(cur, state);
|
|
1124
1132
|
if (value && value.from <= end && value.from >= start && value.to > end)
|
|
1125
1133
|
found = value;
|
|
@@ -1127,6 +1135,10 @@ function syntaxFolding(state, start, end) {
|
|
|
1127
1135
|
}
|
|
1128
1136
|
return found;
|
|
1129
1137
|
}
|
|
1138
|
+
function isUnfinished(node) {
|
|
1139
|
+
let ch = node.lastChild;
|
|
1140
|
+
return ch && ch.to == node.to && ch.type.isError;
|
|
1141
|
+
}
|
|
1130
1142
|
/**
|
|
1131
1143
|
Check whether the given line is foldable. First asks any fold
|
|
1132
1144
|
services registered through
|