Odaklanmadığı zamanlarda Vim'in otomatik olarak bir dosya okumasını nasıl sağlayabilirim?


29

Bir dosyaya yazılan çıktının izlenmesi dahil her türlü şey için (veya bu durumda gVim) VIm kullanıyorum; Kullandığım autoreadVim ben buna Klavye odağını değiştirmek zaman öyle dosyası, yeniden okumasını yapmak.

Klavye odağını değiştirmesem bile Vim'in tamponu güncellemesinin bir yolu var mı? Ayarlamayı denedim, checktimeancak klavye odağı başka bir yerdeyken herhangi bir etkisi görünmüyor.

İzlemekte olduğum çıktı, çıktı dosyasını tamamen değiştiriyor; ve ben ona bakmıyorum tail -f. Her seferinde yeni bir örneğe lesspipetlemek veya içine pipetlemek gibi başka seçenekler var , ancak VIm ile yapılabilirse iyi olurdu.


@Carpetsmoker, peki ya CursorHoldolay? Vim'in odağı yoksa, her n saniyede bir tetiklemesi gerekir.
muru

1
@muru Hayır, CursorHoldyalnızca bir kez yürütülür, bu açıkça şu şekilde belgelenmiştir: "Vim'den biraz kahve yapmak için ayrılırsanız, her" güncelleme zamanı "nı kovmaz. :)"
Martin Tournoij

1
Gvim etiketini tekrar kaldırdım, umarım sorun yoktur ;-) Gördüğüm gibi, bu sorular gerçekten gVim ile ilgili değil , çünkü odak değişikliği Vim'in dosya değiştirilip değiştirilmediğini kontrol ettiği tek bir olaydır (bir demet var, ayrıntılar için cevabımı gör). Çoğu olmasa da, bunu iyileştirmenin yolları hem Vim'de hem de gVim'de iyi sonuç verecektir.
Martin Tournoij

@Carpetsmoker ah, gVim'in klavye odağı varken (böylece bir gVim sorusu yapıyordu) düzenli olarak kontrol ettiği izlenimini edindim, ancak hatalı görünüyordu. Bunu temizlediğin için teşekkürler.
falstro

Yanıtlar:


20

2015-06-25 Güncellemesi :

  • Çok işlevsiz olduğu için "kabuk" yöntemini hurdaya çıkardım. Ekleme kipini durdurdu ve zombi işlemlerini bıraktı. Bak bu ileti düzeltme geçmişinde gerçekten Yine de görmek istediğim.
  • Bundan bir eklenti yaptım: auto_autoread.vim . Şu anda, etkili bir şekilde aşağıdaki kodla aynı, ancak eklentileri kullanmanızı öneririz, çünkü bu güncelleme alıyor olabilir.

Ne yapar autoread?

Bu soruyu cevaplamak için önce anlamak gerekir autoreaddaha önemlisi, hangi seçeneği yapar ve gelmez yapmak.

Maalesef :help 'autoread' bu konuda pek fazla bilgiye sahip değil, sadece "Vim'in dışında bir dosyanın değiştiği tespit edildi" diyor . Vim bir dosyanın değiştiğini nasıl tespit eder? Bazı işlemlerde Vim, dosyanın değişiklik zamanını kontrol eder.

Ne zaman:

  • :checktime kullanıldı;
  • bir tampon girilir;
  • :diffupdate kullanıldı;
  • :e zaten tamponu olan bir dosya için verilir;
  • harici bir komut çalıştırmak !;
  • ön plana geri dönme ( ^Z, fgyalnızca kabuk iş kontrolüne sahipse);

gVim için bu, şu durumlarda da yapılır:

  • "sağ klik" menüsünü kapatmak (bir şeyi seçerek veya yalnızca kapatarak);
  • odak değiştirildi (farkettin budur);
  • Menüden "dosya -> açık", "dosya -> farklı kaydet" seçeneğini kullanırsanız (bazı diğer yerlerin yanı sıra) açılan tarayıcı pencerelerini kapatma.

Bu bilgiyi Vim kaynağından tüm çağrıları buf_check_timestamp(), check_timestamps()işlevleri ve need_check_timestampsayarlı konumları bularak topladım TRUE.

Bazı olayları kaçırmış olabilirim, ancak hatırlanması gereken en önemli şey, Vim'in yalnızca dosyanın çok sınırlı sayıda koşulda değiştirilip değiştirilmediğini kontrol etmesidir . Kesinlikle değil "anket" değişikliklerin sonsuza dek dosyayı yapar n ne sonra konum temelde hangi saniye.

