Vim run autocmd on all filetypes EXCEPT
VimStripAutocmdVim Problem Overview
I have a Vim autocmd that removes trailing whitespace in files before write. I want this almost 100% of the time, but there are a few filetypes that I'd like it disabled. Conventional wisdom is to list the filetypes you want an autocmd to run against in a comma-separated list, eg:
autocmd BufWritePre *.rb, *.js, *.pl
But in this case that would be onerous.
Is there a way to match an autocmd pattern against all files EXCEPT those matching the pattern? I cannot find the equivalent to a NOT matcher in the docs.
Vim Solutions
Solution 1 - Vim
*.rb
isn't a filetype. It's a file pattern. ruby
is the filetype and could even be set on files that don't have a .rb
extension. So, what you most likely want is a function that your autocmd calls to both check for filetypes which shouldn't be acted on and strips the whitespace.
fun! StripTrailingWhitespace()
" Don't strip on these filetypes
if &ft =~ 'ruby\|javascript\|perl'
return
endif
%s/\s\+$//e
endfun
autocmd BufWritePre * call StripTrailingWhitespace()
Building on evan's answer, you could check for a buffer-local variable and determine whether to do the strip using that. This would also allow you to do one-off disabling if you decided that you don't want to strip a buffer that's a filetype you normally would strip.
fun! StripTrailingWhitespace()
" Only strip if the b:noStripeWhitespace variable isn't set
if exists('b:noStripWhitespace')
return
endif
%s/\s\+$//e
endfun
autocmd BufWritePre * call StripTrailingWhitespace()
autocmd FileType ruby,javascript,perl let b:noStripWhitespace=1
Solution 2 - Vim
Another choice of one line way:
let blacklist = ['rb', 'js', 'pl']
autocmd BufWritePre * if index(blacklist, &ft) < 0 | do somthing you like | endif
Then you can do something you like for all filetypes except those in blacklist.
Solution 3 - Vim
A good way would be to set a local variable for the one filetype to true. Then set the automcommand if that variable is false (if set for everything else) or if it exists at all (no need to preset it).
autocmd BufWritePre *.foo let b:foo=true
if !exists("b:foo")
autocmd ...
endif
changed variable prefixes based on comment
Solution 4 - Vim
You can do the except on the same regexp:
autocmd BufWritePre *\(.out\|.diffs\)\@<! <your_command>
That will do <your_command>
for all files extensions except for .out
or .diffs
.
Solution 5 - Vim
This works for Syntax
autocommands, where the pattern (<match>
) is just the filetype. It excludes any rst
files:
au Syntax *\(^rst\)\@<! …
Solution 6 - Vim
Our .vimrc config file runs only once on startup. So if you put an if test at this time, it won't work, because no python file is then currently being edited.
But you can use .vimrc to set up an automatic behaviour: something that vim will do each time it encounters a special condition. The condition can be in your case: "A new file is being editing, and its file type is 'python'". See :h :au