factor word and WORD selectors
This commit is contained in:
parent
7e01867d55
commit
782b557660
24
src/main.cc
24
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); } },
|
||||
|
|
114
src/selectors.cc
114
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)
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue
Block a user