silvanocerza_github-gitless.../src/views/conflicts-resolution/diff.ts
2025-02-13 17:23:43 +01:00

77 lines
2 KiB
TypeScript

type DiffType = "add" | "remove" | "modify" | "equal";
export interface DiffResult {
type: DiffType;
value: string;
oldValue?: string; // For modifications, store both values
newValue?: string;
from: number;
to: number;
}
function diff(oldText: string, newText: string): DiffResult[] {
const oldLines = oldText.split("\n");
const newLines = newText.split("\n");
const result: DiffResult[] = [];
let position = 0;
// First pass: find exact matches and obvious modifications
for (let i = 0; i < Math.max(oldLines.length, newLines.length); i++) {
const oldLine = oldLines[i];
const newLine = newLines[i];
if (!oldLine && newLine) {
// Pure addition
result.push({
type: "add",
value: newLine,
from: position,
to: position + newLine.length,
});
} else if (oldLine && !newLine) {
// Pure removal
result.push({
type: "remove",
value: oldLine,
from: position,
to: position + oldLine.length,
});
} else if (oldLine === newLine) {
// Exact match
result.push({
type: "equal",
value: oldLine,
from: position,
to: position + oldLine.length,
});
} else {
// Different content at same line number - treat as modification
result.push({
type: "modify",
value: newLine,
oldValue: oldLine,
newValue: newLine,
from: position,
to: position + Math.max(oldLine.length, newLine.length),
});
}
position +=
Math.max(oldLine ? oldLine.length : 0, newLine ? newLine.length : 0) + 1;
}
return result;
}
function similarity(s1: string, s2: string): number {
if (s1 === s2) return 1.0;
// Simple word-based similarity
const words1 = s1.split(/\s+/);
const words2 = s2.split(/\s+/);
const commonWords = words1.filter((w) => words2.includes(w)).length;
return commonWords / Math.max(words1.length, words2.length);
}
export default diff;