Vim run autocmd on all filetypes EXCEPT

VimStripAutocmd

Vim 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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjerodsantoView Question on Stackoverflow
Solution 1 - VimjamessanView Answer on Stackoverflow
Solution 2 - VimwedgwoodView Answer on Stackoverflow
Solution 3 - VimevanView Answer on Stackoverflow
Solution 4 - VimSteve ChavezView Answer on Stackoverflow
Solution 5 - VimblueyedView Answer on Stackoverflow
Solution 6 - Vimxinyu yangView Answer on Stackoverflow