summaryrefslogtreecommitdiff
path: root/src/modification.cc
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2014-05-22 09:52:22 +0100
committerMaxime Coste <frrrwww@gmail.com>2014-05-24 02:14:28 +0100
commit695c85f4513241c55296a37d2cf6cf0cd25dbecf (patch)
tree007404cc54a173a8478f4954037e394ca445ec80 /src/modification.cc
parenta7540962cc90266f4f46858184b89f048364f9b2 (diff)
Fix, cleanup and refactor compute_modifications
Diffstat (limited to 'src/modification.cc')
-rw-r--r--src/modification.cc117
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;
+}
+
}