@codemirror/language 6.12.0 → 6.12.2

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,8 +1,16 @@
1
- ## 6.12.0 (2025-12-22)
1
+ ## 6.12.2 (2026-02-25)
2
2
 
3
- ### New features
3
+ ### Bug fixes
4
+
5
+ Make sure brackets are highlighted in the initial editor state.
6
+
7
+ Pause bracket matching updates during composition, to avoid disrupting Mobile Safari's fragile composition handling.
8
+
9
+ ## 6.12.1 (2025-12-22)
10
+
11
+ ### Bug fixes
4
12
 
5
- `LRLanguage.reconfigure` now supports changing the language data associated with the language.
13
+ Improve finding inner language in syntax tree when the nested parse has been marked as bracketed.
6
14
 
7
15
  ## 6.11.3 (2025-08-15)
8
16
 
package/dist/index.cjs CHANGED
@@ -146,7 +146,7 @@ Language.setState = state.StateEffect.define();
146
146
  function topNodeAt(state, pos, side) {
147
147
  let topLang = state.facet(language), tree = syntaxTree(state).topNode;
148
148
  if (!topLang || topLang.allowsNesting) {
149
- for (let node = tree; node; node = node.enter(pos, side, common.IterMode.ExcludeBuffers))
149
+ for (let node = tree; node; node = node.enter(pos, side, common.IterMode.ExcludeBuffers | common.IterMode.EnterBracketed))
150
150
  if (node.type.isTop)
151
151
  tree = node;
152
152
  }
@@ -158,41 +158,25 @@ A subclass of [`Language`](https://codemirror.net/6/docs/ref/#language.Language)
158
158
  parsers.
159
159
  */
160
160
  class LRLanguage extends Language {
161
- constructor(data, parser, languageData, name) {
162
- super(data, parser, languageData ? [data.of(languageData)] : [], name);
161
+ constructor(data, parser, name) {
162
+ super(data, parser, [], name);
163
163
  this.parser = parser;
164
- this.languageData = languageData;
165
164
  }
166
165
  /**
167
166
  Define a language from a parser.
168
167
  */
169
168
  static define(spec) {
170
- let data = defineLanguageFacet();
169
+ let data = defineLanguageFacet(spec.languageData);
171
170
  return new LRLanguage(data, spec.parser.configure({
172
171
  props: [languageDataProp.add(type => type.isTop ? data : undefined)]
173
- }), spec.languageData || null, spec.name);
172
+ }), spec.name);
174
173
  }
175
174
  /**
176
175
  Create a new instance of this language with a reconfigured
177
- version of its parser, language data, and name.
178
-
179
- When `languageData` is given, any property set to `undefined`
180
- in it will be removed from the language's
181
- [data](https://codemirror.net/6/docs/ref/#state.EditorState.languageDataAt), any other property
182
- is added.
176
+ version of its parser and optionally a new name.
183
177
  */
184
178
  configure(options, name) {
185
- let { languageData } = this;
186
- if (options.languageData) {
187
- languageData = {};
188
- for (let prop in options.languageData)
189
- if (options.languageData[prop] !== undefined)
190
- languageData[prop] = options.languageData[prop];
191
- for (let prop in this.languageData)
192
- if (!(prop in options.languageData))
193
- languageData[prop] = this.languageData[prop];
194
- }
195
- return new LRLanguage(this.data, this.parser.configure(options), languageData, name || this.name);
179
+ return new LRLanguage(this.data, this.parser.configure(options), name || this.name);
196
180
  }
197
181
  get allowsNesting() { return this.parser.hasWrappers(); }
198
182
  }
@@ -1878,30 +1862,44 @@ function defaultRenderMatch(match) {
1878
1862
  decorations.push(mark.range(match.end.from, match.end.to));
1879
1863
  return decorations;
1880
1864
  }
1881
- const bracketMatchingState = state.StateField.define({
1882
- create() { return view.Decoration.none; },
1883
- update(deco, tr) {
1884
- if (!tr.docChanged && !tr.selection)
1885
- return deco;
1886
- let decorations = [];
1887
- let config = tr.state.facet(bracketMatchingConfig);
1888
- for (let range of tr.state.selection.ranges) {
1889
- if (!range.empty)
1890
- continue;
1891
- let match = matchBrackets(tr.state, range.head, -1, config)
1892
- || (range.head > 0 && matchBrackets(tr.state, range.head - 1, 1, config))
1893
- || (config.afterCursor &&
1894
- (matchBrackets(tr.state, range.head, 1, config) ||
1895
- (range.head < tr.state.doc.length && matchBrackets(tr.state, range.head + 1, -1, config))));
1896
- if (match)
1897
- 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
+ }
1898
1896
  }
1899
- return view.Decoration.set(decorations, true);
1900
- },
1901
- provide: f => view.EditorView.decorations.from(f)
1897
+ }
1898
+ }, {
1899
+ decorations: v => v.decorations
1902
1900
  });
