How can I trim blank lines at the end of file in Vim?

1. An elegant solution can be based on the :vglobal command (or, which is the same thing, on the :global with ! modifier):

:v/\_s*\S/d

This command executes :delete on every line that does not have non-whitespace characters in it, as well as after it in the remaining text to the end of buffer (see :help /\s, :help /\S, and :help /\_ to understand the pattern). Hence, the command removes the tailing blank lines.

To delete the empty lines in a strict sense—as opposed to blank ones containing only whitespace—change the pattern in that :vglobal command as follows.

:v/\n*./d

2. On huge sparse files containing large blocks of consecutive whitespace characters (starting from about hundreds of kilobytes of whitespace) the above commands might have unacceptable performance. If that is the case, the same elegant idea can be used to transform that :vglobal commands into much faster (but perhaps less elegantly-looking) :delete commands with pattern-defined ranges.

For blank lines:

:0;/^\%(\_s*\S\)\@!/,$d

For empty lines:

:0;/^\%(\n*.\)\@!/,$d

The essence of both commands is the same; namely, removing the lines belonging to the specified ranges, which are defined according to the following three steps:

  1. Move the cursor to the first line of the buffer before interpreting the rest of the range (0;—see :help :;). The difference between 0 and 1 line numbers is that the former allows a match at the first line, when there is a search pattern used to define the ending line of the range.

  2. Search for a line where the pattern describing a non-tailing blank line (\_s*\S or \n*.) does not match (negation is due to the \@! atom—see :help /\@!). Set the starting line of the range to that line.

  3. Set the ending line of the range to the last line of the buffer (,$—see :help :$).

3. To run any of the above commands on saving, trigger it using an autocommand to be fired on the BufWrite event (or its synonym, BufWritePre).


Inspired by solution from @Prince Goulash, add the following to your ~/.vimrc to remove trailing blank lines for every save for Ruby and Python files:

autocmd FileType ruby,python autocmd BufWritePre <buffer> :%s/\($\n\s*\)\+\%$//e

You can put this into your vimrc

au BufWritePre *.txt $put _ | $;?\(^\s*$\)\@!?+1,$d

(replace *.txt with whatever globbing pattern you want)

Detail:

  • BufWritePre is the event before writing a buffer to a file.
  • $put _ appends a blank line at file end (from the always-empty register)
  • | chains Ex commands
  • $;?\(^\s*$\)\@!? goes to end of file ($) then (;) looks up backwards (?…?) for the first line which is not entirely blank (\(^\s*$\)\@!), also see :help /\@! for negative assertions in vim searches.
  • ×××+1,$ forms a range from line ×××+1 till the last line
  • d deletes the line range.

This substitute command should do it:

:%s#\($\n\s*\)\+\%$##

Note that this removes all trailing lines that contain only whitespace. To remove only truly "empty" lines, remove the \s* from the above command.

EDIT

Explanation:

  • \( ..... Start a match group
  • $\n ... Match a new line (end-of-line character followed by a carriage return).
  • \s* ... Allow any amount of whitespace on this new line
  • \) ..... End the match group
  • \+ ..... Allow any number of occurrences of this group (one or more).
  • \%$ ... Match the end of the file

Thus the regex matches any number of adjacent lines containing only whitespace, terminated only by the end of the file. The substitute command then replaces the match with a null string.

Tags:

Vim