diff options
| author | Maxime Coste <frrrwww@gmail.com> | 2012-03-07 19:20:32 +0000 |
|---|---|---|
| committer | Maxime Coste <frrrwww@gmail.com> | 2012-03-07 19:20:32 +0000 |
| commit | 782b5576607fc1ca7efc8ee40a2fc8d2f3c9cfff (patch) | |
| tree | c446e33d0dba80b53a081769f46e7ba16a9c4fa1 /src | |
| parent | 7e01867d55f649ead77acb225dbb4752a40493d4 (diff) | |
factor word and WORD selectors
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.cc | 24 | ||||
| -rw-r--r-- | src/selectors.cc | 114 | ||||
| -rw-r--r-- | src/selectors.hh | 7 |
3 files changed, 62 insertions, 83 deletions
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<Key, std::function<void (Editor& editor, int count)>> 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<false>); } while(--count > 0); } }, + { { Key::Modifiers::None, 'e' }, [](Editor& editor, int count) { do { editor.select(select_to_next_word_end<false>); } while(--count > 0); } }, + { { Key::Modifiers::None, 'b' }, [](Editor& editor, int count) { do { editor.select(select_to_previous_word<false>); } while(--count > 0); } }, + { { Key::Modifiers::None, 'W' }, [](Editor& editor, int count) { do { editor.select(select_to_next_word<false>, true); } while(--count > 0); } }, + { { Key::Modifiers::None, 'E' }, [](Editor& editor, int count) { do { editor.select(select_to_next_word_end<false>, true); } while(--count > 0); } }, + { { Key::Modifiers::None, 'B' }, [](Editor& editor, int count) { do { editor.select(select_to_previous_word<false>, 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<Key, std::function<void (Editor& editor, int count)>> 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<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<true>, true); } while(--count > 0); } }, + { { Key::Modifiers::Alt, 'E' }, [](Editor& editor, int count) { do { editor.select(select_to_next_word_end<true>, true); } while(--count > 0); } }, + { { Key::Modifiers::Alt, 'B' }, [](Editor& editor, int count) { do { editor.select(select_to_previous_word<true>, 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 punctuation_is_word = false> +bool is_word(char c); + +template<> +bool is_word<false>(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<true>(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<bool punctuation_is_not_word = true> -static CharCategories categorize(char c) +template<bool punctuation_is_word = false> +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<typename T> @@ -71,30 +84,37 @@ bool skip_while_reverse(BufferIterator& it, T condition) return not it.is_end() and condition(*it); } +} + +template<bool punctuation_is_word> SelectionAndCaptures select_to_next_word(const Selection& selection) { BufferIterator begin = selection.last(); - if (categorize(*begin) != categorize(*(begin+1))) + if (categorize<punctuation_is_word>(*begin) != + categorize<punctuation_is_word>(*(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<punctuation_is_word>(*begin)) + skip_while(end, is_word<punctuation_is_word>); bool with_end = skip_while(end, is_blank); return Selection(begin, with_end ? end : end-1); } +template SelectionAndCaptures select_to_next_word<false>(const Selection&); +template SelectionAndCaptures select_to_next_word<true>(const Selection&); +template<bool punctuation_is_word> SelectionAndCaptures select_to_next_word_end(const Selection& selection) { BufferIterator begin = selection.last(); - if (categorize(*begin) != categorize(*(begin+1))) + if (categorize<punctuation_is_word>(*begin) != + categorize<punctuation_is_word>(*(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<punctuation_is_word>(*end)) + with_end = skip_while(end, is_word<punctuation_is_word>); return Selection(begin, with_end ? end : end-1); } +template SelectionAndCaptures select_to_next_word_end<false>(const Selection&); +template SelectionAndCaptures select_to_next_word_end<true>(const Selection&); +template<bool punctuation_is_word> SelectionAndCaptures select_to_previous_word(const Selection& selection) { BufferIterator begin = selection.last(); - if (categorize(*begin) != categorize(*(begin-1))) + if (categorize<punctuation_is_word>(*begin) != + categorize<punctuation_is_word>(*(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<false>(*begin) != categorize<false>(*(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<false>(*begin) != categorize<false>(*(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<false>(*begin) != categorize<false>(*(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<punctuation_is_word>(*end)) + with_end = skip_while_reverse(end, is_word<punctuation_is_word>); return Selection(begin, with_end ? end : end+1); } +template SelectionAndCaptures select_to_previous_word<false>(const Selection&); +template SelectionAndCaptures select_to_previous_word<true>(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<bool punctuation_is_word> SelectionAndCaptures select_to_next_word(const Selection& selection); +template<bool punctuation_is_word> SelectionAndCaptures select_to_next_word_end(const Selection& selection); +template<bool punctuation_is_word> 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, |
