From 33740d06eed248787beed8b0f07c83bb8cc93bf4 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Fri, 3 May 2013 13:53:23 +0200 Subject: [PATCH] Editor: tweak behaviour on undo/redo when selecting modified ranges --- src/editor.cc | 52 ++++++++++++++++++++++++------------------------ src/selection.hh | 6 ++++++ 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/editor.cc b/src/editor.cc index aa7fd1d5..ac7f4ec8 100644 --- a/src/editor.cc +++ b/src/editor.cc @@ -128,31 +128,11 @@ static bool compare_selections(const Selection& lhs, const Selection& rhs) return lhs.begin() < rhs.begin(); } -template -void sort_and_merge_overlapping(SelectionList& selections, size_t& main_selection) +template +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(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(m_selections, m_main_sel); + merge_overlapping(m_selections, m_main_sel, touches); } check_invariant(); return res; diff --git a/src/selection.hh b/src/selection.hh index d24bc87e..e5361a4d 100644 --- a/src/selection.hh +++ b/src/selection.hh @@ -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; // A selection is a Range, associated with a CaptureList