Vim 对所有文件类型运行 autocmd,除了

我有一个 Vim autocmd,它在写之前删除文件中的尾随空格。我希望这几乎100% 的时间,但有一些文件类型,我希望它禁用。传统的做法是在逗号分隔的列表中列出您希望 autocmd 运行的文件类型,例如:

autocmd BufWritePre *.rb, *.js, *.pl

但在这种情况下,这将是繁重的。

有没有一种方法可以将 autocmd 模式与所有文件进行匹配,但匹配该模式的文件除外?我找不到相当于一个不匹配的文件。

20272 次浏览

*.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

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

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.

This works for Syntax autocommands, where the pattern (<match>) is just the filetype. It excludes any rst files:

au Syntax *\(^rst\)\@<! …

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

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.