@codemirror/language 6.3.2 → 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/LICENSE +1 -1
- package/dist/index.cjs +95 -23
- package/dist/index.d.ts +22 -6
- package/dist/index.js +94 -24
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
## 6.5.0 (2023-02-07)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Make indentation for stream languages more reliable by having `StringStream.indentation` return overridden indentations from the indent context.
|
|
6
|
+
|
|
7
|
+
### New features
|
|
8
|
+
|
|
9
|
+
The `toggleFold` command folds or unfolds depending on whether there's an existing folded range on the current line.
|
|
10
|
+
|
|
11
|
+
`indentUnit` now accepts any (repeated) whitespace character, not just spaces and tabs.
|
|
12
|
+
|
|
13
|
+
## 6.4.0 (2023-01-12)
|
|
14
|
+
|
|
15
|
+
### New features
|
|
16
|
+
|
|
17
|
+
The `bracketMatchingHandle` node prop can now be used to limit bracket matching behavior for larger nodes to a single subnode (for example the tag name of an HTML tag).
|
|
18
|
+
|
|
1
19
|
## 6.3.2 (2022-12-16)
|
|
2
20
|
|
|
3
21
|
### Bug fixes
|
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (C) 2018-2021 by Marijn Haverbeke <
|
|
3
|
+
Copyright (C) 2018-2021 by Marijn Haverbeke <marijn@haverbeke.berlin> and others
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/dist/index.cjs
CHANGED
|
@@ -229,13 +229,13 @@ function syntaxParserRunning(view) {
|
|
|
229
229
|
}
|
|
230
230
|
// Lezer-style Input object for a Text document.
|
|
231
231
|
class DocInput {
|
|
232
|
-
constructor(doc
|
|
232
|
+
constructor(doc) {
|
|
233
233
|
this.doc = doc;
|
|
234
|
-
this.length = length;
|
|
235
234
|
this.cursorPos = 0;
|
|
236
235
|
this.string = "";
|
|
237
236
|
this.cursor = doc.iter();
|
|
238
237
|
}
|
|
238
|
+
get length() { return this.doc.length; }
|
|
239
239
|
syncTo(pos) {
|
|
240
240
|
this.string = this.cursor.next(pos - this.cursorPos).value;
|
|
241
241
|
this.cursorPos = pos + this.string.length;
|
|
@@ -780,17 +780,18 @@ service.
|
|
|
780
780
|
*/
|
|
781
781
|
const indentService = state.Facet.define();
|
|
782
782
|
/**
|
|
783
|
-
Facet for overriding the unit by which indentation happens.
|
|
784
|
-
|
|
785
|
-
|
|
783
|
+
Facet for overriding the unit by which indentation happens. Should
|
|
784
|
+
be a string consisting either entirely of the same whitespace
|
|
785
|
+
character. When not set, this defaults to 2 spaces.
|
|
786
786
|
*/
|
|
787
787
|
const indentUnit = state.Facet.define({
|
|
788
788
|
combine: values => {
|
|
789
789
|
if (!values.length)
|
|
790
790
|
return " ";
|
|
791
|
-
|
|
791
|
+
let unit = values[0];
|
|
792
|
+
if (!unit || /\S/.test(unit) || Array.from(unit).some(e => e != unit[0]))
|
|
792
793
|
throw new Error("Invalid indent unit: " + JSON.stringify(values[0]));
|
|
793
|
-
return
|
|
794
|
+
return unit;
|
|
794
795
|
}
|
|
795
796
|
});
|
|
796
797
|
/**
|
|
@@ -810,14 +811,16 @@ Will use tabs for as much of the columns as possible when the
|
|
|
810
811
|
tabs.
|
|
811
812
|
*/
|
|
812
813
|
function indentString(state, cols) {
|
|
813
|
-
let result = "", ts = state.tabSize;
|
|
814
|
-
if (
|
|
814
|
+
let result = "", ts = state.tabSize, ch = state.facet(indentUnit)[0];
|
|
815
|
+
if (ch == "\t") {
|
|
815
816
|
while (cols >= ts) {
|
|
816
817
|
result += "\t";
|
|
817
818
|
cols -= ts;
|
|
818
819
|
}
|
|
820
|
+
ch = " ";
|
|
821
|
+
}
|
|
819
822
|
for (let i = 0; i < cols; i++)
|
|
820
|
-
result +=
|
|
823
|
+
result += ch;
|
|
821
824
|
return result;
|
|
822
825
|
}
|
|
823
826
|
/**
|
|
@@ -1400,6 +1403,41 @@ const unfoldAll = view => {
|
|
|
1400
1403
|
view.dispatch({ effects });
|
|
1401
1404
|
return true;
|
|
1402
1405
|
};
|
|
1406
|
+
// Find the foldable region containing the given line, if one exists
|
|
1407
|
+
function foldableContainer(view, lineBlock) {
|
|
1408
|
+
// Look backwards through line blocks until we find a foldable region that
|
|
1409
|
+
// intersects with the line
|
|
1410
|
+
for (let line = lineBlock;;) {
|
|
1411
|
+
let foldableRegion = foldable(view.state, line.from, line.to);
|
|
1412
|
+
if (foldableRegion && foldableRegion.to > lineBlock.from)
|
|
1413
|
+
return foldableRegion;
|
|
1414
|
+
if (!line.from)
|
|
1415
|
+
return null;
|
|
1416
|
+
line = view.lineBlockAt(line.from - 1);
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1419
|
+
/**
|
|
1420
|
+
Toggle folding at cursors. Unfolds if there is an existing fold
|
|
1421
|
+
starting in that line, tries to find a foldable range around it
|
|
1422
|
+
otherwise.
|
|
1423
|
+
*/
|
|
1424
|
+
const toggleFold = (view) => {
|
|
1425
|
+
let effects = [];
|
|
1426
|
+
for (let line of selectedLines(view)) {
|
|
1427
|
+
let folded = findFold(view.state, line.from, line.to);
|
|
1428
|
+
if (folded) {
|
|
1429
|
+
effects.push(unfoldEffect.of(folded), announceFold(view, folded, false));
|
|
1430
|
+
}
|
|
1431
|
+
else {
|
|
1432
|
+
let foldRange = foldableContainer(view, line);
|
|
1433
|
+
if (foldRange)
|
|
1434
|
+
effects.push(foldEffect.of(foldRange), announceFold(view, foldRange));
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
if (effects.length > 0)
|
|
1438
|
+
view.dispatch({ effects: maybeEnable(view.state, effects) });
|
|
1439
|
+
return !!effects.length;
|
|
1440
|
+
};
|
|
1403
1441
|
/**
|
|
1404
1442
|
Default fold-related key bindings.
|
|
1405
1443
|
|
|
@@ -1787,6 +1825,15 @@ highlighting style is used to indicate this.
|
|
|
1787
1825
|
function bracketMatching(config = {}) {
|
|
1788
1826
|
return [bracketMatchingConfig.of(config), bracketMatchingUnique];
|
|
1789
1827
|
}
|
|
1828
|
+
/**
|
|
1829
|
+
When larger syntax nodes, such as HTML tags, are marked as
|
|
1830
|
+
opening/closing, it can be a bit messy to treat the whole node as
|
|
1831
|
+
a matchable bracket. This node prop allows you to define, for such
|
|
1832
|
+
a node, a ‘handle’—the part of the node that is highlighted, and
|
|
1833
|
+
that the cursor must be on to activate highlighting in the first
|
|
1834
|
+
place.
|
|
1835
|
+
*/
|
|
1836
|
+
const bracketMatchingHandle = new common.NodeProp();
|
|
1790
1837
|
function matchingNodes(node, dir, brackets) {
|
|
1791
1838
|
let byProp = node.prop(dir < 0 ? common.NodeProp.openedBy : common.NodeProp.closedBy);
|
|
1792
1839
|
if (byProp)
|
|
@@ -1798,6 +1845,10 @@ function matchingNodes(node, dir, brackets) {
|
|
|
1798
1845
|
}
|
|
1799
1846
|
return null;
|
|
1800
1847
|
}
|
|
1848
|
+
function findHandle(node) {
|
|
1849
|
+
let hasHandle = node.type.prop(bracketMatchingHandle);
|
|
1850
|
+
return hasHandle ? hasHandle(node.node) : node;
|
|
1851
|
+
}
|
|
1801
1852
|
/**
|
|
1802
1853
|
Find the matching bracket for the token at `pos`, scanning
|
|
1803
1854
|
direction `dir`. Only the `brackets` and `maxScanDistance`
|
|
@@ -1809,30 +1860,36 @@ function matchBrackets(state, pos, dir, config = {}) {
|
|
|
1809
1860
|
let tree = syntaxTree(state), node = tree.resolveInner(pos, dir);
|
|
1810
1861
|
for (let cur = node; cur; cur = cur.parent) {
|
|
1811
1862
|
let matches = matchingNodes(cur.type, dir, brackets);
|
|
1812
|
-
if (matches && cur.from < cur.to)
|
|
1813
|
-
|
|
1863
|
+
if (matches && cur.from < cur.to) {
|
|
1864
|
+
let handle = findHandle(cur);
|
|
1865
|
+
if (handle && (dir > 0 ? pos >= handle.from && pos < handle.to : pos > handle.from && pos <= handle.to))
|
|
1866
|
+
return matchMarkedBrackets(state, pos, dir, cur, handle, matches, brackets);
|
|
1867
|
+
}
|
|
1814
1868
|
}
|
|
1815
1869
|
return matchPlainBrackets(state, pos, dir, tree, node.type, maxScanDistance, brackets);
|
|
1816
1870
|
}
|
|
1817
|
-
function matchMarkedBrackets(_state, _pos, dir, token, matching, brackets) {
|
|
1818
|
-
let parent = token.parent, firstToken = { from:
|
|
1871
|
+
function matchMarkedBrackets(_state, _pos, dir, token, handle, matching, brackets) {
|
|
1872
|
+
let parent = token.parent, firstToken = { from: handle.from, to: handle.to };
|
|
1819
1873
|
let depth = 0, cursor = parent === null || parent === void 0 ? void 0 : parent.cursor();
|
|
1820
1874
|
if (cursor && (dir < 0 ? cursor.childBefore(token.from) : cursor.childAfter(token.to)))
|
|
1821
1875
|
do {
|
|
1822
1876
|
if (dir < 0 ? cursor.to <= token.from : cursor.from >= token.to) {
|
|
1823
1877
|
if (depth == 0 && matching.indexOf(cursor.type.name) > -1 && cursor.from < cursor.to) {
|
|
1824
|
-
|
|
1878
|
+
let endHandle = findHandle(cursor);
|
|
1879
|
+
return { start: firstToken, end: endHandle ? { from: endHandle.from, to: endHandle.to } : undefined, matched: true };
|
|
1825
1880
|
}
|
|
1826
1881
|
else if (matchingNodes(cursor.type, dir, brackets)) {
|
|
1827
1882
|
depth++;
|
|
1828
1883
|
}
|
|
1829
1884
|
else if (matchingNodes(cursor.type, -dir, brackets)) {
|
|
1830
|
-
if (depth == 0)
|
|
1885
|
+
if (depth == 0) {
|
|
1886
|
+
let endHandle = findHandle(cursor);
|
|
1831
1887
|
return {
|
|
1832
1888
|
start: firstToken,
|
|
1833
|
-
end:
|
|
1889
|
+
end: endHandle && endHandle.from < endHandle.to ? { from: endHandle.from, to: endHandle.to } : undefined,
|
|
1834
1890
|
matched: false
|
|
1835
1891
|
};
|
|
1892
|
+
}
|
|
1836
1893
|
depth--;
|
|
1837
1894
|
}
|
|
1838
1895
|
}
|
|
@@ -1904,10 +1961,11 @@ class StringStream {
|
|
|
1904
1961
|
/**
|
|
1905
1962
|
The current indent unit size.
|
|
1906
1963
|
*/
|
|
1907
|
-
indentUnit) {
|
|
1964
|
+
indentUnit, overrideIndent) {
|
|
1908
1965
|
this.string = string;
|
|
1909
1966
|
this.tabSize = tabSize;
|
|
1910
1967
|
this.indentUnit = indentUnit;
|
|
1968
|
+
this.overrideIndent = overrideIndent;
|
|
1911
1969
|
/**
|
|
1912
1970
|
The current position on the line.
|
|
1913
1971
|
*/
|
|
@@ -2008,7 +2066,8 @@ class StringStream {
|
|
|
2008
2066
|
Get the indentation column of the current line.
|
|
2009
2067
|
*/
|
|
2010
2068
|
indentation() {
|
|
2011
|
-
|
|
2069
|
+
var _a;
|
|
2070
|
+
return (_a = this.overrideIndent) !== null && _a !== void 0 ? _a : countCol(this.string, null, this.tabSize);
|
|
2012
2071
|
}
|
|
2013
2072
|
/**
|
|
2014
2073
|
Match the input against the given string or regular expression
|
|
@@ -2070,6 +2129,7 @@ function defaultCopyState(state) {
|
|
|
2070
2129
|
}
|
|
2071
2130
|
return newState;
|
|
2072
2131
|
}
|
|
2132
|
+
const IndentedFrom = new WeakMap();
|
|
2073
2133
|
/**
|
|
2074
2134
|
A [language](https://codemirror.net/6/docs/ref/#language.Language) class based on a CodeMirror
|
|
2075
2135
|
5-style [streaming parser](https://codemirror.net/6/docs/ref/#language.StreamParser).
|
|
@@ -2100,7 +2160,14 @@ class StreamLanguage extends Language {
|
|
|
2100
2160
|
at = at.parent;
|
|
2101
2161
|
if (!at)
|
|
2102
2162
|
return null;
|
|
2103
|
-
let
|
|
2163
|
+
let from = undefined;
|
|
2164
|
+
let { overrideIndentation } = cx.options;
|
|
2165
|
+
if (overrideIndentation) {
|
|
2166
|
+
from = IndentedFrom.get(cx.state);
|
|
2167
|
+
if (from != null && from < pos - 1e4)
|
|
2168
|
+
from = undefined;
|
|
2169
|
+
}
|
|
2170
|
+
let start = findState(this, tree, 0, at.from, from !== null && from !== void 0 ? from : pos), statePos, state;
|
|
2104
2171
|
if (start) {
|
|
2105
2172
|
state = start.state;
|
|
2106
2173
|
statePos = start.pos + 1;
|
|
@@ -2114,7 +2181,8 @@ class StreamLanguage extends Language {
|
|
|
2114
2181
|
while (statePos < pos) {
|
|
2115
2182
|
let line = cx.state.doc.lineAt(statePos), end = Math.min(pos, line.to);
|
|
2116
2183
|
if (line.length) {
|
|
2117
|
-
let
|
|
2184
|
+
let indentation = overrideIndentation ? overrideIndentation(line.from) : -1;
|
|
2185
|
+
let stream = new StringStream(line.text, cx.state.tabSize, cx.unit, indentation < 0 ? undefined : indentation);
|
|
2118
2186
|
while (stream.pos < end - line.from)
|
|
2119
2187
|
readToken(this.streamParser.token, stream, state);
|
|
2120
2188
|
}
|
|
@@ -2125,8 +2193,10 @@ class StreamLanguage extends Language {
|
|
|
2125
2193
|
break;
|
|
2126
2194
|
statePos = line.to + 1;
|
|
2127
2195
|
}
|
|
2128
|
-
let
|
|
2129
|
-
|
|
2196
|
+
let line = cx.lineAt(pos);
|
|
2197
|
+
if (overrideIndentation && from == null)
|
|
2198
|
+
IndentedFrom.set(cx.state, line.from);
|
|
2199
|
+
return this.streamParser.indent(state, /^\s*(.*)/.exec(line.text)[1], cx);
|
|
2130
2200
|
}
|
|
2131
2201
|
get allowsNesting() { return false; }
|
|
2132
2202
|
}
|
|
@@ -2404,6 +2474,7 @@ exports.StreamLanguage = StreamLanguage;
|
|
|
2404
2474
|
exports.StringStream = StringStream;
|
|
2405
2475
|
exports.TreeIndentContext = TreeIndentContext;
|
|
2406
2476
|
exports.bracketMatching = bracketMatching;
|
|
2477
|
+
exports.bracketMatchingHandle = bracketMatchingHandle;
|
|
2407
2478
|
exports.codeFolding = codeFolding;
|
|
2408
2479
|
exports.continuedIndent = continuedIndent;
|
|
2409
2480
|
exports.defaultHighlightStyle = defaultHighlightStyle;
|
|
@@ -2439,6 +2510,7 @@ exports.syntaxHighlighting = syntaxHighlighting;
|
|
|
2439
2510
|
exports.syntaxParserRunning = syntaxParserRunning;
|
|
2440
2511
|
exports.syntaxTree = syntaxTree;
|
|
2441
2512
|
exports.syntaxTreeAvailable = syntaxTreeAvailable;
|
|
2513
|
+
exports.toggleFold = toggleFold;
|
|
2442
2514
|
exports.unfoldAll = unfoldAll;
|
|
2443
2515
|
exports.unfoldCode = unfoldCode;
|
|
2444
2516
|
exports.unfoldEffect = unfoldEffect;
|
package/dist/index.d.ts
CHANGED
|
@@ -370,9 +370,9 @@ service.
|
|
|
370
370
|
*/
|
|
371
371
|
declare const indentService: Facet<(context: IndentContext, pos: number) => number | null | undefined, readonly ((context: IndentContext, pos: number) => number | null | undefined)[]>;
|
|
372
372
|
/**
|
|
373
|
-
Facet for overriding the unit by which indentation happens.
|
|
374
|
-
|
|
375
|
-
|
|
373
|
+
Facet for overriding the unit by which indentation happens. Should
|
|
374
|
+
be a string consisting either entirely of the same whitespace
|
|
375
|
+
character. When not set, this defaults to 2 spaces.
|
|
376
376
|
*/
|
|
377
377
|
declare const indentUnit: Facet<string, string>;
|
|
378
378
|
/**
|
|
@@ -450,7 +450,7 @@ declare class IndentContext {
|
|
|
450
450
|
simulateBreak?: number;
|
|
451
451
|
/**
|
|
452
452
|
When `simulateBreak` is given, this can be used to make the
|
|
453
|
-
|
|
453
|
+
simulated break behave like a double line break.
|
|
454
454
|
*/
|
|
455
455
|
simulateDoubleBreak?: boolean;
|
|
456
456
|
});
|
|
@@ -678,6 +678,12 @@ Unfold all folded code.
|
|
|
678
678
|
*/
|
|
679
679
|
declare const unfoldAll: Command;
|
|
680
680
|
/**
|
|
681
|
+
Toggle folding at cursors. Unfolds if there is an existing fold
|
|
682
|
+
starting in that line, tries to find a foldable range around it
|
|
683
|
+
otherwise.
|
|
684
|
+
*/
|
|
685
|
+
declare const toggleFold: Command;
|
|
686
|
+
/**
|
|
681
687
|
Default fold-related key bindings.
|
|
682
688
|
|
|
683
689
|
- Ctrl-Shift-[ (Cmd-Alt-[ on macOS): [`foldCode`](https://codemirror.net/6/docs/ref/#language.foldCode).
|
|
@@ -889,6 +895,15 @@ highlighting style is used to indicate this.
|
|
|
889
895
|
*/
|
|
890
896
|
declare function bracketMatching(config?: Config): Extension;
|
|
891
897
|
/**
|
|
898
|
+
When larger syntax nodes, such as HTML tags, are marked as
|
|
899
|
+
opening/closing, it can be a bit messy to treat the whole node as
|
|
900
|
+
a matchable bracket. This node prop allows you to define, for such
|
|
901
|
+
a node, a ‘handle’—the part of the node that is highlighted, and
|
|
902
|
+
that the cursor must be on to activate highlighting in the first
|
|
903
|
+
place.
|
|
904
|
+
*/
|
|
905
|
+
declare const bracketMatchingHandle: NodeProp<(node: SyntaxNode) => SyntaxNode | null>;
|
|
906
|
+
/**
|
|
892
907
|
The result returned from `matchBrackets`.
|
|
893
908
|
*/
|
|
894
909
|
interface MatchResult {
|
|
@@ -934,6 +949,7 @@ declare class StringStream {
|
|
|
934
949
|
The current indent unit size.
|
|
935
950
|
*/
|
|
936
951
|
indentUnit: number;
|
|
952
|
+
private overrideIndent?;
|
|
937
953
|
/**
|
|
938
954
|
The current position on the line.
|
|
939
955
|
*/
|
|
@@ -955,7 +971,7 @@ declare class StringStream {
|
|
|
955
971
|
/**
|
|
956
972
|
The current indent unit size.
|
|
957
973
|
*/
|
|
958
|
-
indentUnit: number);
|
|
974
|
+
indentUnit: number, overrideIndent?: number | undefined);
|
|
959
975
|
/**
|
|
960
976
|
True if we are at the end of the line.
|
|
961
977
|
*/
|
|
@@ -1103,4 +1119,4 @@ declare class StreamLanguage<State> extends Language {
|
|
|
1103
1119
|
get allowsNesting(): boolean;
|
|
1104
1120
|
}
|
|
1105
1121
|
|
|
1106
|
-
export { Config, HighlightStyle, IndentContext, LRLanguage, Language, LanguageDescription, LanguageSupport, MatchResult, ParseContext, StreamLanguage, StreamParser, StringStream, TagStyle, TreeIndentContext, bracketMatching, codeFolding, continuedIndent, defaultHighlightStyle, defineLanguageFacet, delimitedIndent, ensureSyntaxTree, flatIndent, foldAll, foldCode, foldEffect, foldGutter, foldInside, foldKeymap, foldNodeProp, foldService, foldState, foldable, foldedRanges, forceParsing, getIndentUnit, getIndentation, highlightingFor, indentNodeProp, indentOnInput, indentRange, indentService, indentString, indentUnit, language, languageDataProp, matchBrackets, syntaxHighlighting, syntaxParserRunning, syntaxTree, syntaxTreeAvailable, unfoldAll, unfoldCode, unfoldEffect };
|
|
1122
|
+
export { Config, HighlightStyle, IndentContext, LRLanguage, Language, LanguageDescription, LanguageSupport, MatchResult, ParseContext, StreamLanguage, StreamParser, StringStream, TagStyle, TreeIndentContext, bracketMatching, bracketMatchingHandle, codeFolding, continuedIndent, defaultHighlightStyle, defineLanguageFacet, delimitedIndent, ensureSyntaxTree, flatIndent, foldAll, foldCode, foldEffect, foldGutter, foldInside, foldKeymap, foldNodeProp, foldService, foldState, foldable, foldedRanges, forceParsing, getIndentUnit, getIndentation, highlightingFor, indentNodeProp, indentOnInput, indentRange, indentService, indentString, indentUnit, language, languageDataProp, matchBrackets, syntaxHighlighting, syntaxParserRunning, syntaxTree, syntaxTreeAvailable, toggleFold, unfoldAll, unfoldCode, unfoldEffect };
|
package/dist/index.js
CHANGED
|
@@ -225,13 +225,13 @@ function syntaxParserRunning(view) {
|
|
|
225
225
|
}
|
|
226
226
|
// Lezer-style Input object for a Text document.
|
|
227
227
|
class DocInput {
|
|
228
|
-
constructor(doc
|
|
228
|
+
constructor(doc) {
|
|
229
229
|
this.doc = doc;
|
|
230
|
-
this.length = length;
|
|
231
230
|
this.cursorPos = 0;
|
|
232
231
|
this.string = "";
|
|
233
232
|
this.cursor = doc.iter();
|
|
234
233
|
}
|
|
234
|
+
get length() { return this.doc.length; }
|
|
235
235
|
syncTo(pos) {
|
|
236
236
|
this.string = this.cursor.next(pos - this.cursorPos).value;
|
|
237
237
|
this.cursorPos = pos + this.string.length;
|
|
@@ -776,17 +776,18 @@ service.
|
|
|
776
776
|
*/
|
|
777
777
|
const indentService = /*@__PURE__*/Facet.define();
|
|
778
778
|
/**
|
|
779
|
-
Facet for overriding the unit by which indentation happens.
|
|
780
|
-
|
|
781
|
-
|
|
779
|
+
Facet for overriding the unit by which indentation happens. Should
|
|
780
|
+
be a string consisting either entirely of the same whitespace
|
|
781
|
+
character. When not set, this defaults to 2 spaces.
|
|
782
782
|
*/
|
|
783
783
|
const indentUnit = /*@__PURE__*/Facet.define({
|
|
784
784
|
combine: values => {
|
|
785
785
|
if (!values.length)
|
|
786
786
|
return " ";
|
|
787
|
-
|
|
787
|
+
let unit = values[0];
|
|
788
|
+
if (!unit || /\S/.test(unit) || Array.from(unit).some(e => e != unit[0]))
|
|
788
789
|
throw new Error("Invalid indent unit: " + JSON.stringify(values[0]));
|
|
789
|
-
return
|
|
790
|
+
return unit;
|
|
790
791
|
}
|
|
791
792
|
});
|
|
792
793
|
/**
|
|
@@ -806,14 +807,16 @@ Will use tabs for as much of the columns as possible when the
|
|
|
806
807
|
tabs.
|
|
807
808
|
*/
|
|
808
809
|
function indentString(state, cols) {
|
|
809
|
-
let result = "", ts = state.tabSize;
|
|
810
|
-
if (
|
|
810
|
+
let result = "", ts = state.tabSize, ch = state.facet(indentUnit)[0];
|
|
811
|
+
if (ch == "\t") {
|
|
811
812
|
while (cols >= ts) {
|
|
812
813
|
result += "\t";
|
|
813
814
|
cols -= ts;
|
|
814
815
|
}
|
|
816
|
+
ch = " ";
|
|
817
|
+
}
|
|
815
818
|
for (let i = 0; i < cols; i++)
|
|
816
|
-
result +=
|
|
819
|
+
result += ch;
|
|
817
820
|
return result;
|
|
818
821
|
}
|
|
819
822
|
/**
|
|
@@ -1396,6 +1399,41 @@ const unfoldAll = view => {
|
|
|
1396
1399
|
view.dispatch({ effects });
|
|
1397
1400
|
return true;
|
|
1398
1401
|
};
|
|
1402
|
+
// Find the foldable region containing the given line, if one exists
|
|
1403
|
+
function foldableContainer(view, lineBlock) {
|
|
1404
|
+
// Look backwards through line blocks until we find a foldable region that
|
|
1405
|
+
// intersects with the line
|
|
1406
|
+
for (let line = lineBlock;;) {
|
|
1407
|
+
let foldableRegion = foldable(view.state, line.from, line.to);
|
|
1408
|
+
if (foldableRegion && foldableRegion.to > lineBlock.from)
|
|
1409
|
+
return foldableRegion;
|
|
1410
|
+
if (!line.from)
|
|
1411
|
+
return null;
|
|
1412
|
+
line = view.lineBlockAt(line.from - 1);
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
/**
|
|
1416
|
+
Toggle folding at cursors. Unfolds if there is an existing fold
|
|
1417
|
+
starting in that line, tries to find a foldable range around it
|
|
1418
|
+
otherwise.
|
|
1419
|
+
*/
|
|
1420
|
+
const toggleFold = (view) => {
|
|
1421
|
+
let effects = [];
|
|
1422
|
+
for (let line of selectedLines(view)) {
|
|
1423
|
+
let folded = findFold(view.state, line.from, line.to);
|
|
1424
|
+
if (folded) {
|
|
1425
|
+
effects.push(unfoldEffect.of(folded), announceFold(view, folded, false));
|
|
1426
|
+
}
|
|
1427
|
+
else {
|
|
1428
|
+
let foldRange = foldableContainer(view, line);
|
|
1429
|
+
if (foldRange)
|
|
1430
|
+
effects.push(foldEffect.of(foldRange), announceFold(view, foldRange));
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
if (effects.length > 0)
|
|
1434
|
+
view.dispatch({ effects: maybeEnable(view.state, effects) });
|
|
1435
|
+
return !!effects.length;
|
|
1436
|
+
};
|
|
1399
1437
|
/**
|
|
1400
1438
|
Default fold-related key bindings.
|
|
1401
1439
|
|
|
@@ -1783,6 +1821,15 @@ highlighting style is used to indicate this.
|
|
|
1783
1821
|
function bracketMatching(config = {}) {
|
|
1784
1822
|
return [bracketMatchingConfig.of(config), bracketMatchingUnique];
|
|
1785
1823
|
}
|
|
1824
|
+
/**
|
|
1825
|
+
When larger syntax nodes, such as HTML tags, are marked as
|
|
1826
|
+
opening/closing, it can be a bit messy to treat the whole node as
|
|
1827
|
+
a matchable bracket. This node prop allows you to define, for such
|
|
1828
|
+
a node, a ‘handle’—the part of the node that is highlighted, and
|
|
1829
|
+
that the cursor must be on to activate highlighting in the first
|
|
1830
|
+
place.
|
|
1831
|
+
*/
|
|
1832
|
+
const bracketMatchingHandle = /*@__PURE__*/new NodeProp();
|
|
1786
1833
|
function matchingNodes(node, dir, brackets) {
|
|
1787
1834
|
let byProp = node.prop(dir < 0 ? NodeProp.openedBy : NodeProp.closedBy);
|
|
1788
1835
|
if (byProp)
|
|
@@ -1794,6 +1841,10 @@ function matchingNodes(node, dir, brackets) {
|
|
|
1794
1841
|
}
|
|
1795
1842
|
return null;
|
|
1796
1843
|
}
|
|
1844
|
+
function findHandle(node) {
|
|
1845
|
+
let hasHandle = node.type.prop(bracketMatchingHandle);
|
|
1846
|
+
return hasHandle ? hasHandle(node.node) : node;
|
|
1847
|
+
}
|
|
1797
1848
|
/**
|
|
1798
1849
|
Find the matching bracket for the token at `pos`, scanning
|
|
1799
1850
|
direction `dir`. Only the `brackets` and `maxScanDistance`
|
|
@@ -1805,30 +1856,36 @@ function matchBrackets(state, pos, dir, config = {}) {
|
|
|
1805
1856
|
let tree = syntaxTree(state), node = tree.resolveInner(pos, dir);
|
|
1806
1857
|
for (let cur = node; cur; cur = cur.parent) {
|
|
1807
1858
|
let matches = matchingNodes(cur.type, dir, brackets);
|
|
1808
|
-
if (matches && cur.from < cur.to)
|
|
1809
|
-
|
|
1859
|
+
if (matches && cur.from < cur.to) {
|
|
1860
|
+
let handle = findHandle(cur);
|
|
1861
|
+
if (handle && (dir > 0 ? pos >= handle.from && pos < handle.to : pos > handle.from && pos <= handle.to))
|
|
1862
|
+
return matchMarkedBrackets(state, pos, dir, cur, handle, matches, brackets);
|
|
1863
|
+
}
|
|
1810
1864
|
}
|
|
1811
1865
|
return matchPlainBrackets(state, pos, dir, tree, node.type, maxScanDistance, brackets);
|
|
1812
1866
|
}
|
|
1813
|
-
function matchMarkedBrackets(_state, _pos, dir, token, matching, brackets) {
|
|
1814
|
-
let parent = token.parent, firstToken = { from:
|
|
1867
|
+
function matchMarkedBrackets(_state, _pos, dir, token, handle, matching, brackets) {
|
|
1868
|
+
let parent = token.parent, firstToken = { from: handle.from, to: handle.to };
|
|
1815
1869
|
let depth = 0, cursor = parent === null || parent === void 0 ? void 0 : parent.cursor();
|
|
1816
1870
|
if (cursor && (dir < 0 ? cursor.childBefore(token.from) : cursor.childAfter(token.to)))
|
|
1817
1871
|
do {
|
|
1818
1872
|
if (dir < 0 ? cursor.to <= token.from : cursor.from >= token.to) {
|
|
1819
1873
|
if (depth == 0 && matching.indexOf(cursor.type.name) > -1 && cursor.from < cursor.to) {
|
|
1820
|
-
|
|
1874
|
+
let endHandle = findHandle(cursor);
|
|
1875
|
+
return { start: firstToken, end: endHandle ? { from: endHandle.from, to: endHandle.to } : undefined, matched: true };
|
|
1821
1876
|
}
|
|
1822
1877
|
else if (matchingNodes(cursor.type, dir, brackets)) {
|
|
1823
1878
|
depth++;
|
|
1824
1879
|
}
|
|
1825
1880
|
else if (matchingNodes(cursor.type, -dir, brackets)) {
|
|
1826
|
-
if (depth == 0)
|
|
1881
|
+
if (depth == 0) {
|
|
1882
|
+
let endHandle = findHandle(cursor);
|
|
1827
1883
|
return {
|
|
1828
1884
|
start: firstToken,
|
|
1829
|
-
end:
|
|
1885
|
+
end: endHandle && endHandle.from < endHandle.to ? { from: endHandle.from, to: endHandle.to } : undefined,
|
|
1830
1886
|
matched: false
|
|
1831
1887
|
};
|
|
1888
|
+
}
|
|
1832
1889
|
depth--;
|
|
1833
1890
|
}
|
|
1834
1891
|
}
|
|
@@ -1900,10 +1957,11 @@ class StringStream {
|
|
|
1900
1957
|
/**
|
|
1901
1958
|
The current indent unit size.
|
|
1902
1959
|
*/
|
|
1903
|
-
indentUnit) {
|
|
1960
|
+
indentUnit, overrideIndent) {
|
|
1904
1961
|
this.string = string;
|
|
1905
1962
|
this.tabSize = tabSize;
|
|
1906
1963
|
this.indentUnit = indentUnit;
|
|
1964
|
+
this.overrideIndent = overrideIndent;
|
|
1907
1965
|
/**
|
|
1908
1966
|
The current position on the line.
|
|
1909
1967
|
*/
|
|
@@ -2004,7 +2062,8 @@ class StringStream {
|
|
|
2004
2062
|
Get the indentation column of the current line.
|
|
2005
2063
|
*/
|
|
2006
2064
|
indentation() {
|
|
2007
|
-
|
|
2065
|
+
var _a;
|
|
2066
|
+
return (_a = this.overrideIndent) !== null && _a !== void 0 ? _a : countCol(this.string, null, this.tabSize);
|
|
2008
2067
|
}
|
|
2009
2068
|
/**
|
|
2010
2069
|
Match the input against the given string or regular expression
|
|
@@ -2066,6 +2125,7 @@ function defaultCopyState(state) {
|
|
|
2066
2125
|
}
|
|
2067
2126
|
return newState;
|
|
2068
2127
|
}
|
|
2128
|
+
const IndentedFrom = /*@__PURE__*/new WeakMap();
|
|
2069
2129
|
/**
|
|
2070
2130
|
A [language](https://codemirror.net/6/docs/ref/#language.Language) class based on a CodeMirror
|
|
2071
2131
|
5-style [streaming parser](https://codemirror.net/6/docs/ref/#language.StreamParser).
|
|
@@ -2096,7 +2156,14 @@ class StreamLanguage extends Language {
|
|
|
2096
2156
|
at = at.parent;
|
|
2097
2157
|
if (!at)
|
|
2098
2158
|
return null;
|
|
2099
|
-
let
|
|
2159
|
+
let from = undefined;
|
|
2160
|
+
let { overrideIndentation } = cx.options;
|
|
2161
|
+
if (overrideIndentation) {
|
|
2162
|
+
from = IndentedFrom.get(cx.state);
|
|
2163
|
+
if (from != null && from < pos - 1e4)
|
|
2164
|
+
from = undefined;
|
|
2165
|
+
}
|
|
2166
|
+
let start = findState(this, tree, 0, at.from, from !== null && from !== void 0 ? from : pos), statePos, state;
|
|
2100
2167
|
if (start) {
|
|
2101
2168
|
state = start.state;
|
|
2102
2169
|
statePos = start.pos + 1;
|
|
@@ -2110,7 +2177,8 @@ class StreamLanguage extends Language {
|
|
|
2110
2177
|
while (statePos < pos) {
|
|
2111
2178
|
let line = cx.state.doc.lineAt(statePos), end = Math.min(pos, line.to);
|
|
2112
2179
|
if (line.length) {
|
|
2113
|
-
let
|
|
2180
|
+
let indentation = overrideIndentation ? overrideIndentation(line.from) : -1;
|
|
2181
|
+
let stream = new StringStream(line.text, cx.state.tabSize, cx.unit, indentation < 0 ? undefined : indentation);
|
|
2114
2182
|
while (stream.pos < end - line.from)
|
|
2115
2183
|
readToken(this.streamParser.token, stream, state);
|
|
2116
2184
|
}
|
|
@@ -2121,8 +2189,10 @@ class StreamLanguage extends Language {
|
|
|
2121
2189
|
break;
|
|
2122
2190
|
statePos = line.to + 1;
|
|
2123
2191
|
}
|
|
2124
|
-
let
|
|
2125
|
-
|
|
2192
|
+
let line = cx.lineAt(pos);
|
|
2193
|
+
if (overrideIndentation && from == null)
|
|
2194
|
+
IndentedFrom.set(cx.state, line.from);
|
|
2195
|
+
return this.streamParser.indent(state, /^\s*(.*)/.exec(line.text)[1], cx);
|
|
2126
2196
|
}
|
|
2127
2197
|
get allowsNesting() { return false; }
|
|
2128
2198
|
}
|
|
@@ -2389,4 +2459,4 @@ function docID(data) {
|
|
|
2389
2459
|
return type;
|
|
2390
2460
|
}
|
|
2391
2461
|
|
|
2392
|
-
export { HighlightStyle, IndentContext, LRLanguage, Language, LanguageDescription, LanguageSupport, ParseContext, StreamLanguage, StringStream, TreeIndentContext, bracketMatching, codeFolding, continuedIndent, defaultHighlightStyle, defineLanguageFacet, delimitedIndent, ensureSyntaxTree, flatIndent, foldAll, foldCode, foldEffect, foldGutter, foldInside, foldKeymap, foldNodeProp, foldService, foldState, foldable, foldedRanges, forceParsing, getIndentUnit, getIndentation, highlightingFor, indentNodeProp, indentOnInput, indentRange, indentService, indentString, indentUnit, language, languageDataProp, matchBrackets, syntaxHighlighting, syntaxParserRunning, syntaxTree, syntaxTreeAvailable, unfoldAll, unfoldCode, unfoldEffect };
|
|
2462
|
+
export { HighlightStyle, IndentContext, LRLanguage, Language, LanguageDescription, LanguageSupport, ParseContext, StreamLanguage, StringStream, TreeIndentContext, bracketMatching, bracketMatchingHandle, codeFolding, continuedIndent, defaultHighlightStyle, defineLanguageFacet, delimitedIndent, ensureSyntaxTree, flatIndent, foldAll, foldCode, foldEffect, foldGutter, foldInside, foldKeymap, foldNodeProp, foldService, foldState, foldable, foldedRanges, forceParsing, getIndentUnit, getIndentation, highlightingFor, indentNodeProp, indentOnInput, indentRange, indentService, indentString, indentUnit, language, languageDataProp, matchBrackets, syntaxHighlighting, syntaxParserRunning, syntaxTree, syntaxTreeAvailable, toggleFold, unfoldAll, unfoldCode, unfoldEffect };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codemirror/language",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.5.0",
|
|
4
4
|
"description": "Language support infrastructure for the CodeMirror code editor",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "cm-runtests",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
],
|
|
13
13
|
"author": {
|
|
14
14
|
"name": "Marijn Haverbeke",
|
|
15
|
-
"email": "
|
|
15
|
+
"email": "marijn@haverbeke.berlin",
|
|
16
16
|
"url": "http://marijnhaverbeke.nl"
|
|
17
17
|
},
|
|
18
18
|
"type": "module",
|