@codemirror/language 6.3.2 → 6.4.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 CHANGED
@@ -1,3 +1,9 @@
1
+ ## 6.4.0 (2023-01-12)
2
+
3
+ ### New features
4
+
5
+ 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).
6
+
1
7
  ## 6.3.2 (2022-12-16)
2
8
 
3
9
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -1787,6 +1787,15 @@ highlighting style is used to indicate this.
1787
1787
  function bracketMatching(config = {}) {
1788
1788
  return [bracketMatchingConfig.of(config), bracketMatchingUnique];
1789
1789
  }
1790
+ /**
1791
+ When larger syntax nodes, such as HTML tags, are marked as
1792
+ opening/closing, it can be a bit messy to treat the whole node as
1793
+ a matchable bracket. This node prop allows you to define, for such
1794
+ a node, a ‘handle’—the part of the node that is highlighted, and
1795
+ that the cursor must be on to activate highlighting in the first
1796
+ place.
1797
+ */
1798
+ const bracketMatchingHandle = new common.NodeProp();
1790
1799
  function matchingNodes(node, dir, brackets) {
1791
1800
  let byProp = node.prop(dir < 0 ? common.NodeProp.openedBy : common.NodeProp.closedBy);
1792
1801
  if (byProp)
@@ -1798,6 +1807,10 @@ function matchingNodes(node, dir, brackets) {
1798
1807
  }
1799
1808
  return null;
1800
1809
  }
1810
+ function findHandle(node) {
1811
+ let hasHandle = node.type.prop(bracketMatchingHandle);
1812
+ return hasHandle ? hasHandle(node.node) : node;
1813
+ }
1801
1814
  /**
1802
1815
  Find the matching bracket for the token at `pos`, scanning
1803
1816
  direction `dir`. Only the `brackets` and `maxScanDistance`
@@ -1809,30 +1822,36 @@ function matchBrackets(state, pos, dir, config = {}) {
1809
1822
  let tree = syntaxTree(state), node = tree.resolveInner(pos, dir);
1810
1823
  for (let cur = node; cur; cur = cur.parent) {
1811
1824
  let matches = matchingNodes(cur.type, dir, brackets);
1812
- if (matches && cur.from < cur.to)
1813
- return matchMarkedBrackets(state, pos, dir, cur, matches, brackets);
1825
+ if (matches && cur.from < cur.to) {
1826
+ let handle = findHandle(cur);
1827
+ if (handle && (dir > 0 ? pos >= handle.from && pos < handle.to : pos > handle.from && pos <= handle.to))
1828
+ return matchMarkedBrackets(state, pos, dir, cur, handle, matches, brackets);
1829
+ }
1814
1830
  }
1815
1831
  return matchPlainBrackets(state, pos, dir, tree, node.type, maxScanDistance, brackets);
1816
1832
  }
1817
- function matchMarkedBrackets(_state, _pos, dir, token, matching, brackets) {
1818
- let parent = token.parent, firstToken = { from: token.from, to: token.to };
1833
+ function matchMarkedBrackets(_state, _pos, dir, token, handle, matching, brackets) {
1834
+ let parent = token.parent, firstToken = { from: handle.from, to: handle.to };
1819
1835
  let depth = 0, cursor = parent === null || parent === void 0 ? void 0 : parent.cursor();
1820
1836
  if (cursor && (dir < 0 ? cursor.childBefore(token.from) : cursor.childAfter(token.to)))
1821
1837
  do {
1822
1838
  if (dir < 0 ? cursor.to <= token.from : cursor.from >= token.to) {
1823
1839
  if (depth == 0 && matching.indexOf(cursor.type.name) > -1 && cursor.from < cursor.to) {
1824
- return { start: firstToken, end: { from: cursor.from, to: cursor.to }, matched: true };
1840
+ let endHandle = findHandle(cursor);
1841
+ return { start: firstToken, end: endHandle ? { from: endHandle.from, to: endHandle.to } : undefined, matched: true };
1825
1842
  }
1826
1843
  else if (matchingNodes(cursor.type, dir, brackets)) {
1827
1844
  depth++;
1828
1845
  }
1829
1846
  else if (matchingNodes(cursor.type, -dir, brackets)) {
1830
- if (depth == 0)
1847
+ if (depth == 0) {
1848
+ let endHandle = findHandle(cursor);
1831
1849
  return {
1832
1850
  start: firstToken,
1833
- end: cursor.from == cursor.to ? undefined : { from: cursor.from, to: cursor.to },
1851
+ end: endHandle && endHandle.from < endHandle.to ? { from: endHandle.from, to: endHandle.to } : undefined,
1834
1852
  matched: false
1835
1853
  };
1854
+ }
1836
1855
  depth--;
1837
1856
  }
1838
1857
  }
@@ -2404,6 +2423,7 @@ exports.StreamLanguage = StreamLanguage;
2404
2423
  exports.StringStream = StringStream;
2405
2424
  exports.TreeIndentContext = TreeIndentContext;
2406
2425
  exports.bracketMatching = bracketMatching;
2426
+ exports.bracketMatchingHandle = bracketMatchingHandle;
2407
2427
  exports.codeFolding = codeFolding;
2408
2428
  exports.continuedIndent = continuedIndent;
2409
2429
  exports.defaultHighlightStyle = defaultHighlightStyle;
package/dist/index.d.ts CHANGED
@@ -889,6 +889,15 @@ highlighting style is used to indicate this.
889
889
  */
890
890
  declare function bracketMatching(config?: Config): Extension;
