¿Cómo habilitar / deshabilitar un augroup sobre la marcha?

13

Creé un augroupen mi que .vimrccontiene varios autocmdy necesito habilitar / deshabilitar estos autocommandsobre la marcha.

La idea es crear una asignación (digamos, F4por ejemplo) que habilitaría estos comandos automáticos cuando se presionen una vez y los deshabilitará cuando se presionen nuevamente sin tener que buscar un archivo o volver a cargarlos .vimrc.

¿Cómo puedo hacer eso?

statox
fuente

Respuestas:

17

Sobre la base de su respuesta: no necesita una variable para mantener el estado del augroup, puede usar exists()para eso, siempre que conozca al menos uno de los autocmds que forman parte del grupo:

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>
Sato Katsura
fuente
¡Hola, genial forma de mejorarlo! No sabía que puedes hacer eso.
statox
1
Incluso podría dividir el grupo en 2 partes y eliminar la elserama, ejecutando autocmd!incondicionalmente al principio.
VanLaser
@VanLaser ¿Podrías? ¿Has intentado hacerlo de esa manera? Sugerencia: ¿qué exists('#TestAutoGroup#BufEnter')volvería después de un autocmd!?
Sato Katsura
1
Algo como esto, tal vez: pastebin.com/HEEYjseR
VanLaser
1
@VanLaser Y luego podría hacer que esa operación no tenga estado, deshaciéndose de esa variable global. Tal vez hay una función que podría encargarse de eso. Esa función podría necesitar ... Ow. Derecha. :)
Sato Katsura
9

(De hecho, lo descubrí yo mismo, pero como no encontré una respuesta en este sitio, pensé que podría ser útil para crear una pregunta con respuesta propia )

Para hacerlo, es posible crear la siguiente función y ponerla en .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

La función crea una variable utilizada para determinar si el grupo estaba habilitado previamente o no.

Cuando no estaba habilitado, el grupo se llena con los comandos automáticos deseados. Si el grupo estaba habilitado previamente, lo usamos autocmd!para "restablecerlo", es decir, eliminar el comando que ingresó anteriormente.

Una documentación relevante está aquí

Finalmente, es posible crear el siguiente mapeo:

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

usar F4para llamar a la función.

EDITAR : Karl Yngve Lervåg sugirió una versión mejorada de esta función que redujo el número de líneas de código, sentí que sería bueno mantener ambas versiones, la primera todavía funcionando, tal vez más fácil de entender por un debutante vimscript como yo.

Aquí está la función mejorada de Karl, muchas gracias a él:

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

En esta versión, el grupo siempre se restablece y, si no estaba habilitado, se completa con los comandos automáticos deseados

statox
fuente
7

Encuentro que la manera fácil es usar una variable global. Ejemplo:

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>

Para más ayuda ver:

:h g:
:h get()
:h :if
:h :bar
:h line-continuation
Peter Rincker
fuente
No estoy seguro de entender por qué crees que es una manera fácil: no soy un maestro de vimscript, por lo que tu sintaxis me parece un poco complicada. ¿Cuáles son las ventajas de su método?
statox
Pros: 1) Sin función. 2) Se puede adaptar fácilmente para usar un búfer / ventana de variables locales en lugar de una variable global. 3) Mapeo simple
Peter Rincker
Okay. ¡Gracias por compartir su solución, no hubiera pensado hacerlo de esta manera!
statox