From a33b938652fbb6b9eb1c4e8b7033c5f3179915ca Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Tue, 21 Apr 2020 13:18:09 +1000 Subject: [PATCH] Fix issue with select object and empty matches --- src/selectors.cc | 21 ++++++++++--------- .../cmd | 1 + .../0-select-object-with-empty-begin-match/in | 6 ++++++ .../kak_selections_desc | 1 + 4 files changed, 19 insertions(+), 10 deletions(-) create mode 100644 test/regression/0-select-object-with-empty-begin-match/cmd create mode 100644 test/regression/0-select-object-with-empty-begin-match/in create mode 100644 test/regression/0-select-object-with-empty-begin-match/kak_selections_desc diff --git a/src/selectors.cc b/src/selectors.cc index 9649c6c1..92db5bdc 100644 --- a/src/selectors.cc +++ b/src/selectors.cc @@ -309,7 +309,7 @@ find_opening(Iterator pos, const Container& container, { if (nestable) { - for (auto m [[gnu::unused]] : RegexIt{match[0].second, pos, container.begin(), container.end(), closing}) + for (auto m [[maybe_unused]] : RegexIt{match[0].second, pos, container.begin(), container.end(), closing}) ++level; } @@ -327,17 +327,12 @@ find_closing(Iterator pos, const Container& container, const Regex& opening, const Regex& closing, int level, bool nestable) { - MatchResults res; - if (regex_search(pos, container.end(), container.begin(), container.end(), - res, opening) and res[0].first == pos) - pos = res[0].second; - using RegexIt = RegexIterator; for (auto match : RegexIt{pos, container.end(), container.begin(), container.end(), closing}) { if (nestable) { - for (auto m [[gnu::unused]] : RegexIt{pos, match[0].first, container.begin(), container.end(), opening}) + for (auto m [[maybe_unused]] : RegexIt{pos, match[0].first, container.begin(), container.end(), opening}) ++level; } @@ -355,6 +350,7 @@ find_surrounding(const Container& container, Iterator pos, const Regex& opening, const Regex& closing, ObjectFlags flags, int level) { + auto empty = [](const std::pair& m) { return m.first == m.second; }; const bool nestable = opening != closing; auto first = pos; auto last = pos; @@ -365,18 +361,23 @@ find_surrounding(const Container& container, Iterator pos, first = (flags & ObjectFlags::Inner) ? res->second : res->first; if (flags & ObjectFlags::ToEnd) // ensure we find the matching end { - last = res->first; + last = empty(*res) ? std::next(res->second) : res->second; level = 0; } } else return {}; } + else if (MatchResults res; + regex_search(pos, container.end(), container.begin(), container.end(), res, opening) and + res[0].first == pos) // Skip opening match if pos lies on it + last = empty(res[0]) ? std::next(res[0].second) : res[0].second; + if (flags & ObjectFlags::ToEnd) { if (auto res = find_closing(last, container, opening, closing, level, nestable)) - last = (flags & ObjectFlags::Inner) ? utf8::previous(res->first, container.begin()) - : utf8::previous(res->second, container.begin()); + last = utf8::previous((flags & ObjectFlags::Inner) ? res->first : res->second, + container.begin()); else return {}; } diff --git a/test/regression/0-select-object-with-empty-begin-match/cmd b/test/regression/0-select-object-with-empty-begin-match/cmd new file mode 100644 index 00000000..f28e2705 --- /dev/null +++ b/test/regression/0-select-object-with-empty-begin-match/cmd @@ -0,0 +1 @@ +c^,m diff --git a/test/regression/0-select-object-with-empty-begin-match/in b/test/regression/0-select-object-with-empty-begin-match/in new file mode 100644 index 00000000..9cd3a32e --- /dev/null +++ b/test/regression/0-select-object-with-empty-begin-match/in @@ -0,0 +1,6 @@ + +What is L%(o)rem Ipsum? + +What is Lorem %(I)psum? + +What is Lorem Ipsum%(?) diff --git a/test/regression/0-select-object-with-empty-begin-match/kak_selections_desc b/test/regression/0-select-object-with-empty-begin-match/kak_selections_desc new file mode 100644 index 00000000..d552c749 --- /dev/null +++ b/test/regression/0-select-object-with-empty-begin-match/kak_selections_desc @@ -0,0 +1 @@ +3.1,4.18 2.1,2.12