diff --git a/src/main.cc b/src/main.cc index 0750ffc8..af072638 100644 --- a/src/main.cc +++ b/src/main.cc @@ -548,6 +548,12 @@ std::unordered_map> alt_ke { 'f', [](Window& window, int count) { window.select(std::bind(select_to_reverse, _1, getch(), count, true)); } }, { 'T', [](Window& window, int count) { window.select(std::bind(select_to_reverse, _1, getch(), count, false), true); } }, { 'F', [](Window& window, int count) { window.select(std::bind(select_to_reverse, _1, getch(), count, true), true); } }, + { 'w', [](Window& window, int count) { do { window.select(select_to_next_WORD); } while(--count > 0); } }, + { 'e', [](Window& window, int count) { do { window.select(select_to_next_WORD_end); } while(--count > 0); } }, + { 'b', [](Window& window, int count) { do { window.select(select_to_previous_WORD); } while(--count > 0); } }, + { 'W', [](Window& window, int count) { do { window.select(select_to_next_WORD, true); } while(--count > 0); } }, + { 'E', [](Window& window, int count) { do { window.select(select_to_next_WORD_end, true); } while(--count > 0); } }, + { 'B', [](Window& window, int count) { do { window.select(select_to_previous_WORD, true); } while(--count > 0); } }, }; int main(int argc, char* argv[]) diff --git a/src/selectors.cc b/src/selectors.cc index a30e1fe2..e54704e6 100644 --- a/src/selectors.cc +++ b/src/selectors.cc @@ -41,6 +41,7 @@ enum class CharCategories Punctuation, }; +template static CharCategories categorize(char c) { if (is_word(c)) @@ -49,7 +50,8 @@ static CharCategories categorize(char c) return CharCategories::EndOfLine; if (is_blank(c)) return CharCategories::Blank; - return CharCategories::Punctuation; + return punctuation_is_not_word ? CharCategories::Punctuation + : CharCategories::Word; } template @@ -66,7 +68,6 @@ void skip_while_reverse(BufferIterator& it, T condition) --it; } - Selection select_to_next_word(const BufferIterator& cursor) { BufferIterator begin = cursor; @@ -124,6 +125,54 @@ Selection select_to_previous_word(const BufferIterator& cursor) return Selection(begin, end+1); } +Selection select_to_next_WORD(const BufferIterator& cursor) +{ + BufferIterator begin = cursor; + if (categorize(*begin) != categorize(*(begin+1))) + ++begin; + + skip_while(begin, is_eol); + + BufferIterator end = begin+1; + + skip_while(end, [] (char c) { return !is_blank(c) and !is_eol(c); }); + skip_while(end, is_blank); + + return Selection(begin, end-1); +} + +Selection select_to_next_WORD_end(const BufferIterator& cursor) +{ + BufferIterator begin = cursor; + if (categorize(*begin) != categorize(*(begin+1))) + ++begin; + + skip_while(begin, is_eol); + + BufferIterator end = begin+1; + + skip_while(end, is_blank); + skip_while(end, [] (char c) { return !is_blank(c) and !is_eol(c); }); + + return Selection(begin, end-1); +} + +Selection select_to_previous_WORD(const BufferIterator& cursor) +{ + BufferIterator begin = cursor; + if (categorize(*begin) != categorize(*(begin+1))) + ++begin; + + skip_while_reverse(begin, is_eol); + + BufferIterator end = begin+1; + + skip_while_reverse(end, is_blank); + skip_while_reverse(end, [] (char c) { return !is_blank(c) and !is_eol(c); }); + + return Selection(begin, end+1); +} + Selection select_line(const BufferIterator& cursor) { BufferIterator first = cursor; diff --git a/src/selectors.hh b/src/selectors.hh index 370df3cf..4887a747 100644 --- a/src/selectors.hh +++ b/src/selectors.hh @@ -9,6 +9,9 @@ namespace Kakoune Selection select_to_next_word(const BufferIterator& cursor); Selection select_to_next_word_end(const BufferIterator& cursor); Selection select_to_previous_word(const BufferIterator& cursor); +Selection select_to_next_WORD(const BufferIterator& cursor); +Selection select_to_next_WORD_end(const BufferIterator& cursor); +Selection select_to_previous_WORD(const BufferIterator& cursor); Selection select_line(const BufferIterator& cursor); Selection select_matching(const BufferIterator& cursor);