From 1656628aaa62cf4a3c29408eb24e3de1486573fb Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Thu, 3 Dec 2020 17:31:18 -0500 Subject: fixed handling of CRLF line endings --- buffer.c | 52 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/buffer.c b/buffer.c index a78be8d..3c2dbe1 100644 --- a/buffer.c +++ b/buffer.c @@ -43,8 +43,7 @@ static Status buffer_line_append_char(Line *line, char32_t c) { return true; } -// fp needs to be a binary file for this to work -// (because of the way we're checking the size of the file) +// fp should be a binary file Status buffer_load_file(TextBuffer *buffer, FILE *fp) { assert(fp); fseek(fp, 0, SEEK_END); @@ -66,19 +65,25 @@ Status buffer_load_file(TextBuffer *buffer, FILE *fp) { char32_t c = 0; mbstate_t mbstate = {0}; for (u8 *p = file_contents, *end = p + file_size; p != end; ) { - size_t n = mbrtoc32(&c, (char *)p, (size_t)(end - p), &mbstate); - if (n == 0) { - // null character - c = 0; - ++p; - } else if (n == (size_t)(-3)) { - // no bytes consumed, but a character was produced - } else if (n == (size_t)(-2) || n == (size_t)(-1)) { - // incomplete character at end of file or invalid UTF-8 respectively; just treat it as a byte - c = *p; - ++p; + if (*p == '\r' && p != end-1 && p[1] == '\n') { + // CRLF line endings + p += 2; + c = U'\n'; } else { - p += n; + size_t n = mbrtoc32(&c, (char *)p, (size_t)(end - p), &mbstate); + if (n == 0) { + // null character + c = 0; + ++p; + } else if (n == (size_t)(-3)) { + // no bytes consumed, but a character was produced + } else if (n == (size_t)(-2) || n == (size_t)(-1)) { + // incomplete character at end of file or invalid UTF-8 respectively; just treat it as a byte + c = *p; + ++p; + } else { + p += n; + } } if (c == U'\n') { if (util_is_power_of_2(buffer->nlines)) { @@ -362,6 +367,25 @@ bool buffer_pos_move_right(TextBuffer *buffer, BufferPos *p) { return true; } +bool buffer_pos_move_up(TextBuffer *buffer, BufferPos *pos) { + (void)buffer; + if (pos->line == 0) + return false; + --pos->line; + u32 line_len = buffer->lines[pos->line].len; + if (pos->col >= line_len) pos->col = line_len; + return true; +} + +bool buffer_pos_move_down(TextBuffer *buffer, BufferPos *pos) { + if (pos->line >= buffer->nlines-1) + return false; + ++pos->line; + u32 line_len = buffer->lines[pos->line].len; + if (pos->col >= line_len) pos->col = line_len; + return true; +} + bool buffer_cursor_move_left(TextBuffer *buffer) { return buffer_pos_move_left(buffer, &buffer->cursor_pos); } -- cgit v1.2.3