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
-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 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:

We've been helping engineering teams deliver exceptional products for over 20 years. Our designers, developers, and product managers work closely with teams to solve your toughest software challenges through collaborative design and development. Learn more about us.