自动命令在多个文件保存后执行一次(:wa)

时间:2011-12-23 12:24:19

标签: vim

我在我的插件中为BufWritePost进行了autocmd。 (我在此自动命令中更新整个项目的标签,这是插件Indexer.tar.gz)

有时我需要保存很多文件(我做“:wa”)。当然,我的每个文件都会调用我的autocmd。

我想在ALL filesaves之后调用它。比方说,如果我有20个未保存的缓冲区,我会执行:wa,并且在保存最后一个缓冲区后,我的autocmd只调用一次。 有没有办法做到这一点?

实际上这个插件足够智能,如果可能的话,它会在背景中启动ctags,但无论如何这有点烦人。

2 个答案:

答案 0 :(得分:1)

没有自动命令的一种方法:

function! MyFunction()
    "" Save all buffers.
    bufdo wa  
    "" Run your command once.
    ... your command ... 
endfunction

nnoremap ,wa :call MyFunction()<CR>

在正常模式下推送,wa(不带冒号),所有缓冲区都会被保存,之后它会运行你的命令。

编辑:修改函数以返回上一个缓冲区,因为bufdo更改了它:

function! MyFunction()
    "" Save number of current buffer.
    let l:current_buffer = bufnr("%")

    "" Save all buffers.
    bufdo wa  

    "" Bufdo probably changed the buffer, so return to where we were before running previous command.
    execute "buffer " . l:current_buffer

    "" Run your command once.
    ... your command ... 
endfunction

答案 1 :(得分:0)

CursorHold事件被触发&#34;当用户在“更新时间”&#39;&#34;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39; ; (默认为4秒)。除非用户继续输入,否则在保存文件后将触发此事件updatetime毫秒。 BufWrite自动命令可以暂时使此settimg非常低,例如50ms,并为CursorHold添加自禁用自动命令。 BufWrite自动命令可以检查它是否已经配置了CursorHold处理程序,以避免多次添加它。

为了使它具有一定的灵活性,我将这个构造定制为fire {({3}})事件:当检测到第一个保存时,然后对于&#34;保存批处理中的每个文件&#34;最后当超时发生时。这样我的其他脚本就可以独立处理任何这些事件。

实现:

function! s:WriteTimeoutSchedule()
  if !exists("#WriteTimeout#CursorHold")
    let s:oldUpdateTime = &ut
    set updatetime=50
    augroup WriteTimeout
      au CursorHold * call s:WriteTimeoutFire()
    augroup END
    do User WriteTimeoutPre
  endif
  do User WriteTimeoutEach
endfunction

function! s:WriteTimeoutFire()
  do User WriteTimeoutPost
  au! WriteTimeout
  let &ut=s:oldUpdateTime
endfunction

aug WriteTimeoutSupport
  au!
  au BufWrite * call s:WriteTimeoutSchedule()
aug END

用法示例:User