aboutsummaryrefslogtreecommitdiff
path: root/autoload/strip_trailing_whitespace.vim
diff options
context:
space:
mode:
Diffstat (limited to 'autoload/strip_trailing_whitespace.vim')
-rw-r--r--autoload/strip_trailing_whitespace.vim98
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