Editor merge selections when they overlap
This commit is contained in:
parent
5bb37ad755
commit
a04d1e3a1f
|
@ -99,6 +99,30 @@ std::vector<String> Editor::selections_content() const
|
||||||
return contents;
|
return contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool overlaps(const SelectionAndCaptures& lhs,
|
||||||
|
const SelectionAndCaptures& rhs)
|
||||||
|
{
|
||||||
|
return (lhs.first() <= rhs.first() and lhs.last() >= rhs.first()) or
|
||||||
|
(lhs.first() <= rhs.last() and lhs.last() >= rhs.last());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void merge_overlapping(SelectionAndCapturesList& selections)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < selections.size(); ++i)
|
||||||
|
{
|
||||||
|
for (size_t j = i+1; j < selections.size();)
|
||||||
|
{
|
||||||
|
if (overlaps(selections[i], selections[j]))
|
||||||
|
{
|
||||||
|
selections[i].selection.merge_with(selections[j].selection);
|
||||||
|
selections.erase(selections.begin() + j);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Editor::move_selections(CharCount offset, SelectMode mode)
|
void Editor::move_selections(CharCount offset, SelectMode mode)
|
||||||
{
|
{
|
||||||
assert(mode == SelectMode::Replace or mode == SelectMode::Extend);
|
assert(mode == SelectMode::Replace or mode == SelectMode::Extend);
|
||||||
|
@ -110,6 +134,7 @@ void Editor::move_selections(CharCount offset, SelectMode mode)
|
||||||
utf8::previous(buffer().iterator_at_line_end(last)));
|
utf8::previous(buffer().iterator_at_line_end(last)));
|
||||||
sel.selection = Selection(mode == SelectMode::Extend ? sel.first() : last, last);
|
sel.selection = Selection(mode == SelectMode::Extend ? sel.first() : last, last);
|
||||||
}
|
}
|
||||||
|
merge_overlapping(m_selections);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::move_selections(LineCount offset, SelectMode mode)
|
void Editor::move_selections(LineCount offset, SelectMode mode)
|
||||||
|
@ -122,6 +147,7 @@ void Editor::move_selections(LineCount offset, SelectMode mode)
|
||||||
BufferIterator last = utf8::finish(m_buffer.iterator_at(pos, true));
|
BufferIterator last = utf8::finish(m_buffer.iterator_at(pos, true));
|
||||||
sel.selection = Selection(mode == SelectMode::Extend ? sel.first() : last, last);
|
sel.selection = Selection(mode == SelectMode::Extend ? sel.first() : last, last);
|
||||||
}
|
}
|
||||||
|
merge_overlapping(m_selections);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::clear_selections()
|
void Editor::clear_selections()
|
||||||
|
@ -181,9 +207,9 @@ void Editor::select(const Selector& selector, SelectMode mode)
|
||||||
if (res.captures.empty())
|
if (res.captures.empty())
|
||||||
res.captures = sel.captures;
|
res.captures = sel.captures;
|
||||||
m_selections.push_back(res);
|
m_selections.push_back(res);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
for (auto& sel : m_selections)
|
for (auto& sel : m_selections)
|
||||||
{
|
{
|
||||||
SelectionAndCaptures res = selector(sel.selection);
|
SelectionAndCaptures res = selector(sel.selection);
|
||||||
|
@ -196,6 +222,8 @@ void Editor::select(const Selector& selector, SelectMode mode)
|
||||||
sel.captures = std::move(res.captures);
|
sel.captures = std::move(res.captures);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
merge_overlapping(m_selections);
|
||||||
|
}
|
||||||
|
|
||||||
struct nothing_selected : public runtime_error
|
struct nothing_selected : public runtime_error
|
||||||
{
|
{
|
||||||
|
@ -222,6 +250,7 @@ void Editor::multi_select(const MultiSelector& selector)
|
||||||
if (new_selections.empty())
|
if (new_selections.empty())
|
||||||
throw nothing_selected();
|
throw nothing_selected();
|
||||||
|
|
||||||
|
merge_overlapping(new_selections);
|
||||||
m_selections = std::move(new_selections);
|
m_selections = std::move(new_selections);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user