summaryrefslogtreecommitdiff
path: root/src/selection.cc
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2018-01-12 07:51:19 +1100
committerMaxime Coste <mawww@kakoune.org>2018-01-12 07:51:19 +1100
commite74b581b0a7c6a196d0d6efa1d92e309e48483d1 (patch)
tree3bce59146f99674f57b74258390ae36f9bdcc43d /src/selection.cc
parent2366af29e2472243227b2d8cbfdbe1ab173ad9c4 (diff)
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
Diffstat (limited to 'src/selection.cc')
-rw-r--r--src/selection.cc40
1 files changed, 23 insertions, 17 deletions
diff --git a/src/selection.cc b/src/selection.cc
index 87c8eade..5f323894 100644
--- a/src/selection.cc
+++ b/src/selection.cc
@@ -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)};
}
}