Vim Tips Wiki
(Undo revision 28661 by 93.44.153.210 (talk) (you don't need the g flag here))
(Reviewing, more to do tomorrow. Still need to double check some scripts and clean up comments.)
Line 20: Line 20:
 
</pre>
 
</pre>
   
More rarely, you might want to delete whitespace at the beginning of each line:
+
More rarely, a user might want to delete whitespace at the beginning of each line:
 
<pre>
 
<pre>
 
:%s/^\s\+//
 
:%s/^\s\+//
Line 27: Line 27:
 
</pre>
 
</pre>
   
With the following mapping you can press F5 to delete all trailing whitespace. The variable <tt>_s</tt> is used to save and restore the last search pattern register (so next time you press <tt>n</tt> you will continue your last search), and <tt>:nohl</tt> is used to switch off search highlighting (so trailing spaces won't be highlighted while you are typing). The <tt>e</tt> flag is used in the substitute command so no error is shown if trailing whitespace is not found.
+
With the following mapping a user can press F5 to delete all trailing whitespace. The variable <tt>_s</tt> is used to save and restore the last search pattern register (so next time the user presses <tt>n</tt> they will continue their last search), and <tt>:nohl</tt> is used to switch off search highlighting (so trailing spaces will not be highlighted while the user types). The <tt>e</tt> flag is used in the substitute command so no error is shown if trailing whitespace is not found.
 
<pre>
 
<pre>
 
:nnoremap <silent> <F5> :let _s=@/<Bar>:%s/\s\+$//e<Bar>:let @/=_s<Bar>:nohl<CR>
 
:nnoremap <silent> <F5> :let _s=@/<Bar>:%s/\s\+$//e<Bar>:let @/=_s<Bar>:nohl<CR>
Line 35: Line 35:
   
 
==Display or remove unwanted whitespace with a script==
 
==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.
+
The following 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.
   
 
<pre>
 
<pre>
Line 62: Line 62:
 
</pre>
 
</pre>
   
  +
This is a similar function which similates the manual steps for removing the whitespace.
'''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:
 
 
<pre>
 
<pre>
 
function StripTrailingWhitespace()
 
function StripTrailingWhitespace()

Revision as of 08:07, 6 January 2011

Tip 878 Printable Monobook Previous Next

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, a user 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 a user 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 the user presses n they will continue their last search), and :nohl is used to switch off search highlighting (so trailing spaces will not be highlighted while the user types). 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

The following 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>

This is a similar function which similates the manual steps for removing the whitespace.

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

: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 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)


I modified one of the above scripts to let the user know if whitespace was found

" automatically remove trailing whitespace before write
function! StripTrailingWhitespace()
  normal mZ
  %s/\s\+$//e
  if line("'Z") != line(".")
    echo "Stripped whitespace\n"
  endif
  normal `Z
endfunction
autocmd BufWritePre *.cpp,*.hpp,*.i :call StripTrailingWhitespace()