vis
a vi-like editor based on Plan 9's structural regular expressions
git clone https://9o.is/git/vis.git
commit 24df8036ddeec91c438fd3852f6684963b0c59b0
parent c58613d7b3a9bd1b426c1bff92aada988ab3c7cf
Author: Marc André Tanner <mat@brain-dump.org>
Date: Sun, 6 Nov 2016 10:22:07 +0100
vis: improve handling of \r\n line endings
Change the text_iterator_char_{prev,next} functions to treat
them as a single character, meaning cursor motions will skip
both bytes at the same time.
Diffstat:
| M | text.c | | | 27 | +++++++++++++++++++++------ |
1 file changed, 21 insertions(+), 6 deletions(-)
diff --git a/text.c b/text.c @@ -1464,9 +1464,15 @@ bool text_iterator_codepoint_prev(Iterator *it, char *c) { return false; } -bool text_iterator_char_next(Iterator *it, char *c) { - if (!text_iterator_codepoint_next(it, c)) +bool text_iterator_char_next(Iterator *it, char *ret) { + char c; + if (!ret) + ret = &c; + bool cr = text_iterator_byte_get(it, &c) && c == '\r'; + if (!text_iterator_codepoint_next(it, ret)) return false; + if (cr && *ret == '\n') + return text_iterator_byte_next(it, ret); mbstate_t ps = { 0 }; for (;;) { char buf[MB_CUR_MAX]; @@ -1483,16 +1489,25 @@ bool text_iterator_char_next(Iterator *it, char *c) { int width = wcwidth(wc); if (width != 0) return true; - if (!text_iterator_codepoint_next(it, c)) + if (!text_iterator_codepoint_next(it, ret)) return false; } } return true; } -bool text_iterator_char_prev(Iterator *it, char *c) { - if (!text_iterator_codepoint_prev(it, c)) +bool text_iterator_char_prev(Iterator *it, char *ret) { + char c; + if (!ret) + ret = &c; + if (!text_iterator_codepoint_prev(it, ret)) return false; + if (*ret == '\n') { + if (text_iterator_byte_prev(it, &c) && c != '\r') + text_iterator_byte_next(it, NULL); + return true; + } + for (;;) { char buf[MB_CUR_MAX]; size_t len = text_bytes_get(it->piece->text, it->pos, sizeof buf, buf); @@ -1509,7 +1524,7 @@ bool text_iterator_char_prev(Iterator *it, char *c) { int width = wcwidth(wc); if (width != 0) return true; - if (!text_iterator_codepoint_prev(it, c)) + if (!text_iterator_codepoint_prev(it, ret)) return false; } }