Save/restore main selection from/to strings

Always consider that the first selection in the list is the main
one, save selections that way.

This approach was suggested by PR #1786 but the implementation here
is different, and is used more generally whenever we save selections
to strings.

This is also the prefered way to work only on the main selection:
save selections with Z, reduce to main with <space>, restore with z.

Closes #1786
Fixes #1750
This commit is contained in:
Maxime Coste 2018-01-12 07:51:19 +11:00
parent 2366af29e2
commit e74b581b0a
4 changed files with 33 additions and 24 deletions

View File

@ -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<Selection> sels;
for (auto sel_desc : StringView{desc.begin(), arobase} | split<StringView>(':'))
sels.push_back(selection_from_string(sel_desc));
auto sels = StringView{desc.begin(), arobase} | split<StringView>(':')
| transform(selection_from_string)
| gather<Vector<Selection>>();
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

View File

@ -249,8 +249,8 @@ auto split(Element separator, Element escaper)
template<typename Range1, typename Range2>
struct ConcatView
{
using RangeIt1 = decltype(begin(std::declval<Range1>()));
using RangeIt2 = decltype(begin(std::declval<Range2>()));
using RangeIt1 = decltype(std::declval<Range1>().begin());
using RangeIt2 = decltype(std::declval<Range2>().begin());
using ValueType = typename std::common_type_t<typename std::iterator_traits<RangeIt1>::value_type,
typename std::iterator_traits<RangeIt2>::value_type>;

View File

@ -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<Selection> s, size_t timestamp)
: m_buffer(&buffer), m_selections(std::move(s)), m_timestamp(timestamp)
SelectionList::SelectionList(Buffer& buffer, Vector<Selection> 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<Selection> s)
: SelectionList(buffer, std::move(s), buffer.timestamp()) {}
SelectionList::SelectionList(Buffer& buffer, Vector<Selection> list)
: SelectionList(buffer, std::move(list), buffer.timestamp()) {}
SelectionList::SelectionList(SelectionList::UnsortedTag, Buffer& buffer, Vector<Selection> list)
: SelectionList(UnsortedTag{}, buffer, std::move(list), buffer.timestamp()) {}
SelectionList::SelectionList(SelectionList::UnsortedTag, Buffer& buffer, Vector<Selection> 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<Selection>;
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<Selection> sels;
for (auto sel_desc : desc | split<StringView>(':'))
{
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<StringView>(':')
| transform([&](auto&& d) { auto s = selection_from_string(d); clamp(s, buffer); return s; })
| gather<Vector<Selection>>();
return {SelectionList::UnsortedTag{}, buffer, std::move(sels)};
}
}

View File

@ -87,6 +87,10 @@ struct SelectionList
SelectionList(Buffer& buffer, Vector<Selection> s);
SelectionList(Buffer& buffer, Vector<Selection> s, size_t timestamp);
struct UnsortedTag {};
SelectionList(UnsortedTag, Buffer& buffer, Vector<Selection> s);
SelectionList(UnsortedTag, Buffer& buffer, Vector<Selection> s, size_t timestamp);
void update();
void check_invariant() const;