diff options
author | Mustafa Quraish <mustafaq9@gmail.com> | 2021-09-17 14:33:35 -0400 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-09-24 14:32:52 +0200 |
commit | 6f423ed26e0e1c3221e61f52a4e279d5a65efa53 (patch) | |
tree | bccddc6a6581cc4404c4b767856ed9cd487ff067 /Userland/Libraries/LibDiff/Generator.cpp | |
parent | 35704ba27256d028d9597042e52898934bb738a8 (diff) | |
download | serenity-6f423ed26e0e1c3221e61f52a4e279d5a65efa53.zip |
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.
Diffstat (limited to 'Userland/Libraries/LibDiff/Generator.cpp')
-rw-r--r-- | Userland/Libraries/LibDiff/Generator.cpp | 33 |
1 files 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<Hunk> from_text(StringView const& old_text, StringView const& new_text) } Vector<Hunk> 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; } |