@codemirror/language 6.12.1 → 6.12.3

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,17 @@
1
+ ## 6.12.3 (2026-03-25)
2
+
3
+ ### Bug fixes
4
+
5
+ Fix a crash in `bracketMatching` when composing at end of document.
6
+
7
+ ## 6.12.2 (2026-02-25)
8
+
9
+ ### Bug fixes
10
+
11
+ Make sure brackets are highlighted in the initial editor state.
12
+
13
+ Pause bracket matching updates during composition, to avoid disrupting Mobile Safari's fragile composition handling.
14
+
1
15
  ## 6.12.1 (2025-12-22)
2
16
 
3
17
  ### Bug fixes
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @codemirror/language [![NPM version](https://img.shields.io/npm/v/@codemirror/language.svg)](https://www.npmjs.org/package/@codemirror/language)
2
2
 
3
- [ [**WEBSITE**](https://codemirror.net/) | [**DOCS**](https://codemirror.net/docs/ref/#language) | [**ISSUES**](https://github.com/codemirror/dev/issues) | [**FORUM**](https://discuss.codemirror.net/c/next/) | [**CHANGELOG**](https://github.com/codemirror/language/blob/main/CHANGELOG.md) ]
3
+ [ [**WEBSITE**](https://codemirror.net/) | [**DOCS**](https://codemirror.net/docs/ref/#language) | [**ISSUES**](https://github.com/codemirror/dev/issues) | [**FORUM**](https://discuss.codemirror.net/) | [**CHANGELOG**](https://github.com/codemirror/language/blob/main/CHANGELOG.md) ]
4
4
 
5
5
  This package implements the language support infrastructure for the
6
6
  [CodeMirror](https://codemirror.net/) code editor.
package/dist/index.cjs CHANGED
@@ -1862,30 +1862,44 @@ function defaultRenderMatch(match) {
1862
1862
  decorations.push(mark.range(match.end.from, match.end.to));
1863
1863
  return decorations;
1864
1864
  }
1865
- const bracketMatchingState = state.StateField.define({
1866
- create() { return view.Decoration.none; },
1867
- update(deco, tr) {
1868
- if (!tr.docChanged && !tr.selection)
1869
- return deco;
1870
- let decorations = [];
1871
- let config = tr.state.facet(bracketMatchingConfig);
1872
- for (let range of tr.state.selection.ranges) {
1873
- if (!range.empty)
1874
- continue;
1875
- let match = matchBrackets(tr.state, range.head, -1, config)
1876
- || (range.head > 0 && matchBrackets(tr.state, range.head - 1, 1, config))
1877
- || (config.afterCursor &&
1878
- (matchBrackets(tr.state, range.head, 1, config) ||
1879
- (range.head < tr.state.doc.length && matchBrackets(tr.state, range.head + 1, -1, config))));
1880
- if (match)
1881
- decorations = decorations.concat(config.renderMatch(match, tr.state));
1865
+ function bracketDeco(state) {
1866
+ let decorations = [];
1867
+ let config = state.facet(bracketMatchingConfig);
1868
+ for (let range of state.selection.ranges) {
1869
+ if (!range.empty)
1870
+ continue;
1871
+ let match = matchBrackets(state, range.head, -1, config)
1872
+ || (range.head > 0 && matchBrackets(state, range.head - 1, 1, config))
1873
+ || (config.afterCursor &&
1874
+ (matchBrackets(state, range.head, 1, config) ||
1875
+ (range.head < state.doc.length && matchBrackets(state, range.head + 1, -1, config))));
1876
+ if (match)
1877
+ decorations = decorations.concat(config.renderMatch(match, state));
1878
+ }
1879
+ return view.Decoration.set(decorations, true);
1880
+ }
1881
+ const bracketMatcher = view.ViewPlugin.fromClass(class {
1882
+ constructor(view) {
1883
+ this.paused = false;
1884
+ this.decorations = bracketDeco(view.state);
1885
+ }
1886
+ update(update) {
1887
+ if (update.docChanged || update.selectionSet || this.paused) {
1888
+ if (update.view.composing) {
1889
+ this.decorations = this.decorations.map(update.changes);
1890
+ this.paused = true;
1891
+ }
1892
+ else {
1893
+ this.decorations = bracketDeco(update.state);
1894
+ this.paused = false;
1895
+ }
1882
1896
  }
1883
- return view.Decoration.set(decorations, true);
1884
- },
1885
- provide: f => view.EditorView.decorations.from(f)
1897
+ }
1898
+ }, {
1899
+ decorations: v => v.decorations
1886
1900
  });
1887
1901
  const bracketMatchingUnique = [
1888
- bracketMatchingState,
1902
+ bracketMatcher,
1889
1903
  baseTheme
1890
1904
  ];
1891
1905
  /**
@@ -1969,6 +1983,8 @@ function matchMarkedBrackets(_state, _pos, dir, token, handle, matching, bracket
1969
1983
  return { start: firstToken, matched: false };
1970
1984
  }
1971
1985
  function matchPlainBrackets(state, pos, dir, tree, tokenType, maxScanDistance, brackets) {
1986
+ if (dir < 0 ? !pos : pos == state.doc.length)
1987
+ return null;
1972
1988
  let startCh = dir < 0 ? state.sliceDoc(pos - 1, pos) : state.sliceDoc(pos, pos + 1);
1973
1989
  let bracket = brackets.indexOf(startCh);
1974
1990
  if (bracket < 0 || (bracket % 2 == 0) != (dir > 0))
package/dist/index.js CHANGED
@@ -1860,30 +1860,44 @@ function defaultRenderMatch(match) {
1860
1860
  decorations.push(mark.range(match.end.from, match.end.to));
1861
1861
  return decorations;
1862
1862
  }
1863
- const bracketMatchingState = /*@__PURE__*/StateField.define({
1864
- create() { return Decoration.none; },
1865
- update(deco, tr) {
1866
- if (!tr.docChanged && !tr.selection)
1867
- return deco;
1868
- let decorations = [];
1869
- let config = tr.state.facet(bracketMatchingConfig);
1870
- for (let range of tr.state.selection.ranges) {
1871
- if (!range.empty)
1872
- continue;
1873
- let match = matchBrackets(tr.state, range.head, -1, config)
1874
- || (range.head > 0 && matchBrackets(tr.state, range.head - 1, 1, config))
1875
- || (config.afterCursor &&
1876
- (matchBrackets(tr.state, range.head, 1, config) ||
1877
- (range.head < tr.state.doc.length && matchBrackets(tr.state, range.head + 1, -1, config))));
1878
- if (match)
1879
- decorations = decorations.concat(config.renderMatch(match, tr.state));
1863
+ function bracketDeco(state) {
1864
+ let decorations = [];
1865
+ let config = state.facet(bracketMatchingConfig);
1866
+ for (let range of state.selection.ranges) {
1867
+ if (!range.empty)
1868
+ continue;
1869
+ let match = matchBrackets(state, range.head, -1, config)
1870
+ || (range.head > 0 && matchBrackets(state, range.head - 1, 1, config))
1871
+ || (config.afterCursor &&
1872
+ (matchBrackets(state, range.head, 1, config) ||
1873
+ (range.head < state.doc.length && matchBrackets(state, range.head + 1, -1, config))));
1874
+ if (match)
1875
+ decorations = decorations.concat(config.renderMatch(match, state));
1876
+ }
1877
+ return Decoration.set(decorations, true);
1878
+ }
1879
+ const bracketMatcher = /*@__PURE__*/ViewPlugin.fromClass(class {
1880
+ constructor(view) {
1881
+ this.paused = false;
1882
+ this.decorations = bracketDeco(view.state);
1883
+ }
1884
+ update(update) {
1885
+ if (update.docChanged || update.selectionSet || this.paused) {
1886
+ if (update.view.composing) {
1887
+ this.decorations = this.decorations.map(update.changes);
1888
+ this.paused = true;
1889
+ }
1890
+ else {
1891
+ this.decorations = bracketDeco(update.state);
1892
+ this.paused = false;
1893
+ }
1880
1894
  }
1881
- return Decoration.set(decorations, true);
1882
- },
1883
- provide: f => EditorView.decorations.from(f)
1895
+ }
1896
+ }, {
1897
+ decorations: v => v.decorations
1884
1898
  });
1885
1899
  const bracketMatchingUnique = [
1886
- bracketMatchingState,
1900
+ bracketMatcher,
1887
1901
  baseTheme
1888
1902
  ];
1889
1903
  /**
@@ -1967,6 +1981,8 @@ function matchMarkedBrackets(_state, _pos, dir, token, handle, matching, bracket
1967
1981
  return { start: firstToken, matched: false };
1968
1982
  }
1969
1983
  function matchPlainBrackets(state, pos, dir, tree, tokenType, maxScanDistance, brackets) {
1984
+ if (dir < 0 ? !pos : pos == state.doc.length)
1985
+ return null;
1970
1986
  let startCh = dir < 0 ? state.sliceDoc(pos - 1, pos) : state.sliceDoc(pos, pos + 1);
1971
1987
  let bracket = brackets.indexOf(startCh);
1972
1988
  if (bracket < 0 || (bracket % 2 == 0) != (dir > 0))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/language",
3
- "version": "6.12.1",
3
+ "version": "6.12.3",
4
4
  "description": "Language support infrastructure for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",
@@ -39,6 +39,6 @@
39
39
  },
40
40
  "repository": {
41
41
  "type": "git",
42
- "url": "https://github.com/codemirror/language.git"
42
+ "url": "git+https://github.com/codemirror/language.git"
43
43
  }
44
44
  }