Bu <tamponlayıcı> kullanımı doğru mu?
Doğru olduğunu düşünüyorum, ancak aynı tamponu yeniden yükleyen bir komutu her çalıştırdığınızda autocmd'nin çoğaltılmayacağından emin olmak için onu bir grubun içine sarmanız ve ikincisini temizlemeniz gerekir.
Açıkladığınız gibi, özel desen <buffer>
dosyanın içine yerleştirilmiş yerleşik dosya tipi algılama mekanizmasına güvenmenizi sağlar $VIMRUNTIME/filetype.vim
.
Bu dosyada, belirli bir arabellek için doğru dosya türünü ayarlamaktan sorumlu olan Vim'in yerleşik autocmds'ını bulabilirsiniz. Örneğin, işaretleme için:
" Markdown
au BufNewFile,BufRead *.markdown,*.mdown,*.mkd,*.mkdn,*.mdwn,*.md setf markdown
Dosya türü eklentinizin içinde, yüklediğiniz her autocmd için aynı kalıpları kopyalayabilirsiniz. Örneğin, imleciniz birkaç saniye boyunca hareket etmediğinde arabelleği otomatik olarak kaydetmek için:
au CursorHold *.markdown,*.mdown,*.mkd,*.mkdn,*.mdwn,*.md update
Ama <buffer>
çok daha az ayrıntılı:
au CursorHold <buffer> update
Ayrıca, bir gün başka bir uzantı geçerliyse ve $VIMRUNTIME/filetype.vim
bunu içerecek şekilde güncellenirse, oto cmd'leriniz bilgilendirilmez. Ayrıca tüm dosya türlerini dosya türü eklentilerinizde güncellemeniz gerekir.
Bir tamponu silip bir başkasını açarsam işler dağınık olur mu (umarım sayılar çarpışmaz, ama…)?
Emin değilim ama Vim'in silinmiş bir arabellek arabellek numarasını tekrar kullanabileceğini sanmıyorum. Yardımdan ilgili bölümü bulamadım, ancak bu paragrafı vim.wikia.com'dan buldum :
Hayır. Vim, silinen bir arabellek arabellek numarasını yeni bir arabellek için yeniden kullanmayacaktır. Vim her zaman yeni bir arabellek için bir sonraki sıra numarasını atayacaktır.
Ayrıca, @ Tumbler41'in açıkladığı gibi, bir tamponu sildiğinizde, autocmds kaldırılır. Gönderen :h autocmd-buflocal
:
Bir tampon silindiğinde, tampon-yerel oto komutları da elbette kaybolur.
Kendinizi kontrol etmek istiyorsanız, Vim'in ayrıntı düzeyini 6'ya çıkararak bunu yapabilirsiniz :verbose
. Değiştiriciyi kullanarak geçici olarak, sadece bir komut için yapabilirsiniz . Böylece, işaretleme tamponunuzun içinde şunları yürütebilirsiniz:
:6verbose bwipe
Ardından, Vim'in mesajlarını kontrol ederseniz:
:messages
Şöyle bir çizgi görmelisiniz:
auto-removing autocommand: CursorHold <buffer=42>
42
İşaretleme tamponunuzun sayısı neredeydi .
Dikkat etmem gereken tuzaklar var mı?
Tuzaklar olarak kabul edeceğim ve özel modeli içeren 3 durum var <buffer>
. İkisinde <buffer>
bir sorun olabilir, diğerinde bir çözüm.
Tuzak 1
İlk olarak, arabellek yerel oto cmd'lerinizin ağ gruplarını temizleme şeklinize dikkat etmelisiniz. Bu snippet'e aşina olmalısınız:
augroup your_group_name
autocmd!
autocmd Event pattern command
augroup END
Yani, bu gibi değiştirilmemiş, arabellek-yerel oto cmd'leriniz için kullanmaya cazip olabilirsiniz:
augroup my_markdown
autocmd!
autocmd CursorHold <buffer> update
augroup END
Ancak bunun istenmeyen bir etkisi olacaktır. İlk kez bir işaretleme arabelleği yüklediğinizde, diyelim ki A
, autocmd doğru şekilde kurulacaktır. Ardından, yeniden yüklediğinizde A
, autocmd silinir (nedeniyle autocmd!
) ve yeniden yüklenir. Bu nedenle, ağ grubu autocmd'nin kopyalanmasını doğru şekilde önleyecektir.
Şimdi, ikinci bir işaretleme arabelleği yüklediğinizi varsayalım B
, ikinci bir pencerede diyelim . Augroup'un TÜM autocmds temizlenecek: yani autocmd A
ve biri B
. Ardından, bir SINGLE autocmd yüklenecektir B
.
Bu nedenle, bazı değişiklikler yaptığınızda B
ve CursorHold
işten çıkarılmanız için birkaç saniye beklediğinizde , otomatik olarak kaydedilir. Ancak A
aynı şeye geri dönüp aynı şeyi yaparsanız, arabellek kaydedilmez. Bunun nedeni, en son bir işaretleme arabelleği yüklediğinizde, kaldırdıklarınız ve ekledikleriniz arasında bir dengesizlik olmasıydı. Eklediğinizden daha fazlasını kaldırdınız.
Çözüm, TÜM oto cmd'leri değil, yalnızca özel arabelleği geçirerek geçerli arabellekleri <buffer>
kaldırmaktır :autocmd!
:
augroup my_markdown
autocmd! CursorHold <buffer>
autocmd CursorHold <buffer> update
augroup END
CursorHold
Satırdaki autocmds'i kaldıran herhangi bir etkinliğe uyacak bir yıldızla değiştirebileceğinizi unutmayın:
augroup my_markdown
autocmd! * <buffer>
autocmd CursorHold <buffer> update
augroup END
Bu şekilde, ağ grubunu temizlemek istediğinizde otomatik cmd'lerinizin dinlediği tüm olayları belirtmeniz gerekmez.
Tuzak 2
Başka bir tuzak daha var, ama bu sefer <buffer>
sorun değil, çözüm.
Bir filetype eklentisine yerel bir seçenek eklediğinizde, muhtemelen böyle yaparsınız:
setlocal option1=value
setlocal option2
Bu, arabellek-yerel seçenekler için beklendiği gibi çalışacaktır, ancak her zaman pencere-yerel seçenekler için geçerli olmayacaktır. Sorunu göstermek için aşağıdaki denemeyi deneyebilirsiniz. Dosyayı oluşturun ~/.vim/after/ftdetect/potion.vim
ve içine şunu yazın:
autocmd BufNewFile,BufRead *.pn setfiletype potion
Bu dosya potion
, uzantısı olan herhangi bir dosya için dosya türünü otomatik olarak ayarlar .pn
. Bu tür bir dosya için Vim otomatik olarak yapacak (çünkü), bir grubun içine sarmanıza gerek yok :h ftdetect
.
Ara dizinler sisteminizde yoksa, bunları oluşturabilirsiniz.
Ardından, filetype eklentisini oluşturun ~/.vim/after/ftplugin/potion.vim
ve içine şunu yazın:
setlocal list
Varsayılan olarak, bir potion
dosyada bu ayar, sekme karakterlerinin olarak ^I
ve satır sonu olarak görüntülenmesine neden olur $
.
Şimdi bir minimal oluşturun vimrc
; iç /tmp/vimrc
yazma:
filetype plugin on
... filetype eklentilerini etkinleştirmek için.
Ayrıca, bir iksir dosyası /tmp/pn.pn
ve rastgele bir dosya oluşturun /tmp/file
. İksir dosyasına bir şey yazın:
foo
bar
baz
Rastgele dosyaya, iksir dosyasının yolunu yazın /tmp/pn.pn
:
/tmp/pn.pn
Şimdi, Vim'i minimum başlatmalarla başlatın, sadece kaynak kodlayın vimrc
ve her iki dosyayı dikey görünüm pencerelerinde açın:
$ vim -Nu /tmp/vimrc -O /tmp/pn.pn /tmp/file
2 dikey görünüm alanı görmelisiniz. Soldaki iksir dosyası dolar işareti olan satırların sonunu görüntüler, sağdaki rastgele dosya hiç göstermez.
Odağı rastgele dosyaya verin ve gf
yolu imlecin altında olan iksir dosyasını görüntülemek için tuşuna basın . Şimdi aynı iksir arabelleğini sağ görüntü portunda görüyorsunuz, ancak bu sefer satırların sonu dolar işareti ile gösterilmiyor. Ve yazarsanız :setlocal list?
, Vim cevap vermelidir nolist
:
Bütün olaylar zinciri:
BufRead event → set 'filetype' option → load filetype plugins
... olmadı, çünkü bunlardan ilki, BufRead
bastığınızda gerçekleşmedi gf
. Arabellek zaten yüklendi.
Beklenmedik görünebilir, çünkü setlocal list
iksir dosya türü eklentinizin içine eklediğinizde , 'list'
bir iksir arabelleği görüntüleyen herhangi bir pencerede seçeneği etkinleştireceğini düşünmüş olabilirsiniz .
Sorun bu yeni potion
dosya türüyle ilgili değil. Bir markdown
dosyayla da deneyimleyebilirsiniz .
Seçeneğe de özgü 'list'
değil. Diğer pencere yerel ayarlarla yaşayabilirsiniz gibi 'conceallevel'
, 'foldmethod'
, 'foldexpr'
, 'foldtitle'
, ...
gf
Komuta da özgü değil. Geçerli pencerede görüntülenen arabelleği değiştirebilecek diğer komutlarla karşılaşabilirsiniz: genel işaret, C-o
(pencere-yerel atlama listesinde geri git) :b {buffer_number}
,, ...
Özetlemek gerekirse, pencere yerel seçenekleri yalnızca aşağıdaki durumlarda doğru ayarlanacaktır:
- geçerli Vim oturumu sırasında dosya okunmadı (çünkü
BufRead
işten çıkarılması gerekecek)
- dosya, yerel pencere seçeneklerinin doğru ayarlandığı bir pencerede görüntüleniyor
- yeni pencere gibi bir komutla oluşturulur
:split
(bu durumda, komutun yürütüldüğü pencereden pencere-yerel seçeneklerini devralmalıdır)
Aksi takdirde, pencere yerel seçenekleri doğru ayarlanmamış olabilir.
Olası bir çözüm, onları doğrudan bir dosya türü eklentisinden değil, ikincisinde yüklü bir autocmd'den dinlemektir BufWinEnter
. Bir pencerede her arabellek görüntülendiğinde bu olay başlatılmalıdır.
Örneğin, bunu yazmak yerine:
setlocal list
Bunu yazarsınız:
augroup my_potion
au! * <buffer>
au BufWinEnter <buffer> setlocal list
augroup END
Ve burada, yine özel modeli buluyorsun <buffer>
.
Tuzak 3
Arabellek dosya türünü değiştirirseniz, autocmds kalır. Bunları kaldırmak istiyorsanız, yapılandırmanız b:undo_ftplugin
(bkz. :h undo_ftplugin
) Ve bu komutu içine eklemeniz gerekir:
exe 'au! my_markdown * <buffer>'
Ancak, grubun kendisini kaldırmaya çalışmayın, çünkü içinde autocmds olan bazı işaretleme arabellekleri hala olabilir.
FWIW, ayarlamak için kullandığım UltiSnips snippet'i b:undo_ftplugin
:
snippet undo "undo ftplugin settings" bm
" teardown {{{1
let b:undo_ftplugin = get(b:, 'undo_ftplugin', '')
\ .(empty(get(b:, 'undo_ftplugin', '')) ? '' : '|')
\ ."${1:
\ setl ${2:option}<}${3:
\ | exe '${4:n}unmap <buffer> ${5:lhs}'}${6:
\ | exe 'au! ${7:group_name} * <buffer>'}${8:
\ | unlet! b:${9:variable}}${10:
\ | delcommand ${11:Cmd}}
\ "
$0
endsnippet
Ve işte sahip olduğum değere bir örnek ~/.vim/after/ftplugin/awk.vim
:
let b:undo_ftplugin = get(b:, 'undo_ftplugin', '')
\ .(empty(get(b:, 'undo_ftplugin', '')) ? '' : '|')
\ ."
\ setl cms< cocu< cole< fdm< fdt< tw<
\| exe 'nunmap <buffer> K'
\| exe 'au! my_awk * <buffer>'
\| exe 'au! my_awk_format * <buffer>'
\ "
Bir yan not olarak, soruyu neden sorduğunuzu anlıyorum, çünkü <buffer>
Vim'in varsayılan dosyalarında özel desenin kullanıldığı tüm satırları aradığımda :
:vim /au\%[tocmd!].\{-}<buffer>/ $VIMRUNTIME/**/*
Sadece 9 eşleşme buldum (az ya da çok bulabilirsiniz, Vim sürüm 8.0 kullanıyorum, yamalar kadar 134
). Ve 9 maç arasında 7'si dokümantasyonda, sadece 2 tanesi aslında kaynaklıdır. Bunları $ VIMRUNTIME / sözdizimi / dircolors.vim'de bulmalısınız :
autocmd CursorMoved,CursorMovedI <buffer> call s:preview_color('.')
autocmd CursorHold,CursorHoldI <buffer> call s:reset_colors()
Bir soruna neden olabilir eğer bilmiyorum, ama onlar filetype olan bir tampon yeniden her zaman anlamına gelir augroup, içeride değil dircolors
(eğer adlı bir dosya üzerinde düzeltmeler olur .dircolors
, .dir_colors
ya da kimin yolu uçları ile /etc/DIR_COLORS
), sözdizimi eklentisi yeni bir arabellek-yerel autocmd ekleyecektir.
Bu şekilde kontrol edebilirsiniz:
$ vim ~/.dir_colors
:au * <buffer>
Son komut şunu göstermelidir:
CursorHold
<buffer=1>
call s:reset_colors()
CursorHoldI
<buffer=1>
call s:reset_colors()
CursorMoved
<buffer=1>
call s:preview_color('.')
CursorMovedI
<buffer=1>
call s:preview_color('.')
Şimdi, arabelleği yeniden yükleyin ve geçerli arabelleğin arabellek yerel autocmds'ının ne olduğunu tekrar sorun:
:e
:au * <buffer>
Bu sefer şunu göreceksiniz:
CursorHold
<buffer=1>
call s:reset_colors()
call s:reset_colors()
CursorHoldI
<buffer=1>
call s:reset_colors()
call s:reset_colors()
CursorMoved
<buffer=1>
call s:preview_color('.')
call s:preview_color('.')
CursorMovedI
<buffer=1>
call s:preview_color('.')
call s:preview_color('.')
Her dosyanın yeniden, sonra s:reset_colors()
ve s:preview_color('.')
bir ek süre adı verilecek, olayın her zaman bir CursorHold
, CursorHoldI
, CursorMoved
, CursorMovedI
ateşlenir.
Muhtemelen büyük bir sorun değil, çünkü bir dircolors
dosyayı birkaç kez yeniden yükledikten sonra bile, Vim'den fark edilir bir yavaşlama veya beklenmedik bir davranış görmedim.
Bu sizin için bir sorunsa, sözdizimi eklentisinin koruyucusuna başvurabilirsiniz, ancak bu arada, autocmds'ın çoğaltılmasını önlemek istiyorsanız dircolors
, dosyayı kullanarak dosyalar için kendi sözdizimi eklentinizi oluşturabilirsiniz ~/.vim/syntax/dircolors.vim
. İçinde orijinal sözdizimi eklentisinin içeriğini içe aktaracaksınız:
$ vim ~/.vim/syntax/dircolors.vim
:r $VIMRUNTIME/syntax/dircolors.vim
Sonra, ikincisinde, autocmds'ı temizleyeceğiniz bir grubun içine sarmanız yeterlidir. Yani, şu satırları değiştirirsiniz:
autocmd CursorMoved,CursorMovedI <buffer> call s:preview_color('.')
autocmd CursorHold,CursorHoldI <buffer> call s:reset_colors()
... bunlarla:
augroup my_dircolors_syntax
autocmd! * <buffer>
autocmd CursorMoved,CursorMovedI <buffer> call s:preview_color('.')
autocmd CursorHold,CursorHoldI <buffer> call s:reset_colors()
augroup END
dircolors
Sözdizimi eklentinizi dosyayla oluşturduysanız ~/.vim/after/syntax/dircolors.vim
, varsayılan sözdizimi eklentisinin daha önce kaynaklanacağından işe yaramayacağını unutmayın. Kullanarak ~/.vim/syntax/dircolors.vim
, sözdizimi eklentiniz varsayılandan önce kaynaklanacaktır ve b:current_syntax
bu koruyucuyu içerdiği için varsayılan sözdizimi eklentisinin kaynaklanmasını önleyecek olan tampon yerel değişkeni ayarlayacaktır :
if exists("b:current_syntax")
finish
endif
Genel kural şöyledir: özel bir dosya türü / sözdizimi eklentisi oluşturmak için ~/.vim/ftplugin
ve ~/.vim/syntax
dizinlerini kullanın ve çalışma zamanı yolundaki bir sonraki eklentinin (aynı dosya türü için) kaynaklanmasını (varsayılan olanlar dahil) önleyin. Ve ~/.vim/after/ftplugin
, ~/.vim/after/syntax
diğer eklentilerin kaynaklanmasını önlemek için değil, sadece bazı ayarların değerinde son kelimeye sahip olmak için kullanın.