applyPatch function

PatchResult applyPatch(
  1. String text,
  2. PatchSet patch
)

Apply a patch to text, returning a PatchResult.

Implementation

PatchResult applyPatch(String text, PatchSet patch) {
  if (patch.hunks.isEmpty) {
    return PatchResult(
      text: text,
      appliedHunks: const [],
      conflictHunks: const [],
    );
  }

  final lines = text.split('\n');
  final applied = <Hunk>[];
  final conflicts = <Hunk>[];
  var offset = 0;

  for (final hunk in patch.hunks) {
    final pos = hunk.oldStart - 1 + offset;

    // Verify context lines match
    var contextOk = true;
    var lineIdx = pos;
    for (final hl in hunk.lines) {
      if (hl.type == DiffType.context || hl.type == DiffType.remove) {
        if (lineIdx < 0 ||
            lineIdx >= lines.length ||
            lines[lineIdx] != hl.content) {
          contextOk = false;
          break;
        }
        lineIdx++;
      }
    }

    if (!contextOk) {
      conflicts.add(hunk);
      continue;
    }

    // Apply the hunk
    final newLines = <String>[];
    lineIdx = pos;
    for (final hl in hunk.lines) {
      switch (hl.type) {
        case DiffType.context:
          newLines.add(lines[lineIdx]);
          lineIdx++;
        case DiffType.remove:
          lineIdx++;
        case DiffType.add:
          newLines.add(hl.content);
      }
    }

    lines.replaceRange(pos, pos + hunk.oldCount, newLines);
    offset += hunk.newCount - hunk.oldCount;
    applied.add(hunk);
  }

  return PatchResult(
    text: lines.join('\n'),
    appliedHunks: applied,
    conflictHunks: conflicts,
  );
}