parseUnifiedDiff function

List<DiffHunk> parseUnifiedDiff(
  1. String diff
)

Parse a unified diff string into hunks.

Implementation

List<DiffHunk> parseUnifiedDiff(String diff) {
  final hunks = <DiffHunk>[];
  final lines = diff.split('\n');
  var i = 0;

  while (i < lines.length) {
    final line = lines[i];

    // Find hunk header: @@ -old,count +new,count @@
    final hunkMatch = RegExp(
      r'^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@',
    ).firstMatch(line);
    if (hunkMatch != null) {
      final oldStart = int.parse(hunkMatch.group(1)!);
      final oldCount = int.parse(hunkMatch.group(2) ?? '1');
      final newStart = int.parse(hunkMatch.group(3)!);
      final newCount = int.parse(hunkMatch.group(4) ?? '1');

      final hunkLines = <DiffLine>[];
      i++;

      while (i < lines.length) {
        final l = lines[i];
        if (l.startsWith('@@') ||
            l.startsWith('diff ') ||
            l.startsWith('---') ||
            l.startsWith('+++')) {
          break;
        }
        if (l.startsWith('+')) {
          hunkLines.add(DiffLine(DiffLineType.add, l.substring(1)));
        } else if (l.startsWith('-')) {
          hunkLines.add(DiffLine(DiffLineType.remove, l.substring(1)));
        } else if (l.startsWith(' ')) {
          hunkLines.add(DiffLine(DiffLineType.context, l.substring(1)));
        } else if (l == '\\ No newline at end of file') {
          // Skip
        } else {
          // Treat as context
          hunkLines.add(DiffLine(DiffLineType.context, l));
        }
        i++;
      }

      hunks.add(
        DiffHunk(
          oldStart: oldStart,
          oldCount: oldCount,
          newStart: newStart,
          newCount: newCount,
          lines: hunkLines,
        ),
      );
    } else {
      i++;
    }
  }

  return hunks;
}