33

Is there a .vimrc setting to automatically remove trailing whitespace when saving a file?

Ideally (to be safe) I would like to only have this functionality for certain files, e.g. *.rb

Mateusz Piotrowski
  • 4,623
  • 5
  • 36
  • 70
Michael Durrant
  • 41,213
  • 69
  • 165
  • 232

3 Answers3

38

This works (in the .vimrc file) for all files:

autocmd BufWritePre * :%s/\s\+$//e

This works (in the .vimrc file) for just ruby(.rb) files:

autocmd BufWritePre *.rb :%s/\s\+$//e
JayRizzo
  • 105
  • 4
Michael Durrant
  • 41,213
  • 69
  • 165
  • 232
  • 9
    This solution's nice, but I think @Sukminder's solution below is better, because it repositions the cursor correctly. – hlin117 Mar 19 '15 at 20:41
  • What does that the lastet `e` use? – acgtyrant Dec 28 '15 at 05:55
  • @acgtyrant I tested with and without the 'e'. It seems to be what keeps Vim from spitting an error when you save a file that doesn't have any trailing whitespace. In other words, when the pattern can't be matched, Vim spits an "E486: Pattern not found" error and the 'e' seems to be what suppresses it since you don't really care in this case. – Joe Holloway Apr 19 '21 at 14:54
31

To keep cursor position use something like:

function! <SID>StripTrailingWhitespaces()
    let l = line(".")
    let c = col(".")
    %s/\s\+$//e
    call cursor(l, c)
endfun

else cursor would end up at beginning of line of last replace after save.

Example: You have a space at end of line 122, you are on line 982 and enter :w. Not restoring position, would result in cursor ending up at beginning of line 122 thus killing work flow.

Set up call to function using autocmd, some examples:

" Using file extension
autocmd BufWritePre *.h,*.c,*.java :call <SID>StripTrailingWhitespaces()

" Often files are not necessarily identified by extension, if so use e.g.:
autocmd BufWritePre * if &ft =~ 'sh\|perl\|python' | :call <SID>StripTrailingWhitespaces() | endif

" Or if you want it to be called when file-type i set
autocmd FileType sh,perl,python  :call <SID>StripTrailingWhitespaces()

" etc.

One can also use, but not needed in this case, getpos() by:

let save_cursor = getpos(".")
" Some replace command
call setpos('.', save_cursor)

" To list values to variables use:
let [bufnum, lnum, col, off] = getpos(".")
Runium
  • 28,133
  • 5
  • 50
  • 71
3

My DeleteTrailingWhitespace plugin does this and, in contrast to the various simple :autocmds floating around, also handles special cases, can query the user, or abort writes with trailing whitespace.

The plugin page contains links to alternatives; there's also a large discussion on the Vim Tips Wiki.

Ingo Karkat
  • 11,664
  • 1
  • 34
  • 48