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, '|' }, do_pipe },
|
||||||
{ { Key::Modifiers::None, ' ' }, [](Editor& editor, int count) { if (count == 0) editor.clear_selections();
|
{ { Key::Modifiers::None, ' ' }, [](Editor& editor, int count) { if (count == 0) editor.clear_selections();
|
||||||
else editor.keep_selection(count-1); } },
|
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, '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); } 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); } 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, true); } 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, 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, 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, false); } while(--count > 0); } },
|
||||||
{ { Key::Modifiers::None, 'X' }, [](Editor& editor, int count) { do { editor.select(select_line, true); } 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); } },
|
{ { 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, '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, '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, '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); } 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); } 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, '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); } 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); } 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, false); } while(--count > 0); } },
|
||||||
{ { Key::Modifiers::Alt, 'L' }, [](Editor& editor, int count) { do { editor.select(select_to_eol, true); } 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
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
|
||||||
static bool is_eol(char c)
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
bool is_eol(char c)
|
||||||
{
|
{
|
||||||
return c == '\n';
|
return c == '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_blank(char c)
|
bool is_blank(char c)
|
||||||
{
|
{
|
||||||
return c == ' ' or c == '\t';
|
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')
|
if (c >= '0' and c <= '9')
|
||||||
return true;
|
return true;
|
||||||
|
@ -29,6 +36,12 @@ static bool is_word(char c)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
bool is_word<true>(char c)
|
||||||
|
{
|
||||||
|
return !is_blank(c) and !is_eol(c);
|
||||||
|
}
|
||||||
|
|
||||||
static bool is_punctuation(char c)
|
static bool is_punctuation(char c)
|
||||||
{
|
{
|
||||||
return not (is_word(c) or is_blank(c) or is_eol(c));
|
return not (is_word(c) or is_blank(c) or is_eol(c));
|
||||||
|
@ -42,8 +55,8 @@ enum class CharCategories
|
||||||
Punctuation,
|
Punctuation,
|
||||||
};
|
};
|
||||||
|
|
||||||
template<bool punctuation_is_not_word = true>
|
template<bool punctuation_is_word = false>
|
||||||
static CharCategories categorize(char c)
|
CharCategories categorize(char c)
|
||||||
{
|
{
|
||||||
if (is_word(c))
|
if (is_word(c))
|
||||||
return CharCategories::Word;
|
return CharCategories::Word;
|
||||||
|
@ -51,8 +64,8 @@ static CharCategories categorize(char c)
|
||||||
return CharCategories::EndOfLine;
|
return CharCategories::EndOfLine;
|
||||||
if (is_blank(c))
|
if (is_blank(c))
|
||||||
return CharCategories::Blank;
|
return CharCategories::Blank;
|
||||||
return punctuation_is_not_word ? CharCategories::Punctuation
|
return punctuation_is_word ? CharCategories::Word
|
||||||
: CharCategories::Word;
|
: CharCategories::Punctuation;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -71,30 +84,37 @@ bool skip_while_reverse(BufferIterator& it, T condition)
|
||||||
return not it.is_end() and condition(*it);
|
return not it.is_end() and condition(*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<bool punctuation_is_word>
|
||||||
SelectionAndCaptures select_to_next_word(const Selection& selection)
|
SelectionAndCaptures select_to_next_word(const Selection& selection)
|
||||||
{
|
{
|
||||||
BufferIterator begin = selection.last();
|
BufferIterator begin = selection.last();
|
||||||
if (categorize(*begin) != categorize(*(begin+1)))
|
if (categorize<punctuation_is_word>(*begin) !=
|
||||||
|
categorize<punctuation_is_word>(*(begin+1)))
|
||||||
++begin;
|
++begin;
|
||||||
|
|
||||||
skip_while(begin, is_eol);
|
skip_while(begin, is_eol);
|
||||||
|
|
||||||
BufferIterator end = begin+1;
|
BufferIterator end = begin+1;
|
||||||
|
|
||||||
if (is_punctuation(*begin))
|
if (not punctuation_is_word and is_punctuation(*begin))
|
||||||
skip_while(end, is_punctuation);
|
skip_while(end, is_punctuation);
|
||||||
else if (is_word(*begin))
|
else if (is_word<punctuation_is_word>(*begin))
|
||||||
skip_while(end, is_word);
|
skip_while(end, is_word<punctuation_is_word>);
|
||||||
|
|
||||||
bool with_end = skip_while(end, is_blank);
|
bool with_end = skip_while(end, is_blank);
|
||||||
|
|
||||||
return Selection(begin, with_end ? end : end-1);
|
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)
|
SelectionAndCaptures select_to_next_word_end(const Selection& selection)
|
||||||
{
|
{
|
||||||
BufferIterator begin = selection.last();
|
BufferIterator begin = selection.last();
|
||||||
if (categorize(*begin) != categorize(*(begin+1)))
|
if (categorize<punctuation_is_word>(*begin) !=
|
||||||
|
categorize<punctuation_is_word>(*(begin+1)))
|
||||||
++begin;
|
++begin;
|
||||||
|
|
||||||
skip_while(begin, is_eol);
|
skip_while(begin, is_eol);
|
||||||
|
@ -102,19 +122,23 @@ SelectionAndCaptures select_to_next_word_end(const Selection& selection)
|
||||||
skip_while(end, is_blank);
|
skip_while(end, is_blank);
|
||||||
|
|
||||||
bool with_end = false;
|
bool with_end = false;
|
||||||
if (is_punctuation(*end))
|
if (not punctuation_is_word and is_punctuation(*end))
|
||||||
with_end = skip_while(end, is_punctuation);
|
with_end = skip_while(end, is_punctuation);
|
||||||
else if (is_word(*end))
|
else if (is_word<punctuation_is_word>(*end))
|
||||||
with_end = skip_while(end, is_word);
|
with_end = skip_while(end, is_word<punctuation_is_word>);
|
||||||
|
|
||||||
return Selection(begin, with_end ? end : end-1);
|
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)
|
SelectionAndCaptures select_to_previous_word(const Selection& selection)
|
||||||
{
|
{
|
||||||
BufferIterator begin = selection.last();
|
BufferIterator begin = selection.last();
|
||||||
|
|
||||||
if (categorize(*begin) != categorize(*(begin-1)))
|
if (categorize<punctuation_is_word>(*begin) !=
|
||||||
|
categorize<punctuation_is_word>(*(begin-1)))
|
||||||
--begin;
|
--begin;
|
||||||
|
|
||||||
skip_while_reverse(begin, is_eol);
|
skip_while_reverse(begin, is_eol);
|
||||||
|
@ -122,61 +146,15 @@ SelectionAndCaptures select_to_previous_word(const Selection& selection)
|
||||||
skip_while_reverse(end, is_blank);
|
skip_while_reverse(end, is_blank);
|
||||||
|
|
||||||
bool with_end = false;
|
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);
|
with_end = skip_while_reverse(end, is_punctuation);
|
||||||
else if (is_word(*end))
|
else if (is_word<punctuation_is_word>(*end))
|
||||||
with_end = skip_while_reverse(end, is_word);
|
with_end = skip_while_reverse(end, is_word<punctuation_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); });
|
|
||||||
|
|
||||||
return Selection(begin, with_end ? end : end+1);
|
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)
|
SelectionAndCaptures select_line(const Selection& selection)
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,12 +6,13 @@
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
|
||||||
|
template<bool punctuation_is_word>
|
||||||
SelectionAndCaptures select_to_next_word(const Selection& selection);
|
SelectionAndCaptures select_to_next_word(const Selection& selection);
|
||||||
|
template<bool punctuation_is_word>
|
||||||
SelectionAndCaptures select_to_next_word_end(const Selection& selection);
|
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_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_line(const Selection& selection);
|
||||||
SelectionAndCaptures select_matching(const Selection& selection);
|
SelectionAndCaptures select_matching(const Selection& selection);
|
||||||
SelectionAndCaptures select_surrounding(const Selection& selection,
|
SelectionAndCaptures select_surrounding(const Selection& selection,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user