summaryrefslogtreecommitdiff
path: root/src/normal.cc
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2018-05-19 14:02:11 +1000
committerMaxime Coste <mawww@kakoune.org>2018-05-19 14:15:16 +1000
commit243cfbc4aeb6bd0cccf185a68e926c225fd14af7 (patch)
treedac21dcc38b08499d5e08a74c09f7ab022d171b1 /src/normal.cc
parent60aef5e16d17ff77c4999b81eb8ec68dc7fc4621 (diff)
Fix behaviour of extending to next match when wrapping
If the search wraps to get to next match, drop that selection when extending.
Diffstat (limited to 'src/normal.cc')
-rw-r--r--src/normal.cc56
1 files changed, 43 insertions, 13 deletions
diff --git a/src/normal.cc b/src/normal.cc
index aa7cef98..6db2b4bb 100644
--- a/src/normal.cc
+++ b/src/normal.cc
@@ -804,6 +804,45 @@ void regex_prompt(Context& context, String prompt, String default_regex, T func)
});
}
+template<MatchDirection direction>
+void select_next_matches(Context& context, const Regex& regex, int count)
+{
+ auto& selections = context.selections();
+ do {
+ bool wrapped = false;
+ for (auto& sel : selections)
+ sel = keep_direction(find_next_match<direction>(context, sel, regex, wrapped), sel);
+ selections.sort_and_merge_overlapping();
+ } while (--count > 0);
+}
+
+template<MatchDirection direction>
+void extend_to_next_matches(Context& context, const Regex& regex, int count)
+{
+ Vector<Selection> new_sels;
+ auto& selections = context.selections();
+ do {
+ bool wrapped = false;
+ size_t main_index = selections.main_index();
+ for (auto& sel : selections)
+ {
+ auto new_sel = find_next_match<direction>(context, sel, regex, wrapped);
+ if (not wrapped)
+ {
+ new_sels.push_back(sel);
+ merge_selections(new_sels.back(), new_sel);
+ }
+ else if (new_sels.size() <= main_index)
+ --main_index;
+ }
+ if (new_sels.empty())
+ throw runtime_error{"All selections wrapped"};
+
+ selections.set(std::move(new_sels), main_index);
+ new_sels.clear();
+ } while (--count > 0);
+}
+
template<SelectMode mode, MatchDirection direction>
void search(Context& context, NormalParams params)
{
@@ -831,19 +870,10 @@ void search(Context& context, NormalParams params)
if (regex.empty() or regex.str().empty())
return;
- int c = count;
- auto& selections = context.selections();
- do {
- bool wrapped = false;
- for (auto& sel : selections)
- {
- if (mode == SelectMode::Replace)
- sel = keep_direction(find_next_match<direction>(context, sel, regex, wrapped), sel);
- if (mode == SelectMode::Extend)
- merge_selections(sel, find_next_match<direction>(context, sel, regex, wrapped));
- }
- selections.sort_and_merge_overlapping();
- } while (--c > 0);
+ if (mode == SelectMode::Extend)
+ extend_to_next_matches<direction>(context, regex, count);
+ else
+ select_next_matches<direction>(context, regex, count);
});
}