From: Michael D. Lowis Date: Tue, 18 Sep 2018 16:28:10 +0000 (-0400) Subject: tweaked cursor movement logic to handle CRLF and LF line endings. Also tweaked inser... X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=452a6b8f8d56988cb606ff933453163ac152c6f2;p=projs%2Ftide.git 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. --- 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; }