diff --git a/src/main.cc b/src/main.cc index bde3aa47..d9705d7c 100644 --- a/src/main.cc +++ b/src/main.cc @@ -758,12 +758,12 @@ std::unordered_map> keymap { { Key::Modifiers::None, '|' }, do_pipe }, { { Key::Modifiers::None, ' ' }, [](Editor& editor, int count) { if (count == 0) editor.clear_selections(); else editor.keep_selection(count-1); } }, - { { Key::Modifiers::None, 'w' }, [](Editor& editor, int count) { do { editor.select(select_to_next_word); } while(--count > 0); } }, - { { Key::Modifiers::None, 'e' }, [](Editor& editor, int count) { do { editor.select(select_to_next_word_end); } while(--count > 0); } }, - { { Key::Modifiers::None, 'b' }, [](Editor& editor, int count) { do { editor.select(select_to_previous_word); } while(--count > 0); } }, - { { Key::Modifiers::None, 'W' }, [](Editor& editor, int count) { do { editor.select(select_to_next_word, true); } while(--count > 0); } }, - { { Key::Modifiers::None, 'E' }, [](Editor& editor, int count) { do { editor.select(select_to_next_word_end, true); } while(--count > 0); } }, - { { Key::Modifiers::None, 'B' }, [](Editor& editor, int count) { do { editor.select(select_to_previous_word, true); } while(--count > 0); } }, + { { Key::Modifiers::None, 'w' }, [](Editor& editor, int count) { do { editor.select(select_to_next_word); } while(--count > 0); } }, + { { Key::Modifiers::None, 'e' }, [](Editor& editor, int count) { do { editor.select(select_to_next_word_end); } while(--count > 0); } }, + { { Key::Modifiers::None, 'b' }, [](Editor& editor, int count) { do { editor.select(select_to_previous_word); } while(--count > 0); } }, + { { Key::Modifiers::None, 'W' }, [](Editor& editor, int count) { do { editor.select(select_to_next_word, true); } while(--count > 0); } }, + { { Key::Modifiers::None, 'E' }, [](Editor& editor, int count) { do { editor.select(select_to_next_word_end, true); } while(--count > 0); } }, + { { Key::Modifiers::None, 'B' }, [](Editor& editor, int count) { do { editor.select(select_to_previous_word, true); } while(--count > 0); } }, { { Key::Modifiers::None, 'x' }, [](Editor& editor, int count) { do { editor.select(select_line, false); } while(--count > 0); } }, { { Key::Modifiers::None, 'X' }, [](Editor& editor, int count) { do { editor.select(select_line, true); } while(--count > 0); } }, { { Key::Modifiers::None, 'm' }, [](Editor& editor, int count) { editor.select(select_matching); } }, @@ -785,12 +785,12 @@ std::unordered_map> keymap { { Key::Modifiers::Alt, 'T' }, [](Editor& editor, int count) { editor.select(std::bind(select_to_reverse, _1, get_key().key, count, false), true); } }, { { Key::Modifiers::Alt, 'F' }, [](Editor& editor, int count) { editor.select(std::bind(select_to_reverse, _1, get_key().key, count, true), true); } }, - { { Key::Modifiers::Alt, 'w' }, [](Editor& editor, int count) { do { editor.select(select_to_next_WORD); } while(--count > 0); } }, - { { Key::Modifiers::Alt, 'e' }, [](Editor& editor, int count) { do { editor.select(select_to_next_WORD_end); } while(--count > 0); } }, - { { Key::Modifiers::Alt, 'b' }, [](Editor& editor, int count) { do { editor.select(select_to_previous_WORD); } while(--count > 0); } }, - { { Key::Modifiers::Alt, 'W' }, [](Editor& editor, int count) { do { editor.select(select_to_next_WORD, true); } while(--count > 0); } }, - { { Key::Modifiers::Alt, 'E' }, [](Editor& editor, int count) { do { editor.select(select_to_next_WORD_end, true); } while(--count > 0); } }, - { { Key::Modifiers::Alt, 'B' }, [](Editor& editor, int count) { do { editor.select(select_to_previous_WORD, true); } while(--count > 0); } }, + { { Key::Modifiers::Alt, 'w' }, [](Editor& editor, int count) { do { editor.select(select_to_next_word); } while(--count > 0); } }, + { { Key::Modifiers::Alt, 'e' }, [](Editor& editor, int count) { do { editor.select(select_to_next_word_end); } while(--count > 0); } }, + { { Key::Modifiers::Alt, 'b' }, [](Editor& editor, int count) { do { editor.select(select_to_previous_word); } while(--count > 0); } }, + { { Key::Modifiers::Alt, 'W' }, [](Editor& editor, int count) { do { editor.select(select_to_next_word, true); } while(--count > 0); } }, + { { Key::Modifiers::Alt, 'E' }, [](Editor& editor, int count) { do { editor.select(select_to_next_word_end, true); } while(--count > 0); } }, + { { Key::Modifiers::Alt, 'B' }, [](Editor& editor, int count) { do { editor.select(select_to_previous_word, true); } while(--count > 0); } }, { { Key::Modifiers::Alt, 'l' }, [](Editor& editor, int count) { do { editor.select(select_to_eol, false); } while(--count > 0); } }, { { Key::Modifiers::Alt, 'L' }, [](Editor& editor, int count) { do { editor.select(select_to_eol, true); } while(--count > 0); } }, diff --git a/src/selectors.cc b/src/selectors.cc index 5567de0c..bb88697f 100644 --- a/src/selectors.cc +++ b/src/selectors.cc @@ -6,17 +6,24 @@ namespace Kakoune { -static bool is_eol(char c) +namespace +{ + +bool is_eol(char c) { return c == '\n'; } -static bool is_blank(char c) +bool is_blank(char c) { return c == ' ' or c == '\t'; } -static bool is_word(char c) +template +bool is_word(char c); + +template<> +bool is_word(char c) { if (c >= '0' and c <= '9') return true; @@ -29,6 +36,12 @@ static bool is_word(char c) return false; } +template<> +bool is_word(char c) +{ + return !is_blank(c) and !is_eol(c); +} + static bool is_punctuation(char c) { return not (is_word(c) or is_blank(c) or is_eol(c)); @@ -42,8 +55,8 @@ enum class CharCategories Punctuation, }; -template -static CharCategories categorize(char c) +template +CharCategories categorize(char c) { if (is_word(c)) return CharCategories::Word; @@ -51,8 +64,8 @@ static CharCategories categorize(char c) return CharCategories::EndOfLine; if (is_blank(c)) return CharCategories::Blank; - return punctuation_is_not_word ? CharCategories::Punctuation - : CharCategories::Word; + return punctuation_is_word ? CharCategories::Word + : CharCategories::Punctuation; } template @@ -71,30 +84,37 @@ bool skip_while_reverse(BufferIterator& it, T condition) return not it.is_end() and condition(*it); } +} + +template SelectionAndCaptures select_to_next_word(const Selection& selection) { BufferIterator begin = selection.last(); - if (categorize(*begin) != categorize(*(begin+1))) + if (categorize(*begin) != + categorize(*(begin+1))) ++begin; skip_while(begin, is_eol); - BufferIterator end = begin+1; - if (is_punctuation(*begin)) + if (not punctuation_is_word and is_punctuation(*begin)) skip_while(end, is_punctuation); - else if (is_word(*begin)) - skip_while(end, is_word); + else if (is_word(*begin)) + skip_while(end, is_word); bool with_end = skip_while(end, is_blank); return Selection(begin, with_end ? end : end-1); } +template SelectionAndCaptures select_to_next_word(const Selection&); +template SelectionAndCaptures select_to_next_word(const Selection&); +template SelectionAndCaptures select_to_next_word_end(const Selection& selection) { BufferIterator begin = selection.last(); - if (categorize(*begin) != categorize(*(begin+1))) + if (categorize(*begin) != + categorize(*(begin+1))) ++begin; skip_while(begin, is_eol); @@ -102,19 +122,23 @@ SelectionAndCaptures select_to_next_word_end(const Selection& selection) skip_while(end, is_blank); bool with_end = false; - if (is_punctuation(*end)) + if (not punctuation_is_word and is_punctuation(*end)) with_end = skip_while(end, is_punctuation); - else if (is_word(*end)) - with_end = skip_while(end, is_word); + else if (is_word(*end)) + with_end = skip_while(end, is_word); return Selection(begin, with_end ? end : end-1); } +template SelectionAndCaptures select_to_next_word_end(const Selection&); +template SelectionAndCaptures select_to_next_word_end(const Selection&); +template SelectionAndCaptures select_to_previous_word(const Selection& selection) { BufferIterator begin = selection.last(); - if (categorize(*begin) != categorize(*(begin-1))) + if (categorize(*begin) != + categorize(*(begin-1))) --begin; skip_while_reverse(begin, is_eol); @@ -122,61 +146,15 @@ SelectionAndCaptures select_to_previous_word(const Selection& selection) skip_while_reverse(end, is_blank); bool with_end = false; - if (is_punctuation(*end)) + if (not punctuation_is_word and is_punctuation(*end)) with_end = skip_while_reverse(end, is_punctuation); - else if (is_word(*end)) - with_end = skip_while_reverse(end, is_word); - - return Selection(begin, with_end ? end : end+1); -} - -SelectionAndCaptures select_to_next_WORD(const Selection& selection) -{ - BufferIterator begin = selection.last(); - 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); }); - bool with_end = skip_while(end, is_blank); - - return Selection(begin, with_end ? end : end-1); -} - -SelectionAndCaptures select_to_next_WORD_end(const Selection& selection) -{ - BufferIterator begin = selection.last(); - if (categorize(*begin) != categorize(*(begin+1))) - ++begin; - - skip_while(begin, is_eol); - - BufferIterator end = begin+1; - - skip_while(end, is_blank); - bool with_end = skip_while(end, [] (char c) { return !is_blank(c) - and !is_eol(c); }); - - return Selection(begin, with_end ? end : end-1); -} - -SelectionAndCaptures select_to_previous_WORD(const Selection& selection) -{ - BufferIterator begin = selection.last(); - if (categorize(*begin) != categorize(*(begin-1))) - --begin; - - skip_while_reverse(begin, is_eol); - BufferIterator end = begin; - skip_while_reverse(end, is_blank); - bool with_end = skip_while_reverse(end, [] (char c) { return !is_blank(c) - and !is_eol(c); }); + else if (is_word(*end)) + with_end = skip_while_reverse(end, is_word); return Selection(begin, with_end ? end : end+1); } +template SelectionAndCaptures select_to_previous_word(const Selection&); +template SelectionAndCaptures select_to_previous_word(const Selection&); SelectionAndCaptures select_line(const Selection& selection) { diff --git a/src/selectors.hh b/src/selectors.hh index 116af686..18588454 100644 --- a/src/selectors.hh +++ b/src/selectors.hh @@ -6,12 +6,13 @@ namespace Kakoune { +template SelectionAndCaptures select_to_next_word(const Selection& selection); +template SelectionAndCaptures select_to_next_word_end(const Selection& selection); +template SelectionAndCaptures select_to_previous_word(const Selection& selection); -SelectionAndCaptures select_to_next_WORD(const Selection& selection); -SelectionAndCaptures select_to_next_WORD_end(const Selection& selection); -SelectionAndCaptures select_to_previous_WORD(const Selection& selection); + SelectionAndCaptures select_line(const Selection& selection); SelectionAndCaptures select_matching(const Selection& selection); SelectionAndCaptures select_surrounding(const Selection& selection,