diff options
| author | Maxime Coste <mawww@kakoune.org> | 2017-01-13 13:45:46 +0000 |
|---|---|---|
| committer | Maxime Coste <mawww@kakoune.org> | 2017-01-13 13:52:55 +0000 |
| commit | e7e72747edfcba76f7fc36e2e345577ffeb47eab (patch) | |
| tree | c3fff0f3d12dd95ca1a5e34406c5b9924493714f /src/selection.cc | |
| parent | 5ad44995036274989f82f62b9ff2135687b00394 (diff) | |
Update ranges highlighter options according to buffer changes
Diffstat (limited to 'src/selection.cc')
| -rw-r--r-- | src/selection.cc | 165 |
1 files changed, 6 insertions, 159 deletions
diff --git a/src/selection.cc b/src/selection.cc index 5501bbd0..b0474e67 100644 --- a/src/selection.cc +++ b/src/selection.cc @@ -1,7 +1,8 @@ #include "selection.hh" -#include "utf8.hh" #include "buffer_utils.hh" +#include "changes.hh" +#include "utf8.hh" namespace Kakoune { @@ -96,164 +97,10 @@ Iterator merge_overlapping(Iterator begin, Iterator end, size_t& main, OverlapsF return begin + i + 1; } -// This tracks position changes for changes that are done -// in a forward way (each change takes place at a position) -// *after* the previous one. -struct ForwardChangesTracker -{ - BufferCoord cur_pos; // last change position at current modification - BufferCoord old_pos; // last change position at start - - void update(const Buffer::Change& change) - { - kak_assert(change.begin >= cur_pos); - - if (change.type == Buffer::Change::Insert) - { - old_pos = get_old_coord(change.begin); - cur_pos = change.end; - } - else if (change.type == Buffer::Change::Erase) - { - old_pos = get_old_coord(change.end); - cur_pos = change.begin; - } - } - - void update(const Buffer& buffer, size_t& timestamp) - { - for (auto& change : buffer.changes_since(timestamp)) - update(change); - timestamp = buffer.timestamp(); - } - - BufferCoord get_old_coord(BufferCoord coord) const - { - kak_assert(cur_pos <= coord); - auto pos_change = cur_pos - old_pos; - if (cur_pos.line == coord.line) - { - kak_assert(pos_change.column <= coord.column); - coord.column -= pos_change.column; - } - coord.line -= pos_change.line; - kak_assert(old_pos <= coord); - return coord; - } - - BufferCoord get_new_coord(BufferCoord coord) const - { - kak_assert(old_pos <= coord); - auto pos_change = cur_pos - old_pos; - if (old_pos.line == coord.line) - { - kak_assert(-pos_change.column <= coord.column); - coord.column += pos_change.column; - } - coord.line += pos_change.line; - kak_assert(cur_pos <= coord); - return coord; - } - - BufferCoord get_new_coord_tolerant(BufferCoord coord) const - { - if (coord < old_pos) - return cur_pos; - return get_new_coord(coord); - } - - bool relevant(const Buffer::Change& change, BufferCoord old_coord) const - { - auto new_coord = get_new_coord_tolerant(old_coord); - return change.type == Buffer::Change::Insert ? change.begin <= new_coord - : change.begin < new_coord; - } -}; - -const Buffer::Change* forward_sorted_until(const Buffer::Change* first, const Buffer::Change* last) -{ - if (first != last) { - const Buffer::Change* next = first; - while (++next != last) { - const auto& ref = first->type == Buffer::Change::Insert ? first->end : first->begin; - if (next->begin <= ref) - return next; - first = next; - } - } - return last; } -const Buffer::Change* backward_sorted_until(const Buffer::Change* first, const Buffer::Change* last) -{ - if (first != last) { - const Buffer::Change* next = first; - while (++next != last) { - if (first->begin <= next->end) - return next; - first = next; - } - } - return last; -} - -void update_forward(ConstArrayView<Buffer::Change> changes, Vector<Selection>& selections) -{ - ForwardChangesTracker changes_tracker; - - auto change_it = changes.begin(); - auto advance_while_relevant = [&](const BufferCoord& pos) mutable { - while (change_it != changes.end() and changes_tracker.relevant(*change_it, pos)) - changes_tracker.update(*change_it++); - }; - - for (auto& sel : selections) - { - auto& sel_min = sel.min(); - auto& sel_max = sel.max(); - advance_while_relevant(sel_min); - sel_min = changes_tracker.get_new_coord_tolerant(sel_min); - - advance_while_relevant(sel_max); - sel_max = changes_tracker.get_new_coord_tolerant(sel_max); - } - kak_assert(std::is_sorted(selections.begin(), selections.end(), compare_selections)); -} - -void update_backward(ConstArrayView<Buffer::Change> changes, Vector<Selection>& selections) -{ - ForwardChangesTracker changes_tracker; - - using ReverseIt = std::reverse_iterator<const Buffer::Change*>; - auto change_it = ReverseIt(changes.end()); - auto change_end = ReverseIt(changes.begin()); - auto advance_while_relevant = [&](const BufferCoord& pos) mutable { - while (change_it != change_end) - { - auto change = *change_it; - change.begin = changes_tracker.get_new_coord(change.begin); - change.end = changes_tracker.get_new_coord(change.end); - if (not changes_tracker.relevant(change, pos)) - break; - changes_tracker.update(change); - ++change_it; - } - }; - - for (auto& sel : selections) - { - auto& sel_min = sel.min(); - auto& sel_max = sel.max(); - advance_while_relevant(sel_min); - sel_min = changes_tracker.get_new_coord_tolerant(sel_min); - - advance_while_relevant(sel_max); - sel_max = changes_tracker.get_new_coord_tolerant(sel_max); - } - kak_assert(std::is_sorted(selections.begin(), selections.end(), compare_selections)); -} - -} +BufferCoord& get_first(Selection& sel) { return sel.min(); } +BufferCoord& get_last(Selection& sel) { return sel.max(); } Vector<Selection> compute_modified_ranges(Buffer& buffer, size_t timestamp) { @@ -367,11 +214,11 @@ void update_selections(Vector<Selection>& selections, size_t& main, Buffer& buff update_backward({ change_it, backward_end }, selections); change_it = backward_end; } + kak_assert(std::is_sorted(selections.begin(), selections.end(), + compare_selections)); selections.erase( merge_overlapping(selections.begin(), selections.end(), main, overlaps), selections.end()); - kak_assert(std::is_sorted(selections.begin(), selections.end(), - compare_selections)); } for (auto& sel : selections) clamp(sel, buffer); |
