Jak włączyć / wyłączyć augroup w locie?

13

I stworzył augroupw moim .vimrczawierający kilka autocmdi muszę włączyć / wyłączyć je autocommandw locie.

Chodzi o to, aby utworzyć mapowanie (powiedzmy F4na przykład), które włączałoby te automatyczne polecenia po jednokrotnym naciśnięciu i wyłączało je po ponownym naciśnięciu bez konieczności pobierania pliku lub przeładowywania .vimrc.

Jak mogę to zrobić?

statox
źródło

Odpowiedzi:

17

Opierając się na swojej odpowiedzi: nie potrzebujesz zmiennej, aby zachować stan augroup, możesz exists()do tego użyć , pod warunkiem, że znasz przynajmniej jeden z elementów autocmdnależących do grupy:

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
źródło
Hej fajny sposób, aby to poprawić! Nie wiedziałem, że możesz to zrobić.
statox
1
Możesz nawet podzielić grupę na 2 części i usunąć elsegałąź, uruchamiając autocmd!bezwarunkowo na początku.
VanLaser
@VanLaser Mógłbyś? Próbowałeś to zrobić w ten sposób? Wskazówka: co exists('#TestAutoGroup#BufEnter')wróci po autocmd!?
Sato Katsura
1
Coś w tym stylu, może: pastebin.com/HEEYjseR
VanLaser
1
@VanLaser A potem możesz uczynić tę operację bezstanową, pozbywając się tej zmiennej globalnej. Być może istnieje funkcja, która mogłaby się tym zająć. Ta funkcja może wymagać ... Ow. Dobrze. :)
Sato Katsura
9

(Właściwie to sam to wymyśliłem, ale ponieważ nie znalazłem odpowiedzi na tej stronie, pomyślałem, że może to być przydatne do stworzenia pytania z odpowiedzią )

W tym celu można utworzyć następującą funkcję i umieścić ją w .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

Funkcja tworzy zmienną używaną do ustalenia, czy grupa była wcześniej włączona, czy nie.

Gdy nie jest włączona, grupa jest zapełniana poszukiwanymi poleceniami automatycznymi. Jeśli grupa była wcześniej włączona, używamy jej autocmd!do „resetowania”, tj. Usuwania wcześniej wprowadzonego polecenia.

Odpowiednia dokumentacja jest tutaj

Wreszcie można utworzyć następujące mapowanie:

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

do F4wywołania funkcji.

EDYCJA : Karl Yngve Lervåg zasugerował ulepszoną wersję tej funkcji, która zmniejszyła liczbę wierszy kodu, uważam, że dobrze byłoby zachować obie wersje, ponieważ pierwsza nadal działa, być może łatwiejsza do zrozumienia dla takiego debiutanta vimscript jak ja.

Oto ulepszona funkcja Karla, wiele dzięki niemu:

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

W tej wersji grupa jest zawsze resetowana, a jeśli nie została włączona, jest zapełniana poszukiwanymi poleceniami automatycznymi

statox
źródło
7

Uważam, że najłatwiejszym sposobem jest użycie zmiennej globalnej. Przykład:

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>

Aby uzyskać więcej pomocy, zobacz:

:h g:
:h get()
:h :if
:h :bar
:h line-continuation
Peter Rincker
źródło
Nie jestem pewien, czy rozumiesz, dlaczego uważasz, że jest to łatwy sposób: nie jestem mistrzem vimscript, więc twoja składnia wydaje mi się nieco skomplikowana. Jakie są zalety twojej metody?
statox
Plusy: 1) Brak funkcji. 2) Można łatwo dostosować do używania zmiennych lokalnych bufor / okno zamiast zmiennej globalnej. 3) Proste mapowanie
Peter Rincker
Dobrze. Dziękujemy za podzielenie się swoim rozwiązaniem, nie pomyślałbym o zrobieniu tego w ten sposób!
statox