diff --git a/README.asciidoc b/README.asciidoc index 76930485..16d76d4e 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -209,6 +209,7 @@ object you want. * _'_: select the enclosing single quoted string * _w_: select the whole word * _W_: select the whole WORD + * _s_: select the sentence Registers --------- diff --git a/src/normal.cc b/src/normal.cc index 2ff41a54..b7995762 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -523,6 +523,7 @@ void select_object(Context& context) { { Key::Modifiers::None, '\'' }, std::bind(select_surrounding, _1, CodepointPair{ '\'', '\'' }, flags) }, { { Key::Modifiers::None, 'w' }, std::bind(select_whole_word, _1, flags & SurroundFlags::Inner) }, { { Key::Modifiers::None, 'W' }, std::bind(select_whole_word, _1, flags & SurroundFlags::Inner) }, + { { Key::Modifiers::None, 's' }, std::bind(select_whole_sentence, _1, flags & SurroundFlags::Inner) }, }; auto it = key_to_selector.find(key); diff --git a/src/selectors.cc b/src/selectors.cc index 83b3b8fd..d16b1b43 100644 --- a/src/selectors.cc +++ b/src/selectors.cc @@ -383,6 +383,44 @@ Selection select_whole_word(const Selection& selection, bool inner) template Selection select_whole_word(const Selection&, bool); template Selection select_whole_word(const Selection&, bool); +Selection select_whole_sentence(const Selection& selection, bool inner) +{ + BufferIterator first = selection.last(); + + while (not is_begin(first)) + { + char cur = *first; + char prev = *(first-1); + if (is_eol(prev) and is_eol(cur)) + { + ++first; + break; + } + else if (prev == '.' or prev == ';') + break; + --first; + } + skip_while(first, is_blank); + + BufferIterator last = first; + while (not is_end(last)) + { + char cur = *last; + if (cur == '.' or cur == ';' or cur == '!' or cur == '?' or + (is_eol(cur) and (is_end(last+1) or is_eol(*last+1)))) + break; + ++last; + } + if (not inner and not is_end(last)) + { + ++last; + skip_while(last, is_blank); + --last; + } + + return Selection{first, last}; +} + Selection select_whole_lines(const Selection& selection) { // no need to be utf8 aware for is_eol as we only use \n as line seperator diff --git a/src/selectors.hh b/src/selectors.hh index 6bc85627..07c19494 100644 --- a/src/selectors.hh +++ b/src/selectors.hh @@ -27,6 +27,7 @@ Selection select_to_eol_reverse(const Selection& selection); template Selection select_whole_word(const Selection& selection, bool inner); +Selection select_whole_sentence(const Selection& selection, bool inner); Selection select_whole_lines(const Selection& selection); Selection select_whole_buffer(const Selection& selection); Selection trim_partial_lines(const Selection& selection);