diff --git a/src/changes.hh b/src/changes.hh index 5ebb3ded..9d0328d4 100644 --- a/src/changes.hh +++ b/src/changes.hh @@ -53,8 +53,10 @@ void update_forward(ConstArrayView changes, RangeContainer& rang changes_tracker.update(*it++); }; - for (auto& range : ranges) - update_range(changes_tracker, range, advance_while_relevant); + auto range_it = std::lower_bound(ranges.begin(), ranges.end(), changes.front(), + [](auto& range, const Buffer::Change& change) { return get_last(range) < change.begin; }); + for (auto end = ranges.end(); range_it != end; ++range_it) + update_range(changes_tracker, *range_it, advance_while_relevant); } template diff --git a/src/highlighters.cc b/src/highlighters.cc index c3b996a8..912c41fe 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -1523,14 +1523,16 @@ private: BufferCoord& get_first(RangeAndString& r) { return std::get<0>(r).first; } BufferCoord& get_last(RangeAndString& r) { return std::get<0>(r).last; } +bool option_element_compare(RangeAndString const& lhs, RangeAndString const& rhs) +{ + return std::get<0>(lhs).first == std::get<0>(rhs).first ? + std::get<0>(lhs).last < std::get<0>(rhs).last + : std::get<0>(lhs).first < std::get<0>(rhs).first; +} + void option_list_postprocess(Vector& opt) { - std::sort(opt.begin(), opt.end(), - [](auto& lhs, auto& rhs) { - return std::get<0>(lhs).first == std::get<0>(rhs).first ? - std::get<0>(lhs).last < std::get<0>(rhs).last - : std::get<0>(lhs).first < std::get<0>(rhs).first; - }); + std::sort(opt.begin(), opt.end(), option_element_compare); } void option_update(RangeAndStringList& opt, const Context& context) @@ -1538,6 +1540,19 @@ void option_update(RangeAndStringList& opt, const Context& context) update_ranges(context.buffer(), opt.prefix, opt.list); } +bool option_add_from_strings(Vector& opt, ConstArrayView strs) +{ + auto vec = option_from_strings(Meta::Type>{}, strs); + if (vec.empty()) + return false; + auto middle = opt.insert(opt.end(), + std::make_move_iterator(vec.begin()), + std::make_move_iterator(vec.end())); + std::sort(middle, opt.end(), option_element_compare); + std::inplace_merge(opt.begin(), middle, opt.end(), option_element_compare); + return true; +} + struct RangesHighlighter : OptionBasedHighlighter { using RangesHighlighter::OptionBasedHighlighter::OptionBasedHighlighter; diff --git a/src/highlighters.hh b/src/highlighters.hh index c635b8df..f68f0b26 100644 --- a/src/highlighters.hh +++ b/src/highlighters.hh @@ -38,6 +38,7 @@ constexpr StringView option_type_name(Meta::Type) } void option_update(RangeAndStringList& opt, const Context& context); void option_list_postprocess(Vector& opt); +bool option_add_from_strings(Vector& opt, ConstArrayView strs); }