diff options
| author | Maxime Coste <frrrwww@gmail.com> | 2014-05-22 09:52:22 +0100 |
|---|---|---|
| committer | Maxime Coste <frrrwww@gmail.com> | 2014-05-24 02:14:28 +0100 |
| commit | 695c85f4513241c55296a37d2cf6cf0cd25dbecf (patch) | |
| tree | 007404cc54a173a8478f4954037e394ca445ec80 /src/modification.cc | |
| parent | a7540962cc90266f4f46858184b89f048364f9b2 (diff) | |
Fix, cleanup and refactor compute_modifications
Diffstat (limited to 'src/modification.cc')
| -rw-r--r-- | src/modification.cc | 117 |
1 files changed, 102 insertions, 15 deletions
diff --git a/src/modification.cc b/src/modification.cc index b5e91c1f..2539ea3a 100644 --- a/src/modification.cc +++ b/src/modification.cc @@ -19,6 +19,64 @@ ByteCount change_added_column(const Buffer::Change& change) } +ByteCoord Modification::added_end() const +{ + if (num_added.line) + return { new_coord.line + num_added.line, num_added.column }; + else + return { new_coord.line, new_coord.column + num_added.column }; +} + +ByteCoord Modification::removed_end() const +{ + if (num_removed.line) + return { old_coord.line + num_removed.line, num_removed.column }; + else + return { old_coord.line, old_coord.column + num_removed.column }; +} + +ByteCoord Modification::get_old_coord(ByteCoord coord) const +{ + Modification inverse = { new_coord, old_coord, num_added, num_removed }; + return inverse.get_new_coord(coord); +} + +ByteCoord Modification::get_new_coord(ByteCoord coord) const +{ + if (coord < old_coord) + return coord; + + // apply remove + if (coord < removed_end()) + coord = old_coord; + else if (coord.line == old_coord.line + num_removed.line) + { + coord.line = old_coord.line; + if (num_removed.line != 0) + coord.column += old_coord.column; + coord.column -= num_removed.column; + } + else + coord.line -= num_removed.line; + + // apply move + coord.line += new_coord.line - old_coord.line; + if (coord.line == new_coord.line) + coord.column += new_coord.column - old_coord.column; + + // apply add + if (coord.line == new_coord.line) + { + if (num_added.line == 0) + coord.column += num_added.column; + else + coord.column += num_added.column - new_coord.column; + } + coord.line += num_added.line; + + return coord; +} + std::vector<Modification> compute_modifications(memoryview<Buffer::Change> changes) { std::vector<Modification> res; @@ -45,27 +103,27 @@ std::vector<Modification> compute_modifications(memoryview<Buffer::Change> chang { const LineCount last_line = modif.new_coord.line + modif.num_added.line; - ByteCoord num_added = { change.end.line - change.begin.line, 0 }; - - modif.num_added.line += num_added.line; + modif.num_added.line += change.end.line - change.begin.line; if (change.begin.line == last_line) { if (change.end.line == change.begin.line) - num_added.column = change.end.column - change.begin.column; + modif.num_added.column += change.end.column - change.begin.column; else - num_added.column = change.end.column - modif.num_added.column; - - modif.num_added.column += num_added.column; + modif.num_added.column = change.end.column; kak_assert(modif.num_added.column >= 0); } for (auto it = next; it != res.end(); ++it) { - if (it->new_coord.line == change.begin.line and it->num_added.line == 0) - it->new_coord.column += num_added.column; - - it->new_coord.line += num_added.line; + if (it->new_coord.line == change.begin.line) + it->new_coord.column += change.end.column - change.begin.column; + it->new_coord.line += change.end.line - change.begin.line; + +#ifdef KAK_DEBUG + auto ref_new_coord = (it-1)->get_new_coord(it->old_coord); + kak_assert(it->new_coord == ref_new_coord); +#endif } } else @@ -83,7 +141,7 @@ std::vector<Modification> compute_modifications(memoryview<Buffer::Change> chang for (auto it = next; it != delend; ++it) { { - LineCount removed_from_it = (change.begin.line + num_removed.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); modif.num_added.line += std::max(0_line, it->num_added.line - removed_from_it); } @@ -111,12 +169,28 @@ std::vector<Modification> compute_modifications(memoryview<Buffer::Change> chang for (auto it = next; it != res.end(); ++it) { - if (it->new_coord.line == change.end.line and it->num_added.line == 0) - it->new_coord.column -= num_removed.column; - it->new_coord.line -= num_removed.line; + if (it->new_coord.line == change.end.line) + it->new_coord.column += change.begin.column - change.end.column; + it->new_coord.line += change.begin.line - change.end.line; + +#ifdef KAK_DEBUG + auto ref_new_coord = (it-1)->get_new_coord(it->old_coord); + kak_assert(it->new_coord == ref_new_coord); +#endif } } } + +#ifdef KAK_DEBUG + for (size_t i = 0; i+1 < res.size(); ++i) + { + auto old_coord = res[i].get_old_coord(res[i+1].new_coord); + kak_assert(res[i+1].old_coord == old_coord); + auto new_coord = res[i].get_new_coord(res[i+1].old_coord); + kak_assert(res[i+1].new_coord == new_coord); + } +#endif + return res; } @@ -125,4 +199,17 @@ std::vector<Modification> compute_modifications(const Buffer& buffer, size_t tim return compute_modifications(buffer.changes_since(timestamp)); } +ByteCoord update_pos(memoryview<Modification> modifs, ByteCoord pos) +{ + auto modif_it = std::upper_bound(modifs.begin(), modifs.end(), pos, + [](const ByteCoord& c, const Modification& m) + { return c < m.old_coord; }); + if (modif_it != modifs.begin()) + { + auto& prev = *(modif_it-1); + return prev.get_new_coord(pos); + } + return pos; +} + } |
