我想在两个事件上触发一个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中的一种,并且发生在此缓冲区上的写操作。

可以提供任何帮助。

#1 楼

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

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


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

:help autocmd-buflocal


更新

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

事件发生时,设置了“文件类型”选项。然后,可以将BufWritePost事件的响应设置为'filetype'的值,如以下示例所示。与其他解决方案相比,它的优点是只能创建一个自动命令。

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


评论


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

–flashburn
15年7月17日在15:30

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

– VanLaser
15年7月17日在15:41

上面的FileType autocmd将为您使用正确文件类型打开的每个文件触发,并将为每个文件设置本地缓冲区事件。因此,如果运行:wa,vim将在保存到文件之前为每个缓冲区运行已注册的事件。

– VanLaser
15年7月17日在15:48



因此,如果您打开5个Python文件,则将有5个autocmd而不是一个,所有这些都在写入时。然后,如果说其中有3个文件被隐藏,然后再次显示,则将重新触发FileType,以便在写入时再获得3个autocmds。这真是太棒了,我想知道为什么我没有提出这个解决方案。 :)

–lcd047
15年7月17日在16:59

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

–lcd047
15年7月17日在17:34

#2 楼

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



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')