From 6f423ed26e0e1c3221e61f52a4e279d5a65efa53 Mon Sep 17 00:00:00 2001 From: Mustafa Quraish Date: Fri, 17 Sep 2021 14:33:35 -0400 Subject: [PATCH] LibDiff: Coalesce adjacent changes into the same Hunk Now we keep track of the "current" hunk, and only create a new one if there's at least a single unmodified lines between changes. --- Userland/Libraries/LibDiff/Generator.cpp | 33 +++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/Userland/Libraries/LibDiff/Generator.cpp b/Userland/Libraries/LibDiff/Generator.cpp index b8fa289fab..6994303005 100644 --- a/Userland/Libraries/LibDiff/Generator.cpp +++ b/Userland/Libraries/LibDiff/Generator.cpp @@ -63,23 +63,50 @@ Vector from_text(StringView const& old_text, StringView const& new_text) } Vector hunks; + Hunk cur_hunk; + bool in_hunk = false; + + auto update_hunk = [&](size_t i, size_t j, Direction direction) { + if (!in_hunk) { + in_hunk = true; + cur_hunk = { i, j, {}, {} }; + } + if (direction == Direction::Down) { + cur_hunk.added_lines.append(new_lines[j]); + } else if (direction == Direction::Right) { + cur_hunk.removed_lines.append(old_lines[i]); + } + }; + + auto flush_hunk = [&]() { + if (in_hunk) { + if (cur_hunk.added_lines.size() > 0) + cur_hunk.target_start_line++; + if (cur_hunk.removed_lines.size() > 0) + cur_hunk.original_start_line++; + hunks.append(cur_hunk); + in_hunk = false; + } + }; + size_t i = 0; size_t j = 0; - // FIXME: This creates a hunk per line, very inefficient. while (i < old_lines.size() && j < new_lines.size()) { auto& cell = dp(i, j); if (cell.direction == Direction::Down) { - hunks.append({ i, j, {}, { new_lines[j] } }); + update_hunk(i, j, cell.direction); ++j; } else if (cell.direction == Direction::Right) { - hunks.append({ i, j, { old_lines[i] }, {} }); + update_hunk(i, j, cell.direction); ++i; } else { ++i; ++j; + flush_hunk(); } } + flush_hunk(); return hunks; }