No Newline at End of File

Mike Burns

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
\ 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
~% wc -l text-file
1 text-file
~% echo -n foo > binary-file
~% od -c binary-file
0000000   f   o   o
~% 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 to true.
  • 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: