diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2020-01-23 14:01:41 +0100 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2020-01-23 14:36:12 +0100 |
| commit | 886a5ed603df862a26f0d6d78d6c8dd161623738 (patch) | |
| tree | 07dc9a5183eea871f23b3c26cf86b2e46f37bc4a /text-motions.c | |
| parent | 79a3eb968a09bf1db54e0a024404d0436b7db689 (diff) | |
| download | vis-886a5ed603df862a26f0d6d78d6c8dd161623738.tar.gz vis-886a5ed603df862a26f0d6d78d6c8dd161623738.tar.xz | |
text: fix spurious regex anchor matches
The regex anchors ^ and $ must not match at the start/end of the search
range unless it is preceded/succeeded by a new line.
This is implemented at the text-motion layer by passing the appropriate
REG_NOT{B,E}OL flags to the search backend, meaning the caller can
influence the anchor behavior depending on the context. This is important
as for example in the command language the anchors apply to existing
selections, not line boundaries.
Diffstat (limited to 'text-motions.c')
| -rw-r--r-- | text-motions.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/text-motions.c b/text-motions.c index 533d896..97a7e1e 100644 --- a/text-motions.c +++ b/text-motions.c @@ -618,11 +618,15 @@ size_t text_search_forward(Text *txt, size_t pos, Regex *regex) { size_t start = pos + 1; size_t end = text_size(txt); RegexMatch match[1]; - bool found = start < end && !text_search_range_forward(txt, start, end - start, regex, 1, match, 0); + char c; + int flags = text_byte_get(txt, pos, &c) && c == '\n' ? 0 : REG_NOTBOL; + bool found = start < end && !text_search_range_forward(txt, start, end - start, regex, 1, match, flags); if (!found) { start = 0; - found = !text_search_range_forward(txt, start, end - start, regex, 1, match, 0); + end = pos; + flags = text_byte_get(txt, end, &c) && c == '\n' ? 0 : REG_NOTEOL; + found = !text_search_range_forward(txt, start, end - start, regex, 1, match, flags); } return found ? match[0].start : pos; @@ -632,12 +636,15 @@ size_t text_search_backward(Text *txt, size_t pos, Regex *regex) { size_t start = 0; size_t end = pos; RegexMatch match[1]; - bool found = !text_search_range_backward(txt, start, end, regex, 1, match, 0); + char c; + int flags = text_byte_get(txt, end, &c) && c == '\n' ? 0 : REG_NOTEOL; + bool found = !text_search_range_backward(txt, start, end, regex, 1, match, flags); if (!found) { start = pos + 1; end = text_size(txt); - found = start < end && !text_search_range_backward(txt, start, end - start, regex, 1, match, 0); + flags = text_byte_get(txt, pos, &c) && c == '\n' ? 0 : REG_NOTBOL; + found = start < end && !text_search_range_backward(txt, start, end - start, regex, 1, match, flags); } return found ? match[0].start : pos; |
