diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2014-08-28 13:50:15 +0200 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2014-08-28 13:50:15 +0200 |
| commit | 8a33f6ab4edaf9e43388f99b75229aab1ee7ba23 (patch) | |
| tree | ebf94e4cd47f30624bb477bc7ee6083b89235f15 /text-motions.c | |
| parent | b5d121dc1ca4edc0cfff888ba411f0837e6e0ebc (diff) | |
| download | vis-8a33f6ab4edaf9e43388f99b75229aab1ee7ba23.tar.gz vis-8a33f6ab4edaf9e43388f99b75229aab1ee7ba23.tar.xz | |
Improve text motions
Diffstat (limited to 'text-motions.c')
| -rw-r--r-- | text-motions.c | 44 |
1 files changed, 37 insertions, 7 deletions
diff --git a/text-motions.c b/text-motions.c index 1313c94..8154e2b 100644 --- a/text-motions.c +++ b/text-motions.c @@ -1,8 +1,41 @@ #include <ctype.h> #include "text-motions.h" +#include "util.h" // TODO: consistent usage of iterators either char or byte based where appropriate. +size_t text_find_char_next(Text *txt, size_t pos, const char *s, size_t len) { + char c; + size_t matched = 0; + Iterator it = text_iterator_get(txt, pos); + while (matched < len && text_iterator_byte_get(&it, &c)) { + if (c == s[matched]) + matched++; + else + matched = 0; + text_iterator_byte_next(&it, NULL); + } + return it.pos - (matched == len ? len : 0); +} + +size_t text_find_char_prev(Text *txt, size_t pos, const char *s, size_t len) { + char c; + size_t matched = len - 1; + Iterator it = text_iterator_get(txt, pos); + if (len == 0) + return pos; + while (text_iterator_byte_get(&it, &c)) { + if (c == s[matched]) { + if (matched-- == 0) + break; + } else { + matched = len - 1; + } + text_iterator_byte_next(&it, NULL); + } + return it.pos; +} + size_t text_line_begin(Text *txt, size_t pos) { char c; Iterator it = text_iterator_get(txt, pos); @@ -19,7 +52,7 @@ size_t text_line_begin(Text *txt, size_t pos) { } text_iterator_byte_prev(&it, NULL); } - return pos; + return it.pos; } size_t text_line_start(Text *txt, size_t pos) { @@ -35,18 +68,15 @@ size_t text_line_finish(Text *txt, size_t pos) { Iterator it = text_iterator_get(txt, text_line_end(txt, pos)); do text_iterator_byte_prev(&it, NULL); while (text_iterator_byte_get(&it, &c) && c != '\n' && c != '\r' && isspace(c)); + if (!isutf8(c)) + text_iterator_char_prev(&it, &c); return it.pos; } size_t text_line_end(Text *txt, size_t pos) { - char c; - Iterator it = text_iterator_get(txt, pos); - while (text_iterator_byte_get(&it, &c) && c != '\n') - text_iterator_byte_next(&it, NULL); - return it.pos; + return text_find_char_next(txt, pos, "\n", 1); } - size_t text_word_boundry_start_next(Text *txt, size_t pos, int (*isboundry)(int)) { char c; Iterator it = text_iterator_get(txt, pos); |
