Skip to content

Commit 6933e6f

Browse files
authored
Implements microsoft#164574 for experimental diff algorithm. (microsoft#165136)
1 parent c9200f1 commit 6933e6f

File tree

3 files changed

+36
-17
lines changed

3 files changed

+36
-17
lines changed

src/vs/editor/common/diff/algorithms/diffAlgorithm.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,3 @@ export interface ISequence {
5959
*/
6060
getBoundaryScore?(length: number): number;
6161
}
62-
63-
export class SequenceFromIntArray implements ISequence {
64-
constructor(private readonly arr: number[]) { }
65-
66-
getElement(offset: number): number {
67-
return this.arr[offset];
68-
}
69-
70-
get length(): number {
71-
return this.arr.length;
72-
}
73-
}

src/vs/editor/common/diff/algorithms/joinSequenceDiffs.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ function shiftDiffToBetterPosition(diff: SequenceDiff, sequence1: ISequence, seq
120120
let bestDelta = 0;
121121
let bestScore = -1;
122122
// find best scored delta
123-
for (let delta = -deltaBefore; delta < deltaAfter; delta++) {
123+
for (let delta = -deltaBefore; delta <= deltaAfter; delta++) {
124124
const seq2OffsetStart = diff.seq2Range.start + delta;
125125
const seq2OffsetEndExclusive = diff.seq2Range.endExclusive + delta;
126126
const seq1Offset = diff.seq1Range.start + delta;

src/vs/editor/common/diff/standardLinesDiffComputer.ts

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { assertFn, checkAdjacentItems } from 'vs/base/common/assert';
77
import { CharCode } from 'vs/base/common/charCode';
88
import { Position } from 'vs/editor/common/core/position';
99
import { Range } from 'vs/editor/common/core/range';
10-
import { SequenceFromIntArray, OffsetRange, SequenceDiff, ISequence } from 'vs/editor/common/diff/algorithms/diffAlgorithm';
10+
import { OffsetRange, SequenceDiff, ISequence } from 'vs/editor/common/diff/algorithms/diffAlgorithm';
1111
import { DynamicProgrammingDiffing } from 'vs/editor/common/diff/algorithms/dynamicProgrammingDiffing';
1212
import { optimizeSequenceDiffs } from 'vs/editor/common/diff/algorithms/joinSequenceDiffs';
1313
import { MyersDiffAlgorithm } from 'vs/editor/common/diff/algorithms/myersDiffAlgorithm';
@@ -34,10 +34,10 @@ export class StandardLinesDiffComputer implements ILinesDiffComputer {
3434
const srcDocLines = originalLines.map((l) => getOrCreateHash(l.trim()));
3535
const tgtDocLines = modifiedLines.map((l) => getOrCreateHash(l.trim()));
3636

37-
const sequence1 = new SequenceFromIntArray(srcDocLines);
38-
const sequence2 = new SequenceFromIntArray(tgtDocLines);
37+
const sequence1 = new LineSequence(srcDocLines, originalLines);
38+
const sequence2 = new LineSequence(tgtDocLines, modifiedLines);
3939

40-
const lineAlignments = (() => {
40+
let lineAlignments = (() => {
4141
if (sequence1.length + sequence2.length < 1500) {
4242
// Use the improved algorithm for small files
4343
return this.dynamicProgrammingDiffing.compute(
@@ -58,6 +58,8 @@ export class StandardLinesDiffComputer implements ILinesDiffComputer {
5858
);
5959
})();
6060

61+
lineAlignments = optimizeSequenceDiffs(sequence1, sequence2, lineAlignments);
62+
6163
const alignments: RangeMapping[] = [];
6264

6365
const scanForWhitespaceChanges = (equalLinesCount: number) => {
@@ -182,6 +184,35 @@ function* group<T>(items: Iterable<T>, shouldBeGrouped: (item1: T, item2: T) =>
182184
}
183185
}
184186

187+
export class LineSequence implements ISequence {
188+
constructor(
189+
private readonly trimmedHash: number[],
190+
private readonly lines: string[]
191+
) { }
192+
193+
getElement(offset: number): number {
194+
return this.trimmedHash[offset];
195+
}
196+
197+
get length(): number {
198+
return this.trimmedHash.length;
199+
}
200+
201+
getBoundaryScore(length: number): number {
202+
const indentationBefore = length === 0 ? 0 : getIndentation(this.lines[length - 1]);
203+
const indentationAfter = length === this.lines.length ? 0 : getIndentation(this.lines[length]);
204+
return 1000 - (indentationBefore + indentationAfter);
205+
}
206+
}
207+
208+
function getIndentation(str: string): number {
209+
let i = 0;
210+
while (i < str.length && (str.charCodeAt(i) === CharCode.Space || str.charCodeAt(i) === CharCode.Tab)) {
211+
i++;
212+
}
213+
return i;
214+
}
215+
185216
class Slice implements ISequence {
186217
private readonly elements: Int32Array;
187218
private readonly firstCharOnLineOffsets: Int32Array;

0 commit comments

Comments
 (0)