1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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
|