1903
1901
  const bracketMatchingUnique = [
1904
- bracketMatchingState,
1902
+ bracketMatcher,
1905
1903
  baseTheme
1906
1904
  ];
1907
1905
  /**
@@ -2225,14 +2223,14 @@ A [language](https://codemirror.net/6/docs/ref/#language.Language) class based o
2225
2223
  */
2226
2224
  class StreamLanguage extends Language {
2227
2225
  constructor(parser) {
2228
- let data = defineLanguageFacet();
2226
+ let data = defineLanguageFacet(parser.languageData);
2229
2227
  let p = fullParser(parser), self;
2230
2228
  let impl = new class extends common.Parser {
2231
2229
  createParse(input, fragments, ranges) {
2232
2230
  return new Parse(self, input, fragments, ranges);
2233
2231
  }
2234
2232
  };
2235
- super(data, impl, parser.languageData ? [data.of(parser.languageData)] : [], parser.name);
2233
+ super(data, impl, [], parser.name);
2236
2234
  this.topNode = docID(data, this);
2237
2235
  self = this;
2238
2236
  this.streamParser = p;
package/dist/index.d.cts CHANGED
@@ -143,7 +143,6 @@ parsers.
143
143
  */
144
144
  declare class LRLanguage extends Language {
145
145
  readonly parser: LRParser;
146
- private languageData;
147
146
  private constructor();
148
147
  /**
149
148
  Define a language from a parser.
@@ -169,18 +168,9 @@ declare class LRLanguage extends Language {
169
168
  }): LRLanguage;
170
169
  /**
171
170
  Create a new instance of this language with a reconfigured
172
- version of its parser, language data, and name.
173
-
174
- When `languageData` is given, any property set to `undefined`
175
- in it will be removed from the language's
176
- [data](https://codemirror.net/6/docs/ref/#state.EditorState.languageDataAt), any other property
177
- is added.
171
+ version of its parser and optionally a new name.
178
172
  */
179
- configure(options: ParserConfig & {
180
- languageData?: {
181
- [name: string]: any;
182
- };
183
- }, name?: string): LRLanguage;
173
+ configure(options: ParserConfig, name?: string): LRLanguage;
184
174
  get allowsNesting(): boolean;
185
175
  }
186
176
  /**
package/dist/index.d.ts CHANGED
@@ -143,7 +143,6 @@ parsers.
143
143
  */
144
144
  declare class LRLanguage extends Language {
145
145
  readonly parser: LRParser;
146
- private languageData;
147
146
  private constructor();
148
147
  /**
149
148
  Define a language from a parser.
@@ -169,18 +168,9 @@ declare class LRLanguage extends Language {
169
168
  }): LRLanguage;
170
169
  /**
171
170
  Create a new instance of this language with a reconfigured
172
- version of its parser, language data, and name.
173
-
174
- When `languageData` is given, any property set to `undefined`
175
- in it will be removed from the language's
176
- [data](https://codemirror.net/6/docs/ref/#state.EditorState.languageDataAt), any other property
177
- is added.
171
+ version of its parser and optionally a new name.
178
172
  */
179
- configure(options: ParserConfig & {
180
- languageData?: {
181
- [name: string]: any;
182
- };
183
- }, name?: string): LRLanguage;
173
+ configure(options: ParserConfig, name?: string): LRLanguage;
184
174
  get allowsNesting(): boolean;
185
175
  }
186
176
  /**
package/dist/index.js CHANGED
@@ -144,7 +144,7 @@ Language.setState = /*@__PURE__*/StateEffect.define();
144
144
  function topNodeAt(state, pos, side) {
145
145
  let topLang = state.facet(language), tree = syntaxTree(state).topNode;
146
146
  if (!topLang || topLang.allowsNesting) {
147
- for (let node = tree; node; node = node.enter(pos, side, IterMode.ExcludeBuffers))
147
+ for (let node = tree; node; node = node.enter(pos, side, IterMode.ExcludeBuffers | IterMode.EnterBracketed))
148
148
  if (node.type.isTop)
149
149
  tree = node;
150
150
  }
@@ -156,41 +156,25 @@ A subclass of [`Language`](https://codemirror.net/6/docs/ref/#language.Language)
156
156
  parsers.
157
157
  */
158
158
  class LRLanguage extends Language {
159
- constructor(data, parser, languageData, name) {
160
- super(data, parser, languageData ? [data.of(languageData)] : [], name);
159
+ constructor(data, parser, name) {
160
+ super(data, parser, [], name);
161
161
  this.parser = parser;
162
- this.languageData = languageData;
163
162
  }
164
163
  /**
165
164
  Define a language from a parser.
166
165
  */
167
166
  static define(spec) {
168
- let data = defineLanguageFacet();
167
+ let data = defineLanguageFacet(spec.languageData);
169
168
  return new LRLanguage(data, spec.parser.configure({
170
169
  props: [languageDataProp.add(type => type.isTop ? data : undefined)]
171
- }), spec.languageData || null, spec.name);
170
+ }), spec.name);
172
171
  }
173
172
  /**
174
173
  Create a new instance of this language with a reconfigured
175
- version of its parser, language data, and name.
176
-
177
- When `languageData` is given, any property set to `undefined`
178
- in it will be removed from the language's
179
- [data](https://codemirror.net/6/docs/ref/#state.EditorState.languageDataAt), any other property
180
- is added.
174
+ version of its parser and optionally a new name.
181
175
  */
182
176
  configure(options, name) {
183
- let { languageData } = this;
184
- if (options.languageData) {
185
- languageData = {};
186
- for (let prop in options.languageData)
187
- if (options.languageData[prop] !== undefined)
188
- languageData[prop] = options.languageData[prop];
189
- for (let prop in this.languageData)
190
- if (!(prop in options.languageData))
191
- languageData[prop] = this.languageData[prop];
192
- }
193
- return new LRLanguage(this.data, this.parser.configure(options), languageData, name || this.name);
177
+ return new LRLanguage(this.data, this.parser.configure(options), name || this.name);
194
178
  }
195
179
  get allowsNesting() { return this.parser.hasWrappers(); }
196
180
  }
@@ -1876,30 +1860,44 @@ function defaultRenderMatch(match) {
1876
1860
  decorations.push(mark.range(match.end.from, match.end.to));
1877
1861
  return decorations;
1878
1862
  }
1879
- const bracketMatchingState = /*@__PURE__*/StateField.define({
1880
- create() { return Decoration.none; },
1881
- update(deco, tr) {
1882
- if (!tr.docChanged && !tr.selection)
1883
- return deco;
1884
- let decorations = [];
1885
- let config = tr.state.facet(bracketMatchingConfig);
1886
- for (let range of tr.state.selection.ranges) {
1887
- if (!range.empty)
1888
- continue;
1889
- let match = matchBrackets(tr.state, range.head, -1, config)
1890
- || (range.head > 0 && matchBrackets(tr.state, range.head - 1, 1, config))
1891
- || (config.afterCursor &&
1892
- (matchBrackets(tr.state, range.head, 1, config) ||
1893
- (range.head < tr.state.doc.length && matchBrackets(tr.state, range.head + 1, -1, config))));
1894
- if (match)
1895
- 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
+ }
1896
1894
  }
1897
- return Decoration.set(decorations, true);
1898
- },
1899
- provide: f => EditorView.decorations.from(f)
1895
+ }
1896
+ }, {
1897
+ decorations: v => v.decorations
1900
1898
  });
