diff options
| author | Maxime Coste <frrrwww@gmail.com> | 2012-01-04 14:18:08 +0000 |
|---|---|---|
| committer | Maxime Coste <frrrwww@gmail.com> | 2012-01-04 14:18:08 +0000 |
| commit | 8b1b1d9cd83d3c6b6fa1c0e4a2adb02ab585a985 (patch) | |
| tree | 14f5e45bb72db18d415aa169fd6d9630ce29abb3 /src | |
| parent | e59bdd931e6fa3d4e0c9b7a5d97ca559f894a391 (diff) | |
Selectors: add select_surrounding to select blocks
Alt-a followed by []()<>{}bB selects the block surrounding current
selection end.
Alt-i is similar but selects only the inside of the block.
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.cc | 27 | ||||
| -rw-r--r-- | src/selectors.cc | 49 | ||||
| -rw-r--r-- | src/selectors.hh | 3 |
3 files changed, 79 insertions, 0 deletions
diff --git a/src/main.cc b/src/main.cc index 1501b78c..ce89d0ee 100644 --- a/src/main.cc +++ b/src/main.cc @@ -708,6 +708,30 @@ void do_join(Window& window, int count) window.move_cursor({0, -1}); } +template<bool inside> +void do_select_surrounding(Window& window, int count) +{ + char id = getch(); + + static const std::unordered_map<char, std::pair<char, char>> id_to_matching = + { + { '(', { '(', ')' } }, + { ')', { '(', ')' } }, + { 'b', { '(', ')' } }, + { '{', { '{', '}' } }, + { '}', { '{', '}' } }, + { 'B', { '{', '}' } }, + { '[', { '[', ']' } }, + { ']', { '[', ']' } }, + { '<', { '<', '>' } }, + { '>', { '<', '>' } } + }; + + auto matching = id_to_matching.find(id); + if (matching != id_to_matching.end()) + window.select(std::bind(select_surrounding, _1, matching->second, inside)); +} + std::unordered_map<Key, std::function<void (Window& window, int count)>> keymap = { { { Key::Modifiers::None, 'h' }, [](Window& window, int count) { window.move_cursor(DisplayCoord(0, -std::max(count,1))); } }, @@ -767,6 +791,9 @@ std::unordered_map<Key, std::function<void (Window& window, int count)>> keymap { { Key::Modifiers::None, 'u' }, [](Window& window, int count) { do { if (not window.undo()) { print_status("nothing left to undo"); break; } } while(--count > 0); } }, { { Key::Modifiers::None, 'U' }, [](Window& window, int count) { do { if (not window.redo()) { 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, 't' }, [](Window& window, int count) { window.select(std::bind(select_to_reverse, _1, getch(), count, false)); } }, { { Key::Modifiers::Alt, 'f' }, [](Window& window, int count) { window.select(std::bind(select_to_reverse, _1, getch(), count, true)); } }, { { Key::Modifiers::Alt, 'T' }, [](Window& window, int count) { window.select(std::bind(select_to_reverse, _1, getch(), count, false), true); } }, diff --git a/src/selectors.cc b/src/selectors.cc index 9266514b..342b2170 100644 --- a/src/selectors.cc +++ b/src/selectors.cc @@ -242,6 +242,55 @@ Selection select_matching(const BufferIterator& cursor) return Selection(cursor, cursor); } +Selection select_surrounding(const BufferIterator& cursor, + const std::pair<char, char>& matching, + bool inside) +{ + int level = 0; + BufferIterator first = cursor; + while (not first.is_begin()) + { + if (*first == matching.second) + ++level; + else if (*first == matching.first) + { + if (level == 0) + break; + else + --level; + } + --first; + } + if (level != 0 or *first != matching.first) + return Selection(cursor, cursor); + + level = 0; + BufferIterator last = first + 1; + while (not last.is_end()) + { + if (*last == matching.first) + ++level; + else if (*last == matching.second) + { + if (level == 0) + break; + else + --level; + } + ++last; + } + if (level != 0 or *last != matching.second) + return Selection(cursor, cursor); + + if (inside) + { + ++first; + if (first != last) + --last; + } + return Selection(first, last); +} + Selection select_to(const BufferIterator& cursor, char c, int count, bool inclusive) { BufferIterator end = cursor; diff --git a/src/selectors.hh b/src/selectors.hh index a092e869..79fb53e9 100644 --- a/src/selectors.hh +++ b/src/selectors.hh @@ -14,6 +14,9 @@ Selection select_to_next_WORD_end(const BufferIterator& cursor); Selection select_to_previous_WORD(const BufferIterator& cursor); Selection select_line(const BufferIterator& cursor); Selection select_matching(const BufferIterator& cursor); +Selection select_surrounding(const BufferIterator& cursor, + const std::pair<char, char>& matching, + bool inside); Selection select_to(const BufferIterator& cursor, char c, int count, bool inclusive); Selection select_to_reverse(const BufferIterator& cursor, char c, int count, bool inclusive); |
