From e7e72747edfcba76f7fc36e2e345577ffeb47eab Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Fri, 13 Jan 2017 13:45:46 +0000 Subject: Update ranges highlighter options according to buffer changes --- src/changes.hh | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 src/changes.hh (limited to 'src/changes.hh') diff --git a/src/changes.hh b/src/changes.hh new file mode 100644 index 00000000..963ca786 --- /dev/null +++ b/src/changes.hh @@ -0,0 +1,89 @@ +#ifndef changes_hh_INCLUDED +#define changes_hh_INCLUDED + +#include "buffer.hh" +#include "coord.hh" + +namespace Kakoune +{ + +// 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); + void update(const Buffer& buffer, size_t& timestamp); + + BufferCoord get_old_coord(BufferCoord coord) const; + BufferCoord get_new_coord(BufferCoord coord) const; + BufferCoord get_new_coord_tolerant(BufferCoord coord) const; + + bool relevant(const Buffer::Change& change, BufferCoord old_coord) const; +}; + +const Buffer::Change* forward_sorted_until(const Buffer::Change* first, const Buffer::Change* last); +const Buffer::Change* backward_sorted_until(const Buffer::Change* first, const Buffer::Change* last); + +template +void update_forward(ConstArrayView changes, RangeContainer& ranges) +{ + 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& range : ranges) + { + auto& first = get_first(range); + auto& last = get_last(range); + advance_while_relevant(first); + first = changes_tracker.get_new_coord_tolerant(first); + + advance_while_relevant(last); + last = changes_tracker.get_new_coord_tolerant(last); + } +} + +template +void update_backward(ConstArrayView changes, RangeContainer& ranges) +{ + ForwardChangesTracker changes_tracker; + + using ReverseIt = std::reverse_iterator; + 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& range : ranges) + { + auto& first = get_first(range); + auto& last = get_last(range); + advance_while_relevant(first); + first = changes_tracker.get_new_coord_tolerant(first); + + advance_while_relevant(last); + last = changes_tracker.get_new_coord_tolerant(last); + } +} + +} + +#endif // changes_hh_INCLUDED -- cgit v1.2.3