From 450ca247f397b1b9b059f389f6ee09397211304a Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 25 May 2019 17:42:39 +1200 Subject: Move functions into autoload This adds a dependency on Vim >=7.0. --- README.md | 2 +- autoload/strip_trailing_whitespace.vim | 109 +++++++++++++++++++++++++++++++ doc/strip_trailing_whitespace.txt | 4 +- plugin/strip_trailing_whitespace.vim | 114 +-------------------------------- 4 files changed, 114 insertions(+), 115 deletions(-) create mode 100644 autoload/strip_trailing_whitespace.vim diff --git a/README.md b/README.md index 11b56f0..f1e8618 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ because I could not find a plugin that did this in exactly the way I wanted: - Accept an optional range - Strip trailing lines as well as trailing spaces - Report what was changed, accurately -- Work with even very old Vim (>=6.0) +- Work with old Vim (>=7.0) - Work with a single `undo` - Don't move the cursor - Don't change the search pattern 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 diff --git a/doc/strip_trailing_whitespace.txt b/doc/strip_trailing_whitespace.txt index 6a79128..dc2a324 100644 --- a/doc/strip_trailing_whitespace.txt +++ b/doc/strip_trailing_whitespace.txt @@ -1,4 +1,4 @@ -*strip_trailing_whitespace.txt* For Vim version 6.0 Last change: 2018 Jul 20 +*strip_trailing_whitespace.txt* For Vim version 7.0 Last change: 2019 May 25 DESCRIPTION *strip_trailing_whitespace* @@ -13,7 +13,7 @@ because I could not find a plugin that did this in exactly the way I wanted: - Accept an optional range - Strip trailing lines as well as trailing spaces - Report what was changed, accurately -- Work with even very old Vim (>=6.0) +- Work with old Vim (>=7.0) - Work with a single |undo| - Don't move the cursor - Don't change the search pattern diff --git a/plugin/strip_trailing_whitespace.vim b/plugin/strip_trailing_whitespace.vim index f02f7a0..2cbfb5d 100644 --- a/plugin/strip_trailing_whitespace.vim +++ b/plugin/strip_trailing_whitespace.vim @@ -9,121 +9,11 @@ if exists('loaded_strip_trailing_whitespace') || &compatible finish endif -if !has('user_commands') || v:version < 600 +if v:version < 700 finish endif let 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 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 - " User command for the above command! -range=% StripTrailingWhitespace - \ call Strip(, ) + \ call strip_trailing_whitespace#Strip(, ) -- cgit v1.2.3