summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrank LENORMAND <lenormf@gmail.com>2018-09-30 09:41:17 +0300
committerFrank LENORMAND <lenormf@gmail.com>2018-09-30 19:56:37 +0300
commit2d44712766081a0b3b4f71ac77f73e973e724b02 (patch)
treefa144d01e24ccf1fb4918abcde4f480f1251db11
parent6b7200e4d5c04cfb6d6f5740e3e95f5baad6d7f1 (diff)
src: Implement <a-m> and <a-M>
Closes #2425
-rw-r--r--doc/pages/keys.asciidoc12
-rw-r--r--src/normal.cc6
-rw-r--r--src/selectors.cc17
-rw-r--r--src/selectors.hh1
4 files changed, 33 insertions, 3 deletions
diff --git a/doc/pages/keys.asciidoc b/doc/pages/keys.asciidoc
index d4b4f04d..63e8b55f 100644
--- a/doc/pages/keys.asciidoc
+++ b/doc/pages/keys.asciidoc
@@ -139,6 +139,18 @@ the Shift modifier and moving will extend each selection instead.
select to the next sequence enclosed by matching character, see the
`matching_pairs` option in <<options#,`:doc options`>>
+*M*::
+ extend the current selection to the next sequence enclosed by matching
+ character, see the `matching_pairs` option in <<options#,`:doc options`>>
+
+*<a-m>*::
+ select to the previous sequence enclosed by matching character, see the
+ `matching_pairs` option in <<options#,`:doc options`>>
+
+*<a-M>*::
+ extend the current selection to the previous sequence enclosed by matching
+ character, see the `matching_pairs` option in <<options#,`:doc options`>>
+
*x*::
select line on which the end of each selection lies (or next line when end lies
on an end-of-line)
diff --git a/src/normal.cc b/src/normal.cc
index d7d88ab0..7a1533ee 100644
--- a/src/normal.cc
+++ b/src/normal.cc
@@ -2215,8 +2215,10 @@ static const HashMap<Key, NormalCmd, MemoryDomain::Undefined, KeymapBackend> key
{ {alt('x')}, {"extend selections to whole lines", select<SelectMode::Replace, select_lines>} },
{ {alt('X')}, {"crop selections to whole lines", select<SelectMode::Replace, trim_partial_lines>} },
- { {'m'}, {"select to matching character", select<SelectMode::Replace, select_matching>} },
- { {'M'}, {"extend to matching character", select<SelectMode::Extend, select_matching>} },
+ { {'m'}, {"select to matching character", select<SelectMode::Replace, select_matching<true>>} },
+ { {alt('m')}, {"backward select to matching character", select<SelectMode::Replace, select_matching<false>>} },
+ { {'M'}, {"extend to matching character", select<SelectMode::Extend, select_matching<true>>} },
+ { {alt('M')}, {"backward extend to matching character", select<SelectMode::Extend, select_matching<false>>} },
{ {'/'}, {"select next given regex match", search<SelectMode::Replace, MatchDirection::Forward>} },
{ {'?'}, {"extend with next given regex match", search<SelectMode::Extend, MatchDirection::Forward>} },
diff --git a/src/selectors.cc b/src/selectors.cc
index a11a200d..cbbc3f03 100644
--- a/src/selectors.cc
+++ b/src/selectors.cc
@@ -220,6 +220,7 @@ select_to_first_non_blank(const Context& context, const Selection& selection)
return {it.coord()};
}
+template<bool forward>
Optional<Selection>
select_matching(const Context& context, const Selection& selection)
{
@@ -227,13 +228,23 @@ select_matching(const Context& context, const Selection& selection)
auto& matching_pairs = context.options()["matching_pairs"].get<Vector<Codepoint, MemoryDomain::Options>>();
Utf8Iterator it{buffer.iterator_at(selection.cursor()), buffer};
auto match = matching_pairs.end();
- while (it != buffer.end())
+
+ if (forward) while (it != buffer.end())
{
match = find(matching_pairs, *it);
if (match != matching_pairs.end())
break;
++it;
}
+ else while (true)
+ {
+ match = find(matching_pairs, *it);
+ if (match != matching_pairs.end()
+ or it == buffer.begin())
+ break;
+ --it;
+ }
+
if (match == matching_pairs.end())
return {};
@@ -271,6 +282,10 @@ select_matching(const Context& context, const Selection& selection)
}
return {};
}
+template Optional<Selection>
+select_matching<true>(const Context& context, const Selection& selection);
+template Optional<Selection>
+select_matching<false>(const Context& context, const Selection& selection);
template<typename Iterator, typename Container>
Optional<std::pair<Iterator, Iterator>>
diff --git a/src/selectors.hh b/src/selectors.hh
index 00bc83dd..2e56c214 100644
--- a/src/selectors.hh
+++ b/src/selectors.hh
@@ -31,6 +31,7 @@ select_to_previous_word(const Context& context, const Selection& selection);
Optional<Selection>
select_line(const Context& context, const Selection& selection);
+template<bool forward>
Optional<Selection>
select_matching(const Context& context, const Selection& selection);