diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2018-02-27 15:56:26 +0100 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2018-02-27 18:56:49 +0100 |
| commit | c0832d6fc7eace1c6da9867d8b327bf62c968098 (patch) | |
| tree | d2f1c2175f9eb1a8132d736c4d781eb763c63c21 | |
| parent | f55312ba450c845e65f62b5592696d5f6ae98cda (diff) | |
| download | vis-c0832d6fc7eace1c6da9867d8b327bf62c968098.tar.gz vis-c0832d6fc7eace1c6da9867d8b327bf62c968098.tar.xz | |
text-object: implement more precise paragraph text object
Fix #543
Close #588
| -rw-r--r-- | text-objects.c | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/text-objects.c b/text-objects.c index 6c209f9..27553b8 100644 --- a/text-objects.c +++ b/text-objects.c @@ -7,6 +7,7 @@ #include "text-util.h" #include "util.h" +#define blank(c) ((c) == ' ' || (c) == '\t') #define space(c) (isspace((unsigned char)c)) #define boundary(c) (isboundary((unsigned char)c)) @@ -169,10 +170,38 @@ Filerange text_object_sentence(Text *txt, size_t pos) { return r; } +static bool text_line_blank(Text *txt, size_t pos) { + char c; + bool b = true; + Iterator it = text_iterator_get(txt, text_line_begin(txt, pos)); + while (text_iterator_byte_get(&it, &c) && c != '\n' && (b = blank(c))) + text_iterator_char_next(&it, NULL); + return b; +} + Filerange text_object_paragraph(Text *txt, size_t pos) { + char c; Filerange r; - r.start = text_paragraph_prev(txt, pos); - r.end = text_paragraph_next(txt, pos); + if (text_line_blank(txt, pos)) { + Iterator it = text_iterator_get(txt, pos), rit = it; + while (text_iterator_byte_get(&rit, &c) && (c == '\n' || blank(c))) + text_iterator_byte_prev(&rit, NULL); + if (c == '\n' || blank(c)) + r.start = rit.pos; + else + r.start = text_line_next(txt, rit.pos); + while (text_iterator_byte_get(&it, &c) && (c == '\n' || blank(c))) + text_iterator_byte_next(&it, NULL); + if (it.pos == text_size(txt)) + r.end = rit.pos; + else + r.end = text_line_begin(txt, it.pos); + } else { + r.start = text_line_blank_prev(txt, pos); + if (r.start > 0 || (text_byte_get(txt, r.start, &c) && c == '\n')) + r.start = text_line_next(txt, r.start); + r.end = text_line_blank_next(txt, pos); + } return r; } |
