What's the simplest way to strip trailing whitespace from all lines in a file?

  • It's pretty common when programming or opening text files to encounter files with trailing whitespace at the end of a line. vim has a way to show this by setting the trail option in the listchars option and then turning list on.

    However, what's the easiest way to eliminate that trailing whitespace globally across the whole of a file (ideally without a plugin)?

    Here is a doc entry on topic.

    If you have installed vim-faq, you can get an offline answer there: `:h vim-faq` and search `/trailing`. The hard to memorize tag is `:h faq-12.1`.

  • Use a keybinding to strip all trailing whitespace

    Since some pages that I edit actually need trailing whitespaces (e.g. markdown) and others don't, I set up a keybinding to F5 so that it's trivial to do without being automatic. To do so, add the code below (from vim.wikia) or some variation of it to your .vimrc:

    "Remove all trailing whitespace by pressing F5
    nnoremap <F5> :let [email protected]/<Bar>:%s/\s\+$//e<Bar>:let @/=_s<Bar><CR>
    
    • nnoremap <F5> does a nonrecursive mapping to the key F5 in normal mode
    • :let [email protected]/ stores the last search term (from the macro @/) in the variable _s
    • <Bar> Functions as a pipe symbol | to separate commands, however | would end a command in this context, so <Bar> must be used instead.
    • :%s/\s\+$//e searches for trailing whitespace and deletes it everywhere in the buffer (see CarpetSmoker's answer for a detailed breakdown of this expression)
    • let @/=_s restores your last search term to the macro @/, so that it will be available the next time you hit n.
    • <CR> ends the mapping

    ... or be more selective

    If you have cases in which you don't want to strip all of the trailing whitespace, you can use a pattern to be more selective. For example, the following code shows how I strip trailing whitespace only if it comes after a semicolon (here it's tied to F8).

    nnoremap <F8> :let [email protected]/<Bar>:%s/;\s\+$/;/e<Bar>:let @/=_s<Bar><CR>
    

    This is useful if, like me, you have some files with markdown-like heredocs interspersed among semicolon-terminated programming statements.

    Try `:keeppatterns` to prevent overriding `@/`. And also take a look at `:keepjumps`.

    @Bohr What version of vim are you using? I tried `:help keeppattern` and didn't get anything.

    @ChristopherBottoms At least version 7.4.155.

    @Bohr. Thanks! Come to find out I was still using 7.4.0. I installed the latest version and it's available.

    You can get the same effect by wrapping this command in a function, since then the last search term is automatically restored :-) This way you don't have to muck about with `:nohl` either, if if you were highlighting something, it will keep highlighting it (see my updated answer).

    `:nohl` seems redundant to me - there are no trailing spaces which will be highlighted. Perhaps the previous values of `hl` should be restored? Not just set off.

    @jalanb Thanks! I tried it out and it seemed to work fine without it, so I removed it in the code above.

    Keep in mind that `:keeppatterns` showed up at some point after 7.4 was released so if you work on multiple machines with differing versions of Vim, you'll need to use `if exists(':keeppatterns')` before using it. (I suspect the restoration of the previous search pattern showed up after release as well, otherwise I wouldn't have it in my vimrc.)

    why would a markdown page require trailing whitespace?

    @baxx To keep lines from running together.

License under CC-BY-SA with attribution


Content dated before 6/26/2020 9:53 AM