" " strip_trailing_whitespace.vim: User command to strip both horizontal and " vertical whitespace in a buffer, with optional range, reporting both " accurately and restoring the cursor afterwards. " " Author: Tom Ryder " License: Same as Vim itself " if exists('g:loaded_strip_trailing_whitespace') || &compatible finish endif if !has('user_commands') || v:version < 600 finish endif let g:loaded_strip_trailing_whitespace = 1 " Wrapper function to strip both horizontal and vertical trailing whitespace, " return the cursor to its previous position, and report changes function s:Strip(start, end) abort " Save cursor position let l:line = line('.') let l:col = col('.') " Strip horizontal space let l:horizontal = s:StripHorizontal(a:start, a:end) let l:msg = l:horizontal.' trimmed' let l:changed = l:horizontal > 0 " If we're going to the end, strip vertical space if a:end == line('$') let l:vertical = s:StripVertical() let l:msg = l:msg.', '.l:vertical.' deleted' let l:changed = l:changed || l:vertical > 0 endif " Return the cursor call s:Cursor(l:line, l:col) " Report what changed echomsg l:msg " Return whether anything changed return l:changed endfunction " Strip horizontal trailing whitespace, return the number of lines changed function s:StripHorizontal(start, end) abort " Start a count of lines trimmed let l:count = 0 " Iterate through buffer let l:num = 1 while l:num <= line('$') " If the line has trailing whitespace, strip it off and bump the count let l:line = getline(l:num) if l:line =~# '\s\+$' call setline(l:num, substitute(l:line, '\s*$', '', '')) let l:count = l:count + 1 endif " Bump for next iteration let l:num = l:num + 1 endwhile " Return the number of lines trimmed return l:count endfunction " Strip trailing vertical whitespace, return the number of lines changed function s:StripVertical() abort " Store the number of the last line we found with non-whitespace characters " on it; start at 1 because even if it's empty it's never trailing let l:eof = 1 " Iterate through buffer let l:num = 1 while l:num <= line('$') " If the line has any non-whitespace characters in it, update our pointer " to the end of the file text let l:line = getline(l:num) if l:line =~# '\S' let l:eof = l:num endif " Bump for next iteration let l:num = l:num + 1 endwhile " Get the number of lines to delete; if there are any, build a range and " remove them with :delete, suppressing its normal output (we'll do it) let l:count = line('$') - l:eof if l:count let l:range = (l:eof + 1).',$' silent execute l:range.'delete' endif " Return the number of lines deleted return l:count endfunction " Position the cursor; use cursor() if we have it, :normal if not (Vim 6.0) function s:Cursor(line, col) abort if exists('*cursor') return cursor(a:line, a:col) else execute 'normal! '.a:line.'G'.a:col.'|' return 1 endif endfunction " User command for the above command! -range=% StripTrailingWhitespace \ call Strip(, )