diff options
| author | Maxime Coste <frrrwww@gmail.com> | 2011-09-21 19:09:49 +0000 |
|---|---|---|
| committer | Maxime Coste <frrrwww@gmail.com> | 2011-09-21 19:09:49 +0000 |
| commit | cff69b2556792a1f1f5eb27f7612f0d4668cea08 (patch) | |
| tree | e45d9375499f7f29e13b3859cc580894d5271394 /src | |
| parent | 3af66276f0e60f57b773243188c5a6cf5f69808a (diff) | |
Selectors: add a basic select_matching selector for <([{]])> pairs
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.cc | 2 | ||||
| -rw-r--r-- | src/selectors.cc | 56 | ||||
| -rw-r--r-- | src/selectors.hh | 1 |
3 files changed, 59 insertions, 0 deletions
diff --git a/src/main.cc b/src/main.cc index 26694a43..20c64ad4 100644 --- a/src/main.cc +++ b/src/main.cc @@ -354,6 +354,8 @@ std::unordered_map<char, std::function<void (Window& window, int count)>> keymap { 'b', [](Window& window, int count) { do { window.select(false, select_to_previous_word); } while(--count > 0); } }, { 'B', [](Window& window, int count) { do { window.select(true, select_to_previous_word); } while(--count > 0); } }, { '.', [](Window& window, int count) { do { window.select(false, select_line); } while(--count > 0); } }, + { 'm', [](Window& window, int count) { window.select(false, select_matching); } }, + { 'M', [](Window& window, int count) { window.select(true, select_matching); } }, { '/', [](Window& window, int count) { do_search(window); } }, { 'u', [](Window& window, int count) { do { if (not window.undo()) { print_status("nothing left to undo"); break; } } while(--count > 0); } }, { 'U', [](Window& window, int count) { do { if (not window.redo()) { print_status("nothing left to redo"); break; } } while(--count > 0); } }, diff --git a/src/selectors.cc b/src/selectors.cc index ad65ea2a..8c04d545 100644 --- a/src/selectors.cc +++ b/src/selectors.cc @@ -1,8 +1,15 @@ #include "selectors.hh" +#include <algorithm> + namespace Kakoune { +static bool is_eol(char c) +{ + return c == '\n'; +} + static bool is_blank(char c) { return c == ' ' or c == '\t' or c == '\n'; @@ -75,4 +82,53 @@ Selection move_select(Window& window, const BufferIterator& cursor, const Window return Selection(cursor, window.iterator_at(new_pos)); } +Selection select_matching(const BufferIterator& cursor) +{ + std::vector<char> matching_pairs = { '(', ')', '{', '}', '[', ']', '<', '>' }; + BufferIterator it = cursor; + std::vector<char>::iterator match = matching_pairs.end(); + while (not is_eol(*it)) + { + match = std::find(matching_pairs.begin(), matching_pairs.end(), *it); + if (match != matching_pairs.end()) + break; + ++it; + } + if (match == matching_pairs.end()) + return Selection(cursor, cursor); + + BufferIterator begin = it; + + if (((match - matching_pairs.begin()) % 2) == 0) + { + int level = 0; + const char opening = *match; + const char closing = *(match+1); + while (not it.is_end()) + { + if (*it == opening) + ++level; + else if (*it == closing and --level == 0) + return Selection(begin, it+1); + + ++it; + } + } + else + { + int level = 0; + const char opening = *(match-1); + const char closing = *match; + while (not it.is_begin()) + { + if (*it == closing) + ++level; + else if (*it == opening and --level == 0) + return Selection(begin, it); + --it; + } + } + return Selection(cursor, cursor); +} + } diff --git a/src/selectors.hh b/src/selectors.hh index 0fe7fa17..d304227a 100644 --- a/src/selectors.hh +++ b/src/selectors.hh @@ -11,6 +11,7 @@ Selection select_to_next_word_end(const BufferIterator& cursor); Selection select_to_previous_word(const BufferIterator& cursor); Selection select_line(const BufferIterator& cursor); Selection move_select(Window& window, const BufferIterator& cursor, const WindowCoord& offset); +Selection select_matching(const BufferIterator& cursor); } |
