From c9fce9f83d313d01f72ec78ab62f27a898921889 Mon Sep 17 00:00:00 2001 From: Jason Felice Date: Sun, 27 Oct 2019 13:08:53 -0400 Subject: [PATCH] Merge selection list parsing into selection_list_from_strings --- src/commands.cc | 2 +- src/normal.cc | 15 +-------------- src/selection.cc | 17 ----------------- src/selection.hh | 28 ++++++++++++++++++++++++---- 4 files changed, 26 insertions(+), 36 deletions(-) diff --git a/src/commands.cc b/src/commands.cc index 07abc4ab..6475029c 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -2336,7 +2336,7 @@ const CommandDesc select_cmd = { { auto& buffer = context.buffer(); const size_t timestamp = parser.get_switch("timestamp").map(str_to_int_ifp).cast().value_or(buffer.timestamp()); - context.selections_write_only() = selection_list_from_string(buffer, parser.positionals_from(0), timestamp); + context.selections_write_only() = selection_list_from_strings(buffer, parser.positionals_from(0), timestamp, 0); } }; diff --git a/src/normal.cc b/src/normal.cc index 34352151..3a7565e2 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -1774,20 +1774,7 @@ SelectionList read_selections_from_register(char reg, Context& context) const size_t timestamp = str_to_int(desc[1]); size_t main = str_to_int(desc[2]); - if (timestamp > buffer.timestamp()) - throw runtime_error{"register '{}' refers to an invalid timestamp"}; - - auto sels = content | skip(1) | transform(selection_from_string) | gather>(); - sort_selections(sels, main); - merge_overlapping_selections(sels, main); - if (timestamp < buffer.timestamp()) - update_selections(sels, main, buffer, timestamp); - else - clamp_selections(sels, buffer); - - SelectionList res{buffer, std::move(sels)}; - res.set_main_index(main); - return res; + return selection_list_from_strings(buffer, content | skip(1), timestamp, main); } enum class CombineOp diff --git a/src/selection.cc b/src/selection.cc index 9e300af6..e0dbbecb 100644 --- a/src/selection.cc +++ b/src/selection.cc @@ -27,13 +27,6 @@ SelectionList::SelectionList(Buffer& buffer, Vector list, size_t time SelectionList::SelectionList(Buffer& buffer, Vector list) : SelectionList(buffer, std::move(list), buffer.timestamp()) {} -SelectionList::SelectionList(SelectionList::UnsortedTag, Buffer& buffer, Vector list, size_t timestamp, size_t main) - : m_selections(std::move(list)), m_buffer(&buffer), m_timestamp(timestamp) -{ - sort_and_merge_overlapping(); - check_invariant(); -} - void SelectionList::remove(size_t index) { m_selections.erase(begin() + index); @@ -518,14 +511,4 @@ Selection selection_from_string(StringView desc) return Selection{anchor, cursor}; } -SelectionList selection_list_from_string(Buffer& buffer, ConstArrayView descs, size_t timestamp) -{ - if (descs.empty()) - throw runtime_error{"empty selection description"}; - - auto sels = descs | transform([&](auto&& d) { auto s = selection_from_string(d); clamp(s, buffer); return s; }) - | gather>(); - return {SelectionList::UnsortedTag{}, buffer, std::move(sels), timestamp, 0}; -} - } diff --git a/src/selection.hh b/src/selection.hh index df1459e6..34532f9b 100644 --- a/src/selection.hh +++ b/src/selection.hh @@ -94,9 +94,6 @@ struct SelectionList SelectionList(Buffer& buffer, Vector s); SelectionList(Buffer& buffer, Vector s, size_t timestamp); - struct UnsortedTag {}; - SelectionList(UnsortedTag, Buffer& buffer, Vector s, size_t timestamp, size_t main); - void update(bool merge = true); void check_invariant() const; @@ -163,7 +160,30 @@ Vector compute_modified_ranges(Buffer& buffer, size_t timestamp); String selection_to_string(const Selection& selection); String selection_list_to_string(const SelectionList& selection); Selection selection_from_string(StringView desc); -SelectionList selection_list_from_string(Buffer& buffer, ConstArrayView descs, size_t timestamp); + +template +SelectionList selection_list_from_strings(Buffer& buffer, StringArray&& descs, size_t timestamp, size_t main) +{ + if (timestamp > buffer.timestamp()) + throw runtime_error{format("invalid timestamp '{}'", timestamp)}; + + auto sels = descs | transform(selection_from_string) | gather>(); + if (sels.empty()) + throw runtime_error{"empty selection description"}; + if (main >= sels.size()) + throw runtime_error{"invalid main selection index"}; + + sort_selections(sels, main); + merge_overlapping_selections(sels, main); + if (timestamp < buffer.timestamp()) + update_selections(sels, main, buffer, timestamp); + else + clamp_selections(sels, buffer); + + SelectionList res{buffer, std::move(sels)}; + res.set_main_index(main); + return res; +} }