diff options
| -rw-r--r-- | text-objects.c | 53 | ||||
| -rw-r--r-- | text-objects.h | 3 |
2 files changed, 55 insertions, 1 deletions
diff --git a/text-objects.c b/text-objects.c index 121811d..7595ac7 100644 --- a/text-objects.c +++ b/text-objects.c @@ -1,6 +1,7 @@ #include <ctype.h> #include "text-motions.h" #include "text-objects.h" +#include "util.h" static Filerange empty = { .start = -1, @@ -8,8 +9,8 @@ static Filerange empty = { }; Filerange text_object_word(Text *txt, size_t pos) { - char c, prev = '0', next = '0'; Filerange r; + char c, prev = '0', next = '0'; Iterator it = text_iterator_get(txt, pos); if (!text_iterator_byte_get(&it, &c)) return empty; @@ -53,3 +54,53 @@ Filerange text_object_paragraph(Text *txt, size_t pos) { r.end = text_paragraph_next(txt, pos); return r; } + +Filerange text_object_bracket(Text *txt, size_t pos, char type) { + char c, open, close; + int opened = 1, closed = 1; + + switch (type) { + case '(': case ')': open = '('; close = ')'; break; + case '{': case '}': open = '{'; close = '}'; break; + case '[': case ']': open = '['; close = ']'; break; + case '<': case '>': open = '<'; close = '>'; break; + case '"': open = '"'; close = '"'; break; + case '\'': open = '\''; close = '\''; break; + default: return empty; + } + + Filerange r = empty; + Iterator it = text_iterator_get(txt, pos); + + if (open == close && text_iterator_byte_get(&it, &c) && (c == '"' || c == '\'')) { + size_t match = text_bracket_match(txt, pos); + r.start = MIN(pos, match) + 1; + r.end = MAX(pos, match); + return r; + } + + while (text_iterator_byte_get(&it, &c)) { + if (c == open && --opened == 0) { + r.start = it.pos + 1; + break; + } else if (c == close && it.pos != pos) { + opened++; + } + text_iterator_byte_prev(&it, NULL); + } + + it = text_iterator_get(txt, pos); + while (text_iterator_byte_get(&it, &c)) { + if (c == close && --closed == 0) { + r.end = it.pos; + break; + } else if (c == open && it.pos != pos) { + closed++; + } + text_iterator_byte_next(&it, NULL); + } + + if (r.start == (size_t)-1 || r.end == (size_t)-1 || r.start > r.end) + return empty; + return r; +} diff --git a/text-objects.h b/text-objects.h index de8dcfb..de3fdc3 100644 --- a/text-objects.h +++ b/text-objects.h @@ -11,5 +11,8 @@ Filerange text_object_word_boundry(Text*, size_t pos, int (*isboundry)(int)); Filerange text_object_char(Text*, size_t pos, char c); Filerange text_object_sentence(Text*, size_t pos); Filerange text_object_paragraph(Text*, size_t pos); +/* range delimited by either (), {}, [], <>, ", '. the delimiters themself are not + * included in the range */ +Filerange text_object_bracket(Text*, size_t pos, char type); #endif |
