我在augroup中创建了一个.vimrc,其中包含多个autocmd,我需要即时启用/禁用这些autocommand

想法是创建一个映射(例如说F4),该映射将在一次按下时启用这些自动命令,而在再次按下时禁用这些自动命令,而不必提供文件或重新加载.vimrc

我该怎么办?

#1 楼

以您的答案为基础:不需要变量来保持augroup的状态,只要您知道属于该组的exists()中的至少一个,就可以使用autocmd

function! ToggleTestAutoGroup()
    if !exists('#TestAutoGroup#BufEnter')
        augroup TestAutoGroup
            autocmd!
            autocmd BufEnter   * echom "BufEnter " . bufnr("%")
            autocmd BufLeave   * echom "BufLeave " . bufnr("%")
            autocmd TabEnter   * echom "TabEnter " . tabpagenr()
            autocmd TabLeave   * echom "TabLeave " . tabpagenr()
        augroup END
    else
        augroup TestAutoGroup
            autocmd!
        augroup END
    endif
endfunction

nnoremap <F4> :call ToggleTestAutoGroup()<CR>


评论


嘿,很酷的改善方法!我不知道你能做到

–statox♦
15年7月31日在18:20

您甚至可以通过运行autocmd将组分为两部分并删除else分支!一开始无条件。

– VanLaser
15年7月31日在18:58



@VanLaser可以吗?您是否尝试过这种方式?提示:autocmd之后会返回什么存在的内容('#TestAutoGroup#BufEnter')?

–佐藤桂
15年7月31日在19:08



这样的事情,也许是:pastebin.com/HEEYjseR

– VanLaser
15年7月31日在19:20

@VanLaser然后,您可以摆脱该全局变量,使该操作变为无状态。也许有一个功能可以解决这个问题。该功能可能需要...哦。对。 :)

–佐藤桂
2015年8月1日13:17

#2 楼

(我实际上是自己弄清楚的,但是由于我没有在该站点上找到答案,所以我认为这对于创建一个自我回答的问题可能很有用)。

这样做可以创建以下函数并将其放在.vimrc中:

function! ToggleTestAutoGroup()
    if !exists('g:TestAutoGroupMarker')
        let g:TestAutoGroupMarker = 1
    endif

    " Enable if the group was previously disabled
    if (g:TestAutoGroupMarker == 1)
        let g:TestAutoGroupMarker = 0

        " actual augroup
        augroup TestAutoGroup
            autocmd! BufEnter   * echom "BufEnter " . bufnr("%")
            autocmd! BufLeave   * echom "BufLeave " . bufnr("%")
            autocmd! TabEnter   * echom "TabEnter " . tabpagenr()
            autocmd! TabLeave   * echom "TabLeave " . tabpagenr()
        augroup END
    else    " Clear the group if it was previously enabled
        let g:TestAutoGroupMarker = 1

        " resetting the augroup
        augroup TestAutoGroup
            autocmd!
        augroup END
    endif
endfunction


该函数创建一个变量,用于确定该组之前是否已启用。

未启用时,该组将填充所需的自动命令。如果先前启用了该组,则可以使用autocmd!对其进行“重置”,即删除先前在其中输入的命令。

相关文档在这里

最后可以创建以下映射:

nnoremap <F4> :call ToggleTestAutoGroup()<CR>


使用F4调用该函数。

编辑:Karl YngveLervåg建议对此函数进行改进减少了代码行的数量,我觉得最好让两个版本的第一个版本仍在工作,也许像我这样的vimscript初学者更容易理解。

这是Karl改进的功能,很多多亏了他:

function! ToggleTestAutoGroup()
    " Switch the toggle variable
    let g:TestAutoGroupToggle = !get(g:, 'TestAutoGroupToggle', 1)

    " Reset group
    augroup TestAutoGroup
        autocmd!
    augroup END

    " Enable if toggled on
    if g:TestAutoGroupToggle
        augroup TestAutoGroup
            autocmd! BufEnter   * echom "BufEnter " . bufnr("%")
            autocmd! BufLeave   * echom "BufLeave " . bufnr("%")
            autocmd! TabEnter   * echom "TabEnter " . tabpagenr()
            autocmd! TabLeave   * echom "TabLeave " . tabpagenr()
        augroup END
    endif
endfunction


在此版本中,该组始终被重置,如果未启用该组,则使用所需的自动命令填充该组。

#3 楼

我发现简单的方法是使用全局变量。示例:

augroup TestAutoGroup
  autocmd!
  autocmd BufEnter * |
        \ if get(g:, 'toggle_autocmd', 1) |
        \   echom "BufEnter " . bufnr("%") |
        \ endif
augroup END

nnoremap <f4> :<c-u>let g:toggle_autocmd = !get(g:, 'toggle_autocmd', 1)<cr>


有关更多帮助,请参见:

:h g:
:h get()
:h :if
:h :bar
:h line-continuation


评论


我不确定您为什么认为这是一种简单的方法:我不是vimscript大师,所以您的语法对我来说有点过于复杂。您的方法有哪些优点?

–statox♦
15年7月31日在19:28

优点:1)没有功能。 2)可以轻松地调整为使用缓冲区/窗口局部变量,而不是全局变量。 3)简单的映射

– Peter Rincker
15年7月31日在20:32

好。感谢您分享您的解决方案,我不会想到要这样做!

–statox♦
15年8月1日在9:01