Fix corner case when clamping lines of modify DiffChunks

This commit is contained in:
Silvano Cerza 2025-02-21 18:12:27 +01:00
parent 6c369232e3
commit bca72c4938

View file

@ -11,8 +11,8 @@ function diff(oldText: string, newText: string): DiffChunk[] {
const newLines = newText.split("\n");
const result: DiffChunk[] = [];
let i = 0,
j = 0;
let i = 0;
let j = 0;
while (i < oldLines.length || j < newLines.length) {
// Skip identical lines
@ -88,16 +88,42 @@ function diff(oldText: string, newText: string): DiffChunk[] {
}
return mergeDiffs(
result.map((chunk) => ({
...chunk,
startLeftLine: clampLine(chunk.startLeftLine, oldLines.length),
endLeftLine: clampLine(chunk.endLeftLine, oldLines.length),
startRightLine: clampLine(chunk.startRightLine, newLines.length),
endRightLine: clampLine(chunk.endRightLine, newLines.length),
})),
result.map((chunk) =>
clampChunkLines(chunk, oldLines.length, newLines.length),
),
);
}
// Clamp lines in the change and change its type accordingly
function clampChunkLines(
chunk: DiffChunk,
oldLinesLength: number,
newLinesLength: number,
): DiffChunk {
const startLeftLine = clampLine(chunk.startLeftLine, oldLinesLength);
const endLeftLine = clampLine(chunk.endLeftLine, oldLinesLength);
const startRightLine = clampLine(chunk.startRightLine, newLinesLength);
const endRightLine = clampLine(chunk.endRightLine, newLinesLength);
let type = chunk.type;
if (type === "modify") {
// If we're here it means that the type was modify,
// if the lines on one side are the same number
// we nee to change the type or the change won't be shown correctly.
if (startLeftLine === endLeftLine) {
type = "add";
} else if (startRightLine === endRightLine) {
type = "remove";
}
}
return {
type,
startLeftLine,
endLeftLine,
startRightLine,
endRightLine,
};
}
// Use to make sure the line number in the diff chunk doesn't exceed
// the number of lines of the document.
function clampLine(line: number, maxLines: number): number {