summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2011-09-21 19:09:49 +0000
committerMaxime Coste <frrrwww@gmail.com>2011-09-21 19:09:49 +0000
commitcff69b2556792a1f1f5eb27f7612f0d4668cea08 (patch)
treee45d9375499f7f29e13b3859cc580894d5271394 /src
parent3af66276f0e60f57b773243188c5a6cf5f69808a (diff)
Selectors: add a basic select_matching selector for <([{]])> pairs
Diffstat (limited to 'src')
-rw-r--r--src/main.cc2
-rw-r--r--src/selectors.cc56
-rw-r--r--src/selectors.hh1
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);
}