Add support for @
symbols in selection buffer
The selection descriptions use the format `<buffer>@<timestamp>@<main_index>`. This fails when file paths have `@` symbols in them: the parser splits on `@` symbols and finds more values than it expects. We here modify the behavior to require *at least* two @ symbols, using the last two for `<timestamp>` and `<main_index>` and leaving the remaining text for the <buffer>. This should work for any number of `@` symbols, since `<timestamp>` and `<main_index>` are numbers and should never contain `@` symbols.
This commit is contained in:
parent
2749093143
commit
5596b4b2b9
|
@ -1,5 +1,7 @@
|
|||
#include "normal.hh"
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "buffer.hh"
|
||||
#include "buffer_manager.hh"
|
||||
#include "buffer_utils.hh"
|
||||
|
@ -1774,11 +1776,20 @@ 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));
|
||||
|
||||
struct error : runtime_error { error(size_t) : runtime_error{"expected <buffer>@<timestamp>@main_index"} {} };
|
||||
const auto desc = content[0] | split<StringView>('@') | static_gather<error, 3>();
|
||||
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]);
|
||||
// Use the last two values for timestamp and main_index to allow the buffer
|
||||
// name to have @ symbols
|
||||
struct error : runtime_error { error() : runtime_error{"expected <buffer>@<timestamp>@main_index"} {} };
|
||||
const auto desc = content[0] | split<StringView>('@') | gather<Vector>();
|
||||
const size_t desc_size = desc.size();
|
||||
if (desc_size < 3)
|
||||
throw new error;
|
||||
auto const buffer_name_view = desc | drop(2);
|
||||
auto const buffer_name_temp = accumulate (buffer_name_view, ""_str,
|
||||
[](auto str1, auto str2) { return str1 + "@"_str + str2; });
|
||||
auto const buffer_name = buffer_name_temp.substr (CharCount (1));
|
||||
Buffer& buffer = BufferManager::instance().get_buffer(buffer_name);
|
||||
const size_t timestamp = str_to_int(desc[desc_size - 2]);
|
||||
size_t main = str_to_int(desc[desc_size - 1]);
|
||||
|
||||
return selection_list_from_strings(buffer, ColumnType::Byte, content | skip(1), timestamp, main);
|
||||
}
|
||||
|
|
|
@ -73,6 +73,24 @@ inline auto skip(size_t count)
|
|||
});
|
||||
}
|
||||
|
||||
template<typename Range>
|
||||
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<decay_range<Range>>{std::forward<Range>(range), count};
|
||||
});
|
||||
}
|
||||
|
||||
template<typename Range, typename Filter>
|
||||
struct FilterView
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user