summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2012-03-07 19:20:32 +0000
committerMaxime Coste <frrrwww@gmail.com>2012-03-07 19:20:32 +0000
commit782b5576607fc1ca7efc8ee40a2fc8d2f3c9cfff (patch)
treec446e33d0dba80b53a081769f46e7ba16a9c4fa1 /src
parent7e01867d55f649ead77acb225dbb4752a40493d4 (diff)
factor word and WORD selectors
Diffstat (limited to 'src')
-rw-r--r--src/main.cc24
-rw-r--r--src/selectors.cc114
-rw-r--r--src/selectors.hh7
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,