From 452a6b8f8d56988cb606ff933453163ac152c6f2 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Tue, 18 Sep 2018 12:28:10 -0400 Subject: [PATCH] tweaked cursor movement logic to handle CRLF and LF line endings. Also tweaked insert logic to ignore CR and convert LF into the correct the desired line endings. This ensures that copy+paste, filter commands, and user input all result in consistent line endings based on the file opened. --- TODO.md | 2 ++ lib/buf.c | 34 ++++++++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/TODO.md b/TODO.md index fa52cf8..3547a3a 100644 --- a/TODO.md +++ b/TODO.md @@ -2,6 +2,8 @@ BUGS: +* use internal logic for EOL switching command +* Add tab and eol mode to window title * implement mouse warping on search, jump to line, and focus change * use transaction processing for joining lines * no analysis of line-endings or tabs in document diff --git a/lib/buf.c b/lib/buf.c index fe740ce..71bf15e 100644 --- a/lib/buf.c +++ b/lib/buf.c @@ -66,6 +66,16 @@ static void putb(Buf* buf, char b, Sel* p_sel) { buf->status = MODIFIED; } +static void putch(Buf* buf, char b, Sel* p_sel) { + if (b == '\r') return; + if (b == '\n' && DosLineFeed) { + putb(buf, '\r', p_sel); + putb(buf, '\n', p_sel); + } else { + putb(buf, b, p_sel); + } +} + void buf_init(Buf* buf) { /* cleanup old data if there is any */ if (buf->bufstart) { @@ -316,7 +326,10 @@ size_t buf_end(Buf* buf) { int buf_getrat(Buf* buf, size_t off) { size_t rlen = 0; Rune rune = 0; - while (!utf8decode(&rune, &rlen, getb(buf, off++))); + if (getb(buf, off) == '\r' && getb(buf, off+1) == '\n') + rune = '\n'; + else + while (!utf8decode(&rune, &rlen, getb(buf, off++))); return rune; } @@ -330,7 +343,7 @@ void buf_puts(Buf* buf, char* s) { buf_del(buf); size_t beg = buf_getsel(buf).beg; if (s && *s) { - while (*s) putb(buf, *(s++), &(buf->selection)); + while (*s) putch(buf, *(s++), &(buf->selection)); log_add(buf, beg, buf_getsel(buf).end, NULL); } } @@ -475,8 +488,17 @@ size_t buf_byrune(Buf* buf, size_t pos, int count) { int move = (count < 0 ? -1 : 1); count *= move; // remove the sign if there is one for (; count > 0; count--) { - if ((pos > 0 && move < 0) || (pos < buf_end(buf) && move > 0)) - pos += move; + if (pos > 0 && move < 0) { + if (getb(buf, pos-2) == '\r' && getb(buf, pos-1) == '\n') + pos -= 2; + else + pos += move; + } else if (pos < buf_end(buf) && move > 0) { + if (getb(buf, pos) == '\r' && getb(buf, pos+1) == '\n') + pos += 2; + else + pos += move; + } } return pos; } @@ -505,9 +527,9 @@ size_t buf_byline(Buf* buf, size_t pos, int count) { for (; count > 0; count--) { if (move < 0) { if (pos > buf_eol(buf, 0)) - pos = buf_bol(buf, (buf_bol(buf, pos) - 1)); + pos = buf_byrune(buf, buf_bol(buf, pos), LEFT); } else { - size_t next = (buf_eol(buf, pos) + 1); + size_t next = buf_byrune(buf, buf_eol(buf, pos), RIGHT); if (next <= buf_end(buf)) pos = next; } -- 2.49.0