summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2012-03-12 14:23:30 +0000
committerMaxime Coste <frrrwww@gmail.com>2012-03-12 14:23:30 +0000
commitcd615b35a2a3b4e71d5f6232e307a8c4c07f834a (patch)
tree896910716a19cca0adce65f1126135a9b4e11bce /src
parentdf0f7b46893b9c87d33df246b7012d4058a79eab (diff)
generalize do_select_surrounding in do_select_object and add a whole word selector
Diffstat (limited to 'src')
-rw-r--r--src/main.cc43
-rw-r--r--src/selectors.cc28
-rw-r--r--src/selectors.hh2
3 files changed, 52 insertions, 21 deletions
diff --git a/src/main.cc b/src/main.cc
index 0be62ce3..7faf8712 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -691,29 +691,30 @@ void do_join(Editor& editor, int count)
editor.move_selections({0, -1});
}
-template<bool inside>
-void do_select_surrounding(Editor& editor, int count)
+template<bool inner>
+void do_select_object(Editor& editor, int count)
{
- Key key = get_key();
- const char id = key.key;
-
- static const std::unordered_map<char, std::pair<char, char>> id_to_matching =
+ typedef std::function<SelectionAndCaptures (const Selection&)> Selector;
+ static const std::unordered_map<Key, Selector> key_to_selector =
{
- { '(', { '(', ')' } },
- { ')', { '(', ')' } },
- { 'b', { '(', ')' } },
- { '{', { '{', '}' } },
- { '}', { '{', '}' } },
- { 'B', { '{', '}' } },
- { '[', { '[', ']' } },
- { ']', { '[', ']' } },
- { '<', { '<', '>' } },
- { '>', { '<', '>' } }
+ { { Key::Modifiers::None, '(' }, std::bind(select_surrounding, _1, std::pair<char, char>{ '(', ')' }, inner) },
+ { { Key::Modifiers::None, ')' }, std::bind(select_surrounding, _1, std::pair<char, char>{ '(', ')' }, inner) },
+ { { Key::Modifiers::None, 'b' }, std::bind(select_surrounding, _1, std::pair<char, char>{ '(', ')' }, inner) },
+ { { Key::Modifiers::None, '{' }, std::bind(select_surrounding, _1, std::pair<char, char>{ '{', '}' }, inner) },
+ { { Key::Modifiers::None, '}' }, std::bind(select_surrounding, _1, std::pair<char, char>{ '{', '}' }, inner) },
+ { { Key::Modifiers::None, 'B' }, std::bind(select_surrounding, _1, std::pair<char, char>{ '{', '}' }, inner) },
+ { { Key::Modifiers::None, '[' }, std::bind(select_surrounding, _1, std::pair<char, char>{ '[', ']' }, inner) },
+ { { Key::Modifiers::None, ']' }, std::bind(select_surrounding, _1, std::pair<char, char>{ '[', ']' }, inner) },
+ { { Key::Modifiers::None, '<' }, std::bind(select_surrounding, _1, std::pair<char, char>{ '<', '>' }, inner) },
+ { { Key::Modifiers::None, '>' }, std::bind(select_surrounding, _1, std::pair<char, char>{ '<', '>' }, inner) },
+ { { Key::Modifiers::None, 'w' }, std::bind(select_whole_word<false>, _1, inner) },
+ { { Key::Modifiers::None, 'W' }, std::bind(select_whole_word<true>, _1, inner) },
};
- auto matching = id_to_matching.find(id);
- if (matching != id_to_matching.end())
- editor.select(std::bind(select_surrounding, _1, matching->second, inside));
+ Key key = get_key();
+ auto it = key_to_selector.find(key);
+ if (it != key_to_selector.end())
+ editor.select(it->second);
}
std::unordered_map<Key, std::function<void (Editor& editor, int count)>> keymap =
@@ -779,8 +780,8 @@ std::unordered_map<Key, std::function<void (Editor& editor, int count)>> keymap
{ { Key::Modifiers::None, 'u' }, [](Editor& editor, int count) { do { if (not editor.undo()) { NCurses::print_status("nothing left to undo"); break; } } while(--count > 0); } },
{ { Key::Modifiers::None, 'U' }, [](Editor& editor, int count) { do { if (not editor.redo()) { NCurses::print_status("nothing left to redo"); break; } } while(--count > 0); } },
- { { Key::Modifiers::Alt, 'i' }, do_select_surrounding<true> },
- { { Key::Modifiers::Alt, 'a' }, do_select_surrounding<false> },
+ { { Key::Modifiers::Alt, 'i' }, do_select_object<true> },
+ { { Key::Modifiers::Alt, 'a' }, do_select_object<false> },
{ { Key::Modifiers::Alt, 't' }, [](Editor& editor, int count) { editor.select(std::bind(select_to_reverse, _1, get_key().key, count, false)); } },
{ { Key::Modifiers::Alt, 'f' }, [](Editor& editor, int count) { editor.select(std::bind(select_to_reverse, _1, get_key().key, count, true)); } },
diff --git a/src/selectors.cc b/src/selectors.cc
index bb88697f..bcad49a4 100644
--- a/src/selectors.cc
+++ b/src/selectors.cc
@@ -319,6 +319,34 @@ SelectionAndCaptures select_to_eol_reverse(const Selection& selection)
return Selection(begin, end.is_begin() ? end : end+1);
}
+template<bool punctuation_is_word>
+SelectionAndCaptures select_whole_word(const Selection& selection, bool inner)
+{
+ BufferIterator first = selection.last();
+ BufferIterator last = first;
+ if (is_word(*first))
+ {
+ if (not skip_while_reverse(first, is_word<punctuation_is_word>))
+ ++first;
+ skip_while(last, is_word<punctuation_is_word>);
+ if (not inner)
+ skip_while(last, is_blank);
+ }
+ else if (not inner)
+ {
+ if (not skip_while_reverse(first, is_blank))
+ ++first;
+ skip_while(last, is_blank);
+ if (not is_word<punctuation_is_word>(*last))
+ return selection;
+ skip_while(last, is_word<punctuation_is_word>);
+ }
+ --last;
+ return Selection(first, last);
+}
+template SelectionAndCaptures select_whole_word<false>(const Selection&, bool);
+template SelectionAndCaptures select_whole_word<true>(const Selection&, bool);
+
SelectionAndCaptures select_whole_lines(const Selection& selection)
{
BufferIterator first = selection.first();
diff --git a/src/selectors.hh b/src/selectors.hh
index 18588454..c1d24e88 100644
--- a/src/selectors.hh
+++ b/src/selectors.hh
@@ -27,6 +27,8 @@ SelectionAndCaptures select_to_reverse(const Selection& selection,
SelectionAndCaptures select_to_eol(const Selection& selection);
SelectionAndCaptures select_to_eol_reverse(const Selection& selection);
+template<bool punctuation_is_word>
+SelectionAndCaptures select_whole_word(const Selection& selection, bool inner);
SelectionAndCaptures select_whole_lines(const Selection& selection);
SelectionAndCaptures select_whole_buffer(const Selection& selection);