summaryrefslogtreecommitdiff
path: root/src/line_modification.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/line_modification.cc')
-rw-r--r--src/line_modification.cc109
1 files changed, 46 insertions, 63 deletions
diff --git a/src/line_modification.cc b/src/line_modification.cc
index 96249856..1943350f 100644
--- a/src/line_modification.cc
+++ b/src/line_modification.cc
@@ -5,41 +5,33 @@
namespace Kakoune
{
-namespace
+static LineModification make_line_modif(const Buffer::Change& change)
{
-
-struct LineChange
-{
- LineChange(const Buffer::Change& change)
+ LineModification res = {};
+ res.old_line = change.begin.line;
+ res.new_line = change.begin.line;
+ if (change.type == Buffer::Change::Insert)
{
- ByteCoord begin = change.begin;
- ByteCoord end = change.end;
- if (change.type == Buffer::Change::Insert)
- {
- if (change.at_end and begin != ByteCoord{0,0})
- {
- kak_assert(begin.column == 0);
- --begin.line;
- }
- pos = begin.line;
- num = end.line - begin.line;
- }
- else
- {
- if (change.at_end and begin != ByteCoord{0,0})
- {
- kak_assert(begin.column == 0);
- --begin.line;
- }
- pos = begin.line;
- num = begin.line - end.line;
- }
+ res.num_added = change.end.line - change.begin.line;
+ // inserted a new line at buffer end but end coord is on same line
+ if (change.at_end and change.end.column != 0)
+ ++res.num_added;
}
-
- LineCount pos;
- LineCount num;
-};
-
+ else
+ {
+ res.num_removed = change.end.line - change.begin.line;
+ // removed last line, but end coord is on same line
+ if (change.at_end and change.end.column != 0)
+ ++res.num_removed;
+ }
+ // modified a line
+ if (not change.at_end and
+ (change.begin.column != 0 or change.end.column != 0))
+ {
+ ++res.num_removed;
+ ++res.num_added;
+ }
+ return res;
}
Vector<LineModification> compute_line_modifications(const Buffer& buffer, size_t timestamp)
@@ -47,60 +39,51 @@ Vector<LineModification> compute_line_modifications(const Buffer& buffer, size_t
Vector<LineModification> res;
for (auto& buf_change : buffer.changes_since(timestamp))
{
- const LineChange change(buf_change);
+ auto change = make_line_modif(buf_change);
- auto pos = std::upper_bound(res.begin(), res.end(), change.pos,
+ auto pos = std::upper_bound(res.begin(), res.end(), change.new_line,
[](const LineCount& l, const LineModification& c)
{ return l < c.new_line; });
if (pos != res.begin())
{
auto& prev = *(pos-1);
- if (change.pos <= prev.new_line + prev.num_added)
+ if (change.new_line <= prev.new_line + prev.num_added)
+ {
--pos;
+ LineCount removed_from_previously_added_by_pos = clamp(pos->new_line + pos->num_added - change.new_line, 0_line, std::min(pos->num_added, change.num_removed));
+ pos->num_removed += change.num_removed - removed_from_previously_added_by_pos;
+ pos->num_added += change.num_added - removed_from_previously_added_by_pos;
+ }
else
- pos = res.insert(pos, {change.pos - prev.diff(), change.pos, 0, 0});
+ {
+ change.old_line -= prev.diff();
+ pos = res.insert(pos, change);
+ }
}
else
- pos = res.insert(pos, {change.pos, change.pos, 0, 0});
+ pos = res.insert(pos, change);
auto& modif = *pos;
auto next = pos + 1;
- if (change.num > 0)
+ if (buf_change.type == Buffer::Change::Erase)
{
- modif.num_added += change.num;
- for (auto it = next; it != res.end(); ++it)
- it->new_line += change.num;
- }
- if (change.num < 0)
- {
- const LineCount num_removed = -change.num;
-
- auto delend = std::upper_bound(next, res.end(), change.pos + num_removed,
+ auto delend = std::upper_bound(next, res.end(), change.new_line + change.num_removed,
[](const LineCount& l, const LineModification& c)
{ return l < c.new_line; });
for (auto it = next; it != delend; ++it)
{
- LineCount removed_from_it = (change.pos + num_removed - it->new_line);
- modif.num_removed += it->num_removed - std::min(removed_from_it, it->num_added);
- modif.num_added += std::max(0_line, it->num_added - removed_from_it);
+ LineCount removed_from_previously_added_by_it = std::min(it->num_added, change.new_line + change.num_removed - it->new_line);
+ modif.num_removed += it->num_removed - removed_from_previously_added_by_it;
+ modif.num_added += it->num_added - removed_from_previously_added_by_it;
}
next = res.erase(next, delend);
-
- const LineCount num_added_after_pos =
- modif.new_line + modif.num_added - change.pos;
- const LineCount num_removed_from_added =
- std::min(num_removed, num_added_after_pos);
-
- kak_assert(modif.num_added >= num_removed_from_added);
-
- modif.num_added -= num_removed_from_added;
- modif.num_removed += num_removed - num_removed_from_added;
-
- for (auto it = next; it != res.end(); ++it)
- it->new_line -= num_removed;
}
+
+ auto diff = buf_change.end.line - buf_change.begin.line;
+ for (auto it = next; it != res.end(); ++it)
+ it->new_line += diff;
}
return res;
}