diff options
Diffstat (limited to 'autoload/strip_trailing_whitespace.vim')
-rw-r--r-- | autoload/strip_trailing_whitespace.vim | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/autoload/strip_trailing_whitespace.vim b/autoload/strip_trailing_whitespace.vim new file mode 100644 index 0000000..681016e --- /dev/null +++ b/autoload/strip_trailing_whitespace.vim @@ -0,0 +1,98 @@ +" Wrapper function to strip both horizontal and vertical trailing whitespace, +" return the cursor to its previous position, and report changes +function! strip_trailing_whitespace#Strip(start, end) abort + + " Save cursor position + let pos = getpos('.') + + " Whether we made changes + let changed = 0 + + " If we're going to the end, strip vertical space; we do this first so we + " don't end up reporting having trimmed lines that we deleted + if a:end == line('$') + let vertical = s:StripVertical() + let changed = changed || vertical > 0 + endif + + " Strip horizontal space + let horizontal = s:StripHorizontal(a:start, a:end) + let changed = changed || horizontal > 0 + + " Return the cursor + call setpos('.', pos) + + " Report what changed + let msg = horizontal.' trimmed' + if exists('vertical') + let msg = msg.', '.vertical.' deleted' + endif + echomsg msg + + " Return whether anything changed + return 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 stripped = 0 + + " Iterate through buffer + let num = a:start + while num <= line('$') && num <= a:end + + " If the line has trailing whitespace, strip it off and bump the count + let line = getline(num) + if line =~# '\s\+$' + call setline(num, substitute(line, '\s*$', '', '')) + let stripped = stripped + 1 + endif + + " Bump for next iteration + let num = num + 1 + + endwhile + + " Return the number of lines trimmed + return stripped + +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 eof = 1 + + " Iterate through buffer + let num = 1 + while num <= line('$') + + " If the line has any non-whitespace characters in it, update our pointer + " to the end of the file text + let line = getline(num) + if line =~# '\S' + let eof = num + endif + + " Bump for next iteration + let num = 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 stripped = line('$') - eof + if stripped + let range = (eof + 1).',$' + silent execute range.'delete' + endif + + " Return the number of lines deleted + return stripped + +endfunction |