12
return textEditInfoSecond;
13
}
15
return textEditInfoFirst;
16
}
18
>
// s0: State before any edits
19
>
const s0ToS1Map = new ArrayQueue(toLengthMapping(textEditInfoFirst));
20
>
// s1: State after first edit, but before second edit
21
>
const s1ToS2Map = toLengthMapping(textEditInfoSecond) as (LengthMapping | { lengthBefore: undefined; lengthAfter: undefined; modified: false })[];
22
>
s1ToS2Map.push({ modified: false, lengthBefore: undefined, lengthAfter: undefined }); // Copy everything from old to new
23
>
// s2: State after both edits
24
>
25
>
let curItem: LengthMapping | undefined = s0ToS1Map.dequeue();
26
>
27
>
/**
28
>
* @param s1Length Use undefined for length "infinity"
29
>
*/
30
>
function nextS0ToS1MapWithS1LengthOf(s1Length: Length | undefined): LengthMapping[] {
31
>
if (s1Length === undefined) {
32
>
const arr = s0ToS1Map.takeWhile(v => true) || [];
33
>
if (curItem) {
34
arr.unshift(curItem);
35
}
37
>
}
38
>
39
>
const result: LengthMapping[] = [];
40
>
while (curItem && !lengthIsZero(s1Length)) {
41
>
const [item, remainingItem] = curItem.splitAt(s1Length);
42
>
result.push(item);
43
>
s1Length = lengthDiffNonNegative(item.lengthAfter, s1Length);
44
>
curItem = remainingItem ?? s0ToS1Map.dequeue();
45
>
}
46
>
if (!lengthIsZero(s1Length)) {
47
result.push(new LengthMapping(false, s1Length, s1Length));
48
}
50
>
}
51
>
52
>
const result: TextEditInfo[] = [];
53
>
54
>
function pushEdit(startOffset: Length, endOffset: Length, newLength: Length): void {
55
>
if (result.length > 0 && lengthEquals(result[result.length - 1].endOffset, startOffset)) {
56
const lastResult = result[result.length - 1];
57
result[result.length - 1] = new TextEditInfo(lastResult.startOffset, endOffset, lengthAdd(lastResult.newLength, newLength));
59
>
result.push({ startOffset, endOffset, newLength });
60
>
}
61
>
}
62
>
63
>
let s0offset = lengthZero;
64
>
for (const s1ToS2 of s1ToS2Map) {
65
>
const s0ToS1Map = nextS0ToS1MapWithS1LengthOf(s1ToS2.lengthBefore);
66
>
if (s1ToS2.modified) {
67
>
const s0Length = sumLengths(s0ToS1Map, s => s.lengthBefore);
68
>
const s0EndOffset = lengthAdd(s0offset, s0Length);
69
>
pushEdit(s0offset, s0EndOffset, s1ToS2.lengthAfter);
70
>
s0offset = s0EndOffset;
71
>
} else {
72
>
for (const s1 of s0ToS1Map) {
73
const s0startOffset = s0offset;
74
s0offset = lengthAdd(s0offset, s1.lengthBefore);