57 lines
1.6 KiB
TypeScript
57 lines
1.6 KiB
TypeScript
import type { ScopeTextTemplateDiffLine } from '../types';
|
|
|
|
const buildLcsTable = (a: string[], b: string[]) => {
|
|
const table = Array.from({ length: a.length + 1 }, () => Array(b.length + 1).fill(0));
|
|
|
|
for (let i = a.length - 1; i >= 0; i--) {
|
|
for (let j = b.length - 1; j >= 0; j--) {
|
|
if (a[i] === b[j]) {
|
|
table[i][j] = table[i + 1][j + 1] + 1;
|
|
} else {
|
|
table[i][j] = Math.max(table[i + 1][j], table[i][j + 1]);
|
|
}
|
|
}
|
|
}
|
|
|
|
return table;
|
|
};
|
|
|
|
export const createScopeTextDiff = (previousContent: string, nextContent: string): ScopeTextTemplateDiffLine[] => {
|
|
const previousLines = previousContent.split('\n');
|
|
const nextLines = nextContent.split('\n');
|
|
const table = buildLcsTable(previousLines, nextLines);
|
|
const diff: ScopeTextTemplateDiffLine[] = [];
|
|
|
|
let i = 0;
|
|
let j = 0;
|
|
|
|
while (i < previousLines.length && j < nextLines.length) {
|
|
if (previousLines[i] === nextLines[j]) {
|
|
diff.push({ op: 'equal', text: previousLines[i] });
|
|
i++;
|
|
j++;
|
|
continue;
|
|
}
|
|
|
|
if (table[i + 1][j] >= table[i][j + 1]) {
|
|
diff.push({ op: 'remove', text: previousLines[i] });
|
|
i++;
|
|
} else {
|
|
diff.push({ op: 'add', text: nextLines[j] });
|
|
j++;
|
|
}
|
|
}
|
|
|
|
while (i < previousLines.length) {
|
|
diff.push({ op: 'remove', text: previousLines[i] });
|
|
i++;
|
|
}
|
|
|
|
while (j < nextLines.length) {
|
|
diff.push({ op: 'add', text: nextLines[j] });
|
|
j++;
|
|
}
|
|
|
|
return diff;
|
|
};
|