first commit
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
import type { ConfigDiffView, DiffLine } from "../contracts/workspace";
|
||||
|
||||
export function computeLineDiff(previous: string, next: string): DiffLine[] {
|
||||
const previousLines = previous.split("\n");
|
||||
const nextLines = next.split("\n");
|
||||
const m = previousLines.length;
|
||||
const n = nextLines.length;
|
||||
// classic LCS table; config files are small enough for O(m*n)
|
||||
const lcs: number[][] = Array.from({ length: m + 1 }, () => new Array<number>(n + 1).fill(0));
|
||||
for (let i = m - 1; i >= 0; i -= 1) {
|
||||
for (let j = n - 1; j >= 0; j -= 1) {
|
||||
lcs[i][j] = previousLines[i] === nextLines[j] ? lcs[i + 1][j + 1] + 1 : Math.max(lcs[i + 1][j], lcs[i][j + 1]);
|
||||
}
|
||||
}
|
||||
const lines: DiffLine[] = [];
|
||||
let i = 0;
|
||||
let j = 0;
|
||||
while (i < m && j < n) {
|
||||
if (previousLines[i] === nextLines[j]) {
|
||||
lines.push({ kind: "same", text: previousLines[i] });
|
||||
i += 1;
|
||||
j += 1;
|
||||
} else if (lcs[i + 1][j] >= lcs[i][j + 1]) {
|
||||
lines.push({ kind: "removed", text: previousLines[i] });
|
||||
i += 1;
|
||||
} else {
|
||||
lines.push({ kind: "added", text: nextLines[j] });
|
||||
j += 1;
|
||||
}
|
||||
}
|
||||
while (i < m) {
|
||||
lines.push({ kind: "removed", text: previousLines[i] });
|
||||
i += 1;
|
||||
}
|
||||
while (j < n) {
|
||||
lines.push({ kind: "added", text: nextLines[j] });
|
||||
j += 1;
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
export function buildConfigDiff(serverInstanceId: string, previous: string, next: string): ConfigDiffView {
|
||||
const lines = computeLineDiff(previous, next);
|
||||
const added = lines.filter((line) => line.kind === "added").length;
|
||||
const removed = lines.filter((line) => line.kind === "removed").length;
|
||||
return {
|
||||
serverInstanceId,
|
||||
summary: `+${added} / -${removed} 行变更`,
|
||||
lines,
|
||||
nextContent: next
|
||||
};
|
||||
}
|
||||
|
||||
export function diffHasChanges(diff: ConfigDiffView): boolean {
|
||||
return diff.lines.some((line) => line.kind !== "same");
|
||||
}
|
||||
Reference in New Issue
Block a user