Autocmd içindeki AND olaylarının bir yolu var mı?


21

Bir autocmd iki olayı tetiklemek isterim , ancak genellikle yapıldığı şekilde değil, yani olaylardan biri gerçekleştiyse, bir tetikle autocmd. Her iki olay da olmuşsa tetiklemek istiyorum.

Örneğin:
Bunu yapmanın olağan yolu

autocmd BufWrite,BufRead *.c *.py *.h :call StripTrailingWhitespaces()

Bu kod, BufWrite veya BufRead üzerinde StripTrailingWhiteSpaces () işlevini çağırır.

Gibi bir şey yapmak istiyorum:

autocmd Filetype c,cpp,python AND BufWrite :call StripTrailingWhiteSpaces()

Başka bir deyişle autcmd, filetip c, cpp, python'dan biriyse ve bu tampon üzerine yazma gerçekleştiğinde, bir tetiklenir .

Herhangi bir yardım takdir edilmektedir.

Yanıtlar:


14

Bir olay gerçekleştiğinde bir otomatik komut komutu çalıştırılır. Bir dizi olay meydana geldikten sonra bir komutun yürütülmesini istersiniz. Bunu yapmanın bir yolu bu gibidir:

autocmd FileType c,cpp,python
    \ autocmd BufWritePre <buffer> call StripTrailingWhiteSpaces()

<buffer>Desen akım tampon yazıldığında autocommand tetiklenecek neden olur. Görmek

:help autocmd-buflocal

Güncelleştirme

Yukarıdaki çözüm oldukça basittir ve Yorumlar'da tartışılan bazı kusurları vardır. İşte bu kusurların bazılarını ele alan daha eksiksiz bir çözüm. Otomatik komutları bir gruba koyar ve varsa yeni bir tane oluşturmadan önce BufWritePre otomatik komutunu siler. Yine de tampon başına bir oto-komut oluşturur, fakat sadece bir tane oluşturur.

augroup TrailSpace
    autocmd FileType c,cpp,python
        \ autocmd! TrailSpace BufWritePost <buffer> call SkipTrailingWhiteSpaces()
augroup END

Şimdi silinen lcd047 tarafından gönderilen cevaba benzer başka bir çözüm, FileType olayı gerçekleştiğinde, 'filetype' seçeneğinin ayarlandığını algılamaktır. Ardından, aşağıdaki örnekte olduğu gibi, 'filetype' değerindeki BufWritePost olayına yanıtı koşullandırabilirsiniz. Sadece bir otomatik komutun yaratıldığı diğer çözümlere göre üstünlük sağlar.

autocmd BufWritePre * if count(['c','cpp','python'],&filetype)
    \ | call SkipTrailingWhiteSpaces()
    \ | endif

Bunu şu anda açık olan tüm dosyalarda çalıştırmak istersem, yani yürütürsem: wa?
flashburn

Dosyalar doğru dosya FileTypetüründe açılmışsa , yanıttaki autocmd, kaydedildiğinde ikinci autocmd ( BufWritePre) işlevini başlatmak için önceden ayarlardı .
VanLaser

1
Yukarıdaki FileTypeautocmd , doğru dosya türünde açtığınız her dosya için açılır ve bu dosyaların her biri için bir yerel tampon olay oluşturur . Bu nedenle, çalıştırırsanız , vim dosyaya kaydetmeden önce her arabellek için kayıtlı olayları çalıştırır. :wa
VanLaser

1
Yani 5 Python dosyasını açarsanız autocmd, tümü teker teker yerine 5 sn olacaktır. Sonra, eğer bu dosyalardan 3 tanesi gizlenirse, tekrar gösterilir, FileTypeyeniden tetiklenir, böylece 3 tane daha autocmdyazabilirsiniz. Bu harika, neden bu çözümü bulamadığımı merak ediyorum. :)
lcd047

1
Performans sorun değil. Fonksiyonu stripTrailingWhiteSpaces()aynı dosyaya karşı birkaç kez çalıştırmak, istenmeyen sonuçlara yol açabilir. Ayrıca, autocmdaynı dosya için aynı etkinlik için ne kadar fazla sahipseniz, bazı yarış koşullarına girme olasılığınız o kadar yüksek olur. Bir fikir edinmek için vim_dev arşivlerini aramayı deneyin. Sonra tekrar, ne biliyorum, sadece sizin için işe yarayabilir, değil mi?
lcd047,

4

Daha genel olarak, önce hangi olayın olacağını bilmiyorsanız, her birinin ne zaman ateş ettiğini izlemek için bir yardımcı kullanabilirsiniz ve yalnızca en son ateşlendiğinde komutunuzu uygulayabilirsiniz:

function StripTrailingWhiteSpacesIfReady(event) abort
  if !exists('b:events_for_whitespace')
    let b:events_for_whitespace = {}
  endif
  let b:events_for_whitespace[a:event] = 1
  if has_key(b:events_for_whitespace, 'FileType') && has_key(b:events_for_whitespace, 'Buf')
    " Strip trailing whitespace
    %s/\m\s\+$//
  endif
endfunction
autocmd Filetype c,cpp,python call StripTrailingWhiteSpacesIfReady('FileType')
autocmd BufWrite,BufRead * StripTrailingWhiteSpacesIfReady('Buf')
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.