aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--text.c15
-rw-r--r--text.h2
-rw-r--r--vis.c4
3 files changed, 19 insertions, 2 deletions
diff --git a/text.c b/text.c
index 28115fd..2f3ea17 100644
--- a/text.c
+++ b/text.c
@@ -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,
diff --git a/text.h b/text.h
index 15d0ad1..773e8b6 100644
--- a/text.h
+++ b/text.h
@@ -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*);
diff --git a/vis.c b/vis.c
index d65b45b..c075dc5 100644
--- a/vis.c
+++ b/vis.c
@@ -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) {