在autocmd中是否可以进行AND事件?


21

我想autocmd 在两个事件上触发,但通常不会以某种方式触发它,即,如果其中一个事件发生,则触发autocmd。如果两个事件都发生,我想触发它​​。

例如:
常用的方法

autocmd BufWrite,BufRead *.c *.py *.h :call StripTrailingWhitespaces()

此代码将在BufWrite或BufRead上调用StripTrailingWhiteSpaces()

我想做类似的事情:

autocmd Filetype c,cpp,python AND BufWrite :call StripTrailingWhiteSpaces()

换句话说,autcmd当文件类型为c,cpp,python中的一种时触发,并在此缓冲区上进行写操作。

任何帮助表示赞赏。

Answers:


14

发生一个事件时,将执行自动命令命令。您希望在一系列事件发生后执行命令。一种方法是这样的:

autocmd FileType c,cpp,python
    \ autocmd BufWritePre <buffer> call StripTrailingWhiteSpaces()

<buffer>模式导致在写入当前缓冲区时触发自动命令。看到

:help autocmd-buflocal

更新资料

上面的解决方案非常简单,并且存在一些在注释中讨论的缺陷。这是解决这些缺陷中一些更完整的解决方案。它将自动命令放在一个组中,并在创建新命令之前删除BufWritePre自动命令(如果存在)。它仍然为每个缓冲区创建一个自动命令,但仅创建一个。

augroup TrailSpace
    autocmd FileType c,cpp,python
        \ autocmd! TrailSpace BufWritePost <buffer> call SkipTrailingWhiteSpaces()
augroup END

类似于lcd047发布的答案(现已删除)的另一种解决方案是,识别出发生FileType事件时,设置了'filetype'选项。然后,您可以根据“ filetype”的值来限制对BufWritePost事件的响应,如以下示例所示。与其他解决方案相比,它的优点是仅创建一个自动命令。

autocmd BufWritePre * if count(['c','cpp','python'],&filetype)
    \ | call SkipTrailingWhiteSpaces()
    \ | endif

如果要在当前打开的所有文件上运行此命令,即执行:wa怎么办?
flashburn 2015年

如果使用正确的文件类型打开了文件,则FileType答案中的autocmd将已经设置了第二个autocmd(BufWritePre),以在保存文件时触发。
VanLaser

1
FileType上面会火了自动命令每次你用正确的文件类型打开文件,并将设置一个缓冲区局部事件每个这些文件的。因此,如果运行:wa,vim将在保存到文件之前为每个缓冲区运行已注册的事件。
VanLaser

1
因此,如果您打开5个Python文件,则只有5 autocmds而不是一个s,全部在写入时。然后,如果说其中3个文件被隐藏,然后再次显示,FileType重新触发,那么autocmd在写入时还会多出3 s的时间。这真是太棒了,我想知道为什么我没有提出这个解决方案。:)
lcd047

1
性能不是问题。stripTrailingWhiteSpaces()但是,对同一文件多次运行该功能可能会产生意想不到的后果。同样,autocmd对于同一文件的同一事件,您拥有的事件越多,您遇到实际竞赛情况的可能性就越大。尝试搜索vim_dev档案以获取想法。再说一遍,我知道什么,它可能对您有用,对吗?
lcd047

4

更一般而言,如果您不知道首先发生哪个事件,则可以使用帮助程序来跟踪每个事件何时触发,并且仅在最后一个事件触发时执行命令:

function StripTrailingWhiteSpacesIfReady(event) abort
  if !exists('b:events_for_whitespace')
    let b:events_for_whitespace = {}
  endif
  let b:events_for_whitespace[a:event] = 1
  if has_key(b:events_for_whitespace, 'FileType') && has_key(b:events_for_whitespace, 'Buf')
    " Strip trailing whitespace
    %s/\m\s\+$//
  endif
endfunction
autocmd Filetype c,cpp,python call StripTrailingWhiteSpacesIfReady('FileType')
autocmd BufWrite,BufRead * StripTrailingWhiteSpacesIfReady('Buf')
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.