Editor merge selections when they overlap

This commit is contained in:
Maxime Coste 2012-10-10 19:11:24 +02:00
parent 5bb37ad755
commit a04d1e3a1f

View File

@ -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);
@ -195,6 +221,8 @@ void Editor::select(const Selector& selector, SelectMode mode)
if (not res.captures.empty()) if (not res.captures.empty())
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);
} }