diff --git a/src/normal.cc b/src/normal.cc index f9b1184f..89659c4a 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -1,5 +1,7 @@ #include "normal.hh" +#include + #include "buffer.hh" #include "buffer_manager.hh" #include "buffer_utils.hh" @@ -1774,11 +1776,17 @@ SelectionList read_selections_from_register(char reg, Context& context) if (content.size() < 2) throw runtime_error(format("register '{}' does not contain a selections desc", reg)); + // Use the last two values for timestamp and main_index to allow the buffer + // name to have @ symbols struct error : runtime_error { error(size_t) : runtime_error{"expected @@main_index"} {} }; - const auto desc = content[0] | split('@') | static_gather(); - Buffer& buffer = BufferManager::instance().get_buffer(desc[0]); - const size_t timestamp = str_to_int(desc[1]); - size_t main = str_to_int(desc[2]); + auto end_content = content[0] | reverse() | split('@') | transform([] (auto bounds) { + return StringView{bounds.second.base(), bounds.first.base()}; + }) | static_gather(); + + const size_t main = str_to_int(end_content[0]); + const size_t timestamp = str_to_int(end_content[1]); + const auto buffer_name = StringView{ content[0].begin (), end_content[1].begin () - 1 }; + Buffer& buffer = BufferManager::instance().get_buffer(buffer_name); return selection_list_from_strings(buffer, ColumnType::Byte, content | skip(1), timestamp, main); } diff --git a/src/ranges.hh b/src/ranges.hh index 4cd85a25..02757283 100644 --- a/src/ranges.hh +++ b/src/ranges.hh @@ -37,6 +37,12 @@ struct ReverseView { decltype(auto) begin() { return m_range.rbegin(); } decltype(auto) end() { return m_range.rend(); } + decltype(auto) rbegin() { return m_range.begin(); } + decltype(auto) rend() { return m_range.end(); } + decltype(auto) begin() const { return m_range.rbegin(); } + decltype(auto) end() const { return m_range.rend(); } + decltype(auto) rbegin() const { return m_range.begin(); } + decltype(auto) rend() const { return m_range.end(); } Range m_range; }; @@ -73,6 +79,24 @@ inline auto skip(size_t count) }); } +template +struct DropView +{ + auto begin() const { return std::begin(m_range); } + auto end() const { return std::end(m_range) - m_drop_count; } + + Range m_range; + size_t m_drop_count; +}; + +inline auto drop(size_t count) +{ + return make_view_factory([count](auto&& range) { + using Range = decltype(range); + return DropView>{std::forward(range), count}; + }); +} + template struct FilterView { @@ -477,15 +501,15 @@ auto elements(bool exact_size = false) } template -auto static_gather_impl(std::index_sequence) +auto static_gather_impl(std::index_sequence, bool exact_size) { - return elements(true); + return elements(exact_size); } -template +template auto static_gather() { - return static_gather_impl(std::make_index_sequence()); + return static_gather_impl(std::make_index_sequence(), exact_size); } }