Skip to content

Commit 09af110

Browse files
authored
Insert a final newline if needed (microsoft#300)
1 parent 3841d04 commit 09af110

File tree

1 file changed

+24
-1
lines changed

1 file changed

+24
-1
lines changed

src/buffer/mod.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ pub struct TextBuffer {
204204
ruler: CoordType,
205205
encoding: &'static str,
206206
newlines_are_crlf: bool,
207+
insert_final_newline: bool,
207208
overtype: bool,
208209

209210
wants_cursor_visibility: bool,
@@ -249,7 +250,9 @@ impl TextBuffer {
249250
line_highlight_enabled: false,
250251
ruler: 0,
251252
encoding: "UTF-8",
252-
newlines_are_crlf: cfg!(windows), // Unfortunately Windows users insist on CRLF
253+
// Windows users want CRLF and no final newline.
254+
newlines_are_crlf: cfg!(windows),
255+
insert_final_newline: !cfg!(windows),
253256
overtype: false,
254257

255258
wants_cursor_visibility: false,
@@ -621,6 +624,7 @@ impl TextBuffer {
621624
// * the logical line count
622625
// * the newline type (LF or CRLF)
623626
// * the indentation type (tabs or spaces)
627+
// * whether there's a final newline
624628
{
625629
let chunk = self.read_forward(0);
626630
let mut offset = 0;
@@ -711,10 +715,13 @@ impl TextBuffer {
711715
(_, lines) = unicode::newlines_forward(chunk, offset, lines, CoordType::MAX);
712716
}
713717

718+
let final_newline = chunk.ends_with(b"\n");
719+
714720
// Add 1, because the last line doesn't end in a newline (it ends in the literal end).
715721
self.stats.logical_lines = lines + 1;
716722
self.stats.visual_lines = self.stats.logical_lines;
717723
self.newlines_are_crlf = newlines_are_crlf;
724+
self.insert_final_newline = final_newline;
718725
self.indent_with_tabs = indent_with_tabs;
719726
self.tab_size = tab_size;
720727
}
@@ -1894,6 +1901,22 @@ impl TextBuffer {
18941901
}
18951902
}
18961903

1904+
// POSIX mandates that all valid lines end in a newline.
1905+
// This isn't all that common on Windows and so we have
1906+
// `self.final_newline` to control this.
1907+
//
1908+
// In order to not annoy people with this, we only add a
1909+
// newline if you just edited the very end of the buffer.
1910+
if self.insert_final_newline
1911+
&& self.cursor.offset > 0
1912+
&& self.cursor.offset == self.text_length()
1913+
&& self.cursor.logical_pos.x > 0
1914+
{
1915+
let cursor = self.cursor;
1916+
self.edit_write(if self.newlines_are_crlf { b"\r\n" } else { b"\n" });
1917+
self.set_cursor_internal(cursor);
1918+
}
1919+
18971920
self.edit_end();
18981921
}
18991922

0 commit comments

Comments
 (0)