createPatch function
Create a PatchSet from oldText to newText.
contextLines controls how many context lines surround each hunk.
Implementation
PatchSet createPatch(String oldText, String newText, {int contextLines = 3}) {
final diffs = computeLineDiff(oldText, newText);
if (diffs.every((d) => d.type == DiffType.context)) {
return const PatchSet(hunks: []);
}
// Find ranges of changes and expand with context
final changeIndices = <int>[];
for (var i = 0; i < diffs.length; i++) {
if (diffs[i].type != DiffType.context) {
changeIndices.add(i);
}
}
if (changeIndices.isEmpty) return const PatchSet(hunks: []);
// Group changes into hunks
final hunkGroups = <List<int>>[
[changeIndices.first],
];
for (var i = 1; i < changeIndices.length; i++) {
if (changeIndices[i] - changeIndices[i - 1] <= contextLines * 2 + 1) {
hunkGroups.last.add(changeIndices[i]);
} else {
hunkGroups.add([changeIndices[i]]);
}
}
final hunks = <Hunk>[];
for (final group in hunkGroups) {
final start = math.max(0, group.first - contextLines);
final end = math.min(diffs.length - 1, group.last + contextLines);
final lines = diffs.sublist(start, end + 1);
var oldStart = 1, newStart = 1;
// Count lines up to start
for (var i = 0; i < start; i++) {
if (diffs[i].type != DiffType.add) oldStart++;
if (diffs[i].type != DiffType.remove) newStart++;
}
var oldCount = 0, newCount = 0;
for (final l in lines) {
if (l.type != DiffType.add) oldCount++;
if (l.type != DiffType.remove) newCount++;
}
hunks.add(
Hunk(
oldStart: oldStart,
oldCount: oldCount,
newStart: newStart,
newCount: newCount,
lines: lines,
),
);
}
return PatchSet(hunks: hunks);
}