Mam autocmd dla plików TeX i Markdown, aby automatycznie zapisać plik. Nic niezwykłego:
autocmd CursorHold *.tex,*.md w
Jednak, jak niestandardowe ustawienia dla tych plików wzrosła, podzielić je na ftplugin/tex.vim
a ftplugin/markdown.vim
:
" ftplugin/tex.vim
autocmd CursorHold *.tex w
" ftplugin/markdown.vim
autocmd CursorHold *.md w
Teraz te pliki są pozyskiwane tylko dla odpowiednich plików, więc dopasowanie wzorca jest zbędne. Najwyraźniej autocmd
s może być lokalnie buforowane. Od :h autocmd-buffer-local
:
Buffer-local autocommands are attached to a specific buffer. They are useful
if the buffer does not have a name and when the name does not match a specific
pattern. But it also means they must be explicitly added to each buffer.
Instead of a pattern buffer-local autocommands use one of these forms:
<buffer> current buffer
<buffer=99> buffer number 99
<buffer=abuf> using <abuf> (only when executing autocommands)
<abuf>
Wydaje się, że jest to przeznaczone do takiego użycia. Teraz, zarówno ftplugin/tex.vim
i ftplugin/markdown.vim
może mieć:
autocmd CursorHold <buffer> w
Nie jestem naprawdę zaniepokojony faktycznym przedłużenie Dopóki filetype jest poprawna, więc to ratuje mnie od konieczności martwienia się o *.md
i *.markdown
i cokolwiek innego rozszerzenia są ważne dla promocji cenowych.
Czy to użycie jest <buffer>
prawidłowe? Czy są jakieś pułapki, o których powinienem wiedzieć? Czy sprawy się popsują, jeśli wyczyszczę bufor i otworzę inny (mam nadzieję, że liczby się nie zderzą, ale…)?
up
(skrót od:update
) byłoby lepsze niżw
w twoim autocmd (unikaj niepotrzebnych zapisów).w
nie powiódł się. Wielokrotnie.:up
w tym przypadku nic nie robi. :)Odpowiedzi:
Myślę, że jest poprawny, ale wystarczy owinąć go w grupę aug i wyczyścić tę ostatnią, aby mieć pewność, że autocmd nie będzie duplikowany za każdym razem, gdy wykonasz polecenie, które ponownie ładuje ten sam bufor.
Jak wyjaśniono, specjalny wzorzec
<buffer>
pozwala polegać na wbudowanym mechanizmie wykrywania typu pliku, zaimplementowanym w pliku$VIMRUNTIME/filetype.vim
.W tym pliku możesz znaleźć wbudowane autocmdy Vima, które są odpowiedzialne za ustawienie poprawnego rodzaju pliku dla dowolnego bufora. Na przykład dla obniżki cen:
Wewnątrz wtyczki typu pliku możesz skopiować te same wzorce dla każdej instalowanej aplikacji autocmd. Na przykład, aby automatycznie zapisać bufor, gdy kursor nie poruszy się w ciągu kilku sekund:
Ale
<buffer>
jest o wiele mniej gadatliwy:Poza tym, jeśli któregoś dnia inne rozszerzenie będzie ważne i
$VIMRUNTIME/filetype.vim
zostanie zaktualizowane, aby je uwzględnić, twoje autocmds nie zostaną poinformowane. Będziesz musiał zaktualizować wszystkie ich wzorce we wtyczkach typu pliku.Nie jestem pewien, ale nie sądzę, że Vim może ponownie użyć numeru bufora wyczyszczonego bufora. Nie mogłem znaleźć odpowiedniej sekcji z pomocy, ale znalazłem ten akapit z vim.wikia.com :
Poza tym, jak wyjaśnił @ Tumbler41 , po wyczyszczeniu bufora jego autocmds są usuwane. Od
:h autocmd-buflocal
:Jeśli chcesz się sprawdzić, możesz to zrobić, zwiększając poziom szczegółowości Vima do 6. Możesz to zrobić tymczasowo, tylko dla jednej komendy, używając
:verbose
modyfikatora. Tak więc w buforze przecen możesz wykonać:Następnie, jeśli sprawdzisz wiadomości Vima:
Powinieneś zobaczyć linię wyglądającą tak:
Gdzie
42
był numer bufora przecen.Istnieją 3 sytuacje, które uznałbym za pułapki i które dotyczą specjalnego wzorca
<buffer>
. W dwóch z nich<buffer>
może być problem, w drugim rozwiązanie.Pitfall 1
Po pierwsze, powinieneś uważać na sposób, w jaki usuwasz grupy augocd z lokalnych buforów. Musisz znać ten fragment kodu:
Można więc pokusić się o użycie go w przypadku autocmd-buforów lokalnych, niezmodyfikowanych, takich jak to:
Ale będzie to miało niepożądany efekt. Przy pierwszym załadowaniu bufora przeceny nazwijmy go
A
, jego autocmd zostanie poprawnie zainstalowany. Następnie, gdy przeładujeszA
, autocmd zostanie usunięty (z powoduautocmd!
) i ponownie zainstalowany. Augroup poprawnie zapobiegnie duplikowaniu programu autocmd.Załóżmy teraz, że ładujesz drugi bufor przeceny, nazwijmy go
B
w drugim oknie. Wszystkie autocmds grupy aug zostaną usunięte: to jest autocmdA
i jeden zB
. Następnie zostanie zainstalowany POJEDYNCZY autocmdB
.Tak więc, kiedy wprowadzisz jakieś zmiany
B
i zaczekasz kilka sekund na uruchomienieCursorHold
, zostanie ono automatycznie zapisane. Ale jeśli wróciszA
i zrobisz to samo, bufor nie zostanie zapisany. Jest tak, ponieważ podczas ostatniego ładowania bufora przeceny istniała nierównowaga między tym, co usunąłeś, a tym, co dodałeś. Usunąłeś więcej niż dodałeś.Rozwiązaniem jest nie usuwanie WSZYSTKICH autocmds, ale tylko tych z bieżącego bufora, poprzez przekazanie specjalnego wzorca
<buffer>
do:autocmd!
:Pamiętaj, że możesz zastąpić
CursorHold
gwiazdką, aby dopasować dowolne zdarzenie w wierszu, które usuwa autocmds:W ten sposób nie musisz określać wszystkich zdarzeń, na które nasłuchują autorzy, gdy chcesz wyczyścić grupę aug.
Pitfall 2
Jest jeszcze jedna pułapka, ale tym razem
<buffer>
to nie problem, to rozwiązanie.Po dołączeniu opcji lokalnej do wtyczki typu pliku prawdopodobnie robisz to w następujący sposób:
Będzie to działać zgodnie z oczekiwaniami dla opcji lokalnych buforów, ale nie zawsze dla opcji lokalnych okien. Aby zilustrować problem, możesz wypróbować następujący eksperyment. Utwórz plik
~/.vim/after/ftdetect/potion.vim
, a w nim napisz:Ten plik automatycznie ustawi typ pliku
potion
dla każdego pliku, którego rozszerzenie jest.pn
. Nie musisz owijać go w augroup, ponieważ dla tego rodzaju pliku Vim zrobi to automatycznie (patrz:h ftdetect
).Jeśli katalogi pośrednie nie istnieją w twoim systemie, możesz je utworzyć.
Następnie utwórz wtyczkę typu pliku
~/.vim/after/ftplugin/potion.vim
, a wewnątrz niej napisz:Domyślnie w
potion
pliku to ustawienie spowoduje wyświetlanie znaków tabulacji jako^I
i końca linii jako$
.Teraz stwórz minimum
vimrc
; w środku/tmp/vimrc
napisz:... aby włączyć wtyczki typu pliku.
Utwórz również plik mikstury
/tmp/pn.pn
i plik losowy/tmp/file
. W pliku mikstury napisz coś:W losowym pliku zapisz ścieżkę do pliku mikstury
/tmp/pn.pn
:Teraz uruchom Vima z minimum inicjalizacji, po prostu pozyskaj
vimrc
i otwórz oba pliki w rzutniach pionowych:Powinieneś zobaczyć 2 pionowe rzutnie. Plik mikstury po lewej stronie wyświetla koniec linii ze znakami dolara, losowy plik po prawej w ogóle ich nie wyświetla.
Ustaw fokus na losowym pliku i naciśnij,
gf
aby wyświetlić plik mikstury, którego ścieżka znajduje się pod kursorem. Teraz widzisz ten sam bufor mikstury w prawej rzutni, ale tym razem koniec linii nie jest wyświetlany ze znakami dolara. A jeśli wpiszesz:setlocal list?
, Vim powinien odpowiedziećnolist
:Cały łańcuch wydarzeń:
... nie wystąpił, ponieważ pierwszy z nich
BufRead
nie pojawił się po naciśnięciugf
. Bufor został już załadowany.Może się to wydawać nieoczekiwane, ponieważ po dodaniu
setlocal list
do wtyczki typu pliku mikstury możesz pomyśleć, że włączy ona'list'
opcję w dowolnym oknie wyświetlającym bufor mikstury.Problem nie jest specyficzny dla tego nowego typu
potion
pliku. Możesz także doświadczyć tego zmarkdown
plikiem.Nie jest to również specyficzne dla
'list'
opcji. Można wystąpić z innymi ustawieniami okiennych lokalnego, jak'conceallevel'
,'foldmethod'
,'foldexpr'
,'foldtitle'
, ...Nie jest to również specyficzne dla
gf
polecenia. Możesz tego doświadczyć z innymi poleceniami, które mogą zmienić bufor wyświetlany w bieżącym oknie: znak globalny,C-o
(przesuń się do tyłu w lokalnej liście okien),,:b {buffer_number}
...Podsumowując, opcje lokalne dla okna zostaną poprawnie ustawione, jeśli i tylko jeśli:
BufRead
będzie musiał zostać uruchomiony ):split
(w tym przypadku powinno dziedziczyć opcje okna lokalnego z okna, w którym polecenie zostało wykonane)W przeciwnym razie opcje lokalne dla okna mogą nie być ustawione poprawnie.
Możliwym rozwiązaniem byłoby ustawienie ich nie bezpośrednio z wtyczki typu pliku, ale z autocmd zainstalowanego w tym drugim, który będzie nasłuchiwał
BufWinEnter
. To zdarzenie powinno być uruchamiane za każdym razem, gdy bufor jest wyświetlany w oknie.Na przykład zamiast pisać to:
Napisałbyś to:
I tutaj znów znajdziesz specjalny wzór
<buffer>
.Pitfall 3
Jeśli zmienisz typ pliku bufora, autocmds pozostaną. Jeśli chcesz je usunąć, musisz skonfigurować
b:undo_ftplugin
(patrz:h undo_ftplugin
) i dołączyć do niego następujące polecenie:Nie próbuj jednak usuwać samej grupy augroup, ponieważ nadal mogą istnieć bufory przecen, które zawierają w sobie autocmd.
FWIW, to jest fragment UltiSnips, którego używam do ustawienia
b:undo_ftplugin
:A oto przykład wartości, którą mam
~/.vim/after/ftplugin/awk.vim
:Na marginesie rozumiem, dlaczego zadałeś pytanie, ponieważ kiedy szukałem wszystkich wierszy, w których zastosowano specjalny wzór
<buffer>
w domyślnych plikach Vima:Znalazłem tylko 9 dopasowań (możesz znaleźć mniej więcej, używam Vima w wersji 8.0, z łatami do
134
). A spośród 9 dopasowań, 7 znajduje się w dokumentacji, tylko 2 faktycznie pochodzą. Powinieneś je znaleźć w $ VIMRUNTIME / syntax / dircolors.vim :Nie wiem, czy to może powodować problem, ale nie są one wewnątrz augroup, co oznacza, że za każdym razem przeładować bufor, którego filetype jest
dircolors
(to się dzieje, jeśli edytować plik o nazwie.dircolors
,.dir_colors
lub których końce Ścieżka z/etc/DIR_COLORS
), wtyczka do składni doda nowy autocmd dla bufora lokalnego.Możesz to sprawdzić w następujący sposób:
Ostatnie polecenie powinno wyświetlać to:
Teraz ponownie załaduj bufor i ponownie zapytaj, jakie są lokalne autocmds dla bieżącego bufora:
Tym razem zobaczysz:
Po każdym przeładunku pliku
s:reset_colors()
is:preview_color('.')
będzie nazwany jeden dodatkowy czas, każdy czas imprezyCursorHold
,CursorHoldI
,CursorMoved
,CursorMovedI
zostaje zwolniony.Prawdopodobnie nie jest to duży problem, ponieważ nawet po
dircolors
kilkukrotnym przeładowaniu pliku nie zauważyłem zauważalnego spowolnienia ani nieoczekiwanego zachowania Vima.Jeśli jest to dla Ciebie problem, możesz skontaktować się z opiekunem wtyczki składni, ale w międzyczasie, jeśli chcesz zapobiec powielaniu autocmds, możesz utworzyć własną wtyczkę składni
dircolors
plików, używając tego pliku~/.vim/syntax/dircolors.vim
. Wewnątrz możesz zaimportować zawartość oryginalnej wtyczki składni:Następnie, w tym ostatnim, po prostu owiniesz autocmds wewnątrz grupy aug, którą wyczyścisz. Więc zastąpiłbyś te linie:
... z tymi:
Zauważ, że jeśli utworzyłeś
dircolors
wtyczkę składni z plikiem~/.vim/after/syntax/dircolors.vim
, to nie działałoby, ponieważ wcześniej domyślna wtyczka składniowa byłaby pozyskiwana. Korzystając z tej wtyczki, tworzona jest wtyczka składniowa~/.vim/syntax/dircolors.vim
przed domyślną, i ustawi zmienną lokalną dla buforab:current_syntax
, co zapobiegnie źródłowej wtyczce składni, ponieważ zawiera tę ochronę:Ogólna zasada wygląda następująco: użyj katalogów
~/.vim/ftplugin
i,~/.vim/syntax
aby utworzyć niestandardową wtyczkę typu pliku / składni i zapobiec kolejnemu wtyczce (dla tego samego typu pliku) w ścieżce środowiska wykonawczego (w tym domyślnym). I używaj~/.vim/after/ftplugin
,~/.vim/after/syntax
nie po to, aby zapobiec pozyskiwaniu innych wtyczek, ale po prostu, aby mieć ostatnie słowo na temat wartości niektórych ustawień.źródło
autocmd!
zeautocmd! CursorHold <buffer>
waugroup
blokach jest szczególnie krytyczny haczyka - i powinny być podświetlone góry. Niemniej jednak ... to rażąco niesamowita inwestycja czasu, wysiłku i krwawych łez.