aboutsummaryrefslogtreecommitdiff
path: root/autoload
diff options
context:
space:
mode:
authorTom Ryder <tom@sanctum.geek.nz>2019-05-25 17:42:39 +1200
committerTom Ryder <tom@sanctum.geek.nz>2019-05-25 17:42:39 +1200
commit450ca247f397b1b9b059f389f6ee09397211304a (patch)
treeb3eacc2cfed1a9adfae7f612d2fb6a45662a9b7c /autoload
parentMerge branch 'hotfix/v2.1.1' into develop (diff)
downloadvim-strip-trailing-whitespace-450ca247f397b1b9b059f389f6ee09397211304a.tar.gz
vim-strip-trailing-whitespace-450ca247f397b1b9b059f389f6ee09397211304a.zip
Move functions into autoload
This adds a dependency on Vim >=7.0.
Diffstat (limited to 'autoload')
-rw-r--r--autoload/strip_trailing_whitespace.vim109
1 files changed, 109 insertions, 0 deletions
diff --git a/autoload/strip_trailing_whitespace.vim b/autoload/strip_trailing_whitespace.vim
new file mode 100644
index 0000000..f7292b6
--- /dev/null
+++ b/autoload/strip_trailing_whitespace.vim
@@ -0,0 +1,109 @@
+" 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 line = line('.')
+ let col = col('.')
+
+ " 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 s:Cursor(line, col)
+
+ " 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
+
+" 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