summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2015-11-26 13:36:26 +0000
committerMaxime Coste <frrrwww@gmail.com>2015-11-26 13:36:26 +0000
commitf66bbdf209b428aededcb36d2080d4cef86648ab (patch)
tree5d4f0564e4e8ad5af48d3d7c10d188e22f49057c /src
parentbf7d3a4fec59cc17288fc7a673574aa66d08e0dc (diff)
select/split interpret count parameter as the capture group to use
count being 0 by default, we use the whole match, but we can now specify to use capture 1 with 1s<regex><ret>.
Diffstat (limited to 'src')
-rw-r--r--src/normal.cc10
-rw-r--r--src/selectors.cc20
-rw-r--r--src/selectors.hh4
3 files changed, 21 insertions, 13 deletions
diff --git a/src/normal.cc b/src/normal.cc
index 009a2224..54b062c1 100644
--- a/src/normal.cc
+++ b/src/normal.cc
@@ -704,26 +704,28 @@ void use_selection_as_search_pattern(Context& context, NormalParams params)
void select_regex(Context& context, NormalParams params)
{
const char reg = to_lower(params.reg ? params.reg : '/');
- regex_prompt(context, "select:", [reg](Regex ex, PromptEvent event, Context& context) {
+ unsigned capture = (unsigned)params.count;
+ regex_prompt(context, "select:", [reg, capture](Regex ex, PromptEvent event, Context& context) {
if (ex.empty())
ex = Regex{context.main_sel_register_value(reg)};
else if (event == PromptEvent::Validate)
RegisterManager::instance()[reg] = ex.str();
if (not ex.empty() and not ex.str().empty())
- select_all_matches(context.selections(), ex);
+ select_all_matches(context.selections(), ex, capture);
});
}
void split_regex(Context& context, NormalParams params)
{
const char reg = to_lower(params.reg ? params.reg : '/');
- regex_prompt(context, "split:", [reg](Regex ex, PromptEvent event, Context& context) {
+ unsigned capture = (unsigned)params.count;
+ regex_prompt(context, "split:", [reg, capture](Regex ex, PromptEvent event, Context& context) {
if (ex.empty())
ex = Regex{context.main_sel_register_value(reg)};
else if (event == PromptEvent::Validate)
RegisterManager::instance()[reg] = ex.str();
if (not ex.empty() and not ex.str().empty())
- split_selections(context.selections(), ex);
+ split_selections(context.selections(), ex, capture);
});
}
diff --git a/src/selectors.cc b/src/selectors.cc
index 524ff9e1..c86d2749 100644
--- a/src/selectors.cc
+++ b/src/selectors.cc
@@ -560,8 +560,12 @@ void select_buffer(SelectionList& selections)
using RegexIt = RegexIterator<BufferIterator>;
-void select_all_matches(SelectionList& selections, const Regex& regex)
+void select_all_matches(SelectionList& selections, const Regex& regex, unsigned capture)
{
+ const unsigned mark_count = regex.mark_count();
+ if (capture > mark_count)
+ throw runtime_error("invalid capture number");
+
Vector<Selection> result;
auto& buffer = selections.buffer();
for (auto& sel : selections)
@@ -570,13 +574,12 @@ void select_all_matches(SelectionList& selections, const Regex& regex)
RegexIt re_it(buffer.iterator_at(sel.min()), sel_end, regex);
RegexIt re_end;
- const unsigned mark_count = regex.mark_count();
for (; re_it != re_end; ++re_it)
{
- auto begin = ensure_char_start(buffer, (*re_it)[0].first);
+ auto begin = ensure_char_start(buffer, (*re_it)[capture].first);
if (begin == sel_end)
continue;
- auto end = ensure_char_start(buffer, (*re_it)[0].second);
+ auto end = ensure_char_start(buffer, (*re_it)[capture].second);
CaptureList captures;
captures.reserve(mark_count);
@@ -598,8 +601,11 @@ void select_all_matches(SelectionList& selections, const Regex& regex)
selections = SelectionList{buffer, std::move(result)};
}
-void split_selections(SelectionList& selections, const Regex& regex)
+void split_selections(SelectionList& selections, const Regex& regex, unsigned capture)
{
+ if (capture > regex.mark_count())
+ throw runtime_error("invalid capture number");
+
Vector<Selection> result;
auto& buffer = selections.buffer();
auto buf_end = buffer.end();
@@ -612,13 +618,13 @@ void split_selections(SelectionList& selections, const Regex& regex)
for (; re_it != re_end; ++re_it)
{
- BufferIterator end = (*re_it)[0].first;
+ BufferIterator end = (*re_it)[capture].first;
if (end == buf_end)
continue;
end = ensure_char_start(buffer, end);
result.push_back(keep_direction({ begin.coord(), (begin == end) ? end.coord() : utf8::previous(end, begin).coord() }, sel));
- begin = ensure_char_start(buffer, (*re_it)[0].second);
+ begin = ensure_char_start(buffer, (*re_it)[capture].second);
}
if (begin.coord() <= sel.max())
result.push_back(keep_direction({ begin.coord(), sel.max() }, sel));
diff --git a/src/selectors.hh b/src/selectors.hh
index 7809344f..fff025fc 100644
--- a/src/selectors.hh
+++ b/src/selectors.hh
@@ -292,8 +292,8 @@ Selection find_next_match(const Buffer& buffer, const Selection& sel, const Rege
return {begin.coord(), end.coord(), std::move(captures)};
}
-void select_all_matches(SelectionList& selections, const Regex& regex);
-void split_selections(SelectionList& selections, const Regex& separator_regex);
+void select_all_matches(SelectionList& selections, const Regex& regex, unsigned capture = 0);
+void split_selections(SelectionList& selections, const Regex& separator_regex, unsigned capture = 0);
struct MatchingPair { Codepoint opening, closing; };
Selection select_surrounding(const Buffer& buffer, const Selection& selection,