summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibDiff/Generator.cpp
diff options
context:
space:
mode:
authorMustafa Quraish <mustafaq9@gmail.com>2021-09-17 14:33:35 -0400
committerAndreas Kling <kling@serenityos.org>2021-09-24 14:32:52 +0200
commit6f423ed26e0e1c3221e61f52a4e279d5a65efa53 (patch)
treebccddc6a6581cc4404c4b767856ed9cd487ff067 /Userland/Libraries/LibDiff/Generator.cpp
parent35704ba27256d028d9597042e52898934bb738a8 (diff)
downloadserenity-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.cpp33
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;
}