@codemirror/language 6.9.0 → 6.9.1
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 +50 -39
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +51 -38
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## 6.9.1 (2023-09-20)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Indentation now works a lot better in mixed-language documents that interleave the languages in a complex way.
|
|
6
|
+
|
|
7
|
+
Code folding is now able to pick the right foldable syntax node when the line end falls in a mixed-parsing language that doesn't match the target node.
|
|
8
|
+
|
|
1
9
|
## 6.9.0 (2023-08-16)
|
|
2
10
|
|
|
3
11
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
3
|
var common = require('@lezer/common');
|
|
6
4
|
var state = require('@codemirror/state');
|
|
7
5
|
var view = require('@codemirror/view');
|
|
@@ -538,14 +536,14 @@ class LanguageState {
|
|
|
538
536
|
// state updates with parse work beyond the viewport.
|
|
539
537
|
let upto = this.context.treeLen == tr.startState.doc.length ? undefined
|
|
540
538
|
: Math.max(tr.changes.mapPos(this.context.treeLen), newCx.viewport.to);
|
|
541
|
-
if (!newCx.work(20 /* Apply */, upto))
|
|
539
|
+
if (!newCx.work(20 /* Work.Apply */, upto))
|
|
542
540
|
newCx.takeTree();
|
|
543
541
|
return new LanguageState(newCx);
|
|
544
542
|
}
|
|
545
543
|
static init(state) {
|
|
546
|
-
let vpTo = Math.min(3000 /* InitViewport */, state.doc.length);
|
|
544
|
+
let vpTo = Math.min(3000 /* Work.InitViewport */, state.doc.length);
|
|
547
545
|
let parseState = ParseContext.create(state.facet(language).parser, state, { from: 0, to: vpTo });
|
|
548
|
-
if (!parseState.work(20 /* Apply */, vpTo))
|
|
546
|
+
if (!parseState.work(20 /* Work.Apply */, vpTo))
|
|
549
547
|
parseState.takeTree();
|
|
550
548
|
return new LanguageState(parseState);
|
|
551
549
|
}
|
|
@@ -562,14 +560,14 @@ Language.state = state.StateField.define({
|
|
|
562
560
|
}
|
|
563
561
|
});
|
|
564
562
|
let requestIdle = (callback) => {
|
|
565
|
-
let timeout = setTimeout(() => callback(), 500 /* MaxPause */);
|
|
563
|
+
let timeout = setTimeout(() => callback(), 500 /* Work.MaxPause */);
|
|
566
564
|
return () => clearTimeout(timeout);
|
|
567
565
|
};
|
|
568
566
|
if (typeof requestIdleCallback != "undefined")
|
|
569
567
|
requestIdle = (callback) => {
|
|
570
568
|
let idle = -1, timeout = setTimeout(() => {
|
|
571
|
-
idle = requestIdleCallback(callback, { timeout: 500 /* MaxPause */ - 100 /* MinPause */ });
|
|
572
|
-
}, 100 /* MinPause */);
|
|
569
|
+
idle = requestIdleCallback(callback, { timeout: 500 /* Work.MaxPause */ - 100 /* Work.MinPause */ });
|
|
570
|
+
}, 100 /* Work.MinPause */);
|
|
573
571
|
return () => idle < 0 ? clearTimeout(timeout) : cancelIdleCallback(idle);
|
|
574
572
|
};
|
|
575
573
|
const isInputPending = typeof navigator != "undefined" && ((_a = navigator.scheduling) === null || _a === void 0 ? void 0 : _a.isInputPending)
|
|
@@ -590,9 +588,9 @@ const parseWorker = view.ViewPlugin.fromClass(class ParseWorker {
|
|
|
590
588
|
let cx = this.view.state.field(Language.state).context;
|
|
591
589
|
if (cx.updateViewport(update.view.viewport) || this.view.viewport.to > cx.treeLen)
|
|
592
590
|
this.scheduleWork();
|
|
593
|
-
if (update.docChanged) {
|
|
591
|
+
if (update.docChanged || update.selectionSet) {
|
|
594
592
|
if (this.view.hasFocus)
|
|
595
|
-
this.chunkBudget += 50 /* ChangeBonus */;
|
|
593
|
+
this.chunkBudget += 50 /* Work.ChangeBonus */;
|
|
596
594
|
this.scheduleWork();
|
|
597
595
|
}
|
|
598
596
|
this.checkAsyncSchedule(cx);
|
|
@@ -608,19 +606,19 @@ const parseWorker = view.ViewPlugin.fromClass(class ParseWorker {
|
|
|
608
606
|
this.working = null;
|
|
609
607
|
let now = Date.now();
|
|
610
608
|
if (this.chunkEnd < now && (this.chunkEnd < 0 || this.view.hasFocus)) { // Start a new chunk
|
|
611
|
-
this.chunkEnd = now + 30000 /* ChunkTime */;
|
|
612
|
-
this.chunkBudget = 3000 /* ChunkBudget */;
|
|
609
|
+
this.chunkEnd = now + 30000 /* Work.ChunkTime */;
|
|
610
|
+
this.chunkBudget = 3000 /* Work.ChunkBudget */;
|
|
613
611
|
}
|
|
614
612
|
if (this.chunkBudget <= 0)
|
|
615
613
|
return; // No more budget
|
|
616
614
|
let { state, viewport: { to: vpTo } } = this.view, field = state.field(Language.state);
|
|
617
|
-
if (field.tree == field.context.tree && field.context.isDone(vpTo + 100000 /* MaxParseAhead */))
|
|
615
|
+
if (field.tree == field.context.tree && field.context.isDone(vpTo + 100000 /* Work.MaxParseAhead */))
|
|
618
616
|
return;
|
|
619
|
-
let endTime = Date.now() + Math.min(this.chunkBudget, 100 /* Slice */, deadline && !isInputPending ? Math.max(25 /* MinSlice */, deadline.timeRemaining() - 5) : 1e9);
|
|
617
|
+
let endTime = Date.now() + Math.min(this.chunkBudget, 100 /* Work.Slice */, deadline && !isInputPending ? Math.max(25 /* Work.MinSlice */, deadline.timeRemaining() - 5) : 1e9);
|
|
620
618
|
let viewportFirst = field.context.treeLen < vpTo && state.doc.length > vpTo + 1000;
|
|
621
619
|
let done = field.context.work(() => {
|
|
622
620
|
return isInputPending && isInputPending() || Date.now() > endTime;
|
|
623
|
-
}, vpTo + (viewportFirst ? 0 : 100000 /* MaxParseAhead */));
|
|
621
|
+
}, vpTo + (viewportFirst ? 0 : 100000 /* Work.MaxParseAhead */));
|
|
624
622
|
this.chunkBudget -= Date.now() - now;
|
|
625
623
|
if (done || this.chunkBudget <= 0) {
|
|
626
624
|
field.context.takeTree();
|
|
@@ -996,7 +994,24 @@ indicates that no definitive indentation can be determined.
|
|
|
996
994
|
const indentNodeProp = new common.NodeProp();
|
|
997
995
|
// Compute the indentation for a given position from the syntax tree.
|
|
998
996
|
function syntaxIndentation(cx, ast, pos) {
|
|
999
|
-
|
|
997
|
+
let stack = ast.resolveStack(pos);
|
|
998
|
+
let inner = stack.node.enterUnfinishedNodesBefore(pos);
|
|
999
|
+
if (inner != stack.node) {
|
|
1000
|
+
let add = [];
|
|
1001
|
+
for (let cur = inner; cur != stack.node; cur = cur.parent)
|
|
1002
|
+
add.push(cur);
|
|
1003
|
+
for (let i = add.length - 1; i >= 0; i--)
|
|
1004
|
+
stack = { node: add[i], next: stack };
|
|
1005
|
+
}
|
|
1006
|
+
return indentFor(stack, cx, pos);
|
|
1007
|
+
}
|
|
1008
|
+
function indentFor(stack, cx, pos) {
|
|
1009
|
+
for (let cur = stack; cur; cur = cur.next) {
|
|
1010
|
+
let strategy = indentStrategy(cur.node);
|
|
1011
|
+
if (strategy)
|
|
1012
|
+
return strategy(TreeIndentContext.create(cx, pos, cur));
|
|
1013
|
+
}
|
|
1014
|
+
return 0;
|
|
1000
1015
|
}
|
|
1001
1016
|
function ignoreClosed(cx) {
|
|
1002
1017
|
return cx.pos == cx.options.simulateBreak && cx.options.simulateDoubleBreak;
|
|
@@ -1012,14 +1027,6 @@ function indentStrategy(tree) {
|
|
|
1012
1027
|
}
|
|
1013
1028
|
return tree.parent == null ? topIndent : null;
|
|
1014
1029
|
}
|
|
1015
|
-
function indentFrom(node, pos, base) {
|
|
1016
|
-
for (; node; node = node.parent) {
|
|
1017
|
-
let strategy = indentStrategy(node);
|
|
1018
|
-
if (strategy)
|
|
1019
|
-
return strategy(TreeIndentContext.create(base, pos, node));
|
|
1020
|
-
}
|
|
1021
|
-
return null;
|
|
1022
|
-
}
|
|
1023
1030
|
function topIndent() { return 0; }
|
|
1024
1031
|
/**
|
|
1025
1032
|
Objects of this type provide context information and helper
|
|
@@ -1032,20 +1039,24 @@ class TreeIndentContext extends IndentContext {
|
|
|
1032
1039
|
*/
|
|
1033
1040
|
pos,
|
|
1034
1041
|
/**
|
|
1035
|
-
|
|
1036
|
-
applies.
|
|
1042
|
+
@internal
|
|
1037
1043
|
*/
|
|
1038
|
-
|
|
1044
|
+
context) {
|
|
1039
1045
|
super(base.state, base.options);
|
|
1040
1046
|
this.base = base;
|
|
1041
1047
|
this.pos = pos;
|
|
1042
|
-
this.
|
|
1048
|
+
this.context = context;
|
|
1043
1049
|
}
|
|
1044
1050
|
/**
|
|
1051
|
+
The syntax tree node to which the indentation strategy
|
|
1052
|
+
applies.
|
|
1053
|
+
*/
|
|
1054
|
+
get node() { return this.context.node; }
|
|
1055
|
+
/**
|
|
1045
1056
|
@internal
|
|
1046
1057
|
*/
|
|
1047
|
-
static create(base, pos,
|
|
1048
|
-
return new TreeIndentContext(base, pos,
|
|
1058
|
+
static create(base, pos, context) {
|
|
1059
|
+
return new TreeIndentContext(base, pos, context);
|
|
1049
1060
|
}
|
|
1050
1061
|
/**
|
|
1051
1062
|
Get the text directly after `this.pos`, either the entire line
|
|
@@ -1086,8 +1097,7 @@ class TreeIndentContext extends IndentContext {
|
|
|
1086
1097
|
and return the result of that.
|
|
1087
1098
|
*/
|
|
1088
1099
|
continue() {
|
|
1089
|
-
|
|
1090
|
-
return parent ? indentFrom(parent, this.pos, this.base) : 0;
|
|
1100
|
+
return indentFor(this.context.next, this.base, this.pos);
|
|
1091
1101
|
}
|
|
1092
1102
|
}
|
|
1093
1103
|
function isParent(parent, of) {
|
|
@@ -1229,9 +1239,10 @@ function syntaxFolding(state, start, end) {
|
|
|
1229
1239
|
let tree = syntaxTree(state);
|
|
1230
1240
|
if (tree.length < end)
|
|
1231
1241
|
return null;
|
|
1232
|
-
let
|
|
1242
|
+
let stack = tree.resolveStack(end, 1);
|
|
1233
1243
|
let found = null;
|
|
1234
|
-
for (let
|
|
1244
|
+
for (let iter = stack; iter; iter = iter.next) {
|
|
1245
|
+
let cur = iter.node;
|
|
1235
1246
|
if (cur.to <= end || cur.from > end)
|
|
1236
1247
|
continue;
|
|
1237
1248
|
if (found && cur.from < start)
|
|
@@ -2222,7 +2233,7 @@ class StreamLanguage extends Language {
|
|
|
2222
2233
|
state = this.streamParser.startState(cx.unit);
|
|
2223
2234
|
statePos = 0;
|
|
2224
2235
|
}
|
|
2225
|
-
if (pos - statePos > 10000 /* MaxIndentScanDist */)
|
|
2236
|
+
if (pos - statePos > 10000 /* C.MaxIndentScanDist */)
|
|
2226
2237
|
return null;
|
|
2227
2238
|
while (statePos < pos) {
|
|
2228
2239
|
let line = cx.state.doc.lineAt(statePos), end = Math.min(pos, line.to);
|
|
@@ -2304,7 +2315,7 @@ class Parse {
|
|
|
2304
2315
|
this.chunks.push(tree.children[i]);
|
|
2305
2316
|
this.chunkPos.push(tree.positions[i]);
|
|
2306
2317
|
}
|
|
2307
|
-
if (context && this.parsedPos < context.viewport.from - 100000 /* MaxDistanceBeforeViewport */) {
|
|
2318
|
+
if (context && this.parsedPos < context.viewport.from - 100000 /* C.MaxDistanceBeforeViewport */) {
|
|
2308
2319
|
this.state = this.lang.streamParser.startState(getIndentUnit(context.state));
|
|
2309
2320
|
context.skipUntilInView(this.parsedPos, context.viewport.from);
|
|
2310
2321
|
this.parsedPos = context.viewport.from;
|
|
@@ -2314,7 +2325,7 @@ class Parse {
|
|
|
2314
2325
|
advance() {
|
|
2315
2326
|
let context = ParseContext.get();
|
|
2316
2327
|
let parseEnd = this.stoppedAt == null ? this.to : Math.min(this.to, this.stoppedAt);
|
|
2317
|
-
let end = Math.min(parseEnd, this.chunkStart + 2048 /* ChunkSize */);
|
|
2328
|
+
let end = Math.min(parseEnd, this.chunkStart + 2048 /* C.ChunkSize */);
|
|
2318
2329
|
if (context)
|
|
2319
2330
|
end = Math.min(end, context.viewport.to);
|
|
2320
2331
|
while (this.parsedPos < end)
|
|
@@ -2398,7 +2409,7 @@ class Parse {
|
|
|
2398
2409
|
let token = readToken(streamParser.token, stream, this.state);
|
|
2399
2410
|
if (token)
|
|
2400
2411
|
offset = this.emitToken(this.lang.tokenTable.resolve(token), this.parsedPos + stream.start, this.parsedPos + stream.pos, 4, offset);
|
|
2401
|
-
if (stream.start > 10000 /* MaxLineLength */)
|
|
2412
|
+
if (stream.start > 10000 /* C.MaxLineLength */)
|
|
2402
2413
|
break;
|
|
2403
2414
|
}
|
|
2404
2415
|
}
|
|
@@ -2414,7 +2425,7 @@ class Parse {
|
|
|
2414
2425
|
length: this.parsedPos - this.chunkStart,
|
|
2415
2426
|
nodeSet,
|
|
2416
2427
|
topID: 0,
|
|
2417
|
-
maxBufferLength: 2048 /* ChunkSize */,
|
|
2428
|
+
maxBufferLength: 2048 /* C.ChunkSize */,
|
|
2418
2429
|
reused: this.chunkReused
|
|
2419
2430
|
});
|
|
2420
2431
|
tree = new common.Tree(tree.type, tree.children, tree.positions, tree.length, [[this.lang.stateAfter, this.lang.streamParser.copyState(this.state)]]);
|
package/dist/index.d.cts
CHANGED
|
@@ -567,12 +567,12 @@ declare class TreeIndentContext extends IndentContext {
|
|
|
567
567
|
The position at which indentation is being computed.
|
|
568
568
|
*/
|
|
569
569
|
readonly pos: number;
|
|
570
|
+
private constructor();
|
|
570
571
|
/**
|
|
571
572
|
The syntax tree node to which the indentation strategy
|
|
572
573
|
applies.
|
|
573
574
|
*/
|
|
574
|
-
|
|
575
|
-
private constructor();
|
|
575
|
+
get node(): SyntaxNode;
|
|
576
576
|
/**
|
|
577
577
|
Get the text directly after `this.pos`, either the entire line
|
|
578
578
|
or the next 100 characters, whichever is shorter.
|
|
@@ -689,7 +689,7 @@ declare function foldable(state: EditorState, lineStart: number, lineEnd: number
|
|
|
689
689
|
from: number;
|
|
690
690
|
to: number;
|
|
691
691
|
} | null;
|
|
692
|
-
|
|
692
|
+
type DocRange = {
|
|
693
693
|
from: number;
|
|
694
694
|
to: number;
|
|
695
695
|
};
|
|
@@ -790,7 +790,7 @@ interface FoldConfig {
|
|
|
790
790
|
Create an extension that configures code folding.
|
|
791
791
|
*/
|
|
792
792
|
declare function codeFolding(config?: FoldConfig): Extension;
|
|
793
|
-
|
|
793
|
+
type Handlers = {
|
|
794
794
|
[event: string]: (view: EditorView, line: BlockInfo, event: Event) => boolean;
|
|
795
795
|
};
|
|
796
796
|
interface FoldGutterConfig {
|
package/dist/index.d.ts
CHANGED
|
@@ -567,12 +567,12 @@ declare class TreeIndentContext extends IndentContext {
|
|
|
567
567
|
The position at which indentation is being computed.
|
|
568
568
|
*/
|
|
569
569
|
readonly pos: number;
|
|
570
|
+
private constructor();
|
|
570
571
|
/**
|
|
571
572
|
The syntax tree node to which the indentation strategy
|
|
572
573
|
applies.
|
|
573
574
|
*/
|
|
574
|
-
|
|
575
|
-
private constructor();
|
|
575
|
+
get node(): SyntaxNode;
|
|
576
576
|
/**
|
|
577
577
|
Get the text directly after `this.pos`, either the entire line
|
|
578
578
|
or the next 100 characters, whichever is shorter.
|
|
@@ -689,7 +689,7 @@ declare function foldable(state: EditorState, lineStart: number, lineEnd: number
|
|
|
689
689
|
from: number;
|
|
690
690
|
to: number;
|
|
691
691
|
} | null;
|
|
692
|
-
|
|
692
|
+
type DocRange = {
|
|
693
693
|
from: number;
|
|
694
694
|
to: number;
|
|
695
695
|
};
|
|
@@ -790,7 +790,7 @@ interface FoldConfig {
|
|
|
790
790
|
Create an extension that configures code folding.
|
|
791
791
|
*/
|
|
792
792
|
declare function codeFolding(config?: FoldConfig): Extension;
|
|
793
|
-
|
|
793
|
+
type Handlers = {
|
|
794
794
|
[event: string]: (view: EditorView, line: BlockInfo, event: Event) => boolean;
|
|
795
795
|
};
|
|
796
796
|
interface FoldGutterConfig {
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NodeProp,
|
|
1
|
+
import { NodeProp, IterMode, Tree, TreeFragment, Parser, NodeType, NodeSet } from '@lezer/common';
|
|
2
2
|
import { StateEffect, StateField, Facet, EditorState, countColumn, combineConfig, RangeSet, RangeSetBuilder, Prec } from '@codemirror/state';
|
|
3
3
|
import { ViewPlugin, logException, EditorView, Decoration, WidgetType, gutter, GutterMarker } from '@codemirror/view';
|
|
4
4
|
import { tags, tagHighlighter, highlightTree, styleTags } from '@lezer/highlight';
|
|
@@ -534,14 +534,14 @@ class LanguageState {
|
|
|
534
534
|
// state updates with parse work beyond the viewport.
|
|
535
535
|
let upto = this.context.treeLen == tr.startState.doc.length ? undefined
|
|
536
536
|
: Math.max(tr.changes.mapPos(this.context.treeLen), newCx.viewport.to);
|
|
537
|
-
if (!newCx.work(20 /* Apply */, upto))
|
|
537
|
+
if (!newCx.work(20 /* Work.Apply */, upto))
|
|
538
538
|
newCx.takeTree();
|
|
539
539
|
return new LanguageState(newCx);
|
|
540
540
|
}
|
|
541
541
|
static init(state) {
|
|
542
|
-
let vpTo = Math.min(3000 /* InitViewport */, state.doc.length);
|
|
542
|
+
let vpTo = Math.min(3000 /* Work.InitViewport */, state.doc.length);
|
|
543
543
|
let parseState = ParseContext.create(state.facet(language).parser, state, { from: 0, to: vpTo });
|
|
544
|
-
if (!parseState.work(20 /* Apply */, vpTo))
|
|
544
|
+
if (!parseState.work(20 /* Work.Apply */, vpTo))
|
|
545
545
|
parseState.takeTree();
|
|
546
546
|
return new LanguageState(parseState);
|
|
547
547
|
}
|
|
@@ -558,14 +558,14 @@ Language.state = /*@__PURE__*/StateField.define({
|
|
|
558
558
|
}
|
|
559
559
|
});
|
|
560
560
|
let requestIdle = (callback) => {
|
|
561
|
-
let timeout = setTimeout(() => callback(), 500 /* MaxPause */);
|
|
561
|
+
let timeout = setTimeout(() => callback(), 500 /* Work.MaxPause */);
|
|
562
562
|
return () => clearTimeout(timeout);
|
|
563
563
|
};
|
|
564
564
|
if (typeof requestIdleCallback != "undefined")
|
|
565
565
|
requestIdle = (callback) => {
|
|
566
566
|
let idle = -1, timeout = setTimeout(() => {
|
|
567
|
-
idle = requestIdleCallback(callback, { timeout: 500 /* MaxPause */ - 100 /* MinPause */ });
|
|
568
|
-
}, 100 /* MinPause */);
|
|
567
|
+
idle = requestIdleCallback(callback, { timeout: 500 /* Work.MaxPause */ - 100 /* Work.MinPause */ });
|
|
568
|
+
}, 100 /* Work.MinPause */);
|
|
569
569
|
return () => idle < 0 ? clearTimeout(timeout) : cancelIdleCallback(idle);
|
|
570
570
|
};
|
|
571
571
|
const isInputPending = typeof navigator != "undefined" && ((_a = navigator.scheduling) === null || _a === void 0 ? void 0 : _a.isInputPending)
|
|
@@ -586,9 +586,9 @@ const parseWorker = /*@__PURE__*/ViewPlugin.fromClass(class ParseWorker {
|
|
|
586
586
|
let cx = this.view.state.field(Language.state).context;
|
|
587
587
|
if (cx.updateViewport(update.view.viewport) || this.view.viewport.to > cx.treeLen)
|
|
588
588
|
this.scheduleWork();
|
|
589
|
-
if (update.docChanged) {
|
|
589
|
+
if (update.docChanged || update.selectionSet) {
|
|
590
590
|
if (this.view.hasFocus)
|
|
591
|
-
this.chunkBudget += 50 /* ChangeBonus */;
|
|
591
|
+
this.chunkBudget += 50 /* Work.ChangeBonus */;
|
|
592
592
|
this.scheduleWork();
|
|
593
593
|
}
|
|
594
594
|
this.checkAsyncSchedule(cx);
|
|
@@ -604,19 +604,19 @@ const parseWorker = /*@__PURE__*/ViewPlugin.fromClass(class ParseWorker {
|
|
|
604
604
|
this.working = null;
|
|
605
605
|
let now = Date.now();
|
|
606
606
|
if (this.chunkEnd < now && (this.chunkEnd < 0 || this.view.hasFocus)) { // Start a new chunk
|
|
607
|
-
this.chunkEnd = now + 30000 /* ChunkTime */;
|
|
608
|
-
this.chunkBudget = 3000 /* ChunkBudget */;
|
|
607
|
+
this.chunkEnd = now + 30000 /* Work.ChunkTime */;
|
|
608
|
+
this.chunkBudget = 3000 /* Work.ChunkBudget */;
|
|
609
609
|
}
|
|
610
610
|
if (this.chunkBudget <= 0)
|
|
611
611
|
return; // No more budget
|
|
612
612
|
let { state, viewport: { to: vpTo } } = this.view, field = state.field(Language.state);
|
|
613
|
-
if (field.tree == field.context.tree && field.context.isDone(vpTo + 100000 /* MaxParseAhead */))
|
|
613
|
+
if (field.tree == field.context.tree && field.context.isDone(vpTo + 100000 /* Work.MaxParseAhead */))
|
|
614
614
|
return;
|
|
615
|
-
let endTime = Date.now() + Math.min(this.chunkBudget, 100 /* Slice */, deadline && !isInputPending ? Math.max(25 /* MinSlice */, deadline.timeRemaining() - 5) : 1e9);
|
|
615
|
+
let endTime = Date.now() + Math.min(this.chunkBudget, 100 /* Work.Slice */, deadline && !isInputPending ? Math.max(25 /* Work.MinSlice */, deadline.timeRemaining() - 5) : 1e9);
|
|
616
616
|
let viewportFirst = field.context.treeLen < vpTo && state.doc.length > vpTo + 1000;
|
|
617
617
|
let done = field.context.work(() => {
|
|
618
618
|
return isInputPending && isInputPending() || Date.now() > endTime;
|
|
619
|
-
}, vpTo + (viewportFirst ? 0 : 100000 /* MaxParseAhead */));
|
|
619
|
+
}, vpTo + (viewportFirst ? 0 : 100000 /* Work.MaxParseAhead */));
|
|
620
620
|
this.chunkBudget -= Date.now() - now;
|
|
621
621
|
if (done || this.chunkBudget <= 0) {
|
|
622
622
|
field.context.takeTree();
|
|
@@ -992,7 +992,24 @@ indicates that no definitive indentation can be determined.
|
|
|
992
992
|
const indentNodeProp = /*@__PURE__*/new NodeProp();
|
|
993
993
|
// Compute the indentation for a given position from the syntax tree.
|
|
994
994
|
function syntaxIndentation(cx, ast, pos) {
|
|
995
|
-
|
|
995
|
+
let stack = ast.resolveStack(pos);
|
|
996
|
+
let inner = stack.node.enterUnfinishedNodesBefore(pos);
|
|
997
|
+
if (inner != stack.node) {
|
|
998
|
+
let add = [];
|
|
999
|
+
for (let cur = inner; cur != stack.node; cur = cur.parent)
|
|
1000
|
+
add.push(cur);
|
|
1001
|
+
for (let i = add.length - 1; i >= 0; i--)
|
|
1002
|
+
stack = { node: add[i], next: stack };
|
|
1003
|
+
}
|
|
1004
|
+
return indentFor(stack, cx, pos);
|
|
1005
|
+
}
|
|
1006
|
+
function indentFor(stack, cx, pos) {
|
|
1007
|
+
for (let cur = stack; cur; cur = cur.next) {
|
|
1008
|
+
let strategy = indentStrategy(cur.node);
|
|
1009
|
+
if (strategy)
|
|
1010
|
+
return strategy(TreeIndentContext.create(cx, pos, cur));
|
|
1011
|
+
}
|
|
1012
|
+
return 0;
|
|
996
1013
|
}
|
|
997
1014
|
function ignoreClosed(cx) {
|
|
998
1015
|
return cx.pos == cx.options.simulateBreak && cx.options.simulateDoubleBreak;
|
|
@@ -1008,14 +1025,6 @@ function indentStrategy(tree) {
|
|
|
1008
1025
|
}
|
|
1009
1026
|
return tree.parent == null ? topIndent : null;
|
|
1010
1027
|
}
|
|
1011
|
-
function indentFrom(node, pos, base) {
|
|
1012
|
-
for (; node; node = node.parent) {
|
|
1013
|
-
let strategy = indentStrategy(node);
|
|
1014
|
-
if (strategy)
|
|
1015
|
-
return strategy(TreeIndentContext.create(base, pos, node));
|
|
1016
|
-
}
|
|
1017
|
-
return null;
|
|
1018
|
-
}
|
|
1019
1028
|
function topIndent() { return 0; }
|
|
1020
1029
|
/**
|
|
1021
1030
|
Objects of this type provide context information and helper
|
|
@@ -1028,20 +1037,24 @@ class TreeIndentContext extends IndentContext {
|
|
|
1028
1037
|
*/
|
|
1029
1038
|
pos,
|
|
1030
1039
|
/**
|
|
1031
|
-
|
|
1032
|
-
applies.
|
|
1040
|
+
@internal
|
|
1033
1041
|
*/
|
|
1034
|
-
|
|
1042
|
+
context) {
|
|
1035
1043
|
super(base.state, base.options);
|
|
1036
1044
|
this.base = base;
|
|
1037
1045
|
this.pos = pos;
|
|
1038
|
-
this.
|
|
1046
|
+
this.context = context;
|
|
1039
1047
|
}
|
|
1040
1048
|
/**
|
|
1049
|
+
The syntax tree node to which the indentation strategy
|
|
1050
|
+
applies.
|
|
1051
|
+
*/
|
|
1052
|
+
get node() { return this.context.node; }
|
|
1053
|
+
/**
|
|
1041
1054
|
@internal
|
|
1042
1055
|
*/
|
|
1043
|
-
static create(base, pos,
|
|
1044
|
-
return new TreeIndentContext(base, pos,
|
|
1056
|
+
static create(base, pos, context) {
|
|
1057
|
+
return new TreeIndentContext(base, pos, context);
|
|
1045
1058
|
}
|
|
1046
1059
|
/**
|
|
1047
1060
|
Get the text directly after `this.pos`, either the entire line
|
|
@@ -1082,8 +1095,7 @@ class TreeIndentContext extends IndentContext {
|
|
|
1082
1095
|
and return the result of that.
|
|
1083
1096
|
*/
|
|
1084
1097
|
continue() {
|
|
1085
|
-
|
|
1086
|
-
return parent ? indentFrom(parent, this.pos, this.base) : 0;
|
|
1098
|
+
return indentFor(this.context.next, this.base, this.pos);
|
|
1087
1099
|
}
|
|
1088
1100
|
}
|
|
1089
1101
|
function isParent(parent, of) {
|
|
@@ -1225,9 +1237,10 @@ function syntaxFolding(state, start, end) {
|
|
|
1225
1237
|
let tree = syntaxTree(state);
|
|
1226
1238
|
if (tree.length < end)
|
|
1227
1239
|
return null;
|
|
1228
|
-
let
|
|
1240
|
+
let stack = tree.resolveStack(end, 1);
|
|
1229
1241
|
let found = null;
|
|
1230
|
-
for (let
|
|
1242
|
+
for (let iter = stack; iter; iter = iter.next) {
|
|
1243
|
+
let cur = iter.node;
|
|
1231
1244
|
if (cur.to <= end || cur.from > end)
|
|
1232
1245
|
continue;
|
|
1233
1246
|
if (found && cur.from < start)
|
|
@@ -2218,7 +2231,7 @@ class StreamLanguage extends Language {
|
|
|
2218
2231
|
state = this.streamParser.startState(cx.unit);
|
|
2219
2232
|
statePos = 0;
|
|
2220
2233
|
}
|
|
2221
|
-
if (pos - statePos > 10000 /* MaxIndentScanDist */)
|
|
2234
|
+
if (pos - statePos > 10000 /* C.MaxIndentScanDist */)
|
|
2222
2235
|
return null;
|
|
2223
2236
|
while (statePos < pos) {
|
|
2224
2237
|
let line = cx.state.doc.lineAt(statePos), end = Math.min(pos, line.to);
|
|
@@ -2300,7 +2313,7 @@ class Parse {
|
|
|
2300
2313
|
this.chunks.push(tree.children[i]);
|
|
2301
2314
|
this.chunkPos.push(tree.positions[i]);
|
|
2302
2315
|
}
|
|
2303
|
-
if (context && this.parsedPos < context.viewport.from - 100000 /* MaxDistanceBeforeViewport */) {
|
|
2316
|
+
if (context && this.parsedPos < context.viewport.from - 100000 /* C.MaxDistanceBeforeViewport */) {
|
|
2304
2317
|
this.state = this.lang.streamParser.startState(getIndentUnit(context.state));
|
|
2305
2318
|
context.skipUntilInView(this.parsedPos, context.viewport.from);
|
|
2306
2319
|
this.parsedPos = context.viewport.from;
|
|
@@ -2310,7 +2323,7 @@ class Parse {
|
|
|
2310
2323
|
advance() {
|
|
2311
2324
|
let context = ParseContext.get();
|
|
2312
2325
|
let parseEnd = this.stoppedAt == null ? this.to : Math.min(this.to, this.stoppedAt);
|
|
2313
|
-
let end = Math.min(parseEnd, this.chunkStart + 2048 /* ChunkSize */);
|
|
2326
|
+
let end = Math.min(parseEnd, this.chunkStart + 2048 /* C.ChunkSize */);
|
|
2314
2327
|
if (context)
|
|
2315
2328
|
end = Math.min(end, context.viewport.to);
|
|
2316
2329
|
while (this.parsedPos < end)
|
|
@@ -2394,7 +2407,7 @@ class Parse {
|
|
|
2394
2407
|
let token = readToken(streamParser.token, stream, this.state);
|
|
2395
2408
|
if (token)
|
|
2396
2409
|
offset = this.emitToken(this.lang.tokenTable.resolve(token), this.parsedPos + stream.start, this.parsedPos + stream.pos, 4, offset);
|
|
2397
|
-
if (stream.start > 10000 /* MaxLineLength */)
|
|
2410
|
+
if (stream.start > 10000 /* C.MaxLineLength */)
|
|
2398
2411
|
break;
|
|
2399
2412
|
}
|
|
2400
2413
|
}
|
|
@@ -2410,7 +2423,7 @@ class Parse {
|
|
|
2410
2423
|
length: this.parsedPos - this.chunkStart,
|
|
2411
2424
|
nodeSet,
|
|
2412
2425
|
topID: 0,
|
|
2413
|
-
maxBufferLength: 2048 /* ChunkSize */,
|
|
2426
|
+
maxBufferLength: 2048 /* C.ChunkSize */,
|
|
2414
2427
|
reused: this.chunkReused
|
|
2415
2428
|
});
|
|
2416
2429
|
tree = new Tree(tree.type, tree.children, tree.positions, tree.length, [[this.lang.stateAfter, this.lang.streamParser.copyState(this.state)]]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codemirror/language",
|
|
3
|
-
"version": "6.9.
|
|
3
|
+
"version": "6.9.1",
|
|
4
4
|
"description": "Language support infrastructure for the CodeMirror code editor",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "cm-runtests",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@codemirror/state": "^6.0.0",
|
|
30
30
|
"@codemirror/view": "^6.0.0",
|
|
31
|
-
"@lezer/common": "^1.
|
|
31
|
+
"@lezer/common": "^1.1.0",
|
|
32
32
|
"@lezer/highlight": "^1.0.0",
|
|
33
33
|
"@lezer/lr": "^1.0.0",
|
|
34
34
|
"style-mod": "^4.0.0"
|