diff options
| -rw-r--r-- | text.c | 15 | ||||
| -rw-r--r-- | text.h | 2 | ||||
| -rw-r--r-- | vis.c | 4 |
3 files changed, 19 insertions, 2 deletions
@@ -120,6 +120,7 @@ struct Text { int fd; /* the file descriptor of the original mmap-ed data */ LineCache lines; /* mapping between absolute pos in bytes and logical line breaks */ const char *marks[26]; /* a mark is a pointer into an underlying buffer */ + int newlines; /* 0: unknown, 1: \n, -1: \r\n */ }; /* buffer management */ @@ -832,6 +833,20 @@ 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 */ + 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 */ + } + } + + return txt->newlines < 0; +} + static bool text_iterator_init(Iterator *it, size_t pos, Piece *p, size_t off) { *it = (Iterator){ .pos = pos, @@ -76,6 +76,8 @@ void text_mark_clear_all(Text*); 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*); int text_save(Text*, const char *file); void text_free(Text*); @@ -848,8 +848,8 @@ static void insert_tab(const Arg *arg) { } static void insert_newline(const Arg *arg) { - // TODO determine file type to insert \r\n or \n - insert(&(const Arg){ .s = "\n" }); + insert(&(const Arg){ .s = + text_newlines_crnl(vis->win->text) ? "\r\n" : "\n" }); } static void openline(const Arg *arg) { |
