Как включить / отключить группу на лету?

13

Я создал augroupв моем .vimrcсодержащий несколько , autocmdи мне нужно , чтобы включить / отключить их autocommandна лету.

Идея состоит в том, чтобы создать отображение (скажем, F4например), которое включало бы эти автокоманды при однократном нажатии и отключало их при повторном нажатии без необходимости создания исходного файла или перезагрузки .vimrc.

Как я могу это сделать?

statox
источник

Ответы:

17

Опираясь на ваш ответ: вам не нужна переменная для сохранения состояния 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
1
Вы даже можете разделить группу на 2 части и удалить elseветку, выполнив autocmd!безоговорочно в начале.
VanLaser
@VanLaser Не могли бы вы? Вы пытались сделать это таким образом? Подсказка: что бы exists('#TestAutoGroup#BufEnter')вернуться после autocmd!?
Сато Катсура
1
Примерно так, может быть: pastebin.com/HEEYjseR
VanLaser,
1
@VanLaser А затем вы можете сделать эту операцию без сохранения состояния, избавившись от этой глобальной переменной. Возможно, есть функция, которая может позаботиться об этом. Эта функция может потребоваться ... Ой. Правильно. :)
Сато Кацура
9

(Я действительно понял это сам, но так как я не нашел ответа на этом сайте, я подумал, что это может быть полезно для создания вопроса с самостоятельным ответом )

Для этого можно создать следующую функцию и поместить ее в .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для вызова функции.

РЕДАКТИРОВАТЬ : Карл Ингве Lervåg предложил улучшенную версию этой функции, которая уменьшила количество строк кода, я чувствовал, что было бы хорошо, чтобы обе версии, первая из которых все еще работает, может быть легче понять таким дебютантом vimscript, как я.

Вот улучшенная функция Карла, большое ему спасибо:

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

В этой версии группа всегда сбрасывается, и если она не была включена, она заполняется требуемыми автокомандами

statox
источник
7

Я считаю, что простой способ заключается в использовании глобальной переменной. Пример:

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
Плюсы: 1) Нет функции. 2) Может быть легко адаптирован для использования локальных переменных буфера / окна вместо глобальной переменной. 3) Простое картирование
Питер Ринкер
Хорошо. Спасибо, что поделились своим решением, я бы не подумал сделать это таким образом!
statox