diff --git a/README.asciidoc b/README.asciidoc index d37f93e5..6fac63d5 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -340,6 +340,7 @@ object you want. * _s_: select the sentence * _p_: select the paragraph * _i_: select the current indentation block + * _n_: select the number For nestable objects, a count can be used in order to specify which surrounding level to select. diff --git a/src/normal.cc b/src/normal.cc index 882fbc3a..3c78e1f2 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -918,6 +918,7 @@ void select_object(Context& context, int param) { 's', select_sentence }, { 'p', select_paragraph }, { 'i', select_indent }, + { 'n', select_number }, }; for (auto& sel : selectors) { diff --git a/src/selectors.cc b/src/selectors.cc index 94c4fac7..ee1bf680 100644 --- a/src/selectors.cc +++ b/src/selectors.cc @@ -218,6 +218,31 @@ Selection select_to_eol_reverse(const Buffer& buffer, const Selection& selection return utf8_range(begin, end == buffer.begin() ? end : end+1); } +Selection select_number(const Buffer& buffer, const Selection& selection, ObjectFlags flags) +{ + auto is_number = [&](char c) { + return (c >= '0' and c <= '9') or + (not (flags & ObjectFlags::Inner) and c == '.'); + }; + + BufferIterator first = buffer.iterator_at(selection.cursor()); + if (flags & ObjectFlags::ToBegin) + { + skip_while_reverse(first, buffer.begin(), is_number); + if (not is_number(*first) or not *first == '-') + ++first; + } + BufferIterator last = buffer.iterator_at(selection.cursor()); + if (flags & ObjectFlags::ToEnd) + { + skip_while(last, buffer.end(), is_number); + --last; + } + + return (flags & ObjectFlags::ToEnd) ? Selection{first.coord(), last.coord()} + : Selection{last.coord(), first.coord()}; +} + static bool is_end_of_sentence(char c) { return c == '.' or c == ';' or c == '!' or c == '?'; diff --git a/src/selectors.hh b/src/selectors.hh index e6a3022a..d96adf97 100644 --- a/src/selectors.hh +++ b/src/selectors.hh @@ -134,10 +134,8 @@ Selection select_to_previous_word(const Buffer& buffer, const Selection& selecti return utf8_range(begin, with_end ? end : end+1); } -Selection select_line(const Buffer& buffer, -const Selection& selection); -Selection select_matching(const Buffer& buffer, - const Selection& selection); +Selection select_line(const Buffer& buffer, const Selection& selection); +Selection select_matching(const Buffer& buffer, const Selection& selection); Selection select_to(const Buffer& buffer, const Selection& selection, Codepoint c, int count, bool inclusive); @@ -159,7 +157,9 @@ constexpr ObjectFlags operator|(ObjectFlags lhs, ObjectFlags rhs) { return (ObjectFlags)((int)lhs | (int) rhs); } template -Selection select_word(const Buffer& buffer, const Selection& selection, ObjectFlags flags) +Selection select_word(const Buffer& buffer, + const Selection& selection, + ObjectFlags flags) { Utf8Iterator first = buffer.iterator_at(selection.cursor()); Utf8Iterator last = first; @@ -200,6 +200,10 @@ Selection select_word(const Buffer& buffer, const Selection& selection, ObjectFl : utf8_range(last, first); } +Selection select_number(const Buffer& buffer, + const Selection& selection, + ObjectFlags flags); + Selection select_sentence(const Buffer& buffer, const Selection& selection, ObjectFlags flags);