@codemirror/language 6.2.1 → 6.3.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,11 @@
1
+ ## 6.3.0 (2022-10-24)
2
+
3
+ ### New features
4
+
5
+ `HighlightStyle` objects now have a `specs` property holding the tag styles that were used to define them.
6
+
7
+ `Language` objects now have a `name` field holding the language name.
8
+
1
9
  ## 6.2.1 (2022-07-21)
2
10
 
3
11
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -49,8 +49,13 @@ class Language {
49
49
  The [language data](https://codemirror.net/6/docs/ref/#state.EditorState.languageDataAt) facet
50
50
  used for this language.
51
51
  */
52
- data, parser, extraExtensions = []) {
52
+ data, parser, extraExtensions = [],
53
+ /**
54
+ A language name.
55
+ */
56
+ name = "") {
53
57
  this.data = data;
58
+ this.name = name;
54
59
  // Kludge to define EditorState.tree as a debugging helper,
55
60
  // without the EditorState package actually knowing about
56
61
  // languages and lezer trees.
@@ -138,8 +143,8 @@ A subclass of [`Language`](https://codemirror.net/6/docs/ref/#language.Language)
138
143
  parsers.
139
144
  */
140
145
  class LRLanguage extends Language {
141
- constructor(data, parser) {
142
- super(data, parser);
146
+ constructor(data, parser, name) {
147
+ super(data, parser, [], name);
143
148
  this.parser = parser;
144
149
  }
145
150
  /**
@@ -149,14 +154,14 @@ class LRLanguage extends Language {
149
154
  let data = defineLanguageFacet(spec.languageData);
150
155
  return new LRLanguage(data, spec.parser.configure({
151
156
  props: [languageDataProp.add(type => type.isTop ? data : undefined)]
152
- }));
157
+ }), spec.name);
153
158
  }
154
159
  /**
155
160
  Create a new instance of this language with a reconfigured
156
- version of its parser.
161
+ version of its parser and optionally a new name.
157
162
  */
158
- configure(options) {
159
- return new LRLanguage(this.data, this.parser.configure(options));
163
+ configure(options, name) {
164
+ return new LRLanguage(this.data, this.parser.configure(options), name || this.name);
160
165
  }
161
166
  get allowsNesting() { return this.parser.hasWrappers(); }
162
167
  }
@@ -503,14 +508,14 @@ class LanguageState {
503
508
  // state updates with parse work beyond the viewport.
504
509
  let upto = this.context.treeLen == tr.startState.doc.length ? undefined
505
510
  : Math.max(tr.changes.mapPos(this.context.treeLen), newCx.viewport.to);
506
- if (!newCx.work(20 /* Apply */, upto))
511
+ if (!newCx.work(20 /* Work.Apply */, upto))
507
512
  newCx.takeTree();
508
513
  return new LanguageState(newCx);
509
514
  }
510
515
  static init(state) {
511
- let vpTo = Math.min(3000 /* InitViewport */, state.doc.length);
516
+ let vpTo = Math.min(3000 /* Work.InitViewport */, state.doc.length);
512
517
  let parseState = ParseContext.create(state.facet(language).parser, state, { from: 0, to: vpTo });
513
- if (!parseState.work(20 /* Apply */, vpTo))
518
+ if (!parseState.work(20 /* Work.Apply */, vpTo))
514
519
  parseState.takeTree();
515
520
  return new LanguageState(parseState);
516
521
  }
@@ -527,14 +532,14 @@ Language.state = state.StateField.define({
527
532
  }
528
533
  });
529
534
  let requestIdle = (callback) => {
530
- let timeout = setTimeout(() => callback(), 500 /* MaxPause */);
535
+ let timeout = setTimeout(() => callback(), 500 /* Work.MaxPause */);
531
536
  return () => clearTimeout(timeout);
532
537
  };
533
538
  if (typeof requestIdleCallback != "undefined")
534
539
  requestIdle = (callback) => {
535
540
  let idle = -1, timeout = setTimeout(() => {
536
- idle = requestIdleCallback(callback, { timeout: 500 /* MaxPause */ - 100 /* MinPause */ });
537
- }, 100 /* MinPause */);
541
+ idle = requestIdleCallback(callback, { timeout: 500 /* Work.MaxPause */ - 100 /* Work.MinPause */ });
542
+ }, 100 /* Work.MinPause */);
538
543
  return () => idle < 0 ? clearTimeout(timeout) : cancelIdleCallback(idle);
539
544
  };
540
545
  const isInputPending = typeof navigator != "undefined" && ((_a = navigator.scheduling) === null || _a === void 0 ? void 0 : _a.isInputPending)
@@ -557,7 +562,7 @@ const parseWorker = view.ViewPlugin.fromClass(class ParseWorker {
557
562
  this.scheduleWork();
558
563
  if (update.docChanged) {
559
564
  if (this.view.hasFocus)
560
- this.chunkBudget += 50 /* ChangeBonus */;
565
+ this.chunkBudget += 50 /* Work.ChangeBonus */;
561
566
  this.scheduleWork();
562
567
  }
563
568
  this.checkAsyncSchedule(cx);
@@ -573,19 +578,19 @@ const parseWorker = view.ViewPlugin.fromClass(class ParseWorker {
573
578
  this.working = null;
574
579
  let now = Date.now();
575
580
  if (this.chunkEnd < now && (this.chunkEnd < 0 || this.view.hasFocus)) { // Start a new chunk
576
- this.chunkEnd = now + 30000 /* ChunkTime */;
577
- this.chunkBudget = 3000 /* ChunkBudget */;
581
+ this.chunkEnd = now + 30000 /* Work.ChunkTime */;
582
+ this.chunkBudget = 3000 /* Work.ChunkBudget */;
578
583
  }
579
584
  if (this.chunkBudget <= 0)
580
585
  return; // No more budget
581
586
  let { state, viewport: { to: vpTo } } = this.view, field = state.field(Language.state);
582
- if (field.tree == field.context.tree && field.context.isDone(vpTo + 100000 /* MaxParseAhead */))
587
+ if (field.tree == field.context.tree && field.context.isDone(vpTo + 100000 /* Work.MaxParseAhead */))
583
588
  return;
584
- let endTime = Date.now() + Math.min(this.chunkBudget, 100 /* Slice */, deadline && !isInputPending ? Math.max(25 /* MinSlice */, deadline.timeRemaining() - 5) : 1e9);
589
+ let endTime = Date.now() + Math.min(this.chunkBudget, 100 /* Work.Slice */, deadline && !isInputPending ? Math.max(25 /* Work.MinSlice */, deadline.timeRemaining() - 5) : 1e9);
585
590
  let viewportFirst = field.context.treeLen < vpTo && state.doc.length > vpTo + 1000;
586
591
  let done = field.context.work(() => {
587
592
  return isInputPending && isInputPending() || Date.now() > endTime;
588
- }, vpTo + (viewportFirst ? 0 : 100000 /* MaxParseAhead */));
593
+ }, vpTo + (viewportFirst ? 0 : 100000 /* Work.MaxParseAhead */));
589
594
  this.chunkBudget -= Date.now() - now;
590
595
  if (done || this.chunkBudget <= 0) {
591
596
  field.context.takeTree();
@@ -623,7 +628,14 @@ current language on a state.
623
628
  */
624
629
  const language = state.Facet.define({
625
630
  combine(languages) { return languages.length ? languages[0] : null; },
626
- enables: [Language.state, parseWorker]
631
+ enables: language => [
632
+ Language.state,
633
+ parseWorker,
634
+ view.EditorView.contentAttributes.compute([language], state => {
635
+ let lang = state.facet(language);
636
+ return lang && lang.name ? { "data-language": lang.name } : {};
637
+ })
638
+ ]
627
639
  });
628
640
  /**
629
641
  This class bundles a [language](https://codemirror.net/6/docs/ref/#language.Language) with an
@@ -753,8 +765,10 @@ class LanguageDescription {
753
765
 
754
766
  /**
755
767
  Facet that defines a way to provide a function that computes the
756
- appropriate indentation depth at the start of a given line, or
757
- `null` to indicate no appropriate indentation could be determined.
768
+ appropriate indentation depth, as a column number (see
769
+ [`indentString`](https://codemirror.net/6/docs/ref/#language.indentString)), at the start of a given
770
+ line, or `null` to indicate no appropriate indentation could be
771
+ determined.
758
772
  */
759
773
  const indentService = state.Facet.define();
760
774
  /**
@@ -799,12 +813,13 @@ function indentString(state, cols) {
799
813
  return result;
800
814
  }
801
815
  /**
802
- Get the indentation at the given position. Will first consult any
803
- [indent services](https://codemirror.net/6/docs/ref/#language.indentService) that are registered,
804
- and if none of those return an indentation, this will check the
805
- syntax tree for the [indent node prop](https://codemirror.net/6/docs/ref/#language.indentNodeProp)
806
- and use that if found. Returns a number when an indentation could
807
- be determined, and null otherwise.
816
+ Get the indentation, as a column number, at the given position.
817
+ Will first consult any [indent services](https://codemirror.net/6/docs/ref/#language.indentService)
818
+ that are registered, and if none of those return an indentation,
819
+ this will check the syntax tree for the [indent node
820
+ prop](https://codemirror.net/6/docs/ref/#language.indentNodeProp) and use that if found. Returns a
821
+ number when an indentation could be determined, and null
822
+ otherwise.
808
823
  */
809
824
  function getIndentation(context, pos) {
810
825
  if (context instanceof state.EditorState)
@@ -939,8 +954,9 @@ class IndentContext {
939
954
  /**
940
955
  A syntax tree node prop used to associate indentation strategies
941
956
  with node types. Such a strategy is a function from an indentation
942
- context to a column number or null, where null indicates that no
943
- definitive indentation can be determined.
957
+ context to a column number (see also
958
+ [`indentString`](https://codemirror.net/6/docs/ref/#language.indentString)) or null, where null
959
+ indicates that no definitive indentation can be determined.
944
960
  */
945
961
  const indentNodeProp = new common.NodeProp();
946
962
  // Compute the indentation for a given position from the syntax tree.
@@ -1531,7 +1547,12 @@ A highlight style associates CSS styles with higlighting
1531
1547
  [tags](https://lezer.codemirror.net/docs/ref#highlight.Tag).
1532
1548
  */
1533
1549
  class HighlightStyle {
1534
- constructor(spec, options) {
1550
+ constructor(
1551
+ /**
1552
+ The tag styles used to create this highlight style.
1553
+ */
1554
+ specs, options) {
1555
+ this.specs = specs;
1535
1556
  let modSpec;
1536
1557
  function def(spec) {
1537
1558
  let cls = styleMod.StyleModule.newName();
@@ -1542,7 +1563,7 @@ class HighlightStyle {
1542
1563
  const scopeOpt = options.scope;
1543
1564
  this.scope = scopeOpt instanceof Language ? (type) => type.prop(languageDataProp) == scopeOpt.data
1544
1565
  : scopeOpt ? (type) => type == scopeOpt : undefined;
1545
- this.style = highlight.tagHighlighter(spec.map(style => ({
1566
+ this.style = highlight.tagHighlighter(specs.map(style => ({
1546
1567
  tag: style.tag,
1547
1568
  class: style.class || def(Object.assign({}, style, { tag: null }))
1548
1569
  })), {
@@ -2021,6 +2042,7 @@ class StringStream {
2021
2042
 
2022
2043
  function fullParser(spec) {
2023
2044
  return {
2045
+ name: spec.name || "",
2024
2046
  token: spec.token,
2025
2047
  blankLine: spec.blankLine || (() => { }),
2026
2048
  startState: spec.startState || (() => true),
@@ -2053,7 +2075,7 @@ class StreamLanguage extends Language {
2053
2075
  return new Parse(self, input, fragments, ranges);
2054
2076
  }
2055
2077
  };
2056
- super(data, impl, [indentService.of((cx, pos) => this.getIndent(cx, pos))]);
2078
+ super(data, impl, [indentService.of((cx, pos) => this.getIndent(cx, pos))], parser.name);
2057
2079
  this.topNode = docID(data);
2058
2080
  self = this;
2059
2081
  this.streamParser = p;
@@ -2079,7 +2101,7 @@ class StreamLanguage extends Language {
2079
2101
  state = this.streamParser.startState(cx.unit);
2080
2102
  statePos = 0;
2081
2103
  }
2082
- if (pos - statePos > 10000 /* MaxIndentScanDist */)
2104
+ if (pos - statePos > 10000 /* C.MaxIndentScanDist */)
2083
2105
  return null;
2084
2106
  while (statePos < pos) {
2085
2107
  let line = cx.state.doc.lineAt(statePos), end = Math.min(pos, line.to);
@@ -2158,7 +2180,7 @@ class Parse {
2158
2180
  this.chunks.push(tree.children[i]);
2159
2181
  this.chunkPos.push(tree.positions[i]);
2160
2182
  }
2161
- if (context && this.parsedPos < context.viewport.from - 100000 /* MaxDistanceBeforeViewport */) {
2183
+ if (context && this.parsedPos < context.viewport.from - 100000 /* C.MaxDistanceBeforeViewport */) {
2162
2184
  this.state = this.lang.streamParser.startState(getIndentUnit(context.state));
2163
2185
  context.skipUntilInView(this.parsedPos, context.viewport.from);
2164
2186
  this.parsedPos = context.viewport.from;
@@ -2168,7 +2190,7 @@ class Parse {
2168
2190
  advance() {
2169
2191
  let context = ParseContext.get();
2170
2192
  let parseEnd = this.stoppedAt == null ? this.to : Math.min(this.to, this.stoppedAt);
2171
- let end = Math.min(parseEnd, this.chunkStart + 2048 /* ChunkSize */);
2193
+ let end = Math.min(parseEnd, this.chunkStart + 2048 /* C.ChunkSize */);
2172
2194
  if (context)
2173
2195
  end = Math.min(end, context.viewport.to);
2174
2196
  while (this.parsedPos < end)
@@ -2252,7 +2274,7 @@ class Parse {
2252
2274
  let token = readToken(streamParser.token, stream, this.state);
2253
2275
  if (token)
2254
2276
  offset = this.emitToken(this.lang.tokenTable.resolve(token), this.parsedPos + stream.start, this.parsedPos + stream.pos, 4, offset);
2255
- if (stream.start > 10000 /* MaxLineLength */)
2277
+ if (stream.start > 10000 /* C.MaxLineLength */)
2256
2278
  break;
2257
2279
  }
2258
2280
  }
@@ -2268,7 +2290,7 @@ class Parse {
2268
2290
  length: this.parsedPos - this.chunkStart,
2269
2291
  nodeSet,
2270
2292
  topID: 0,
2271
- maxBufferLength: 2048 /* ChunkSize */,
2293
+ maxBufferLength: 2048 /* C.ChunkSize */,
2272
2294
  reused: this.chunkReused
2273
2295
  });
2274
2296
  tree = new common.Tree(tree.type, tree.children, tree.positions, tree.length, [[this.lang.stateAfter, this.lang.streamParser.copyState(this.state)]]);
package/dist/index.d.ts CHANGED
@@ -48,6 +48,10 @@ declare class Language {
48
48
  [name: string]: any;
49
49
  }>;
50
50
  /**
51
+ A language name.
52
+ */
53
+ readonly name: string;
54
+ /**
51
55
  The extension value to install this as the document language.
52
56
  */
53
57
  readonly extension: Extension;
@@ -70,7 +74,11 @@ declare class Language {
70
74
  */
71
75
  data: Facet<{
72
76
  [name: string]: any;
73
- }>, parser: Parser, extraExtensions?: Extension[]);
77
+ }>, parser: Parser, extraExtensions?: Extension[],
78
+ /**
79
+ A language name.
80
+ */
81
+ name?: string);
74
82
  /**
75
83
  Query whether this language is active at the given position.
76
84
  */
@@ -102,6 +110,10 @@ declare class LRLanguage extends Language {
102
110
  Define a language from a parser.
103
111
  */
104
112
  static define(spec: {
113
+ /**
114
+ The [name](https://codemirror.net/6/docs/ref/#Language.name) of the language.
115
+ */
116
+ name?: string;
105
117
  /**
106
118
  The parser to use. Should already have added editor-relevant
107
119
  node props (and optionally things like dialect and top rule)
@@ -118,9 +130,9 @@ declare class LRLanguage extends Language {
118
130
  }): LRLanguage;
119
131
  /**
120
132
  Create a new instance of this language with a reconfigured
121
- version of its parser.
133
+ version of its parser and optionally a new name.
122
134
  */
123
- configure(options: ParserConfig): LRLanguage;
135
+ configure(options: ParserConfig, name?: string): LRLanguage;
124
136
  get allowsNesting(): boolean;
125
137
  }
126
138
  /**
@@ -349,8 +361,10 @@ declare class LanguageDescription {
349
361
 
350
362
  /**
351
363
  Facet that defines a way to provide a function that computes the
352
- appropriate indentation depth at the start of a given line, or
353
- `null` to indicate no appropriate indentation could be determined.
364
+ appropriate indentation depth, as a column number (see
365
+ [`indentString`](https://codemirror.net/6/docs/ref/#language.indentString)), at the start of a given
366
+ line, or `null` to indicate no appropriate indentation could be
367
+ determined.
354
368
  */
355
369
  declare const indentService: Facet<(context: IndentContext, pos: number) => number | null, readonly ((context: IndentContext, pos: number) => number | null)[]>;
356
370
  /**
@@ -374,12 +388,13 @@ tabs.
374
388
  */
375
389
  declare function indentString(state: EditorState, cols: number): string;
376
390
  /**
377
- Get the indentation at the given position. Will first consult any
378
- [indent services](https://codemirror.net/6/docs/ref/#language.indentService) that are registered,
379
- and if none of those return an indentation, this will check the
380
- syntax tree for the [indent node prop](https://codemirror.net/6/docs/ref/#language.indentNodeProp)
381
- and use that if found. Returns a number when an indentation could
382
- be determined, and null otherwise.
391
+ Get the indentation, as a column number, at the given position.
392
+ Will first consult any [indent services](https://codemirror.net/6/docs/ref/#language.indentService)
393
+ that are registered, and if none of those return an indentation,
394
+ this will check the syntax tree for the [indent node
395
+ prop](https://codemirror.net/6/docs/ref/#language.indentNodeProp) and use that if found. Returns a
396
+ number when an indentation could be determined, and null
397
+ otherwise.
383
398
  */
384
399
  declare function getIndentation(context: IndentContext | EditorState, pos: number): number | null;
385
400
  /**
@@ -477,8 +492,9 @@ declare class IndentContext {
477
492
  /**
478
493
  A syntax tree node prop used to associate indentation strategies
479
494
  with node types. Such a strategy is a function from an indentation
480
- context to a column number or null, where null indicates that no
481
- definitive indentation can be determined.
495
+ context to a column number (see also
496
+ [`indentString`](https://codemirror.net/6/docs/ref/#language.indentString)) or null, where null
497
+ indicates that no definitive indentation can be determined.
482
498
  */
483
499
  declare const indentNodeProp: NodeProp<(context: TreeIndentContext) => number | null>;
484
500
  /**
@@ -732,6 +748,10 @@ A highlight style associates CSS styles with higlighting
732
748
  [tags](https://lezer.codemirror.net/docs/ref#highlight.Tag).
733
749
  */
734
750
  declare class HighlightStyle implements Highlighter {
751
+ /**
752
+ The tag styles used to create this highlight style.
753
+ */
754
+ readonly specs: readonly TagStyle[];
735
755
  /**
736
756
  A style module holding the CSS rules for this highlight style.
737
757
  When using
@@ -1013,6 +1033,10 @@ copyable) object with state, in which it can store information
1013
1033
  about the current context.
1014
1034
  */
1015
1035
  interface StreamParser<State> {
1036
+ /**
1037
+ A name for this language.
1038
+ */
1039
+ name?: string;
1016
1040
  /**
1017
1041
  Produce a start state for the parser.
1018
1042
  */
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { NodeProp, Tree, IterMode, TreeFragment, Parser, NodeType, NodeSet } from '@lezer/common';
2
2
  import { StateEffect, StateField, Facet, EditorState, countColumn, combineConfig, RangeSet, RangeSetBuilder, Prec } from '@codemirror/state';
3
- import { ViewPlugin, logException, Decoration, EditorView, WidgetType, gutter, GutterMarker } from '@codemirror/view';
3
+ import { ViewPlugin, logException, EditorView, Decoration, WidgetType, gutter, GutterMarker } from '@codemirror/view';
4
4
  import { tags, tagHighlighter, highlightTree, styleTags } from '@lezer/highlight';
5
5
  import { StyleModule } from 'style-mod';
6
6
 
@@ -45,8 +45,13 @@ class Language {
45
45
  The [language data](https://codemirror.net/6/docs/ref/#state.EditorState.languageDataAt) facet
46
46
  used for this language.
47
47
  */
48
- data, parser, extraExtensions = []) {
48
+ data, parser, extraExtensions = [],
49
+ /**
50
+ A language name.
51
+ */
52
+ name = "") {
49
53
  this.data = data;
54
+ this.name = name;
50
55
  // Kludge to define EditorState.tree as a debugging helper,
51
56
  // without the EditorState package actually knowing about
52
57
  // languages and lezer trees.
@@ -134,8 +139,8 @@ A subclass of [`Language`](https://codemirror.net/6/docs/ref/#language.Language)
134
139
  parsers.
135
140
  */
136
141
  class LRLanguage extends Language {
137
- constructor(data, parser) {
138
- super(data, parser);
142
+ constructor(data, parser, name) {
143
+ super(data, parser, [], name);
139
144
  this.parser = parser;
140
145
  }
141
146
  /**
@@ -145,14 +150,14 @@ class LRLanguage extends Language {
145
150
  let data = defineLanguageFacet(spec.languageData);
146
151
  return new LRLanguage(data, spec.parser.configure({
147
152
  props: [languageDataProp.add(type => type.isTop ? data : undefined)]
148
- }));
153
+ }), spec.name);
149
154
  }
150
155
  /**
151
156
  Create a new instance of this language with a reconfigured
152
- version of its parser.
157
+ version of its parser and optionally a new name.
153
158
  */
154
- configure(options) {
155
- return new LRLanguage(this.data, this.parser.configure(options));
159
+ configure(options, name) {
160
+ return new LRLanguage(this.data, this.parser.configure(options), name || this.name);
156
161
  }
157
162
  get allowsNesting() { return this.parser.hasWrappers(); }
158
163
  }
@@ -499,14 +504,14 @@ class LanguageState {
499
504
  // state updates with parse work beyond the viewport.
500
505
  let upto = this.context.treeLen == tr.startState.doc.length ? undefined
501
506
  : Math.max(tr.changes.mapPos(this.context.treeLen), newCx.viewport.to);
502
- if (!newCx.work(20 /* Apply */, upto))
507
+ if (!newCx.work(20 /* Work.Apply */, upto))
503
508
  newCx.takeTree();
504
509
  return new LanguageState(newCx);
505
510
  }
506
511
  static init(state) {
507
- let vpTo = Math.min(3000 /* InitViewport */, state.doc.length);
512
+ let vpTo = Math.min(3000 /* Work.InitViewport */, state.doc.length);
508
513
  let parseState = ParseContext.create(state.facet(language).parser, state, { from: 0, to: vpTo });
509
- if (!parseState.work(20 /* Apply */, vpTo))
514
+ if (!parseState.work(20 /* Work.Apply */, vpTo))
510
515
  parseState.takeTree();
511
516
  return new LanguageState(parseState);
512
517
  }
@@ -523,14 +528,14 @@ Language.state = /*@__PURE__*/StateField.define({
523
528
  }
524
529
  });
525
530
  let requestIdle = (callback) => {
526
- let timeout = setTimeout(() => callback(), 500 /* MaxPause */);
531
+ let timeout = setTimeout(() => callback(), 500 /* Work.MaxPause */);
527
532
  return () => clearTimeout(timeout);
528
533
  };
529
534
  if (typeof requestIdleCallback != "undefined")
530
535
  requestIdle = (callback) => {
531
536
  let idle = -1, timeout = setTimeout(() => {
532
- idle = requestIdleCallback(callback, { timeout: 500 /* MaxPause */ - 100 /* MinPause */ });
533
- }, 100 /* MinPause */);
537
+ idle = requestIdleCallback(callback, { timeout: 500 /* Work.MaxPause */ - 100 /* Work.MinPause */ });
538
+ }, 100 /* Work.MinPause */);
534
539
  return () => idle < 0 ? clearTimeout(timeout) : cancelIdleCallback(idle);
535
540
  };
536
541
  const isInputPending = typeof navigator != "undefined" && ((_a = navigator.scheduling) === null || _a === void 0 ? void 0 : _a.isInputPending)
@@ -553,7 +558,7 @@ const parseWorker = /*@__PURE__*/ViewPlugin.fromClass(class ParseWorker {
553
558
  this.scheduleWork();
554
559
  if (update.docChanged) {
555
560
  if (this.view.hasFocus)
556
- this.chunkBudget += 50 /* ChangeBonus */;
561
+ this.chunkBudget += 50 /* Work.ChangeBonus */;
557
562
  this.scheduleWork();
558
563
  }
559
564
  this.checkAsyncSchedule(cx);
@@ -569,19 +574,19 @@ const parseWorker = /*@__PURE__*/ViewPlugin.fromClass(class ParseWorker {
569
574
  this.working = null;
570
575
  let now = Date.now();
571
576
  if (this.chunkEnd < now && (this.chunkEnd < 0 || this.view.hasFocus)) { // Start a new chunk
572
- this.chunkEnd = now + 30000 /* ChunkTime */;
573
- this.chunkBudget = 3000 /* ChunkBudget */;
577
+ this.chunkEnd = now + 30000 /* Work.ChunkTime */;
578
+ this.chunkBudget = 3000 /* Work.ChunkBudget */;
574
579
  }
575
580
  if (this.chunkBudget <= 0)
576
581
  return; // No more budget
577
582
  let { state, viewport: { to: vpTo } } = this.view, field = state.field(Language.state);
578
- if (field.tree == field.context.tree && field.context.isDone(vpTo + 100000 /* MaxParseAhead */))
583
+ if (field.tree == field.context.tree && field.context.isDone(vpTo + 100000 /* Work.MaxParseAhead */))
579
584
  return;
580
- let endTime = Date.now() + Math.min(this.chunkBudget, 100 /* Slice */, deadline && !isInputPending ? Math.max(25 /* MinSlice */, deadline.timeRemaining() - 5) : 1e9);
585
+ let endTime = Date.now() + Math.min(this.chunkBudget, 100 /* Work.Slice */, deadline && !isInputPending ? Math.max(25 /* Work.MinSlice */, deadline.timeRemaining() - 5) : 1e9);
581
586
  let viewportFirst = field.context.treeLen < vpTo && state.doc.length > vpTo + 1000;
582
587
  let done = field.context.work(() => {
583
588
  return isInputPending && isInputPending() || Date.now() > endTime;
584
- }, vpTo + (viewportFirst ? 0 : 100000 /* MaxParseAhead */));
589
+ }, vpTo + (viewportFirst ? 0 : 100000 /* Work.MaxParseAhead */));
585
590
  this.chunkBudget -= Date.now() - now;
586
591
  if (done || this.chunkBudget <= 0) {
587
592
  field.context.takeTree();
@@ -619,7 +624,14 @@ current language on a state.
619
624
  */
620
625
  const language = /*@__PURE__*/Facet.define({
621
626
  combine(languages) { return languages.length ? languages[0] : null; },
622
- enables: [Language.state, parseWorker]
627
+ enables: language => [
628
+ Language.state,
629
+ parseWorker,
630
+ EditorView.contentAttributes.compute([language], state => {
631
+ let lang = state.facet(language);
632
+ return lang && lang.name ? { "data-language": lang.name } : {};
633
+ })
634
+ ]
623
635
  });
624
636
  /**
625
637
  This class bundles a [language](https://codemirror.net/6/docs/ref/#language.Language) with an
@@ -749,8 +761,10 @@ class LanguageDescription {
749
761
 
750
762
  /**
751
763
  Facet that defines a way to provide a function that computes the
752
- appropriate indentation depth at the start of a given line, or
753
- `null` to indicate no appropriate indentation could be determined.
764
+ appropriate indentation depth, as a column number (see
765
+ [`indentString`](https://codemirror.net/6/docs/ref/#language.indentString)), at the start of a given
766
+ line, or `null` to indicate no appropriate indentation could be
767
+ determined.
754
768
  */
755
769
  const indentService = /*@__PURE__*/Facet.define();
756
770
  /**
@@ -795,12 +809,13 @@ function indentString(state, cols) {
795
809
  return result;
796
810
  }
797
811
  /**
798
- Get the indentation at the given position. Will first consult any
799
- [indent services](https://codemirror.net/6/docs/ref/#language.indentService) that are registered,
800
- and if none of those return an indentation, this will check the
801
- syntax tree for the [indent node prop](https://codemirror.net/6/docs/ref/#language.indentNodeProp)
802
- and use that if found. Returns a number when an indentation could
803
- be determined, and null otherwise.
812
+ Get the indentation, as a column number, at the given position.
813
+ Will first consult any [indent services](https://codemirror.net/6/docs/ref/#language.indentService)
814
+ that are registered, and if none of those return an indentation,
815
+ this will check the syntax tree for the [indent node
816
+ prop](https://codemirror.net/6/docs/ref/#language.indentNodeProp) and use that if found. Returns a
817
+ number when an indentation could be determined, and null
818
+ otherwise.
804
819
  */
805
820
  function getIndentation(context, pos) {
806
821
  if (context instanceof EditorState)
@@ -935,8 +950,9 @@ class IndentContext {
935
950
  /**
936
951
  A syntax tree node prop used to associate indentation strategies
937
952
  with node types. Such a strategy is a function from an indentation
938
- context to a column number or null, where null indicates that no
939
- definitive indentation can be determined.
953
+ context to a column number (see also
954
+ [`indentString`](https://codemirror.net/6/docs/ref/#language.indentString)) or null, where null
955
+ indicates that no definitive indentation can be determined.
940
956
  */
941
957
  const indentNodeProp = /*@__PURE__*/new NodeProp();
942
958
  // Compute the indentation for a given position from the syntax tree.
@@ -1527,7 +1543,12 @@ A highlight style associates CSS styles with higlighting
1527
1543
  [tags](https://lezer.codemirror.net/docs/ref#highlight.Tag).
1528
1544
  */
1529
1545
  class HighlightStyle {
1530
- constructor(spec, options) {
1546
+ constructor(
1547
+ /**
1548
+ The tag styles used to create this highlight style.
1549
+ */
1550
+ specs, options) {
1551
+ this.specs = specs;
1531
1552
  let modSpec;
1532
1553
  function def(spec) {
1533
1554
  let cls = StyleModule.newName();
@@ -1538,7 +1559,7 @@ class HighlightStyle {
1538
1559
  const scopeOpt = options.scope;
1539
1560
  this.scope = scopeOpt instanceof Language ? (type) => type.prop(languageDataProp) == scopeOpt.data
1540
1561
  : scopeOpt ? (type) => type == scopeOpt : undefined;
1541
- this.style = tagHighlighter(spec.map(style => ({
1562
+ this.style = tagHighlighter(specs.map(style => ({
1542
1563
  tag: style.tag,
1543
1564
  class: style.class || def(Object.assign({}, style, { tag: null }))
1544
1565
  })), {
@@ -2017,6 +2038,7 @@ class StringStream {
2017
2038
 
2018
2039
  function fullParser(spec) {
2019
2040
  return {
2041
+ name: spec.name || "",
2020
2042
  token: spec.token,
2021
2043
  blankLine: spec.blankLine || (() => { }),
2022
2044
  startState: spec.startState || (() => true),
@@ -2049,7 +2071,7 @@ class StreamLanguage extends Language {
2049
2071
  return new Parse(self, input, fragments, ranges);
2050
2072
  }
2051
2073
  };
2052
- super(data, impl, [indentService.of((cx, pos) => this.getIndent(cx, pos))]);
2074
+ super(data, impl, [indentService.of((cx, pos) => this.getIndent(cx, pos))], parser.name);
2053
2075
  this.topNode = docID(data);
2054
2076
  self = this;
2055
2077
  this.streamParser = p;
@@ -2075,7 +2097,7 @@ class StreamLanguage extends Language {
2075
2097
  state = this.streamParser.startState(cx.unit);
2076
2098
  statePos = 0;
2077
2099
  }
2078
- if (pos - statePos > 10000 /* MaxIndentScanDist */)
2100
+ if (pos - statePos > 10000 /* C.MaxIndentScanDist */)
2079
2101
  return null;
2080
2102
  while (statePos < pos) {
2081
2103
  let line = cx.state.doc.lineAt(statePos), end = Math.min(pos, line.to);
@@ -2154,7 +2176,7 @@ class Parse {
2154
2176
  this.chunks.push(tree.children[i]);
2155
2177
  this.chunkPos.push(tree.positions[i]);
2156
2178
  }
2157
- if (context && this.parsedPos < context.viewport.from - 100000 /* MaxDistanceBeforeViewport */) {
2179
+ if (context && this.parsedPos < context.viewport.from - 100000 /* C.MaxDistanceBeforeViewport */) {
2158
2180
  this.state = this.lang.streamParser.startState(getIndentUnit(context.state));
2159
2181
  context.skipUntilInView(this.parsedPos, context.viewport.from);
2160
2182
  this.parsedPos = context.viewport.from;
@@ -2164,7 +2186,7 @@ class Parse {
2164
2186
  advance() {
2165
2187
  let context = ParseContext.get();
2166
2188
  let parseEnd = this.stoppedAt == null ? this.to : Math.min(this.to, this.stoppedAt);
2167
- let end = Math.min(parseEnd, this.chunkStart + 2048 /* ChunkSize */);
2189
+ let end = Math.min(parseEnd, this.chunkStart + 2048 /* C.ChunkSize */);
2168
2190
  if (context)
2169
2191
  end = Math.min(end, context.viewport.to);
2170
2192
  while (this.parsedPos < end)
@@ -2248,7 +2270,7 @@ class Parse {
2248
2270
  let token = readToken(streamParser.token, stream, this.state);
2249
2271
  if (token)
2250
2272
  offset = this.emitToken(this.lang.tokenTable.resolve(token), this.parsedPos + stream.start, this.parsedPos + stream.pos, 4, offset);
2251
- if (stream.start > 10000 /* MaxLineLength */)
2273
+ if (stream.start > 10000 /* C.MaxLineLength */)
2252
2274
  break;
2253
2275
  }
2254
2276
  }
@@ -2264,7 +2286,7 @@ class Parse {
2264
2286
  length: this.parsedPos - this.chunkStart,
2265
2287
  nodeSet,
2266
2288
  topID: 0,
2267
- maxBufferLength: 2048 /* ChunkSize */,
2289
+ maxBufferLength: 2048 /* C.ChunkSize */,
2268
2290
  reused: this.chunkReused
2269
2291
  });
2270
2292
  tree = new Tree(tree.type, tree.children, tree.positions, tree.length, [[this.lang.stateAfter, this.lang.streamParser.copyState(this.state)]]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/language",
3
- "version": "6.2.1",
3
+ "version": "6.3.0",
4
4
  "description": "Language support infrastructure for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",