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\\+$","","")'))
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).