summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2014-05-24 13:03:37 +0100
committerMaxime Coste <frrrwww@gmail.com>2014-05-24 13:15:59 +0100
commit0aa5c4e779f5ef28eafd745a0a24540882fbb52c (patch)
tree43c0182a5ee0145d1bc9a1ccea0c0a69a7224400 /src
parenta6de024c1fb9b1bcc04d9cea48c10131bb2f4168 (diff)
Still more fixes for Modification
Diffstat (limited to 'src')
-rw-r--r--src/modification.cc45
-rw-r--r--src/unit_tests.cc27
2 files changed, 55 insertions, 17 deletions
diff --git a/src/modification.cc b/src/modification.cc
index 876463f1..ba22a373 100644
--- a/src/modification.cc
+++ b/src/modification.cc
@@ -134,6 +134,9 @@ std::vector<Modification> compute_modifications(memoryview<Buffer::Change> chang
else
num_removed.column = change.end.column - change.begin.column;
+ ByteCoord num_added;
+
+ // merge modifications lying in the erased range.
auto delend = std::upper_bound(next, res.end(), change.end,
[](const ByteCoord& l, const Modification& c)
{ return l < c.new_coord; });
@@ -142,36 +145,44 @@ std::vector<Modification> compute_modifications(memoryview<Buffer::Change> chang
{
{
LineCount removed_from_it = change.end.line - it->new_coord.line;
- modif.num_removed.line += it->num_removed.line - std::min(removed_from_it, it->num_added.line);
- modif.num_added.line += std::max(0_line, it->num_added.line - removed_from_it);
+ num_removed.line += it->num_removed.line - std::min(removed_from_it, it->num_added.line);
+ num_added.line += std::max(0_line, it->num_added.line - removed_from_it);
}
if (it->new_coord.line == change.end.line)
+ num_removed.column += it->num_removed.column;
+ if (it->new_coord.line + it->num_added.line == change.end.line)
{
- ByteCount removed_from_it = num_removed.column - it->new_coord.column;
- modif.num_removed.column += it->num_removed.column - std::min(removed_from_it, it->num_added.column);
- modif.num_added.column += std::max(0_byte, it->num_added.column - removed_from_it);
+ ByteCount removed_from_added = std::min(num_removed.column, it->num_added.column);
+ num_added.column += std::max(0_byte, it->num_added.column - removed_from_added);
+ num_removed.column -= removed_from_added;
}
+ if (it->new_coord.line == change.begin.line)
+ num_removed.column += it->new_coord.column - change.begin.column;
}
next = res.erase(next, delend);
- ByteCoord num_added_after_pos = { modif.new_coord.line + modif.num_added.line - change.begin.line, 0 };
- if (change.begin.line == modif.new_coord.line + modif.num_added.line)
+ // update modification with changes
+ if (change.end.line == modif.new_coord.line + modif.num_added.line)
{
- if (modif.num_added.line == 0)
- num_added_after_pos.column = modif.new_coord.column + modif.num_added.column - change.begin.column;
- else
- num_added_after_pos.column = modif.num_added.column - change.begin.column;
+ ByteCount removed_from_added = std::min(num_removed.column, modif.num_added.column);
+ modif.num_added.column = std::max(0_byte, modif.num_added.column - removed_from_added) + num_added.column;
+ modif.num_removed.column += num_removed.column - removed_from_added;
+ }
+ else if (change.end.line > modif.new_coord.line + modif.num_added.line)
+ {
+ modif.num_added.column = num_added.column;
+ modif.num_removed.column = num_removed.column;
}
- ByteCoord num_removed_from_added = std::min(num_removed, num_added_after_pos);
- modif.num_added -= num_removed_from_added;
-
if (change.begin.line == modif.new_coord.line)
modif.num_added.column += change.begin.column - modif.new_coord.column;
- else
- modif.num_added.column += change.begin.column;
- modif.num_removed += num_removed - num_removed_from_added;
+ {
+ LineCount change_pos_in_modif = change.begin.line - modif.new_coord.line;
+ LineCount removed_from_added = std::min(num_removed.line, modif.num_added.line - change_pos_in_modif);
+ modif.num_added.line = std::max(0_line, modif.num_added.line - removed_from_added) + num_added.line;
+ modif.num_removed.line += num_removed.line - removed_from_added;
+ }
for (auto it = next; it != res.end(); ++it)
{
diff --git a/src/unit_tests.cc b/src/unit_tests.cc
index 36c885bd..16b6b122 100644
--- a/src/unit_tests.cc
+++ b/src/unit_tests.cc
@@ -217,6 +217,33 @@ void test_modification()
kak_assert(modif.num_added == ByteCoord{0 COMMA 10});
kak_assert(modif.num_removed == ByteCoord{0 COMMA 10});
}
+ {
+ std::vector<Buffer::Change> change = {
+ { Buffer::Change::Insert, {1, 10}, {2, 20}, false },
+ { Buffer::Change::Erase, {1, 5}, {2, 10}, false },
+ };
+ auto modifs = compute_modifications(change);
+ kak_assert(modifs.size() == 1);
+ auto& modif = modifs[0];
+ kak_assert(modif.old_coord == ByteCoord{1 COMMA 5});
+ kak_assert(modif.new_coord == ByteCoord{1 COMMA 5});
+ kak_assert(modif.num_added == ByteCoord{0 COMMA 10});
+ kak_assert(modif.num_removed == ByteCoord{0 COMMA 5});
+ }
+ {
+ std::vector<Buffer::Change> change = {
+ { Buffer::Change::Insert, {1, 10}, {2, 20}, false },
+ { Buffer::Change::Erase, {1, 5}, {2, 10}, false },
+ { Buffer::Change::Erase, {1, 10}, {2, 0}, false },
+ };
+ auto modifs = compute_modifications(change);
+ kak_assert(modifs.size() == 1);
+ auto& modif = modifs[0];
+ kak_assert(modif.old_coord == ByteCoord{1 COMMA 5});
+ kak_assert(modif.new_coord == ByteCoord{1 COMMA 5});
+ kak_assert(modif.num_added == ByteCoord{0 COMMA 5});
+ kak_assert(modif.num_removed == ByteCoord{1 COMMA 0});
+ }
Buffer buffer("test", Buffer::Flags::None,
{ "tchou mutch\n",