aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2016-11-06 10:22:07 +0100
committerMarc André Tanner <mat@brain-dump.org>2017-02-23 22:07:31 +0100
commit0fc532329cbd9b287e2e7bdc0d837348d0a2a703 (patch)
tree5456b60af91f19f6d8a39720bc012cf430ef010b
parent138bc80f5bec0f192cdba189b6ad8920050eb5cf (diff)
downloadvis-0fc532329cbd9b287e2e7bdc0d837348d0a2a703.tar.gz
vis-0fc532329cbd9b287e2e7bdc0d837348d0a2a703.tar.xz
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.
-rw-r--r--text.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/text.c b/text.c
index f82223d..f75a5e7 100644
--- 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;
}
}