@codemirror/language 0.19.7 → 0.19.10
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 +20 -0
- package/dist/index.cjs +25 -11
- package/dist/index.d.ts +1 -1
- package/dist/index.js +25 -11
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
## 0.19.10 (2022-03-31)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Autocompletion may now also trigger automatic indentation on input.
|
|
6
|
+
|
|
7
|
+
## 0.19.9 (2022-03-30)
|
|
8
|
+
|
|
9
|
+
### Bug fixes
|
|
10
|
+
|
|
11
|
+
Make sure nodes that end at the end of a partial parse aren't treated as valid fold targets.
|
|
12
|
+
|
|
13
|
+
Fix an issue where the parser sometimes wouldn't reuse parsing work done in the background on transactions.
|
|
14
|
+
|
|
15
|
+
## 0.19.8 (2022-03-03)
|
|
16
|
+
|
|
17
|
+
### Bug fixes
|
|
18
|
+
|
|
19
|
+
Fix an issue that could cause indentation logic to use the wrong line content when indenting multiple lines at once.
|
|
20
|
+
|
|
1
21
|
## 0.19.7 (2021-12-02)
|
|
2
22
|
|
|
3
23
|
### 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(); } }
|
|
@@ -822,9 +830,11 @@ class IndentContext {
|
|
|
822
830
|
*/
|
|
823
831
|
lineAt(pos, bias = 1) {
|
|
824
832
|
let line = this.state.doc.lineAt(pos);
|
|
825
|
-
let { simulateBreak } = this.options;
|
|
833
|
+
let { simulateBreak, simulateDoubleBreak } = this.options;
|
|
826
834
|
if (simulateBreak != null && simulateBreak >= line.from && simulateBreak <= line.to) {
|
|
827
|
-
if (
|
|
835
|
+
if (simulateDoubleBreak && simulateBreak == pos)
|
|
836
|
+
return { text: "", from: pos };
|
|
837
|
+
else if (bias < 0 ? simulateBreak < pos : simulateBreak <= pos)
|
|
828
838
|
return { text: line.text.slice(simulateBreak - line.from), from: simulateBreak };
|
|
829
839
|
else
|
|
830
840
|
return { text: line.text.slice(0, simulateBreak - line.from), from: line.from };
|
|
@@ -1057,7 +1067,7 @@ added at the start of a line.
|
|
|
1057
1067
|
*/
|
|
1058
1068
|
function indentOnInput() {
|
|
1059
1069
|
return state.EditorState.transactionFilter.of(tr => {
|
|
1060
|
-
if (!tr.docChanged || !tr.isUserEvent("input.type"))
|
|
1070
|
+
if (!tr.docChanged || !tr.isUserEvent("input.type") && !tr.isUserEvent("input.complete"))
|
|
1061
1071
|
return tr;
|
|
1062
1072
|
let rules = tr.startState.languageDataAt("indentOnInput", tr.startState.selection.main.head);
|
|
1063
1073
|
if (!rules.length)
|
|
@@ -1121,7 +1131,7 @@ function syntaxFolding(state, start, end) {
|
|
|
1121
1131
|
if (found && cur.from < start)
|
|
1122
1132
|
break;
|
|
1123
1133
|
let prop = cur.type.prop(foldNodeProp);
|
|
1124
|
-
if (prop) {
|
|
1134
|
+
if (prop && (cur.to < tree.length - 50 || tree.length == state.doc.length || !isUnfinished(cur))) {
|
|
1125
1135
|
let value = prop(cur, state);
|
|
1126
1136
|
if (value && value.from <= end && value.from >= start && value.to > end)
|
|
1127
1137
|
found = value;
|
|
@@ -1129,6 +1139,10 @@ function syntaxFolding(state, start, end) {
|
|
|
1129
1139
|
}
|
|
1130
1140
|
return found;
|
|
1131
1141
|
}
|
|
1142
|
+
function isUnfinished(node) {
|
|
1143
|
+
let ch = node.lastChild;
|
|
1144
|
+
return ch && ch.to == node.to && ch.type.isError;
|
|
1145
|
+
}
|
|
1132
1146
|
/**
|
|
1133
1147
|
Check whether the given line is foldable. First asks any fold
|
|
1134
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(); } }
|
|
@@ -818,9 +826,11 @@ class IndentContext {
|
|
|
818
826
|
*/
|
|
819
827
|
lineAt(pos, bias = 1) {
|
|
820
828
|
let line = this.state.doc.lineAt(pos);
|
|
821
|
-
let { simulateBreak } = this.options;
|
|
829
|
+
let { simulateBreak, simulateDoubleBreak } = this.options;
|
|
822
830
|
if (simulateBreak != null && simulateBreak >= line.from && simulateBreak <= line.to) {
|
|
823
|
-
if (
|
|
831
|
+
if (simulateDoubleBreak && simulateBreak == pos)
|
|
832
|
+
return { text: "", from: pos };
|
|
833
|
+
else if (bias < 0 ? simulateBreak < pos : simulateBreak <= pos)
|
|
824
834
|
return { text: line.text.slice(simulateBreak - line.from), from: simulateBreak };
|
|
825
835
|
else
|
|
826
836
|
return { text: line.text.slice(0, simulateBreak - line.from), from: line.from };
|
|
@@ -1053,7 +1063,7 @@ added at the start of a line.
|
|
|
1053
1063
|
*/
|
|
1054
1064
|
function indentOnInput() {
|
|
1055
1065
|
return EditorState.transactionFilter.of(tr => {
|
|
1056
|
-
if (!tr.docChanged || !tr.isUserEvent("input.type"))
|
|
1066
|
+
if (!tr.docChanged || !tr.isUserEvent("input.type") && !tr.isUserEvent("input.complete"))
|
|
1057
1067
|
return tr;
|
|
1058
1068
|
let rules = tr.startState.languageDataAt("indentOnInput", tr.startState.selection.main.head);
|
|
1059
1069
|
if (!rules.length)
|
|
@@ -1117,7 +1127,7 @@ function syntaxFolding(state, start, end) {
|
|
|
1117
1127
|
if (found && cur.from < start)
|
|
1118
1128
|
break;
|
|
1119
1129
|
let prop = cur.type.prop(foldNodeProp);
|
|
1120
|
-
if (prop) {
|
|
1130
|
+
if (prop && (cur.to < tree.length - 50 || tree.length == state.doc.length || !isUnfinished(cur))) {
|
|
1121
1131
|
let value = prop(cur, state);
|
|
1122
1132
|
if (value && value.from <= end && value.from >= start && value.to > end)
|
|
1123
1133
|
found = value;
|
|
@@ -1125,6 +1135,10 @@ function syntaxFolding(state, start, end) {
|
|
|
1125
1135
|
}
|
|
1126
1136
|
return found;
|
|
1127
1137
|
}
|
|
1138
|
+
function isUnfinished(node) {
|
|
1139
|
+
let ch = node.lastChild;
|
|
1140
|
+
return ch && ch.to == node.to && ch.type.isError;
|
|
1141
|
+
}
|
|
1128
1142
|
/**
|
|
1129
1143
|
Check whether the given line is foldable. First asks any fold
|
|
1130
1144
|
services registered through
|