parseUnifiedDiff function
Parse a unified diff string into hunks.
Implementation
List<DiffHunk> parseUnifiedDiff(String diffText) {
final hunks = <DiffHunk>[];
final lines = diffText.split('\n');
int i = 0;
// Skip file headers (--- / +++)
while (i < lines.length &&
!lines[i].startsWith('@@') &&
!lines[i].startsWith('diff ')) {
i++;
}
while (i < lines.length) {
final line = lines[i];
if (line.startsWith('@@')) {
final hunkMatch = RegExp(
r'^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@',
).firstMatch(line);
if (hunkMatch == null) {
i++;
continue;
}
final oldStart = int.parse(hunkMatch.group(1)!);
final oldLines = int.tryParse(hunkMatch.group(2) ?? '1') ?? 1;
final newStart = int.parse(hunkMatch.group(3)!);
final newLines = int.tryParse(hunkMatch.group(4) ?? '1') ?? 1;
final hunkLines = <DiffLine>[];
var oldLine = oldStart;
var newLine = newStart;
i++;
while (i < lines.length && !lines[i].startsWith('@@')) {
final l = lines[i];
if (l.startsWith('+')) {
hunkLines.add(
DiffLine(
type: DiffLineType.addition,
content: l.substring(1),
newLineNumber: newLine++,
),
);
} else if (l.startsWith('-')) {
hunkLines.add(
DiffLine(
type: DiffLineType.removal,
content: l.substring(1),
oldLineNumber: oldLine++,
),
);
} else if (l.startsWith(' ') || l.isEmpty) {
hunkLines.add(
DiffLine(
type: DiffLineType.context,
content: l.isEmpty ? '' : l.substring(1),
oldLineNumber: oldLine++,
newLineNumber: newLine++,
),
);
} else if (l.startsWith('\\')) {
// "\ No newline at end of file" — skip
} else {
break; // Next diff section
}
i++;
}
hunks.add(
DiffHunk(
oldStart: oldStart,
oldLines: oldLines,
newStart: newStart,
newLines: newLines,
lines: hunkLines,
),
);
} else {
i++;
}
}
return hunks;
}