@codemirror/state 6.3.3 → 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,15 @@
1
+ ## 6.4.0 (2023-12-28)
2
+
3
+ ### Bug fixes
4
+
5
+ When multiple ranges in a single range set overlap, put the smaller ones inside the bigger ones, so that overlapping decorations don't break up each other's elements when coming from the same source.
6
+
7
+ ### New features
8
+
9
+ Selection and selection range `eq` methods now support an optional argument that makes them also compare by cursor associativity.
10
+
11
+ The `RangeSet.join` function can be used to join multiple range sets together.
12
+
1
13
  ## 6.3.3 (2023-12-06)
2
14
 
3
15
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -1391,8 +1391,9 @@ class SelectionRange {
1391
1391
  /**
1392
1392
  Compare this range to another range.
1393
1393
  */
1394
- eq(other) {
1395
- return this.anchor == other.anchor && this.head == other.head;
1394
+ eq(other, includeAssoc = false) {
1395
+ return this.anchor == other.anchor && this.head == other.head &&
1396
+ (!includeAssoc || !this.empty || this.assoc == other.assoc);
1396
1397
  }
1397
1398
  /**
1398
1399
  Return a JSON-serializable object representing the range.
@@ -1442,14 +1443,17 @@ class EditorSelection {
1442
1443
  return EditorSelection.create(this.ranges.map(r => r.map(change, assoc)), this.mainIndex);
1443
1444
  }
1444
1445
  /**
1445
- Compare this selection to another selection.
1446
+ Compare this selection to another selection. By default, ranges
1447
+ are compared only by position. When `includeAssoc` is true,
1448
+ cursor ranges must also have the same
1449
+ [`assoc`](https://codemirror.net/6/docs/ref/#state.SelectionRange.assoc) value.
1446
1450
  */
1447
- eq(other) {
1451
+ eq(other, includeAssoc = false) {
1448
1452
  if (this.ranges.length != other.ranges.length ||
1449
1453
  this.mainIndex != other.mainIndex)
1450
1454
  return false;
1451
1455
  for (let i = 0; i < this.ranges.length; i++)
1452
- if (!this.ranges[i].eq(other.ranges[i]))
1456
+ if (!this.ranges[i].eq(other.ranges[i], includeAssoc))
1453
1457
  return false;
1454
1458
  return true;
1455
1459
  }
@@ -3419,6 +3423,19 @@ class RangeSet {
3419
3423
  build.add(range.from, range.to, range.value);
3420
3424
  return build.finish();
3421
3425
  }
3426
+ /**
3427
+ Join an array of range sets into a single set.
3428
+ */
3429
+ static join(sets) {
3430
+ if (!sets.length)
3431
+ return RangeSet.empty;
3432
+ let result = sets[sets.length - 1];
3433
+ for (let i = sets.length - 2; i >= 0; i--) {
3434
+ for (let layer = sets[i]; layer != RangeSet.empty; layer = layer.nextLayer)
3435
+ result = new RangeSet(layer.chunkPos, layer.chunk, result, Math.max(layer.maxPoint, result.maxPoint));
3436
+ }
3437
+ return result;
3438
+ }
3422
3439
  }
3423
3440
  /**
3424
3441
  The empty set of ranges.
@@ -3736,7 +3753,8 @@ class SpanCursor {
3736
3753
  }
3737
3754
  addActive(trackOpen) {
3738
3755
  let i = 0, { value, to, rank } = this.cursor;
3739
- while (i < this.activeRank.length && this.activeRank[i] <= rank)
3756
+ // Organize active marks by rank first, then by size
3757
+ while (i < this.activeRank.length && (rank - this.activeRank[i] || to - this.activeTo[i]) > 0)
3740
3758
  i++;
3741
3759
  insert(this.active, i, value);
3742
3760
  insert(this.activeTo, i, to);
package/dist/index.d.cts CHANGED
@@ -400,7 +400,7 @@ declare class SelectionRange {
400
400
  /**
401
401
  Compare this range to another range.
402
402
  */
403
- eq(other: SelectionRange): boolean;
403
+ eq(other: SelectionRange, includeAssoc?: boolean): boolean;
404
404
  /**
405
405
  Return a JSON-serializable object representing the range.
406
406
  */
@@ -432,9 +432,12 @@ declare class EditorSelection {
432
432
  */
433
433
  map(change: ChangeDesc, assoc?: number): EditorSelection;
434
434
  /**
435
- Compare this selection to another selection.
435
+ Compare this selection to another selection. By default, ranges
436
+ are compared only by position. When `includeAssoc` is true,
437
+ cursor ranges must also have the same
438
+ [`assoc`](https://codemirror.net/6/docs/ref/#state.SelectionRange.assoc) value.
436
439
  */
437
- eq(other: EditorSelection): boolean;
440
+ eq(other: EditorSelection, includeAssoc?: boolean): boolean;
438
441
  /**
439
442
  Get the primary selection range. Usually, you should make sure
440
443
  your code applies to _all_ ranges, by using methods like
@@ -1604,6 +1607,10 @@ declare class RangeSet<T extends RangeValue> {
1604
1607
  */
1605
1608
  static of<T extends RangeValue>(ranges: readonly Range<T>[] | Range<T>, sort?: boolean): RangeSet<T>;
1606
1609
  /**
1610
+ Join an array of range sets into a single set.
1611
+ */
1612
+ static join<T extends RangeValue>(sets: readonly RangeSet<T>[]): RangeSet<T>;
1613
+ /**
1607
1614
  The empty set of ranges.
1608
1615
  */
1609
1616
  static empty: RangeSet<any>;
@@ -1683,4 +1690,4 @@ situation.
1683
1690
  */
1684
1691
  declare function findColumn(string: string, col: number, tabSize: number, strict?: boolean): number;
1685
1692
 
1686
- export { Annotation, AnnotationType, ChangeDesc, ChangeSet, ChangeSpec, CharCategory, Compartment, EditorSelection, EditorState, EditorStateConfig, Extension, Facet, FacetReader, Line, MapMode, Prec, Range, RangeComparator, RangeCursor, RangeSet, RangeSetBuilder, RangeValue, SelectionRange, SpanIterator, StateCommand, StateEffect, StateEffectType, StateField, Text, TextIterator, Transaction, TransactionSpec, codePointAt, codePointSize, combineConfig, countColumn, findClusterBreak, findColumn, fromCodePoint };
1693
+ export { Annotation, AnnotationType, ChangeDesc, ChangeSet, type ChangeSpec, CharCategory, Compartment, EditorSelection, EditorState, type EditorStateConfig, type Extension, Facet, type FacetReader, Line, MapMode, Prec, Range, type RangeComparator, type RangeCursor, RangeSet, RangeSetBuilder, RangeValue, SelectionRange, type SpanIterator, type StateCommand, StateEffect, StateEffectType, StateField, Text, type TextIterator, Transaction, type TransactionSpec, codePointAt, codePointSize, combineConfig, countColumn, findClusterBreak, findColumn, fromCodePoint };
package/dist/index.d.ts CHANGED
@@ -400,7 +400,7 @@ declare class SelectionRange {
400
400
  /**
401
401
  Compare this range to another range.
402
402
  */
403
- eq(other: SelectionRange): boolean;
403
+ eq(other: SelectionRange, includeAssoc?: boolean): boolean;
404
404
  /**
405
405
  Return a JSON-serializable object representing the range.
406
406
  */
@@ -432,9 +432,12 @@ declare class EditorSelection {
432
432
  */
433
433
  map(change: ChangeDesc, assoc?: number): EditorSelection;
434
434
  /**
435
- Compare this selection to another selection.
435
+ Compare this selection to another selection. By default, ranges
436
+ are compared only by position. When `includeAssoc` is true,
437
+ cursor ranges must also have the same
438
+ [`assoc`](https://codemirror.net/6/docs/ref/#state.SelectionRange.assoc) value.
436
439
  */
437
- eq(other: EditorSelection): boolean;
440
+ eq(other: EditorSelection, includeAssoc?: boolean): boolean;
438
441
  /**
439
442
  Get the primary selection range. Usually, you should make sure
440
443
  your code applies to _all_ ranges, by using methods like
@@ -1604,6 +1607,10 @@ declare class RangeSet<T extends RangeValue> {
1604
1607
  */
1605
1608
  static of<T extends RangeValue>(ranges: readonly Range<T>[] | Range<T>, sort?: boolean): RangeSet<T>;
1606
1609
  /**
1610
+ Join an array of range sets into a single set.
1611
+ */
1612
+ static join<T extends RangeValue>(sets: readonly RangeSet<T>[]): RangeSet<T>;
1613
+ /**
1607
1614
  The empty set of ranges.
1608
1615
  */
1609
1616
  static empty: RangeSet<any>;
@@ -1683,4 +1690,4 @@ situation.
1683
1690
  */
1684
1691
  declare function findColumn(string: string, col: number, tabSize: number, strict?: boolean): number;
1685
1692
 
1686
- export { Annotation, AnnotationType, ChangeDesc, ChangeSet, ChangeSpec, CharCategory, Compartment, EditorSelection, EditorState, EditorStateConfig, Extension, Facet, FacetReader, Line, MapMode, Prec, Range, RangeComparator, RangeCursor, RangeSet, RangeSetBuilder, RangeValue, SelectionRange, SpanIterator, StateCommand, StateEffect, StateEffectType, StateField, Text, TextIterator, Transaction, TransactionSpec, codePointAt, codePointSize, combineConfig, countColumn, findClusterBreak, findColumn, fromCodePoint };
1693
+ export { Annotation, AnnotationType, ChangeDesc, ChangeSet, type ChangeSpec, CharCategory, Compartment, EditorSelection, EditorState, type EditorStateConfig, type Extension, Facet, type FacetReader, Line, MapMode, Prec, Range, type RangeComparator, type RangeCursor, RangeSet, RangeSetBuilder, RangeValue, SelectionRange, type SpanIterator, type StateCommand, StateEffect, StateEffectType, StateField, Text, type TextIterator, Transaction, type TransactionSpec, codePointAt, codePointSize, combineConfig, countColumn, findClusterBreak, findColumn, fromCodePoint };
package/dist/index.js CHANGED
@@ -1388,8 +1388,9 @@ class SelectionRange {
1388
1388
  /**
1389
1389
  Compare this range to another range.
1390
1390
  */
1391
- eq(other) {
1392
- return this.anchor == other.anchor && this.head == other.head;
1391
+ eq(other, includeAssoc = false) {
1392
+ return this.anchor == other.anchor && this.head == other.head &&
1393
+ (!includeAssoc || !this.empty || this.assoc == other.assoc);
1393
1394
  }
1394
1395
  /**
1395
1396
  Return a JSON-serializable object representing the range.
@@ -1439,14 +1440,17 @@ class EditorSelection {
1439
1440
  return EditorSelection.create(this.ranges.map(r => r.map(change, assoc)), this.mainIndex);
1440
1441
  }
1441
1442
  /**
1442
- Compare this selection to another selection.
1443
+ Compare this selection to another selection. By default, ranges
1444
+ are compared only by position. When `includeAssoc` is true,
1445
+ cursor ranges must also have the same
1446
+ [`assoc`](https://codemirror.net/6/docs/ref/#state.SelectionRange.assoc) value.
1443
1447
  */
1444
- eq(other) {
1448
+ eq(other, includeAssoc = false) {
1445
1449
  if (this.ranges.length != other.ranges.length ||
1446
1450
  this.mainIndex != other.mainIndex)
1447
1451
  return false;
1448
1452
  for (let i = 0; i < this.ranges.length; i++)
1449
- if (!this.ranges[i].eq(other.ranges[i]))
1453
+ if (!this.ranges[i].eq(other.ranges[i], includeAssoc))
1450
1454
  return false;
1451
1455
  return true;
1452
1456
  }
@@ -3415,6 +3419,19 @@ class RangeSet {
3415
3419
  build.add(range.from, range.to, range.value);
3416
3420
  return build.finish();
3417
3421
  }
3422
+ /**
3423
+ Join an array of range sets into a single set.
3424
+ */
3425
+ static join(sets) {
3426
+ if (!sets.length)
3427
+ return RangeSet.empty;
3428
+ let result = sets[sets.length - 1];
3429
+ for (let i = sets.length - 2; i >= 0; i--) {
3430
+ for (let layer = sets[i]; layer != RangeSet.empty; layer = layer.nextLayer)
3431
+ result = new RangeSet(layer.chunkPos, layer.chunk, result, Math.max(layer.maxPoint, result.maxPoint));
3432
+ }
3433
+ return result;
3434
+ }
3418
3435
  }
3419
3436
  /**
3420
3437
  The empty set of ranges.
@@ -3732,7 +3749,8 @@ class SpanCursor {
3732
3749
  }
3733
3750
  addActive(trackOpen) {
3734
3751
  let i = 0, { value, to, rank } = this.cursor;
3735
- while (i < this.activeRank.length && this.activeRank[i] <= rank)
3752
+ // Organize active marks by rank first, then by size
3753
+ while (i < this.activeRank.length && (rank - this.activeRank[i] || to - this.activeTo[i]) > 0)
3736
3754
  i++;
3737
3755
  insert(this.active, i, value);
3738
3756
  insert(this.activeTo, i, to);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/state",
3
- "version": "6.3.3",
3
+ "version": "6.4.0",
4
4
  "description": "Editor state data structures for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",