Why is Vim adding a newline? Is this a convention?

10,566

Solution 1

The convention for Unix text files is that every line is terminated by a newline, and that newlines are line terminators, not line separators.

When Vim saves a buffer as a file, it terminates every line with the end-of-line sequence for that file format, which for Unix is a newline. See

:help 'fileformat'

If you're using Unix text-processing tools, it's best to stick with this convention. However, if you have some need to not put a newline at the end of the last line of a file, you can do so. Vim considers such files to be "binary". See

:help 'binary'
:help edit-binary

Solution 2

Vim 8.0 now provides for this with the fixeol option. Specifically if you do:

:set nofixeol

then Vim won't add a trailing newline character at the end of the final line if the file didn't already have one.

That could go in a filetype plugin, or possibly even your .vimrc.

(This is an improvement on :set binary because it only affects the final line-break character, whereas binary also changes a bunch of other behaviours, which you probably don't want unless you're actually editing a binary file.)

A newly created file will still have a trailing line-break character by default. You can change that (and switch a file that already has a final newline to not having one) by additionally doing:

:set noeol

That has to be set specifically for each file you wish to change: loading a file into a buffer will always set eol to match the file's current state.

Solution 3

Vim is not adding anything that you didn't put there yourself.

A "newline" character is not a "new line" and both examples are perfectly normal:

  • in the first one, the file only contains one line so you get one "newline" character,
  • in the second one, the file contains two lines so you get two "newline" characters.

Solution 4

Using the 'j' command you can join all the lines into one.

If you also want to remove the LF or CRLF on the last line do the following in vi.

$ vi file
:set binary
:set noeol
:w!
:f          look for [noeol] on the status line
:q
Share:
10,566

Related videos on Youtube

dotancohen
Author by

dotancohen

Updated on September 18, 2022

Comments

  • dotancohen
    dotancohen over 1 year

    If I open Vim and type itest<Esc>:wq then I get a file that has no newlines in Vim but does seem to have a newline in the code:

    $ vim -u NONE test.txt
    $ cat test.txt | hd
    00000000  74 65 73 74 0a                    |test.|
    00000005
    

    If I open Vim and type itest<Return><Esc>:wq then I get a file that has one newline in Vim but two newlines in the code:

    $ rm test.txt
    $ vim -u NONE test.txt
    $ cat test.txt | hd
    00000000  74 65 73 74 0a 0a                 |test..|
    00000006
    

    Note that I am opening Vim with -u NONE so there is no local configuration being used. Note also that this might be related to a previous question of mine.

    This is my system info:

    $ uname -a
    Linux awsAlpha 3.2.0-60-virtual #91-Ubuntu SMP Wed Feb 19 04:13:28 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
    $ vim --version
    VIM - Vi IMproved 7.3 (2010 Aug 15, compiled May  4 2012 04:25:35)
    Included patches: 1-429
    Modified by [email protected]
    Compiled by buildd@
    

    I can confirm the exact same behaviour on this system as well:

    $ uname -a
    Linux bruno 3.5.0-48-generic #72-Ubuntu SMP Mon Mar 10 23:18:29 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
    $ vim --version
    VIM - Vi IMproved 7.3 (2010 Aug 15, compiled Oct 26 2012 16:45:33)
    Included patches: 1-547
    Modified by [email protected]
    Compiled by buildd@
    

    Why is Vim adding a newline? Is this a convention?

    Here is some clarification about the hd command as installed on Ubuntu Server:

    $ man hd | head -4
    HEXDUMP(1)            BSD General Commands Manual            HEXDUMP(1)
    
    NAME
         hexdump, hd — ASCII, decimal, hexadecimal, octal dump
    
  • barlop
    barlop about 10 years
    oh that's interesting. So besides the famous \r\n vs \n. Windows uses line separators and unix uses line terminators? and is that documented anywhere? I know it's defined here presumably applying to unix "ISO/IEC 9899:2011, Section §7.21.2 Streams says: A text stream is an ordered sequence of characters composed into lines, each line consisting of zero or more characters plus a terminating new-line character"
  • barlop
    barlop about 10 years
    but where is it documented that windows uses a line separator?
  • Ruslan
    Ruslan about 10 years
    It does add the newline. Test it as follows: printf "\x41" > /tmp/test.txt, then check that it has only single 'A' character with xxd /tmp/test.txt. Now vim /tmp/test.txt<ENTER>:wq. Check again to see the file having two bytes: 'A\n'.
  • romainl
    romainl about 10 years
    Lines end with a newline character. You have one line thus you have one newline character.
  • Ruslan
    Ruslan about 10 years
    Well, after printf here I had no well-formed "lines". After vim I have one. So, it does add something that I didn't put there.
  • romainl
    romainl about 10 years
    What you printf is not a line unless you append \n. Being a text editor, Vim deals with lines by default, and any text you insert in the file is on, at the very least, a line, unless you explicitely tell Vim to not do that.