From 287521cba09765d9d0901b79d8911a27de1af4e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Wed, 22 Apr 2015 21:20:59 +0200 Subject: Cleanup line ending type detection and insertion --- text.c | 20 +++++++++++++------- text.h | 11 +++++++++-- vis.c | 13 +++++++++++-- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/text.c b/text.c index 553a3cb..eca86db 100644 --- a/text.c +++ b/text.c @@ -118,7 +118,7 @@ struct Text { struct stat info; /* stat as proped on load time */ int fd; /* the file descriptor of the original mmap-ed data */ LineCache lines; /* mapping between absolute pos in bytes and logical line breaks */ - int newlines; /* 0: unknown, 1: \n, -1: \r\n */ + enum TextNewLine newlines; /* which type of new lines does the file use */ }; /* buffer management */ @@ -902,18 +902,23 @@ bool text_modified(Text *txt) { return txt->saved_action != txt->undo; } -bool text_newlines_crnl(Text *txt){ - if (txt->newlines == 0) { - txt->newlines = 1; /* default to UNIX style \n new lines */ +enum TextNewLine text_newline_type(Text *txt){ + if (!txt->newlines) { + txt->newlines = TEXT_NEWLINE_NL; /* default to UNIX style \n new lines */ const char *start = txt->buf.data; if (start) { const char *nl = memchr(start, '\n', txt->buf.len); if (nl > start && nl[-1] == '\r') - txt->newlines = -1; /* Windows style \r\n */ + txt->newlines = TEXT_NEWLINE_CRNL; + } else { + char c; + size_t nl = lines_skip_forward(txt, 0, 1, NULL); + if (nl > 1 && text_byte_get(txt, nl-2, &c) && c == '\r') + txt->newlines = TEXT_NEWLINE_CRNL; } } - return txt->newlines < 0; + return txt->newlines; } static bool text_iterator_init(Iterator *it, size_t pos, Piece *p, size_t off) { @@ -1088,7 +1093,8 @@ static size_t lines_skip_forward(Text *txt, size_t pos, size_t lines, size_t *li if (lines == 0) break; } - *lines_skipped = lines_old - lines; + if (lines_skipped) + *lines_skipped = lines_old - lines; return pos; } diff --git a/text.h b/text.h index 9f350f9..099cbe4 100644 --- a/text.h +++ b/text.h @@ -82,8 +82,15 @@ size_t text_history_get(Text*, size_t index); size_t text_size(Text*); bool text_modified(Text*); -/* test whether the underlying file uses UNIX style \n or Windows style \r\n newlines */ -bool text_newlines_crnl(Text*); + +/* which type of new lines does the text use? */ +enum TextNewLine { + TEXT_NEWLINE_NL = 1, + TEXT_NEWLINE_CRNL, +}; + +enum TextNewLine text_newline_type(Text*); + bool text_save(Text*, const char *file); bool text_range_save(Text*, Filerange*, const char *file); ssize_t text_write(Text*, int fd); diff --git a/vis.c b/vis.c index 8466034..e1ed0de 100644 --- a/vis.c +++ b/vis.c @@ -1092,8 +1092,17 @@ static void copy_indent_from_previous_line(View *view, Text *text) { } static void insert_newline(const Arg *arg) { - insert(&(const Arg){ .s = - text_newlines_crnl(vis->win->file->text) ? "\r\n" : "\n" }); + const char *nl; + switch (text_newline_type(vis->win->file->text)) { + case TEXT_NEWLINE_CRNL: + nl = "\r\n"; + break; + default: + nl = "\n"; + break; + } + + insert(&(const Arg){ .s = nl }); if (vis->autoindent) copy_indent_from_previous_line(vis->win->view, vis->win->file->text); -- cgit v1.2.3