summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2020-05-29 11:59:59 +1000
committerMaxime Coste <mawww@kakoune.org>2020-05-29 12:00:02 +1000
commit63371da8aa9edd7f7812c8a56ad573e46df111fd (patch)
treee92e603b5b4463c95d80ef9eb21d61af08b7dd25
parent94f33bb63862357557ef533126a41d64b12f1c53 (diff)
Avoid to_remove vector in select helper function
Remove the need to allocate anything when removing selections.
-rw-r--r--src/normal.cc17
-rw-r--r--src/selection.cc9
-rw-r--r--src/selection.hh1
3 files changed, 20 insertions, 7 deletions
diff --git a/src/normal.cc b/src/normal.cc
index 53e745e2..8796c86f 100644
--- a/src/normal.cc
+++ b/src/normal.cc
@@ -92,14 +92,16 @@ void select(Context& context, T func)
}
else
{
- Vector<int> to_remove;
- for (int i = 0; i < (int)selections.size(); ++i)
+ auto main_index = selections.main_index();
+ auto new_end = selections.begin();
+ for (size_t i = 0; i < selections.size(); ++i)
{
auto& sel = selections[i];
auto res = func(context, sel);
if (not res)
{
- to_remove.push_back(i);
+ if (i <= main_index and main_index != 0)
+ --main_index;
continue;
}
@@ -112,12 +114,13 @@ void select(Context& context, T func)
}
if (not res->captures().empty())
sel.captures() = std::move(res->captures());
+ *new_end++ = std::move(sel);
}
-
- if (to_remove.size() == selections.size())
+ if (new_end == selections.begin())
throw no_selections_remaining{};
- for (auto& i : to_remove | reverse())
- selections.remove(i);
+
+ selections.set_main_index(main_index);
+ selections.remove_from(new_end - selections.begin());
}
selections.sort_and_merge_overlapping();
diff --git a/src/selection.cc b/src/selection.cc
index d637e007..4c908efb 100644
--- a/src/selection.cc
+++ b/src/selection.cc
@@ -33,6 +33,15 @@ void SelectionList::remove(size_t index)
if (index < m_main or m_main == m_selections.size())
--m_main;
}
+
+void SelectionList::remove_from(size_t index)
+{
+ kak_assert(index > 0);
+ m_selections.erase(begin() + index, end());
+ if (index <= m_main)
+ m_main = m_selections.size() - 1;
+}
+
void SelectionList::set(Vector<Selection> list, size_t main)
{
kak_assert(main < list.size());
diff --git a/src/selection.hh b/src/selection.hh
index af56856e..28eca5f2 100644
--- a/src/selection.hh
+++ b/src/selection.hh
@@ -125,6 +125,7 @@ struct SelectionList
const_iterator end() const { return m_selections.end(); }
void remove(size_t index);
+ void remove_from(size_t index);
const Selection* data() const { return m_selections.data(); }
size_t size() const { return m_selections.size(); }