Still more fixes for Modification

This commit is contained in:
Maxime Coste 2014-05-24 13:03:37 +01:00
parent a6de024c1f
commit 0aa5c4e779
2 changed files with 55 additions and 17 deletions

View File

@ -134,6 +134,9 @@ std::vector<Modification> compute_modifications(memoryview<Buffer::Change> chang
else else
num_removed.column = change.end.column - change.begin.column; 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, auto delend = std::upper_bound(next, res.end(), change.end,
[](const ByteCoord& l, const Modification& c) [](const ByteCoord& l, const Modification& c)
{ return l < c.new_coord; }); { 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; 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); 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_added.line += std::max(0_line, it->num_added.line - removed_from_it);
} }
if (it->new_coord.line == change.end.line) 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; ByteCount removed_from_added = std::min(num_removed.column, it->num_added.column);
modif.num_removed.column += it->num_removed.column - std::min(removed_from_it, it->num_added.column); num_added.column += std::max(0_byte, it->num_added.column - removed_from_added);
modif.num_added.column += std::max(0_byte, it->num_added.column - removed_from_it); 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); next = res.erase(next, delend);
ByteCoord num_added_after_pos = { modif.new_coord.line + modif.num_added.line - change.begin.line, 0 }; // update modification with changes
if (change.begin.line == modif.new_coord.line + modif.num_added.line) if (change.end.line == modif.new_coord.line + modif.num_added.line)
{ {
if (modif.num_added.line == 0) ByteCount removed_from_added = std::min(num_removed.column, modif.num_added.column);
num_added_after_pos.column = modif.new_coord.column + modif.num_added.column - change.begin.column; modif.num_added.column = std::max(0_byte, modif.num_added.column - removed_from_added) + num_added.column;
else modif.num_removed.column += num_removed.column - removed_from_added;
num_added_after_pos.column = modif.num_added.column - change.begin.column; }
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) if (change.begin.line == modif.new_coord.line)
modif.num_added.column += change.begin.column - modif.new_coord.column; 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) for (auto it = next; it != res.end(); ++it)
{ {

View File

@ -217,6 +217,33 @@ void test_modification()
kak_assert(modif.num_added == ByteCoord{0 COMMA 10}); kak_assert(modif.num_added == ByteCoord{0 COMMA 10});
kak_assert(modif.num_removed == 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, Buffer buffer("test", Buffer::Flags::None,
{ "tchou mutch\n", { "tchou mutch\n",