vis

a vi-like editor based on Plan 9's structural regular expressions

git clone https://9o.is/git/vis.git

commit cf70be4279f9b4d36a0ba4d6793c108540780c41
parent e24e46370917f07e0d483c2d1f8ac54f37e0537a
Author: Marc André Tanner <mat@brain-dump.org>
Date:   Sat,  1 Aug 2015 19:42:15 +0200

text-motion: fix text_find_{next,prev}

It is after all a stupid O(n*m) algorithm, hence restart after
a failed partial match.

Code like this would benefit from a proper test suite ...

Diffstat:
Mtext-motions.c | 17++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/text-motions.c b/text-motions.c @@ -50,12 +50,16 @@ size_t text_find_next(Text *txt, size_t pos, const char *s) { if (!s) return pos; size_t len = strlen(s), matched = 0; - Iterator it = text_iterator_get(txt, pos); + Iterator it = text_iterator_get(txt, pos), sit; for (char c; matched < len && text_iterator_byte_get(&it, &c); ) { - if (c == s[matched]) + if (c == s[matched]) { + if (matched == 0) + sit = it; matched++; - else + } else if (matched > 0) { + it = sit; matched = 0; + } text_iterator_byte_next(&it, NULL); } return matched == len ? it.pos - len : pos; @@ -65,15 +69,18 @@ size_t text_find_prev(Text *txt, size_t pos, const char *s) { if (!s) return pos; size_t len = strlen(s), matched = len - 1; - Iterator it = text_iterator_get(txt, pos); + Iterator it = text_iterator_get(txt, pos), sit; if (len == 0) return pos; for (char c; text_iterator_byte_get(&it, &c); ) { if (c == s[matched]) { if (matched == 0) break; + if (matched == len - 1) + sit = it; matched--; - } else { + } else if (matched < len - 1) { + it = sit; matched = len - 1; } text_iterator_byte_prev(&it, NULL);