@uiw/react-codemirror 4.21.19 → 4.21.21

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/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  # react-codemirror
8
8
 
9
- [![jsdelivr CDN](https://data.jsdelivr.com/v1/package/npm/@uiw/react-codemirror/badge)](https://www.jsdelivr.com/package/npm/@uiw/react-codemirror)
9
+ [![Buy me a coffee](https://img.shields.io/badge/Buy%20me%20a%20coffee-048754?logo=buymeacoffee)](https://jaywcjlove.github.io/#/sponsor)
10
10
  [![NPM Downloads](https://img.shields.io/npm/dm/@uiw/react-codemirror.svg?style=flat)](https://www.npmjs.com/package/@uiw/react-codemirror)
11
11
  [![Build & Deploy](https://github.com/uiwjs/react-codemirror/actions/workflows/ci.yml/badge.svg)](https://github.com/uiwjs/react-codemirror/actions)
12
12
  [![Open in unpkg](https://img.shields.io/badge/Open%20in-unpkg-blue)](https://uiwjs.github.io/npm-unpkg/#/pkg/@uiw/react-codemirror/file/README.md)
@@ -53,8 +53,8 @@ npm install @uiw/react-codemirror --save
53
53
  | [`@uiw/codemirror-extensions-zebra-stripes`](https://uiwjs.github.io/react-codemirror/#/extensions/zebra-stripes) | [![npm version](https://img.shields.io/npm/v/@uiw/codemirror-extensions-zebra-stripes.svg)](https://www.npmjs.com/package/@uiw/codemirror-extensions-zebra-stripes) [![NPM Downloads](https://img.shields.io/npm/dm/@uiw/codemirror-extensions-zebra-stripes.svg?style=flat)](https://www.npmjs.com/package/@uiw/codemirror-extensions-zebra-stripes) |
54
54
  | [`@uiw/codemirror-themes`](https://uiwjs.github.io/react-codemirror/#/theme/doc) | [![npm version](https://img.shields.io/npm/v/@uiw/codemirror-themes.svg)](https://www.npmjs.com/package/@uiw/codemirror-themes) [![NPM Downloads](https://img.shields.io/npm/dm/@uiw/codemirror-themes.svg?style=flat)](https://www.npmjs.com/package/@uiw/codemirror-themes) |
55
55
 
56
- | Name | NPM Version | Website |
57
- | :----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
56
+ | Name | NPM Version |
57
+ | :----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
58
58
  | [`@uiw/codemirror-themes-all`](https://uiwjs.github.io/react-codemirror/#/theme/all) | [![npm version](https://img.shields.io/npm/v/@uiw/codemirror-themes-all.svg)](https://www.npmjs.com/package/@uiw/codemirror-themes-all) [![NPM Downloads](https://img.shields.io/npm/dm/@uiw/codemirror-themes-all.svg?style=flat)](https://www.npmjs.com/package/@uiw/codemirror-themes-all) |
59
59
  | [`@uiw/codemirror-theme-abcdef`](https://uiwjs.github.io/react-codemirror/#/theme/data/abcdef) | [![npm version](https://img.shields.io/npm/v/@uiw/codemirror-theme-abcdef.svg)](https://www.npmjs.com/package/@uiw/codemirror-theme-abcdef) [![NPM Downloads](https://img.shields.io/npm/dm/@uiw/codemirror-theme-abcdef.svg?style=flat)](https://www.npmjs.com/package/@uiw/codemirror-theme-abcdef) |
60
60
  | [`@uiw/codemirror-theme-abyss`](https://uiwjs.github.io/react-codemirror/#/theme/data/abyss) | [![npm version](https://img.shields.io/npm/v/@uiw/codemirror-theme-abyss.svg)](https://www.npmjs.com/package/@uiw/codemirror-theme-abyss) [![NPM Downloads](https://img.shields.io/npm/dm/@uiw/codemirror-theme-abyss.svg?style=flat)](https://www.npmjs.com/package/@uiw/codemirror-theme-abyss) |
@@ -538,7 +538,31 @@ export interface Statistics {
538
538
  export declare const getStatistics: (view: ViewUpdate) => Statistics;
539
539
  ```
540
540
 
541
- ### Related
541
+ ## Development
542
+
543
+ 1. Install dependencies
544
+
545
+ ```bash
546
+ $ npm install # Installation dependencies
547
+ $ npm run build # Compile all package
548
+ ```
549
+
550
+ 2. Development `@uiw/react-codemirror` package:
551
+
552
+ ```bash
553
+ $ cd core
554
+ # listen to the component compile and output the .js file
555
+ # listen for compilation output type .d.ts file
556
+ $ npm run watch # Monitor the compiled package `@uiw/react-codemirror`
557
+ ```
558
+
559
+ 3. Launch documentation site
560
+
561
+ ```bash
562
+ npm run start
563
+ ```
564
+
565
+ ## Related
542
566
 
543
567
  - [@uiw/react-textarea-code-editor](https://github.com/uiwjs/react-textarea-code-editor): A simple code editor with syntax highlighting.
544
568
  - [@uiw/react-md-editor](https://github.com/uiwjs/react-md-editor): A simple markdown editor with preview, implemented with React.js and TypeScript.
@@ -555,7 +579,7 @@ As always, thanks to our amazing contributors!
555
579
  <img src="https://uiwjs.github.io/react-codemirror/CONTRIBUTORS.svg" />
556
580
  </a>
557
581
 
558
- Made with [github-action-contributors](https://github.com/jaywcjlove/github-action-contributors).
582
+ Made with [contributors](https://github.com/jaywcjlove/github-action-contributors).
559
583
 
560
584
  ## License
561
585
 
@@ -1623,7 +1623,8 @@ const completionConfig = /*@__PURE__*/state_.Facet.define({
1623
1623
  addToOptions: [],
1624
1624
  positionInfo: defaultPositionInfo,
1625
1625
  compareCompletions: (a, b) => a.label.localeCompare(b.label),
1626
- interactionDelay: 75
1626
+ interactionDelay: 75,
1627
+ updateSyncTime: 100
1627
1628
  }, {
1628
1629
  defaultKeymap: (a, b) => a && b,
1629
1630
  closeOnBlur: (a, b) => a && b,
@@ -1685,7 +1686,7 @@ function optionContent(config) {
1685
1686
  position: 20
1686
1687
  });
1687
1688
  content.push({
1688
- render(completion, _s, match) {
1689
+ render(completion, _s, _v, match) {
1689
1690
  let labelElt = document.createElement("span");
1690
1691
  labelElt.className = "cm-completionLabel";
1691
1692
  let label = completion.displayLabel || completion.label, off = 0;
@@ -1753,6 +1754,7 @@ class CompletionTooltip {
1753
1754
  this.dom.className = "cm-tooltip-autocomplete";
1754
1755
  this.updateTooltipClass(view.state);
1755
1756
  this.dom.addEventListener("mousedown", (e) => {
1757
+ let { options } = view.state.field(stateField).open;
1756
1758
  for (let dom = e.target, match; dom && dom != this.dom; dom = dom.parentNode) {
1757
1759
  if (dom.nodeName == "LI" && (match = /-(\d+)$/.exec(dom.id)) && +match[1] < options.length) {
1758
1760
  this.applyCompletion(view, options[+match[1]]);
@@ -1767,22 +1769,32 @@ class CompletionTooltip {
1767
1769
  e.relatedTarget != view.contentDOM)
1768
1770
  view.dispatch({ effects: closeCompletionEffect.of(null) });
1769
1771
  });
1770
- this.list = this.dom.appendChild(this.createListBox(options, cState.id, this.range));
1772
+ this.showOptions(options, cState.id);
1773
+ }
1774
+ mount() { this.updateSel(); }
1775
+ showOptions(options, id) {
1776
+ if (this.list)
1777
+ this.list.remove();
1778
+ this.list = this.dom.appendChild(this.createListBox(options, id, this.range));
1771
1779
  this.list.addEventListener("scroll", () => {
1772
1780
  if (this.info)
1773
1781
  this.view.requestMeasure(this.placeInfoReq);
1774
1782
  });
1775
1783
  }
1776
- mount() { this.updateSel(); }
1777
1784
  update(update) {
1778
- var _a, _b, _c;
1785
+ var _a;
1779
1786
  let cState = update.state.field(this.stateField);
1780
1787
  let prevState = update.startState.field(this.stateField);
1781
1788
  this.updateTooltipClass(update.state);
1782
1789
  if (cState != prevState) {
1790
+ let { options, selected, disabled } = cState.open;
1791
+ if (!prevState.open || prevState.open.options != options) {
1792
+ this.range = rangeAroundSelected(options.length, selected, update.state.facet(completionConfig).maxRenderedOptions);
1793
+ this.showOptions(options, cState.id);
1794
+ }
1783
1795
  this.updateSel();
1784
- if (((_a = cState.open) === null || _a === void 0 ? void 0 : _a.disabled) != ((_b = prevState.open) === null || _b === void 0 ? void 0 : _b.disabled))
1785
- this.dom.classList.toggle("cm-tooltip-autocomplete-disabled", !!((_c = cState.open) === null || _c === void 0 ? void 0 : _c.disabled));
1796
+ if (disabled != ((_a = prevState.open) === null || _a === void 0 ? void 0 : _a.disabled))
1797
+ this.dom.classList.toggle("cm-tooltip-autocomplete-disabled", !!disabled);
1786
1798
  }
1787
1799
  }
1788
1800
  updateTooltipClass(state) {
@@ -1806,12 +1818,7 @@ class CompletionTooltip {
1806
1818
  let cState = this.view.state.field(this.stateField), open = cState.open;
1807
1819
  if (open.selected > -1 && open.selected < this.range.from || open.selected >= this.range.to) {
1808
1820
  this.range = rangeAroundSelected(open.options.length, open.selected, this.view.state.facet(completionConfig).maxRenderedOptions);
1809
- this.list.remove();
1810
- this.list = this.dom.appendChild(this.createListBox(open.options, cState.id, this.range));
1811
- this.list.addEventListener("scroll", () => {
1812
- if (this.info)
1813
- this.view.requestMeasure(this.placeInfoReq);
1814
- });
1821
+ this.showOptions(open.options, cState.id);
1815
1822
  }
1816
1823
  if (this.updateSelectedOption(open.selected)) {
1817
1824
  this.destroyInfo();
@@ -1928,7 +1935,7 @@ class CompletionTooltip {
1928
1935
  if (cls)
1929
1936
  li.className = cls;
1930
1937
  for (let source of this.optionContent) {
1931
- let node = source(completion, this.view.state, match);
1938
+ let node = source(completion, this.view.state, this.view, match);
1932
1939
  if (node)
1933
1940
  li.appendChild(node);
1934
1941
  }
@@ -1951,8 +1958,6 @@ class CompletionTooltip {
1951
1958
  this.destroyInfo();
1952
1959
  }
1953
1960
  }
1954
- // We allocate a new function instance every time the completion
1955
- // changes to force redrawing/repositioning of the tooltip
1956
1961
  function completionTooltip(stateField, applyCompletion) {
1957
1962
  return (view) => new CompletionTooltip(view, stateField, applyCompletion);
1958
1963
  }
@@ -2060,7 +2065,7 @@ class CompletionDialog {
2060
2065
  }
2061
2066
  return new CompletionDialog(options, makeAttrs(id, selected), {
2062
2067
  pos: active.reduce((a, b) => b.hasResult() ? Math.min(a, b.from) : a, 1e8),
2063
- create: completionTooltip(completionState, applyCompletion),
2068
+ create: createTooltip,
2064
2069
  above: conf.aboveCursor,
2065
2070
  }, prev ? prev.timestamp : Date.now(), selected, false);
2066
2071
  }
@@ -2236,6 +2241,7 @@ function applyCompletion(view, option) {
2236
2241
  apply(view, option.completion, result.from, result.to);
2237
2242
  return true;
2238
2243
  }
2244
+ const createTooltip = /*@__PURE__*/completionTooltip(completionState, applyCompletion);
2239
2245
 
2240
2246
  /**
2241
2247
  Returns a command that moves the completion selection forward or
@@ -2302,7 +2308,7 @@ class RunningQuery {
2302
2308
  this.done = undefined;
2303
2309
  }
2304
2310
  }
2305
- const DebounceTime = 50, MaxUpdateCount = 50, MinAbortTime = 1000;
2311
+ const MaxUpdateCount = 50, MinAbortTime = 1000;
2306
2312
  const completionPlugin = /*@__PURE__*/view_.ViewPlugin.fromClass(class {
2307
2313
  constructor(view) {
2308
2314
  this.view = view;
@@ -2343,7 +2349,7 @@ const completionPlugin = /*@__PURE__*/view_.ViewPlugin.fromClass(class {
2343
2349
  if (this.debounceUpdate > -1)
2344
2350
  clearTimeout(this.debounceUpdate);
2345
2351
  this.debounceUpdate = cState.active.some(a => a.state == 1 /* State.Pending */ && !this.running.some(q => q.active.source == a.source))
2346
- ? setTimeout(() => this.startUpdate(), DebounceTime) : -1;
2352
+ ? setTimeout(() => this.startUpdate(), 50) : -1;
2347
2353
  if (this.composing != 0 /* CompositionState.None */)
2348
2354
  for (let tr of update.transactions) {
2349
2355
  if (getUserEvent(tr) == "input")
@@ -2379,7 +2385,7 @@ const completionPlugin = /*@__PURE__*/view_.ViewPlugin.fromClass(class {
2379
2385
  if (this.running.every(q => q.done !== undefined))
2380
2386
  this.accept();
2381
2387
  else if (this.debounceAccept < 0)
2382
- this.debounceAccept = setTimeout(() => this.accept(), DebounceTime);
2388
+ this.debounceAccept = setTimeout(() => this.accept(), this.view.state.facet(completionConfig).updateSyncTime);
2383
2389
  }
2384
2390
  // For each finished query in this.running, try to create a result
2385
2391
  // or, if appropriate, restart the query.
@@ -2844,7 +2850,7 @@ const snippetPointerHandler = /*@__PURE__*/view_.EditorView.domEventHandlers({
2844
2850
  });
2845
2851
 
2846
2852
  function wordRE(wordChars) {
2847
- let escaped = wordChars.replace(/[\\[.+*?(){|^$]/g, "\\$&");
2853
+ let escaped = wordChars.replace(/[\]\-\\]/g, "\\$&");
2848
2854
  try {
2849
2855
  return new RegExp(`[\\p{Alphabetic}\\p{Number}_${escaped}]+`, "ug");
2850
2856
  }
@@ -2939,10 +2945,8 @@ const bracketState = /*@__PURE__*/state_.StateField.define({
2939
2945
  create() { return state_.RangeSet.empty; },
2940
2946
  update(value, tr) {
2941
2947
  if (tr.selection) {
2942
- let lineStart = tr.state.doc.lineAt(tr.selection.main.head).from;
2943
- let prevLineStart = tr.startState.doc.lineAt(tr.startState.selection.main.head).from;
2944
- if (lineStart != tr.changes.mapPos(prevLineStart, -1))
2945
- value = state_.RangeSet.empty;
2948
+ let line = tr.state.doc.lineAt(tr.selection.main.head);
2949
+ value = value.update({ filter: from => from >= line.from && from <= line.to });
2946
2950
  }
2947
2951
  value = value.map(tr.changes);
2948
2952
  for (let effect of tr.effects)
@@ -6363,10 +6367,10 @@ function styleTags(spec) {
6363
6367
  tags = [tags];
6364
6368
  for (let part of prop.split(" "))
6365
6369
  if (part) {
6366
- let pieces = [], mode = 2 /* Normal */, rest = part;
6370
+ let pieces = [], mode = 2 /* Mode.Normal */, rest = part;
6367
6371
  for (let pos = 0;;) {
6368
6372
  if (rest == "..." && pos > 0 && pos + 3 == part.length) {
6369
- mode = 1 /* Inherit */;
6373
+ mode = 1 /* Mode.Inherit */;
6370
6374
  break;
6371
6375
  }
6372
6376
  let m = /^"(?:[^"\\]|\\.)*?"|[^\/!]+/.exec(rest);
@@ -6378,7 +6382,7 @@ function styleTags(spec) {
6378
6382
  break;
6379
6383
  let next = part[pos++];
6380
6384
  if (pos == part.length && next == "!") {
6381
- mode = 0 /* Opaque */;
6385
+ mode = 0 /* Mode.Opaque */;
6382
6386
  break;
6383
6387
  }
6384
6388
  if (next != "/")
@@ -6402,8 +6406,8 @@ class Rule {
6402
6406
  this.context = context;
6403
6407
  this.next = next;
6404
6408
  }
6405
- get opaque() { return this.mode == 0 /* Opaque */; }
6406
- get inherit() { return this.mode == 1 /* Inherit */; }
6409
+ get opaque() { return this.mode == 0 /* Mode.Opaque */; }
6410
+ get inherit() { return this.mode == 1 /* Mode.Inherit */; }
6407
6411
  sort(other) {
6408
6412
  if (!other || other.depth < this.depth) {
6409
6413
  this.next = other;
@@ -6414,7 +6418,7 @@ class Rule {
6414
6418
  }
6415
6419
  get depth() { return this.context ? this.context.length : 0; }
6416
6420
  }
6417
- Rule.empty = new Rule([], 2 /* Normal */, null);
6421
+ Rule.empty = new Rule([], 2 /* Mode.Normal */, null);
6418
6422
  /**
6419
6423
  Define a [highlighter](#highlight.Highlighter) from an array of
6420
6424
  tag/class pairs. Classes associated with more specific tags will
@@ -6458,7 +6462,9 @@ function highlightTags(highlighters, tags) {
6458
6462
  }
6459
6463
  /**
6460
6464
  Highlight the given [tree](#common.Tree) with the given
6461
- [highlighter](#highlight.Highlighter).
6465
+ [highlighter](#highlight.Highlighter). Often, the higher-level
6466
+ [`highlightCode`](#highlight.highlightCode) function is easier to
6467
+ use.
6462
6468
  */
6463
6469
  function highlightTree(tree, highlighter,
6464
6470
  /**
@@ -6479,6 +6485,35 @@ to = tree.length) {
6479
6485
  builder.highlightRange(tree.cursor(), from, to, "", builder.highlighters);
6480
6486
  builder.flush(to);
6481
6487
  }
6488
+ /**
6489
+ Highlight the given tree with the given highlighter, calling
6490
+ `putText` for every piece of text, either with a set of classes or
6491
+ with the empty string when unstyled, and `putBreak` for every line
6492
+ break.
6493
+ */
6494
+ function highlightCode(code, tree, highlighter, putText, putBreak, from = 0, to = code.length) {
6495
+ let pos = from;
6496
+ function writeTo(p, classes) {
6497
+ if (p <= pos)
6498
+ return;
6499
+ for (let text = code.slice(pos, p), i = 0;;) {
6500
+ let nextBreak = text.indexOf("\n", i);
6501
+ let upto = nextBreak < 0 ? text.length : nextBreak;
6502
+ if (upto > i)
6503
+ putText(text.slice(i, upto), classes);
6504
+ if (nextBreak < 0)
6505
+ break;
6506
+ putBreak();
6507
+ i = nextBreak + 1;
6508
+ }
6509
+ pos = p;
6510
+ }
6511
+ highlightTree(tree, highlighter, (from, to, classes) => {
6512
+ writeTo(from, "");
6513
+ writeTo(to, classes);
6514
+ }, from, to);
6515
+ writeTo(to, "");
6516
+ }
6482
6517
  class HighlightBuilder {
6483
6518
  constructor(at, highlighters, span) {
6484
6519
  this.at = at;
@@ -6511,7 +6546,7 @@ class HighlightBuilder {
6511
6546
  if (cls)
6512
6547
  cls += " ";
6513
6548
  cls += tagCls;
6514
- if (rule.mode == 1 /* Inherit */)
6549
+ if (rule.mode == 1 /* Mode.Inherit */)
6515
6550
  inheritedClass += (inheritedClass ? " " : "") + tagCls;
6516
6551
  }
6517
6552
  this.startSpan(Math.max(from, start), cls);
@@ -9702,31 +9737,36 @@ function warnForPart(part, msg) {
9702
9737
  console.warn(msg);
9703
9738
  }
9704
9739
  function createTokenType(extra, tagStr) {
9705
- let tag = null;
9706
- for (let part of tagStr.split(".")) {
9707
- let value = (extra[part] || tags[part]);
9708
- if (!value) {
9709
- warnForPart(part, `Unknown highlighting tag ${part}`);
9710
- }
9711
- else if (typeof value == "function") {
9712
- if (!tag)
9713
- warnForPart(part, `Modifier ${part} used at start of tag`);
9714
- else
9715
- tag = value(tag);
9716
- }
9717
- else {
9718
- if (tag)
9719
- warnForPart(part, `Tag ${part} used as modifier`);
9720
- else
9721
- tag = value;
9740
+ let tags$1 = [];
9741
+ for (let name of tagStr.split(" ")) {
9742
+ let found = [];
9743
+ for (let part of name.split(".")) {
9744
+ let value = (extra[part] || tags[part]);
9745
+ if (!value) {
9746
+ warnForPart(part, `Unknown highlighting tag ${part}`);
9747
+ }
9748
+ else if (typeof value == "function") {
9749
+ if (!found.length)
9750
+ warnForPart(part, `Modifier ${part} used at start of tag`);
9751
+ else
9752
+ found = found.map(value);
9753
+ }
9754
+ else {
9755
+ if (found.length)
9756
+ warnForPart(part, `Tag ${part} used as modifier`);
9757
+ else
9758
+ found = Array.isArray(value) ? value : [value];
9759
+ }
9722
9760
  }
9761
+ for (let tag of found)
9762
+ tags$1.push(tag);
9723
9763
  }
9724
- if (!tag)
9764
+ if (!tags$1.length)
9725
9765
  return 0;
9726
9766
  let name = tagStr.replace(/ /g, "_"), type = dist/* NodeType */.Jq.define({
9727
9767
  id: typeArray.length,
9728
9768
  name,
9729
- props: [styleTags({ [name]: tag })]
9769
+ props: [styleTags({ [name]: tags$1 })]
9730
9770
  });
9731
9771
  typeArray.push(type);
9732
9772
  return type.id;
@@ -10640,8 +10680,6 @@ class BufferNode extends BaseNode {
10640
10680
  function iterStack(heads) {
10641
10681
  if (!heads.length)
10642
10682
  return null;
10643
- if (heads.length == 1)
10644
- return heads[0];
10645
10683
  let pick = 0, picked = heads[0];
10646
10684
  for (let i = 1; i < heads.length; i++) {
10647
10685
  let node = heads[i];
@@ -10677,7 +10715,7 @@ function stackIterator(tree, pos, side) {
10677
10715
  let mount = MountedTree.get(scan.tree);
10678
10716
  // Relevant overlay branching off
10679
10717
  if (mount && mount.overlay && mount.overlay[0].from <= pos && mount.overlay[mount.overlay.length - 1].to >= pos) {
10680
- let root = new TreeNode(mount.tree, mount.overlay[0].from + scan.from, 0, null);
10718
+ let root = new TreeNode(mount.tree, mount.overlay[0].from + scan.from, -1, scan);
10681
10719
  (layers || (layers = [inner])).push(resolveNode(root, pos, side, false));
10682
10720
  }
10683
10721
  }
@@ -10741,6 +10779,9 @@ class TreeCursor {
10741
10779
  this.to = start + buffer.buffer[index + 2];
10742
10780
  return true;
10743
10781
  }
10782
+ /**
10783
+ @internal
10784
+ */
10744
10785
  yield(node) {
10745
10786
  if (!node)
10746
10787
  return false;
@@ -11006,7 +11047,7 @@ function buildTree(data) {
11006
11047
  let cursor = Array.isArray(buffer) ? new FlatBufferCursor(buffer, buffer.length) : buffer;
11007
11048
  let types = nodeSet.types;
11008
11049
  let contextHash = 0, lookAhead = 0;
11009
- function takeNode(parentStart, minPos, children, positions, inRepeat) {
11050
+ function takeNode(parentStart, minPos, children, positions, inRepeat, depth) {
11010
11051
  let { id, start, end, size } = cursor;
11011
11052
  let lookAheadAtStart = lookAhead;
11012
11053
  while (size < 0) {
@@ -11055,8 +11096,11 @@ function buildTree(data) {
11055
11096
  }
11056
11097
  cursor.next();
11057
11098
  }
11099
+ else if (depth > 2500 /* CutOff.Depth */) {
11100
+ takeFlatNode(start, endPos, localChildren, localPositions);
11101
+ }
11058
11102
  else {
11059
- takeNode(start, endPos, localChildren, localPositions, localInRepeat);
11103
+ takeNode(start, endPos, localChildren, localPositions, localInRepeat, depth + 1);
11060
11104
  }
11061
11105
  }
11062
11106
  if (localInRepeat >= 0 && lastGroup > 0 && lastGroup < localChildren.length)
@@ -11074,6 +11118,38 @@ function buildTree(data) {
11074
11118
  children.push(node);
11075
11119
  positions.push(startPos);
11076
11120
  }
11121
+ function takeFlatNode(parentStart, minPos, children, positions) {
11122
+ let nodes = []; // Temporary, inverted array of leaf nodes found, with absolute positions
11123
+ let nodeCount = 0, stopAt = -1;
11124
+ while (cursor.pos > minPos) {
11125
+ let { id, start, end, size } = cursor;
11126
+ if (size > 4) { // Not a leaf
11127
+ cursor.next();
11128
+ }
11129
+ else if (stopAt > -1 && start < stopAt) {
11130
+ break;
11131
+ }
11132
+ else {
11133
+ if (stopAt < 0)
11134
+ stopAt = end - maxBufferLength;
11135
+ nodes.push(id, start, end);
11136
+ nodeCount++;
11137
+ cursor.next();
11138
+ }
11139
+ }
11140
+ if (nodeCount) {
11141
+ let buffer = new Uint16Array(nodeCount * 4);
11142
+ let start = nodes[nodes.length - 2];
11143
+ for (let i = nodes.length - 3, j = 0; i >= 0; i -= 3) {
11144
+ buffer[j++] = nodes[i];
11145
+ buffer[j++] = nodes[i + 1] - start;
11146
+ buffer[j++] = nodes[i + 2] - start;
11147
+ buffer[j++] = j;
11148
+ }
11149
+ children.push(new TreeBuffer(buffer, nodes[2] - start, nodeSet));
11150
+ positions.push(start - parentStart);
11151
+ }
11152
+ }
11077
11153
  function makeBalanced(type) {
11078
11154
  return (children, positions, length) => {
11079
11155
  let lookAhead = 0, lastI = children.length - 1, last, lookAheadProp;
@@ -11184,7 +11260,7 @@ function buildTree(data) {
11184
11260
  }
11185
11261
  let children = [], positions = [];
11186
11262
  while (cursor.pos > 0)
11187
- takeNode(data.start || 0, data.bufferStart || 0, children, positions, -1);
11263
+ takeNode(data.start || 0, data.bufferStart || 0, children, positions, -1, 0);
11188
11264
  let length = (_a = data.length) !== null && _a !== void 0 ? _a : (children.length ? positions[0] + children[0].length : 0);
11189
11265
  return new Tree(types[data.topID], children.reverse(), positions.reverse(), length);
11190
11266
  }
@@ -11465,16 +11541,18 @@ function parseMixed(nest) {
11465
11541
  return (parse, input, fragments, ranges) => new MixedParse(parse, nest, input, fragments, ranges);
11466
11542
  }
11467
11543
  class InnerParse {
11468
- constructor(parser, parse, overlay, target, ranges) {
11544
+ constructor(parser, parse, overlay, target, from) {
11469
11545
  this.parser = parser;
11470
11546
  this.parse = parse;
11471
11547
  this.overlay = overlay;
11472
11548
  this.target = target;
11473
- this.ranges = ranges;
11474
- if (!ranges.length || ranges.some(r => r.from >= r.to))
11475
- throw new RangeError("Invalid inner parse ranges given: " + JSON.stringify(ranges));
11549
+ this.from = from;
11476
11550
  }
11477
11551
  }
11552
+ function checkRanges(ranges) {
11553
+ if (!ranges.length || ranges.some(r => r.from >= r.to))
11554
+ throw new RangeError("Invalid inner parse ranges given: " + JSON.stringify(ranges));
11555
+ }
11478
11556
  class ActiveOverlay {
11479
11557
  constructor(parser, predicate, mounts, index, start, target, prev) {
11480
11558
  this.parser = parser;
@@ -11537,7 +11615,7 @@ class MixedParse {
11537
11615
  return 0;
11538
11616
  let pos = this.input.length;
11539
11617
  for (let i = this.innerDone; i < this.inner.length; i++) {
11540
- if (this.inner[i].ranges[0].from < pos)
11618
+ if (this.inner[i].from < pos)
11541
11619
  pos = Math.min(pos, this.inner[i].parse.parsedPos);
11542
11620
  }
11543
11621
  return pos;
@@ -11555,9 +11633,12 @@ class MixedParse {
11555
11633
  let overlay = null;
11556
11634
  let covered = null;
11557
11635
  let cursor = new TreeCursor(new TreeNode(this.baseTree, this.ranges[0].from, 0, null), IterMode.IncludeAnonymous | IterMode.IgnoreMounts);
11558
- scan: for (let nest, isCovered; this.stoppedAt == null || cursor.from < this.stoppedAt;) {
11636
+ scan: for (let nest, isCovered;;) {
11559
11637
  let enter = true, range;
11560
- if (fragmentCursor.hasNode(cursor)) {
11638
+ if (this.stoppedAt != null && cursor.from >= this.stoppedAt) {
11639
+ enter = false;
11640
+ }
11641
+ else if (fragmentCursor.hasNode(cursor)) {
11561
11642
  if (overlay) {
11562
11643
  let match = overlay.mounts.find(m => m.frag.from <= cursor.from && m.frag.to >= cursor.to && m.mount.overlay);
11563
11644
  if (match)
@@ -11572,7 +11653,8 @@ class MixedParse {
11572
11653
  else if (covered && (isCovered = checkCover(covered.ranges, cursor.from, cursor.to))) {
11573
11654
  enter = isCovered != 2 /* Cover.Full */;
11574
11655
  }
11575
- else if (!cursor.type.isAnonymous && cursor.from < cursor.to && (nest = this.nest(cursor, this.input))) {
11656
+ else if (!cursor.type.isAnonymous && (nest = this.nest(cursor, this.input)) &&
11657
+ (cursor.from < cursor.to || !nest.overlay)) {
11576
11658
  if (!cursor.tree)
11577
11659
  materialize(cursor);
11578
11660
  let oldMounts = fragmentCursor.findMounts(cursor.from, nest.parser);
@@ -11580,9 +11662,13 @@ class MixedParse {
11580
11662
  overlay = new ActiveOverlay(nest.parser, nest.overlay, oldMounts, this.inner.length, cursor.from, cursor.tree, overlay);
11581
11663
  }
11582
11664
  else {
11583
- let ranges = punchRanges(this.ranges, nest.overlay || [new Range(cursor.from, cursor.to)]);
11665
+ let ranges = punchRanges(this.ranges, nest.overlay ||
11666
+ (cursor.from < cursor.to ? [new Range(cursor.from, cursor.to)] : []));
11584
11667
  if (ranges.length)
11585
- this.inner.push(new InnerParse(nest.parser, nest.parser.startParse(this.input, enterFragments(oldMounts, ranges), ranges), nest.overlay ? nest.overlay.map(r => new Range(r.from - cursor.from, r.to - cursor.from)) : null, cursor.tree, ranges));
11668
+ checkRanges(ranges);
11669
+ if (ranges.length || !nest.overlay)
11670
+ this.inner.push(new InnerParse(nest.parser, ranges.length ? nest.parser.startParse(this.input, enterFragments(oldMounts, ranges), ranges)
11671
+ : nest.parser.startParse(""), nest.overlay ? nest.overlay.map(r => new Range(r.from - cursor.from, r.to - cursor.from)) : null, cursor.tree, ranges.length ? ranges[0].from : cursor.from));
11586
11672
  if (!nest.overlay)
11587
11673
  enter = false;
11588
11674
  else if (ranges.length)
@@ -11609,8 +11695,10 @@ class MixedParse {
11609
11695
  break scan;
11610
11696
  if (overlay && !--overlay.depth) {
11611
11697
  let ranges = punchRanges(this.ranges, overlay.ranges);
11612
- if (ranges.length)
11613
- this.inner.splice(overlay.index, 0, new InnerParse(overlay.parser, overlay.parser.startParse(this.input, enterFragments(overlay.mounts, ranges), ranges), overlay.ranges.map(r => new Range(r.from - overlay.start, r.to - overlay.start)), overlay.target, ranges));
11698
+ if (ranges.length) {
11699
+ checkRanges(ranges);
11700
+ this.inner.splice(overlay.index, 0, new InnerParse(overlay.parser, overlay.parser.startParse(this.input, enterFragments(overlay.mounts, ranges), ranges), overlay.ranges.map(r => new Range(r.from - overlay.start, r.to - overlay.start)), overlay.target, ranges[0].from));
11701
+ }
11614
11702
  overlay = overlay.prev;
11615
11703
  }
11616
11704
  if (covered && !--covered.depth)
@@ -11644,11 +11732,11 @@ function sliceBuf(buf, startI, endI, nodes, positions, off) {
11644
11732
  // parse that was ran via the mix parser, and thus aren't shared with
11645
11733
  // any other code, making violations of the immutability safe.
11646
11734
  function materialize(cursor) {
11647
- let { node } = cursor, depth = 0;
11735
+ let { node } = cursor, stack = [];
11648
11736
  // Scan up to the nearest tree
11649
11737
  do {
11738
+ stack.push(cursor.index);
11650
11739
  cursor.parent();
11651
- depth++;
11652
11740
  } while (!cursor.tree);
11653
11741
  // Find the index of the buffer in that tree
11654
11742
  let i = 0, base = cursor.tree, off = 0;
@@ -11657,26 +11745,29 @@ function materialize(cursor) {
11657
11745
  if (off <= node.from && off + base.children[i].length >= node.to)
11658
11746
  break;
11659
11747
  }
11660
- let buf = base.children[i], b = buf.buffer;
11748
+ let buf = base.children[i], b = buf.buffer, newStack = [i];
11661
11749
  // Split a level in the buffer, putting the nodes before and after
11662
11750
  // the child that contains `node` into new buffers.
11663
- function split(startI, endI, type, innerOffset, length) {
11664
- let i = startI;
11665
- while (b[i + 2] + off <= node.from)
11666
- i = b[i + 3];
11751
+ function split(startI, endI, type, innerOffset, length, stackPos) {
11752
+ let targetI = stack[stackPos];
11667
11753
  let children = [], positions = [];
11668
- sliceBuf(buf, startI, i, children, positions, innerOffset);
11669
- let from = b[i + 1], to = b[i + 2];
11670
- let isTarget = from + off == node.from && to + off == node.to && b[i] == node.type.id;
11671
- children.push(isTarget ? node.toTree() : split(i + 4, b[i + 3], buf.set.types[b[i]], from, to - from));
11754
+ sliceBuf(buf, startI, targetI, children, positions, innerOffset);
11755
+ let from = b[targetI + 1], to = b[targetI + 2];
11756
+ newStack.push(children.length);
11757
+ let child = stackPos
11758
+ ? split(targetI + 4, b[targetI + 3], buf.set.types[b[targetI]], from, to - from, stackPos - 1)
11759
+ : node.toTree();
11760
+ children.push(child);
11672
11761
  positions.push(from - innerOffset);
11673
- sliceBuf(buf, b[i + 3], endI, children, positions, innerOffset);
11762
+ sliceBuf(buf, b[targetI + 3], endI, children, positions, innerOffset);
11674
11763
  return new Tree(type, children, positions, length);
11675
11764
  }
11676
- base.children[i] = split(0, b.length, NodeType.none, 0, buf.length);
11765
+ base.children[i] = split(0, b.length, NodeType.none, 0, buf.length, stack.length - 1);
11677
11766
  // Move the cursor back to the target node
11678
- for (let d = 0; d <= depth; d++)
11679
- cursor.childAfter(node.from);
11767
+ for (let index of newStack) {
11768
+ let tree = cursor.tree.children[index], pos = cursor.tree.positions[index];
11769
+ cursor.yield(new TreeNode(tree, pos + cursor.from, index, cursor._tree));
11770
+ }
11680
11771
  }
11681
11772
  class StructureCursor {
11682
11773
  constructor(root, offset) {