created February 18, 2005 · complexity intermediate · author Bertram Scharpf · version 6.0
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\+// " Same thing (:le = :left = left-align given range): :%le
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>
Note: Some comments (and/or pointers) explaining what the respective functions' individual lines actually do would be very helpful.
An alternative function simulating manual steps:
function StripTrailingWhitespace() if !&binary && &filetype != 'diff' normal mz normal Hmy %s/\s\+$//e normal 'yz<CR> normal `z endif endfunction
However, this has minor side-effects, such as influencing undo history and sometimes changing scroll position.
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 preferred setting of list and listchars:
set list listchars=tab:»·,trail:·
This gives:
»·······text after tab with four spaces after it····
Or try
set list lcs=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)