891
891
  /**
892
+ When larger syntax nodes, such as HTML tags, are marked as
893
+ opening/closing, it can be a bit messy to treat the whole node as
894
+ a matchable bracket. This node prop allows you to define, for such
895
+ a node, a ‘handle’—the part of the node that is highlighted, and
896
+ that the cursor must be on to activate highlighting in the first
897
+ place.
898
+ */
899
+ declare const bracketMatchingHandle: NodeProp<(node: SyntaxNode) => SyntaxNode | null>;
900
+ /**
892
901
  The result returned from `matchBrackets`.
893
902
  */
894
903
  interface MatchResult {
@@ -1103,4 +1112,4 @@ declare class StreamLanguage<State> extends Language {
1103
1112
  get allowsNesting(): boolean;
1104
1113
  }
1105
1114
 
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 };
1115
+ 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, unfoldAll, unfoldCode, unfoldEffect };
package/dist/index.js CHANGED
@@ -1783,6 +1783,15 @@ highlighting style is used to indicate this.
1783
1783
  function bracketMatching(config = {}) {
1784
1784
  return [bracketMatchingConfig.of(config), bracketMatchingUnique];
1785
1785
  }
1786
+ /**
1787
+ When larger syntax nodes, such as HTML tags, are marked as
1788
+ opening/closing, it can be a bit messy to treat the whole node as
1789
+ a matchable bracket. This node prop allows you to define, for such
1790
+ a node, a ‘handle’—the part of the node that is highlighted, and
1791
+ that the cursor must be on to activate highlighting in the first
1792
+ place.
1793
+ */
1794
+ const bracketMatchingHandle = /*@__PURE__*/new NodeProp();
1786
1795
  function matchingNodes(node, dir, brackets) {
1787
1796
  let byProp = node.prop(dir < 0 ? NodeProp.openedBy : NodeProp.closedBy);
1788
1797
  if (byProp)
@@ -1794,6 +1803,10 @@ function matchingNodes(node, dir, brackets) {
1794
1803
  }
1795
1804
  return null;
1796
1805
  }
1806
+ function findHandle(node) {
1807
+ let hasHandle = node.type.prop(bracketMatchingHandle);
1808
+ return hasHandle ? hasHandle(node.node) : node;
1809
+ }
1797
1810
  /**
1798
1811
  Find the matching bracket for the token at `pos`, scanning
1799
1812
  direction `dir`. Only the `brackets` and `maxScanDistance`
@@ -1805,30 +1818,36 @@ function matchBrackets(state, pos, dir, config = {}) {
1805
1818
  let tree = syntaxTree(state), node = tree.resolveInner(pos, dir);
1806
1819
  for (let cur = node; cur; cur = cur.parent) {
1807
1820
  let matches = matchingNodes(cur.type, dir, brackets);
1808
- if (matches && cur.from < cur.to)
1809
- return matchMarkedBrackets(state, pos, dir, cur, matches, brackets);
1821
+ if (matches && cur.from < cur.to) {
1822
+ let handle = findHandle(cur);
1823
+ if (handle && (dir > 0 ? pos >= handle.from && pos < handle.to : pos > handle.from && pos <= handle.to))
1824
+ return matchMarkedBrackets(state, pos, dir, cur, handle, matches, brackets);
1825
+ }
1810
1826
  }
1811
1827
  return matchPlainBrackets(state, pos, dir, tree, node.type, maxScanDistance, brackets);
1812
1828
  }
1813
- function matchMarkedBrackets(_state, _pos, dir, token, matching, brackets) {
1814
- let parent = token.parent, firstToken = { from: token.from, to: token.to };
1829
+ function matchMarkedBrackets(_state, _pos, dir, token, handle, matching, brackets) {
1830
+ let parent = token.parent, firstToken = { from: handle.from, to: handle.to };
1815
1831
  let depth = 0, cursor = parent === null || parent === void 0 ? void 0 : parent.cursor();
1816
1832
  if (cursor && (dir < 0 ? cursor.childBefore(token.from) : cursor.childAfter(token.to)))
1817
1833
  do {
1818
1834
  if (dir < 0 ? cursor.to <= token.from : cursor.from >= token.to) {
1819
1835
  if (depth == 0 && matching.indexOf(cursor.type.name) > -1 && cursor.from < cursor.to) {
1820
- return { start: firstToken, end: { from: cursor.from, to: cursor.to }, matched: true };
1836
+ let endHandle = findHandle(cursor);
1837
+ return { start: firstToken, end: endHandle ? { from: endHandle.from, to: endHandle.to } : undefined, matched: true };
1821
1838
  }
1822
1839
  else if (matchingNodes(cursor.type, dir, brackets)) {
1823
1840
  depth++;
1824
1841
  }
1825
1842
  else if (matchingNodes(cursor.type, -dir, brackets)) {
1826
- if (depth == 0)
1843
+ if (depth == 0) {
1844
+ let endHandle = findHandle(cursor);
1827
1845
  return {
1828
1846
  start: firstToken,
1829
- end: cursor.from == cursor.to ? undefined : { from: cursor.from, to: cursor.to },
1847
+ end: endHandle && endHandle.from < endHandle.to ? { from: endHandle.from, to: endHandle.to } : undefined,
1830
1848
  matched: false
1831
1849
  };
1850
+ }
1832
1851
  depth--;
1833
1852
  }
1834
1853
  }
@@ -2389,4 +2408,4 @@ function docID(data) {
2389
2408
  return type;
2390
2409
  }
2391
2410
 
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 };
2411
+ 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, unfoldAll, unfoldCode, unfoldEffect };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/language",
3
- "version": "6.3.2",
3
+ "version": "6.4.0",
4
4
  "description": "Language support infrastructure for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",