Consider the following vimscript:
function! DecideWhetherToStrip()
let l:search = @/
" Check if a file being opened has trailing spaces in the first place.
let b:dostrip = !search('\s\+$', 'npw')
let @/ = l:search
endfunction
function! StripTrailingWhitespace()
if b:dostrip
let l:search = @/
let l:winview = winsaveview()
%s/\s\+$//e " Kill spaces at EOL
%s/\($\n\s*\)\+\%$//e " Kill lines at EOF
let @/ = l:search
call winrestview(l:winview)
endif
endfunction
augroup whitespace
autocmd!
autocmd BufReadPost * call DecideWhetherToStrip()
autocmd BufWritePre * call StripTrailingWhitespace()
augroup END
The StripTrailingWhitespace
function is probably familiar to many people as I've mostly stolen it from the internet, but the DecideWhetherToStrip
and the b:dostrip
variable were put together by me, just now.
The intention of this code is that I want to detect whether a newly opened file contains trailing whitespace, and then only strip trailing whitespace if the file didn't have any to begin with. This is because I need to edit certain files that actually require trailing whitespace, but for the most part I want files to start clean and stay clean.
My question is: does this code work the way I think it does?
It seems to work in my preliminary testing but I'm worried that there will be unexpected surprises down the line, in certain corner cases. Like what if I have two files open, one with b:dostrip
set to 1
, and one 0
. How does StripTrailingWhitespace
know which buffer it's operating on? What if two files are modified and I call :wall!
, is autocmd
smart enough to call StripTrailingWhitespace
once each with each buffer active? Or will I run into issues where StripTrailingWhitespace
will only be called once with the setting from one buffer but will actually modify both buffers?
Are there any other failure modes to this code I should be wary of?
Thanks.
b:foo
is local to whatever buffer is the current buffer and yes, your autocommands will run for every file.