Як увімкнути / вимкнути аугруппу на льоту?


13

Я створив augroupсвоє, .vimrcщо містить декілька, autocmdі мені потрібно вмикати / вимикати їх autocommandна льоту.

Ідея полягає у створенні відображення (скажімо, F4наприклад), яке б дало змогу цим автокомандам при натисканні одного разу та відключити їх при натисканні знову, не потребуючи джерела файлу чи перезавантаження .vimrc.

Як я можу це зробити?

Відповіді:


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для виклику функції.

EDIT : Карл Інгве Лервег запропонував вдосконалену версію цієї функції, яка зменшила кількість рядків коду, я вважав, що було б добре зберегти обидві версії, коли перша ще працює, може бути легше зрозуміти дебютант 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

У цій версії група завжди скидається, і якщо вона не була включена, вона заповнюється потрібними автокомандами


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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.