GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS

Written by thoughtbot

No Newline at End of File

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 TextMate users, you can install the Avian Missing Bundle and add TM_STRIP_WHITESPACE_ON_SAVE = true to your .tm_properties file.
  • For Sublime users, set the ensure_newline_at_eof_on_save option to true.
  • For RubyMine, set "Ensure line feed at file end on Save" under "Editor."

What's next?

If this satisfied your curiosity, you might also enjoy: