Editor: tweak behaviour on undo/redo when selecting modified ranges

This commit is contained in:
Maxime Coste 2013-05-03 13:53:23 +02:00
parent 564cfb084e
commit 33740d06ee
2 changed files with 32 additions and 26 deletions

View File

@ -128,31 +128,11 @@ static bool compare_selections(const Selection& lhs, const Selection& rhs)
return lhs.begin() < rhs.begin();
}
template<bool already_sorted = false>
void sort_and_merge_overlapping(SelectionList& selections, size_t& main_selection)
template<typename OverlapsFunc>
void merge_overlapping(SelectionList& selections, size_t& main_selection,
OverlapsFunc overlaps)
{
if (selections.size() == 1)
return;
if (already_sorted)
{
kak_assert(std::is_sorted(selections.begin(), selections.end(), compare_selections));
}
else
{
const auto& main = selections[main_selection];
const auto main_begin = main.begin();
main_selection = std::count_if(selections.begin(), selections.end(),
[&](const Selection& sel) {
auto begin = sel.begin();
if (begin == main_begin)
return &sel < &main;
else
return sel.begin() < main_begin;
});
std::stable_sort(selections.begin(), selections.end(), compare_selections);
}
kak_assert(std::is_sorted(selections.begin(), selections.end(), compare_selections));
for (size_t i = 0; i+1 < selections.size() and selections.size() > 1;)
{
if (overlaps(selections[i], selections[i+1]))
@ -167,6 +147,26 @@ void sort_and_merge_overlapping(SelectionList& selections, size_t& main_selectio
}
}
void sort_and_merge_overlapping(SelectionList& selections, size_t& main_selection)
{
if (selections.size() == 1)
return;
const auto& main = selections[main_selection];
const auto main_begin = main.begin();
main_selection = std::count_if(selections.begin(), selections.end(),
[&](const Selection& sel) {
auto begin = sel.begin();
if (begin == main_begin)
return &sel < &main;
else
return sel.begin() < main_begin;
});
std::stable_sort(selections.begin(), selections.end(), compare_selections);
merge_overlapping(selections, main_selection, overlaps);
}
void Editor::move_selections(CharCount offset, SelectMode mode)
{
kak_assert(mode == SelectMode::Replace or mode == SelectMode::Extend);
@ -391,7 +391,7 @@ bool Editor::undo()
{
m_selections = std::move(listener.ranges());
m_main_sel = m_selections.size() - 1;
sort_and_merge_overlapping<true>(m_selections, m_main_sel);
merge_overlapping(m_selections, m_main_sel, touches);
}
check_invariant();
return res;
@ -405,7 +405,7 @@ bool Editor::redo()
{
m_selections = std::move(listener.ranges());
m_main_sel = m_selections.size() - 1;
sort_and_merge_overlapping<true>(m_selections, m_main_sel);
merge_overlapping(m_selections, m_main_sel, touches);
}
check_invariant();
return res;

View File

@ -45,6 +45,12 @@ inline bool overlaps(const Range& lhs, const Range& rhs)
(lhs.first() <= rhs.last() and lhs.last() >= rhs.last());
}
inline bool touches(const Range& lhs, const Range& rhs)
{
return lhs.begin() <= rhs.begin() ? lhs.end() >= rhs.begin()
: lhs.begin() <= rhs.end();
}
using CaptureList = std::vector<String>;
// A selection is a Range, associated with a CaptureList