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:
parent
2366af29e2
commit
e74b581b0a
|
@ -1620,14 +1620,13 @@ SelectionList read_selections_from_register(char reg, Context& context)
|
||||||
Buffer& buffer = BufferManager::instance().get_buffer({arobase+1, percent});
|
Buffer& buffer = BufferManager::instance().get_buffer({arobase+1, percent});
|
||||||
size_t timestamp = str_to_int({percent + 1, desc.end()});
|
size_t timestamp = str_to_int({percent + 1, desc.end()});
|
||||||
|
|
||||||
Vector<Selection> sels;
|
auto sels = StringView{desc.begin(), arobase} | split<StringView>(':')
|
||||||
for (auto sel_desc : StringView{desc.begin(), arobase} | split<StringView>(':'))
|
| transform(selection_from_string)
|
||||||
sels.push_back(selection_from_string(sel_desc));
|
| gather<Vector<Selection>>();
|
||||||
|
|
||||||
if (sels.empty())
|
if (sels.empty())
|
||||||
throw runtime_error(format("Register {} contains an empty selection list", reg));
|
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
|
enum class CombineOp
|
||||||
|
|
|
@ -249,8 +249,8 @@ auto split(Element separator, Element escaper)
|
||||||
template<typename Range1, typename Range2>
|
template<typename Range1, typename Range2>
|
||||||
struct ConcatView
|
struct ConcatView
|
||||||
{
|
{
|
||||||
using RangeIt1 = decltype(begin(std::declval<Range1>()));
|
using RangeIt1 = decltype(std::declval<Range1>().begin());
|
||||||
using RangeIt2 = decltype(begin(std::declval<Range2>()));
|
using RangeIt2 = decltype(std::declval<Range2>().begin());
|
||||||
using ValueType = typename std::common_type_t<typename std::iterator_traits<RangeIt1>::value_type,
|
using ValueType = typename std::common_type_t<typename std::iterator_traits<RangeIt1>::value_type,
|
||||||
typename std::iterator_traits<RangeIt2>::value_type>;
|
typename std::iterator_traits<RangeIt2>::value_type>;
|
||||||
|
|
||||||
|
|
|
@ -16,16 +16,26 @@ SelectionList::SelectionList(Buffer& buffer, Selection s, size_t timestamp)
|
||||||
SelectionList::SelectionList(Buffer& buffer, Selection s)
|
SelectionList::SelectionList(Buffer& buffer, Selection s)
|
||||||
: SelectionList(buffer, std::move(s), buffer.timestamp()) {}
|
: SelectionList(buffer, std::move(s), buffer.timestamp()) {}
|
||||||
|
|
||||||
SelectionList::SelectionList(Buffer& buffer, Vector<Selection> s, size_t timestamp)
|
SelectionList::SelectionList(Buffer& buffer, Vector<Selection> list, size_t timestamp)
|
||||||
: m_buffer(&buffer), m_selections(std::move(s)), m_timestamp(timestamp)
|
: m_buffer(&buffer), m_selections(std::move(list)), m_timestamp(timestamp)
|
||||||
{
|
{
|
||||||
kak_assert(size() > 0);
|
kak_assert(size() > 0);
|
||||||
m_main = size() - 1;
|
m_main = size() - 1;
|
||||||
check_invariant();
|
check_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectionList::SelectionList(Buffer& buffer, Vector<Selection> s)
|
SelectionList::SelectionList(Buffer& buffer, Vector<Selection> list)
|
||||||
: SelectionList(buffer, std::move(s), buffer.timestamp()) {}
|
: 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)
|
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)
|
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)
|
Selection selection_from_string(StringView desc)
|
||||||
|
@ -510,18 +524,10 @@ SelectionList selection_list_from_string(Buffer& buffer, StringView desc)
|
||||||
if (desc.empty())
|
if (desc.empty())
|
||||||
throw runtime_error{"empty selection description"};
|
throw runtime_error{"empty selection description"};
|
||||||
|
|
||||||
Vector<Selection> sels;
|
auto sels = desc | split<StringView>(':')
|
||||||
for (auto sel_desc : desc | split<StringView>(':'))
|
| transform([&](auto&& d) { auto s = selection_from_string(d); clamp(s, buffer); return s; })
|
||||||
{
|
| gather<Vector<Selection>>();
|
||||||
auto sel = selection_from_string(sel_desc);
|
return {SelectionList::UnsortedTag{}, buffer, std::move(sels)};
|
||||||
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)};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,6 +87,10 @@ struct SelectionList
|
||||||
SelectionList(Buffer& buffer, Vector<Selection> s);
|
SelectionList(Buffer& buffer, Vector<Selection> s);
|
||||||
SelectionList(Buffer& buffer, Vector<Selection> s, size_t timestamp);
|
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 update();
|
||||||
|
|
||||||
void check_invariant() const;
|
void check_invariant() const;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user