Comment activer / désactiver un augroup à la volée?

13

J'ai créé un augroupdans mon .vimrccontenant plusieurs autocmdet je dois les activer / désactiver autocommandà la volée.

L'idée est de créer un mappage (disons F4par exemple) qui activerait ces commandes automatiques une fois pressées et les désactiverait une nouvelle fois sans avoir à sourcener un fichier ou recharger le fichier .vimrc.

Comment puis je faire ça?

statox
la source

Réponses:

17

En s'appuyant sur votre réponse: vous n'avez pas besoin d'une variable pour garder l'état de la augroup, vous pouvez l'utiliser exists()pour cela, à condition que vous connaissiez au moins l'un des autocmds qui font partie du groupe:

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
la source
Hé cool pour l'améliorer! Je ne savais pas que tu pouvais faire ça.
statox
1
Vous pouvez même diviser le groupe en 2 parties et supprimer la elsebranche, en exécutant autocmd!inconditionnellement au début.
VanLaser
@VanLaser Pourriez-vous? Avez-vous essayé de le faire de cette façon? Astuce: que exists('#TestAutoGroup#BufEnter')reviendrait après un autocmd!?
Sato Katsura
1
Quelque chose comme ça, peut-être: pastebin.com/HEEYjseR
VanLaser
1
@VanLaser Et alors vous pourriez rendre cette opération sans état, en vous débarrassant de cette variable globale. Il y a peut-être une fonction qui pourrait s'en occuper. Cette fonction pourrait devoir ... Ow. Droite. :)
Sato Katsura
9

(J'ai en fait compris par moi-même mais comme je n'ai pas trouvé de réponse sur ce site, j'ai pensé que cela pourrait être utile pour créer une question auto-répondue )

Pour ce faire, il est possible de créer la fonction suivante et de la placer dans .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 fonction crée une variable utilisée pour déterminer si le groupe a été précédemment activé ou non.

Lorsqu'il n'était pas activé, le groupe est rempli avec les autocommandes souhaitées. Si le groupe était précédemment activé, nous l'utilisons autocmd!pour le "réinitialiser", c'est-à- dire en supprimant la commande précédemment entrée.

Une documentation pertinente est ici

Enfin, il est possible de créer la cartographie suivante:

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

utiliser F4pour appeler la fonction.

EDIT : Karl Yngve Lervåg a suggéré une version améliorée de cette fonction qui réduisait le nombre de lignes de code, je pensais qu'il serait bon de garder les deux versions, la première fonctionnant toujours, peut-être plus facile à comprendre par un débutant vimscript comme moi.

Voici la fonction améliorée de Karl, merci beaucoup à lui:

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

Dans cette version, le groupe est toujours réinitialisé, et s'il n'était pas activé, il est rempli avec les autocommandes souhaitées

statox
la source
7

Je trouve que le moyen le plus simple est d'utiliser une variable globale. Exemple:

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>

Pour plus d'aide, voir:

:h g:
:h get()
:h :if
:h :bar
:h line-continuation
Peter Rincker
la source
Je ne suis pas sûr de comprendre pourquoi vous pensez que c'est un moyen facile: je ne suis pas un maître vimscript, donc votre syntaxe me semble un peu trop compliquée. Quels sont les avantages de votre méthode?
statox
Avantages: 1) Aucune fonction. 2) Peut facilement être adapté pour utiliser une variable locale tampon / fenêtre au lieu d'une variable globale. 3) Cartographie simple
Peter Rincker
D'accord. Merci d'avoir partagé votre solution, je n'aurais pas pensé à le faire de cette façon!
statox