I'm trying to write a snippet of VimL to allow the user to toggle the hilighting of unwanted trailing whitespace with a hotkey. (This is my first-ever Vim script, beyond copy-pasting things into my .vimrc
, so … grain of salt :P)
I wish for the ‘are we currently hilighting trailing whitespace?’ to be buffer-specific state; but I'm having a lot of trouble figuring out how autocommands interact with buffers.
For instance, here's my first stab at an augroup
of buffer-local autocmd
s:
augroup ExtraWhitespace
au!
au BufEnter <buffer=abuf> match ExtraWhitespace /\s\+$/
au InsertEnter <buffer=abuf> match ExtraWhitespace /\s\+\%#\@<!$/
au InsertLeave <buffer=abuf> match ExtraWhiteSpace /\s\+$/
augroup END
… unfortunately, this immediately trips up when invoked:
Error detected while processing function ToggleExtraWhitespace:
line 19:
E680: <buffer=0>: invalid buffer number
line 20:
E680: <buffer=0>: invalid buffer number
line 21:
E680: <buffer=0>: invalid buffer number
No matching autocommands
I don't understand why <abuf>
is 0
, when bufnr('%')
is 1
, or how to get the autocommands to execute for buffer 1
instead. (Of course 0
is invalid!)
For the moment, I've swapped out <buffer=abuf>
for *
; but this screws up the functionality of this function when there are multiple buffers loaded, and That Is Bad. So, any help figuring this out is welcome. /=
First, I don't know how It appears the the behavior for <buffer=abuf>
works. The documentation for it seems to be conflicting.<buffer=abuf>
was changed/fixed with patch 7.4.637, before It was causing problems even if used correctly. <buffer=abuf>
must only be used when an autocmd is running. So your function would probably have worked if you called it in VimEnter or BufAdd.
The following a modified version of what you attempted which doesn't use <buffer=abuf>
augroup ExtraWhitespace
autocmd! * <buffer>
autocmd BufEnter <buffer> match ExtraWhitespace /\s\+$/
autocmd InsertEnter <buffer> match ExtraWhitespace /\s\+\%#\@<!$/
autocmd InsertLeave <buffer> match ExtraWhitespace /\s\+$/
augroup END
The first things you should notice is that au!
has been replaced with autocmd! * <buffer>
. au!
shouldn't be there since this will remove all autocmd in the ExtraWhitespace group from all buffers. This means that you can only define it in one buffer. (autocmd! * <buffer>
only deletes the autocmds in the current buffer)
The second thing you should notice is that <buffer>
is used. This means that the autocmd will be created only for the current buffer when when the function is called. Buffer local autocmd must be called for each buffer that you want to define.
Other miscellaneous comments
You have
fun! HighlightExtraWhitespace()
if exists('b:ews') && b:ews == 1
"echom "-- Adding ExtraWhitespace hilighting"
highlight ExtraWhitespace ctermbg=red guibg=red
else
"echom "-- Removing ExtraWhitespace hilighting"
highlight clear ExtraWhitespace
endif
endfun
au ColorScheme * call HighlightExtraWhitespace()
Highlighting is global, so clearing it in one buffer is going to remove the highlight group everywhere. So its better to just leave the highlighting in place and redefine it every time the colorscheme changes.
autocmd ColorScheme * highlight ExtraWhitespace ctermbg=red guibg=red
It is recommended to use the long form of command names in scripts. (Short form used only for typing). The long form is more readable and easily identifiable, so au
would be come autocmd
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With