diff options
| author | Maxime Coste <mawww@kakoune.org> | 2018-03-01 15:21:55 +1100 |
|---|---|---|
| committer | Maxime Coste <mawww@kakoune.org> | 2018-03-01 15:21:55 +1100 |
| commit | f907e6cc46c4b3e63a6d984c0bd51b4e1e67e456 (patch) | |
| tree | e541c5e6933549467093abec539108a20744f8b1 /src/normal.cc | |
| parent | 34c7db0ea724b16a32ca72601448b7eb29bf9112 (diff) | |
Reintroduce complex selection merging behaviour
Selection merging is necessary if we want X to work nicely when we are
on EOL (jumping to next line is as nice as it could be, and we are much
more often on EOL nowadays).
Diffstat (limited to 'src/normal.cc')
| -rw-r--r-- | src/normal.cc | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/src/normal.cc b/src/normal.cc index 171132ba..176f8c0c 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -20,6 +20,7 @@ #include "shell_manager.hh" #include "string.hh" #include "user_interface.hh" +#include "unit_tests.hh" #include "window.hh" namespace Kakoune @@ -34,6 +35,33 @@ enum class SelectMode Append, }; +void merge_selections(Selection& sel, const Selection& new_sel) +{ + const bool forward = sel.cursor() >= sel.anchor(); + const bool new_forward = new_sel.cursor() > new_sel.anchor(); + if (forward and new_forward) + sel.anchor() = std::min(sel.anchor(), new_sel.anchor()); + const bool backward = sel.cursor() <= sel.anchor(); + const bool new_backward = new_sel.cursor() < new_sel.anchor(); + if (backward and new_backward) + sel.anchor() = std::max(sel.anchor(), new_sel.anchor()); + + sel.cursor() = new_sel.cursor(); +} + +UnitTest test_merge_selection{[] { + auto merge = [](Selection sel, const Selection& new_sel) { + merge_selections(sel, new_sel); + return sel; + }; + kak_assert(merge({{0, 1}, {0, 2} }, {{0, 3}, {0, 4}}) == Selection{{0, 1}, {0, 4}}); + kak_assert(merge({{0, 1}, {0, 2} }, {{0, 1}, {0, 2}}) == Selection{{0, 1}, {0, 2}}); + kak_assert(merge({{0, 1}, {0, 2} }, {{0, 0}, {0, 0}}) == Selection{{0, 1}, {0, 0}}); + kak_assert(merge({{0, 1}, {0, 2} }, {{0, 0}, {0, 3}}) == Selection{{0, 0}, {0, 3}}); + kak_assert(merge({{0, 1}, {0, 3} }, {{0, 4}, {0, 2}}) == Selection{{0, 1}, {0, 2}}); + kak_assert(merge({{0, 1}, {0, 2} }, {{0, 1}, {0, 1}}) == Selection{{0, 1}, {0, 1}}); +}}; + template<SelectMode mode, typename T> void select(Context& context, T func) { @@ -63,7 +91,7 @@ void select(Context& context, T func) } if (mode == SelectMode::Extend) - sel.cursor() = res->cursor(); + merge_selections(sel, *res); else { sel.anchor() = res->anchor(); @@ -788,7 +816,7 @@ void search(Context& context, NormalParams params) if (mode == SelectMode::Replace) sel = keep_direction(find_next_match<direction>(context, sel, regex, wrapped), sel); if (mode == SelectMode::Extend) - sel.cursor() = find_next_match<direction>(context, sel, regex, wrapped).cursor(); + merge_selections(sel, find_next_match<direction>(context, sel, regex, wrapped)); } selections.sort_and_merge_overlapping(); } while (--c > 0); |
