Vim Tips Wiki
Advertisement
Tip 878 Printable Monobook Previous Next

created February 18, 2005 · complexity intermediate · author Bertram Scharpf · version 5.7


Simple commands to remove unwanted whitespace

In a search, \s finds whitespace (a space or a tab), and \+ finds one or more occurrences.

Delete all trailing whitespace (at the end of each line) with:

:%s/\s\+$//

More rarely, you might want to delete whitespace at the beginning of each line:

:%s/^\s\+//

With the following mapping you can press F5 to delete all trailing whitespace. The variable _s is used to save and restore the last search pattern register (so next time you press n you will continue your last search), and :nohl is used to switch off search highlighting (so trailing spaces won't be highlighted while you are typing). The e flag is used in the substitute command so no error is shown if trailing whitespace is not found.

:nnoremap <silent> <F5> :let _s=@/<Bar>:%s/\s\+$//e<Bar>:let @/=_s<Bar>:nohl<CR>

See Highlighting whitespaces at end of line to display, rather than delete, unwanted whitespace.

Display or remove unwanted whitespace with a script

Here is a more elaborate procedure that can display or remove unwanted whitespace. Here, "unwanted" means any spaces before a tab character, or any space or tab at the end of a line.

function ShowSpaces(...)
  let @/="\\v(\\s+$)|( +\\ze\\t)"
  let oldhlsearch=&hlsearch
  if !a:0
    let &hlsearch=!&hlsearch
  else
    let &hlsearch=a:1
  end
  return oldhlsearch
endfunction

function TrimSpaces() range
  let oldhlsearch=ShowSpaces(1)
  execute a:firstline.",".a:lastline."substitute ///gec"
  let &hlsearch=oldhlsearch
endfunction

command -bar -nargs=? ShowSpaces call ShowSpaces(<args>)
command -bar -nargs=0 -range=% TrimSpaces <line1>,<line2>call TrimSpaces()
nnoremap <F12>     :ShowSpaces 1<CR>
nnoremap <S-F12>   m`:TrimSpaces<CR>``
vnoremap <S-F12>   :TrimSpaces<CR>

Automatically removing all trailing whitespace

Just put the following line in your vimrc file. Everytime you issue a :w command, Vim will automatically remove all trailing whitespace before saving.

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

This is a very dangerous autocmd to have! This will *always* strip trailing whitespace from *every* file you save. Sometimes, trailing whitespace is desired, or even essential!

For example, if in your .vimrc you have the following:

set wrap
set linebreak
" note trailing space at end of next line
set showbreak=>\ \ \

then saving your .vimrc will make it use ">  \" instead of ">   " to prepend to wrapped lines!


Remember you can also specify filetype

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

or how about having this operate when you Enter the file:

autocmd BufEnter *.php :%s/\s\+$//e

And let's get rid of those pesky ^M at the same time

autocmd BufEnter *.php :%s/[ \t\r]\+$//e

With a ":call" instead of ":%s" (keep last used search/replace) and using FileType:

autocmd FileType c,cpp,java,php autocmd BufWritePre <buffer> :call setline(1,map(getline(1,"$"),'substitute(v:val,"\\s\\+$","","")'))

:help :autocmd

Comments

Here's what I use in my .vimrc:

" Removes trailing spaces
function TrimWhiteSpace()
  %s/\s*$//
  ''
:endfunction

set list listchars=trail:.,extends:>
autocmd FileWritePre * :call TrimWhiteSpace()
autocmd FileAppendPre * :call TrimWhiteSpace()
autocmd FilterWritePre * :call TrimWhiteSpace()
autocmd BufWritePre * :call TrimWhiteSpace()

map <F2> :call TrimWhiteSpace()<CR>
map! <F2> :call TrimWhiteSpace()<CR>

My prefered setting of list and listchars:

set list listchars=tab:»·,trail:·

This gives:
»·······text after tab with four spaces after it····


There is one occasion where I want to keep my trailing space. But even in those documents, I want to keep it in only one place, and not every occurrence.

Here is my substitution pattern:

s/\(^--\)\@<!\s*$//

This will eliminate all trailing whitespaces except for the one in an email signature marker (-- ). See wikipedia:Signature block.

In the function in the tip, this expands to:

execute a:firstline.",".a:lastline."substitute /\\(^--\\)\\@<!\\s*$//ge"

Also, I've found the autocmds to work better like this:

autocmd FileWritePre * :TrimSpaces
autocmd FileAppendPre * :TrimSpaces
autocmd FilterWritePre * :TrimSpaces
autocmd BufWritePre * :TrimSpaces

(taking advantage of the default range defined in Betram's command definition)

Propose to delete following contribution

The following comment is from tip 721 (now removed). However it relies on two different scripts on vim.org and is just too complex to merge into this tip, so I propose deleting it.

I use the (possibly overkill) version here:

function! StripTrailingSpaces()
  if ( GetVar( "noStripSpaces" ) != 1 )
    let currPos=Mark()
    exec 'v:^--\s*$:s:\s\+$::e'
    exe currPos
  endif
endfunction
" Remove trailing blanks upon saving except from lines containing sigdashes
au BufWritePre * silent! call StripTrailingSpaces()

The Mark() function is from Benji's foo.vim and is used simply to restore the cursor location when done. The variable 'noStripSpaces' can be set to 1 to prevent the stripping of spaces for a file if you like (:let b:noStripSpaces=1); this uses my getVar.vim script. (Both scripts can be found on vim.org.)

The substitute I use leaves lines that consist of -- followed by spaces (used to separate email signatures from the rest of the text): I don't use them anywhere else so it doesn't cause me any problems.


 TO DO 

  • Finish merge in of info from tips 721 and 1487 (tips now removed; have copied all needed info from those tips; need to merge it better here).

Advertisement