Selectors: add a basic select_matching selector for <([{]])> pairs

This commit is contained in:
Maxime Coste 2011-09-21 19:09:49 +00:00
parent 3af66276f0
commit cff69b2556
3 changed files with 59 additions and 0 deletions

View File

@ -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(false, select_to_previous_word); } while(--count > 0); } },
{ 'B', [](Window& window, int count) { do { window.select(true, 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); } }, { '.', [](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); } }, { '/', [](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.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); } }, { 'U', [](Window& window, int count) { do { if (not window.redo()) { print_status("nothing left to redo"); break; } } while(--count > 0); } },

View File

@ -1,8 +1,15 @@
#include "selectors.hh" #include "selectors.hh"
#include <algorithm>
namespace Kakoune namespace Kakoune
{ {
static bool is_eol(char c)
{
return c == '\n';
}
static bool is_blank(char c) static bool is_blank(char c)
{ {
return c == ' ' or c == '\t' or c == '\n'; 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)); 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);
}
} }

View File

@ -11,6 +11,7 @@ Selection select_to_next_word_end(const BufferIterator& cursor);
Selection select_to_previous_word(const BufferIterator& cursor); Selection select_to_previous_word(const BufferIterator& cursor);
Selection select_line(const BufferIterator& cursor); Selection select_line(const BufferIterator& cursor);
Selection move_select(Window& window, const BufferIterator& cursor, const WindowCoord& offset); Selection move_select(Window& window, const BufferIterator& cursor, const WindowCoord& offset);
Selection select_matching(const BufferIterator& cursor);
} }