Yani, amacınız için set autoreadyeterli değil.

Python'u Kullanma

Bu, arka planda çalıştırmak için bir Python iş parçacığı zamanlar, :checktimeher n saniyede bir çalışır. Eğer autoreadbir etkin , bu aksi takdirde sadece uyaracak diskten tampon yeniden yükleyecektir.

Bu, Vim'in içinde +pythonveya +python3içinde olmasını gerektirir :version. Tüm platformlarda çalışmalıdır (Windows dahil).

fun! AutoreadPython()
python << EOF
import time, vim
try: import thread
except ImportError: import _thread as thread # Py3

def autoread():
    vim.command('checktime')  # Run the 'checktime' command
    vim.command('redraw')     # Actually update the display

def autoread_loop():
    while True:
        time.sleep(1)
        autoread()

thread.start_new_thread(autoread_loop, ())
EOF
endfun

Bunu kullanarak başlayabilirsiniz :call AutoreadPython(); elbette bunu bir autocmd içinde yapabilirsiniz; Örneğin:

autocmd *.c call AutoreadPython()

Sonsöz

Aslında daha fazla yöntem var, örneğin, bir dosyayı değişiklikler için izlemek entriçin Python inotifyveya gaminmodül gibi bir araç kullanabilirsiniz , :checktimeherhangi bir argüman verilmezse tüm arabellekleri de denetler, bu yalnızca bir arabellek denetleyerek geliştirilebilir. belirli bir dosya.
Ancak, bu cevap zaten oldukça uzun :-) Bu yöntem (umarım!) Çoğu senaryo için iyi çalışmalı veya senaryoya kolayca uyarlanmalıdır.

PS. Ruby'yi de kullanmaya çalıştım, ancak ne yazık ki Ruby konu başlıkları (kullanarak Thread) Python'un yaptığı gibi arka planda çalışmadı, bu yüzden çalışmasını sağlayamadım (belki de başka bir yol var mı?)


2

Arka planda arabellek zaman uyumsuz olarak güncelleştirmek için kullanılan küçük bir eklenti vim-autoread yaptımtail -f . Bu açıkça Vim Version 8'in iş özelliğini gerektiriyor.

:AutoReadAçmak ve kapatmak için kullanın :AutoRead!.


NeoVim uyumlu bir versiyon harika olurdu!
Andrew,

@AndrewMacFie Anlamadım, neden Neovim'de işe yaramayacaktı.
Christian Brabandt

NeoVim'de Vim 8 iş eksikliğinin destek olduğunu düşündüm?
Andrew,

@AndrewMacFie oh bu muhtemelen doğru. Neovim kullanmadığım için NeoVim ile uyumlu hale getiremiyorum. Ancak bir PR memnuniyetle karşılanacaktır :)
Christian Brabandt

yeterince adil
Andrew,

1

Neovim'de, tail komutunu çalıştıran bir terminal arabelleği açacak olan aşağıdaki komutu kullanabilirsiniz.

:enew | call termopen('tail --follow=name --retry /path/to/file.log')

Dosya kaldırılsa ve yeniden yaratılsa bile bu çalışmaya devam edecektir.

Veya aşağıdakileri $MYVIMRC

" :Tail /path/to/file
function! Tail(file)
  enew
  call termopen('tail --follow=name --retry ' . fnameescape(a:file))
endfunction
command! -nargs=1 Tail call Tail(<f-args>)

1

bu cevaptan ( PhanHaiQuang tarafından verilen bir cevaba ve flukus'un bir yorumuna atıfta bulunulduğunda )

Biri gerektiğinde bu oneliner'i ex'ten (vim içinde) çalıştırabilir (veya her komutu log-dosyaları açıldığında vimrc'ye koyabilirsiniz).

:set autoread | au CursorHold * checktime | call feedkeys("lh")

Açıklama:
- otomatik okuma : hayır iç zamanlayıcı ya da böyle bir şey yoktur, dışarıdan değişti dosyasını okur (ama kendi başına doesnt iş sadece vim eski bir komutla gibi bir eylem yapar dosyayı okuyacak. :!
- İmleçHold * kontrol süresi : imleç kullanıcı tarafından 'updatetime' da (varsayılan olarak 4000 milisaniye olan) belirtilen süre boyunca hareket etmediğinde, dosyanın dışından yapılan değişiklikleri denetleyen kontrol süresi yürütülür
- çağrı besleme tuşları ("lh") : imleç (biz var demektir CursorHold tetiklenir ki ... hangi araçlar sağa, bir kez taşındı ve sol arka ve sonra hiçbir şey olmuyor. döngü )

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.