" " strip_trailing_whitespace.vim: User-defined key mapping to strip trailing " whitespace in the whole document. " " Author: Tom Ryder " License: Same as Vim itself " if exists('g:loaded_strip_trailing_whitespace') || &compatible finish endif let g:loaded_strip_trailing_whitespace = 1 " Define function for stripping whitespace function! s:StripTrailingWhitespace() " Line number of last line that had non-whitespace characters on it let l:cutoff = 0 " Tracking lines trimmed between non-whitespace lines and then totalling let l:trimmed_buffer = 0 let l:trimmed = 0 " Line number of the file's last line let l:last = line('$') " Iterate over the lines let l:li = 1 while l:li <= l:last " Get the line text let l:line = getline(l:li) " If the current line contains trailing whitespace, substitute it out if l:line =~# '\s\+$' call setline(l:li, substitute(l:line, '\s\+$', '', '')) let l:trimmed_buffer = l:trimmed_buffer + 1 endif " If this line has any non-whitespace characters on it, update our cutoff " point using its index, and push the trimmed lines we've counted since " the last non-whitespace line onto the trimmed total if l:line =~# '\S' let l:cutoff = l:li let l:trimmed = l:trimmed + l:trimmed_buffer let l:trimmed_buffer = 0 endif " Increment the line counter for the next iteration let l:li = l:li + 1 endwhile " If the last non-whitespace line was before the last line proper, we can " delete all lines after it let l:deleted = 0 if l:cutoff < l:last " Get the current line and column so we can return to it " (Yes I know about winsaveview() and winrestview(); I want this to work " even on very old versions of Vim if possible) let l:cursor_line = line('.') let l:cursor_col = col('.') " Delete the rest of the lines, which will move the cursor silent execute l:cutoff + 1 . ',$ delete _' " Return the cursor to the saved position (Vim 6.0 fallback) if exists('*cursor') call cursor(l:cursor_line, l:cursor_col) else execute 'normal! ' \ . l:cursor_line . 'G' \ . l:cursor_col . '|' endif " Record the number of lines deleted let l:deleted = l:last - l:cutoff endif " Print what we did echomsg l:trimmed . ' trimmed, ' . l:deleted . ' deleted' " Return the number of affected lines return l:trimmed + l:deleted endfunction " Create mapping proxy to the function just defined noremap \ StripTrailingWhitespace \ :call StripTrailingWhitespace()