Have you ever seen “No newline at end of file” in your git diffs? Us, too.
~/.dotfiles% git diff
diff --git a/vimrc b/vimrc
index 7e31913..a8b5f95 100644
--- a/vimrc
+++ b/vimrc
@@ -2,4 +2,4 @@
let configs = split(glob("~/.vim/configs/*"), "\n")
for filename in configs
execute 'source ' filename
-endfor
+endfor
\ No newline at end of file
Why does this happen and what does it mean?
Try it in your shell
Here I have made a text file and, by definition, a non-text file:
~% echo foo > text-file
~% od -c text-file
0000000 f o o \n
0000004
~% wc -l text-file
1 text-file
~% echo -n foo > binary-file
~% od -c binary-file
0000000 f o o
0000003
~% wc -l binary-file
0 binary-file
If you open each file in vim, they will display similarly. The intuition behind
what vim is doing is “separate each line with a line break”, which is different
from “display each \n
as a line break”.
However, the binary-file
will cause vim to display [noeol]
in its status
line (with the default status line).
History lesson
This comes from an old C decision that has been passed down through Unix history:
A source file that is not empty shall end in a new-line character, which shall not be immediately preceded by a backslash character.
Since this is a “shall” clause, we must emit a diagnostic message for a violation of this rule.
So, it turns out that, according to POSIX, every text file (including
Ruby and JavaScript source files) should end with a \n
, or “newline” (not “a
new line”) character. This acts as the eol
, or the “end of line”
character. It is a line “terminator”.
Following the rules in your editor
You can make sure you follow this rule easily:
- For Vim users, you’re all set out of the box! Just don’t change your
eol
setting. - For Emacs users, add
(setq require-final-newline t)
to your.emacs
or.emacs.d/init.el
file. - For Android Studio, RubyMine, PyCharm, and other IntelliJ, set “Ensure line feed at file end on Save” under “Editor.”
- For Atom, you’re also all set out of the box. Keep that via the Whitespace plugin.
- For VS Code, set
"files.insertFinalNewline": true
. - For Sublime, set the
ensure_newline_at_eof_on_save
option totrue
. - For TextMate, you can install the Avian Missing
Bundle
and add
TM_STRIP_WHITESPACE_ON_SAVE = true
to your.tm_properties
file.
What’s next
If this satisfied your curiosity, you might also enjoy: