diff --git a/src/normal.cc b/src/normal.cc index dea938eb..fe129216 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -1620,14 +1620,13 @@ SelectionList read_selections_from_register(char reg, Context& context) Buffer& buffer = BufferManager::instance().get_buffer({arobase+1, percent}); size_t timestamp = str_to_int({percent + 1, desc.end()}); - Vector sels; - for (auto sel_desc : StringView{desc.begin(), arobase} | split(':')) - sels.push_back(selection_from_string(sel_desc)); - + auto sels = StringView{desc.begin(), arobase} | split(':') + | transform(selection_from_string) + | gather>(); if (sels.empty()) throw runtime_error(format("Register {} contains an empty selection list", reg)); - return {buffer, std::move(sels), timestamp}; + return {SelectionList::UnsortedTag{}, buffer, std::move(sels), timestamp}; } enum class CombineOp diff --git a/src/ranges.hh b/src/ranges.hh index aebe6f50..df622ea5 100644 --- a/src/ranges.hh +++ b/src/ranges.hh @@ -249,8 +249,8 @@ auto split(Element separator, Element escaper) template struct ConcatView { - using RangeIt1 = decltype(begin(std::declval())); - using RangeIt2 = decltype(begin(std::declval())); + using RangeIt1 = decltype(std::declval().begin()); + using RangeIt2 = decltype(std::declval().begin()); using ValueType = typename std::common_type_t::value_type, typename std::iterator_traits::value_type>; diff --git a/src/selection.cc b/src/selection.cc index 87c8eade..5f323894 100644 --- a/src/selection.cc +++ b/src/selection.cc @@ -16,16 +16,26 @@ SelectionList::SelectionList(Buffer& buffer, Selection s, size_t timestamp) SelectionList::SelectionList(Buffer& buffer, Selection s) : SelectionList(buffer, std::move(s), buffer.timestamp()) {} -SelectionList::SelectionList(Buffer& buffer, Vector s, size_t timestamp) - : m_buffer(&buffer), m_selections(std::move(s)), m_timestamp(timestamp) +SelectionList::SelectionList(Buffer& buffer, Vector list, size_t timestamp) + : m_buffer(&buffer), m_selections(std::move(list)), m_timestamp(timestamp) { kak_assert(size() > 0); m_main = size() - 1; check_invariant(); } -SelectionList::SelectionList(Buffer& buffer, Vector s) - : SelectionList(buffer, std::move(s), buffer.timestamp()) {} +SelectionList::SelectionList(Buffer& buffer, Vector list) + : SelectionList(buffer, std::move(list), buffer.timestamp()) {} + +SelectionList::SelectionList(SelectionList::UnsortedTag, Buffer& buffer, Vector list) + : SelectionList(UnsortedTag{}, buffer, std::move(list), buffer.timestamp()) {} + +SelectionList::SelectionList(SelectionList::UnsortedTag, Buffer& buffer, Vector list, size_t timestamp) + : m_buffer(&buffer), m_selections(std::move(list)), m_timestamp(timestamp) +{ + sort_and_merge_overlapping(); + check_invariant(); +} void SelectionList::remove(size_t index) { @@ -480,7 +490,11 @@ String selection_to_string(const Selection& selection) String selection_list_to_string(const SelectionList& selections) { - return join(selections | transform(selection_to_string), ':', false); + auto beg = &*selections.begin(), end = &*selections.end(); + auto main = beg + selections.main_index(); + using View = ConstArrayView; + return join(concatenated(View{main, end}, View{beg, main}) | + transform(selection_to_string), ':', false); } Selection selection_from_string(StringView desc) @@ -510,18 +524,10 @@ SelectionList selection_list_from_string(Buffer& buffer, StringView desc) if (desc.empty()) throw runtime_error{"empty selection description"}; - Vector sels; - for (auto sel_desc : desc | split(':')) - { - auto sel = selection_from_string(sel_desc); - clamp(sel, buffer); - sels.push_back(sel); - } - size_t main = 0; - std::sort(sels.begin(), sels.end(), compare_selections); - sels.erase(merge_overlapping(sels.begin(), sels.end(), main, overlaps), sels.end()); - - return {buffer, std::move(sels)}; + auto sels = desc | split(':') + | transform([&](auto&& d) { auto s = selection_from_string(d); clamp(s, buffer); return s; }) + | gather>(); + return {SelectionList::UnsortedTag{}, buffer, std::move(sels)}; } } diff --git a/src/selection.hh b/src/selection.hh index 1f492b43..864b02d8 100644 --- a/src/selection.hh +++ b/src/selection.hh @@ -87,6 +87,10 @@ struct SelectionList SelectionList(Buffer& buffer, Vector s); SelectionList(Buffer& buffer, Vector s, size_t timestamp); + struct UnsortedTag {}; + SelectionList(UnsortedTag, Buffer& buffer, Vector s); + SelectionList(UnsortedTag, Buffer& buffer, Vector s, size_t timestamp); + void update(); void check_invariant() const;