@codemirror/state 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 +18 -0
- package/dist/index.cjs +34 -6
- package/dist/index.d.cts +11 -4
- package/dist/index.d.ts +11 -4
- package/dist/index.js +34 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
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
|
+
|
|
13
|
+
## 6.3.3 (2023-12-06)
|
|
14
|
+
|
|
15
|
+
### Bug fixes
|
|
16
|
+
|
|
17
|
+
Fix an issue where `Text.slice` and `Text.replace` could return objects with incorrect `length` when the given `from`/`to` values were out of range for the text.
|
|
18
|
+
|
|
1
19
|
## 6.3.2 (2023-11-27)
|
|
2
20
|
|
|
3
21
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -24,6 +24,7 @@ class Text {
|
|
|
24
24
|
Replace a range of the text with the given content.
|
|
25
25
|
*/
|
|
26
26
|
replace(from, to, text) {
|
|
27
|
+
[from, to] = clip(this, from, to);
|
|
27
28
|
let parts = [];
|
|
28
29
|
this.decompose(0, from, parts, 2 /* Open.To */);
|
|
29
30
|
if (text.length)
|
|
@@ -41,6 +42,7 @@ class Text {
|
|
|
41
42
|
Retrieve the text between the given points.
|
|
42
43
|
*/
|
|
43
44
|
slice(from, to = this.length) {
|
|
45
|
+
[from, to] = clip(this, from, to);
|
|
44
46
|
let parts = [];
|
|
45
47
|
this.decompose(from, to, parts, 0);
|
|
46
48
|
return TextNode.from(parts, to - from);
|
|
@@ -167,6 +169,7 @@ class TextLeaf extends Text {
|
|
|
167
169
|
replace(from, to, text) {
|
|
168
170
|
if (!(text instanceof TextLeaf))
|
|
169
171
|
return super.replace(from, to, text);
|
|
172
|
+
[from, to] = clip(this, from, to);
|
|
170
173
|
let lines = appendText(this.text, appendText(text.text, sliceText(this.text, 0, from)), to);
|
|
171
174
|
let newLen = this.length + text.length - (to - from);
|
|
172
175
|
if (lines.length <= 32 /* Tree.Branch */)
|
|
@@ -174,6 +177,7 @@ class TextLeaf extends Text {
|
|
|
174
177
|
return TextNode.from(TextLeaf.split(lines, []), newLen);
|
|
175
178
|
}
|
|
176
179
|
sliceString(from, to = this.length, lineSep = "\n") {
|
|
180
|
+
[from, to] = clip(this, from, to);
|
|
177
181
|
let result = "";
|
|
178
182
|
for (let pos = 0, i = 0; pos <= to && i < this.text.length; i++) {
|
|
179
183
|
let line = this.text[i], end = pos + line.length;
|
|
@@ -242,6 +246,7 @@ class TextNode extends Text {
|
|
|
242
246
|
}
|
|
243
247
|
}
|
|
244
248
|
replace(from, to, text) {
|
|
249
|
+
[from, to] = clip(this, from, to);
|
|
245
250
|
if (text.lines < this.lines)
|
|
246
251
|
for (let i = 0, pos = 0; i < this.children.length; i++) {
|
|
247
252
|
let child = this.children[i], end = pos + child.length;
|
|
@@ -264,6 +269,7 @@ class TextNode extends Text {
|
|
|
264
269
|
return super.replace(from, to, text);
|
|
265
270
|
}
|
|
266
271
|
sliceString(from, to = this.length, lineSep = "\n") {
|
|
272
|
+
[from, to] = clip(this, from, to);
|
|
267
273
|
let result = "";
|
|
268
274
|
for (let i = 0, pos = 0; i < this.children.length && pos <= to; i++) {
|
|
269
275
|
let child = this.children[i], end = pos + child.length;
|
|
@@ -551,6 +557,10 @@ class Line {
|
|
|
551
557
|
*/
|
|
552
558
|
get length() { return this.to - this.from; }
|
|
553
559
|
}
|
|
560
|
+
function clip(text, from, to) {
|
|
561
|
+
from = Math.max(0, Math.min(text.length, from));
|
|
562
|
+
return [from, Math.max(from, Math.min(text.length, to))];
|
|
563
|
+
}
|
|
554
564
|
|
|
555
565
|
// Compressed representation of the Grapheme_Cluster_Break=Extend
|
|
556
566
|
// information from
|
|
@@ -1381,8 +1391,9 @@ class SelectionRange {
|
|
|
1381
1391
|
/**
|
|
1382
1392
|
Compare this range to another range.
|
|
1383
1393
|
*/
|
|
1384
|
-
eq(other) {
|
|
1385
|
-
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);
|
|
1386
1397
|
}
|
|
1387
1398
|
/**
|
|
1388
1399
|
Return a JSON-serializable object representing the range.
|
|
@@ -1432,14 +1443,17 @@ class EditorSelection {
|
|
|
1432
1443
|
return EditorSelection.create(this.ranges.map(r => r.map(change, assoc)), this.mainIndex);
|
|
1433
1444
|
}
|
|
1434
1445
|
/**
|
|
1435
|
-
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.
|
|
1436
1450
|
*/
|
|
1437
|
-
eq(other) {
|
|
1451
|
+
eq(other, includeAssoc = false) {
|
|
1438
1452
|
if (this.ranges.length != other.ranges.length ||
|
|
1439
1453
|
this.mainIndex != other.mainIndex)
|
|
1440
1454
|
return false;
|
|
1441
1455
|
for (let i = 0; i < this.ranges.length; i++)
|
|
1442
|
-
if (!this.ranges[i].eq(other.ranges[i]))
|
|
1456
|
+
if (!this.ranges[i].eq(other.ranges[i], includeAssoc))
|
|
1443
1457
|
return false;
|
|
1444
1458
|
return true;
|
|
1445
1459
|
}
|
|
@@ -3409,6 +3423,19 @@ class RangeSet {
|
|
|
3409
3423
|
build.add(range.from, range.to, range.value);
|
|
3410
3424
|
return build.finish();
|
|
3411
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
|
+
}
|
|
3412
3439
|
}
|
|
3413
3440
|
/**
|
|
3414
3441
|
The empty set of ranges.
|
|
@@ -3726,7 +3753,8 @@ class SpanCursor {
|
|
|
3726
3753
|
}
|
|
3727
3754
|
addActive(trackOpen) {
|
|
3728
3755
|
let i = 0, { value, to, rank } = this.cursor;
|
|
3729
|
-
|
|
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)
|
|
3730
3758
|
i++;
|
|
3731
3759
|
insert(this.active, i, value);
|
|
3732
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
|
@@ -22,6 +22,7 @@ class Text {
|
|
|
22
22
|
Replace a range of the text with the given content.
|
|
23
23
|
*/
|
|
24
24
|
replace(from, to, text) {
|
|
25
|
+
[from, to] = clip(this, from, to);
|
|
25
26
|
let parts = [];
|
|
26
27
|
this.decompose(0, from, parts, 2 /* Open.To */);
|
|
27
28
|
if (text.length)
|
|
@@ -39,6 +40,7 @@ class Text {
|
|
|
39
40
|
Retrieve the text between the given points.
|
|
40
41
|
*/
|
|
41
42
|
slice(from, to = this.length) {
|
|
43
|
+
[from, to] = clip(this, from, to);
|
|
42
44
|
let parts = [];
|
|
43
45
|
this.decompose(from, to, parts, 0);
|
|
44
46
|
return TextNode.from(parts, to - from);
|
|
@@ -165,6 +167,7 @@ class TextLeaf extends Text {
|
|
|
165
167
|
replace(from, to, text) {
|
|
166
168
|
if (!(text instanceof TextLeaf))
|
|
167
169
|
return super.replace(from, to, text);
|
|
170
|
+
[from, to] = clip(this, from, to);
|
|
168
171
|
let lines = appendText(this.text, appendText(text.text, sliceText(this.text, 0, from)), to);
|
|
169
172
|
let newLen = this.length + text.length - (to - from);
|
|
170
173
|
if (lines.length <= 32 /* Tree.Branch */)
|
|
@@ -172,6 +175,7 @@ class TextLeaf extends Text {
|
|
|
172
175
|
return TextNode.from(TextLeaf.split(lines, []), newLen);
|
|
173
176
|
}
|
|
174
177
|
sliceString(from, to = this.length, lineSep = "\n") {
|
|
178
|
+
[from, to] = clip(this, from, to);
|
|
175
179
|
let result = "";
|
|
176
180
|
for (let pos = 0, i = 0; pos <= to && i < this.text.length; i++) {
|
|
177
181
|
let line = this.text[i], end = pos + line.length;
|
|
@@ -240,6 +244,7 @@ class TextNode extends Text {
|
|
|
240
244
|
}
|
|
241
245
|
}
|
|
242
246
|
replace(from, to, text) {
|
|
247
|
+
[from, to] = clip(this, from, to);
|
|
243
248
|
if (text.lines < this.lines)
|
|
244
249
|
for (let i = 0, pos = 0; i < this.children.length; i++) {
|
|
245
250
|
let child = this.children[i], end = pos + child.length;
|
|
@@ -262,6 +267,7 @@ class TextNode extends Text {
|
|
|
262
267
|
return super.replace(from, to, text);
|
|
263
268
|
}
|
|
264
269
|
sliceString(from, to = this.length, lineSep = "\n") {
|
|
270
|
+
[from, to] = clip(this, from, to);
|
|
265
271
|
let result = "";
|
|
266
272
|
for (let i = 0, pos = 0; i < this.children.length && pos <= to; i++) {
|
|
267
273
|
let child = this.children[i], end = pos + child.length;
|
|
@@ -549,6 +555,10 @@ class Line {
|
|
|
549
555
|
*/
|
|
550
556
|
get length() { return this.to - this.from; }
|
|
551
557
|
}
|
|
558
|
+
function clip(text, from, to) {
|
|
559
|
+
from = Math.max(0, Math.min(text.length, from));
|
|
560
|
+
return [from, Math.max(from, Math.min(text.length, to))];
|
|
561
|
+
}
|
|
552
562
|
|
|
553
563
|
// Compressed representation of the Grapheme_Cluster_Break=Extend
|
|
554
564
|
// information from
|
|
@@ -1378,8 +1388,9 @@ class SelectionRange {
|
|
|
1378
1388
|
/**
|
|
1379
1389
|
Compare this range to another range.
|
|
1380
1390
|
*/
|
|
1381
|
-
eq(other) {
|
|
1382
|
-
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);
|
|
1383
1394
|
}
|
|
1384
1395
|
/**
|
|
1385
1396
|
Return a JSON-serializable object representing the range.
|
|
@@ -1429,14 +1440,17 @@ class EditorSelection {
|
|
|
1429
1440
|
return EditorSelection.create(this.ranges.map(r => r.map(change, assoc)), this.mainIndex);
|
|
1430
1441
|
}
|
|
1431
1442
|
/**
|
|
1432
|
-
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.
|
|
1433
1447
|
*/
|
|
1434
|
-
eq(other) {
|
|
1448
|
+
eq(other, includeAssoc = false) {
|
|
1435
1449
|
if (this.ranges.length != other.ranges.length ||
|
|
1436
1450
|
this.mainIndex != other.mainIndex)
|
|
1437
1451
|
return false;
|
|
1438
1452
|
for (let i = 0; i < this.ranges.length; i++)
|
|
1439
|
-
if (!this.ranges[i].eq(other.ranges[i]))
|
|
1453
|
+
if (!this.ranges[i].eq(other.ranges[i], includeAssoc))
|
|
1440
1454
|
return false;
|
|
1441
1455
|
return true;
|
|
1442
1456
|
}
|
|
@@ -3405,6 +3419,19 @@ class RangeSet {
|
|
|
3405
3419
|
build.add(range.from, range.to, range.value);
|
|
3406
3420
|
return build.finish();
|
|
3407
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
|
+
}
|
|
3408
3435
|
}
|
|
3409
3436
|
/**
|
|
3410
3437
|
The empty set of ranges.
|
|
@@ -3722,7 +3749,8 @@ class SpanCursor {
|
|
|
3722
3749
|
}
|
|
3723
3750
|
addActive(trackOpen) {
|
|
3724
3751
|
let i = 0, { value, to, rank } = this.cursor;
|
|
3725
|
-
|
|
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)
|
|
3726
3754
|
i++;
|
|
3727
3755
|
insert(this.active, i, value);
|
|
3728
3756
|
insert(this.activeTo, i, to);
|