1901
1899
  const bracketMatchingUnique = [
1902
- bracketMatchingState,
1900
+ bracketMatcher,
1903
1901
  baseTheme
1904
1902
  ];
1905
1903
  /**
@@ -2223,14 +2221,14 @@ A [language](https://codemirror.net/6/docs/ref/#language.Language) class based o
2223
2221
  */
2224
2222
  class StreamLanguage extends Language {
2225
2223
  constructor(parser) {
2226
- let data = defineLanguageFacet();
2224
+ let data = defineLanguageFacet(parser.languageData);
2227
2225
  let p = fullParser(parser), self;
2228
2226
  let impl = new class extends Parser {
2229
2227
  createParse(input, fragments, ranges) {
2230
2228
  return new Parse(self, input, fragments, ranges);
2231
2229
  }
2232
2230
  };
2233
- super(data, impl, parser.languageData ? [data.of(parser.languageData)] : [], parser.name);
2231
+ super(data, impl, [], parser.name);
2234
2232
  this.topNode = docID(data, this);
2235
2233
  self = this;
2236
2234
  this.streamParser = p;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/language",
3
- "version": "6.12.0",
3
+ "version": "6.12.2",
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.23.0",
31
- "@lezer/common": "^1.1.0",
31
+ "@lezer/common": "^1.5.0",
32
32
  "@lezer/highlight": "^1.0.0",
33
33
  "@lezer/lr": "^1.0.0",
34
34
  "style-mod": "^4.0.0"
@@ -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
  }