:!<command>
Kabukta bir komut çalıştırmak için kullanılabilir. Fakat bu benim terminalimi “devraldı” ve onu stdout
bu özel komutla doldurdu .
Arka planda yalnızca sıfır olmayan bir çıkış kodunda beni bilgilendiren bir komutu nasıl uygularım?
:!<command>
Kabukta bir komut çalıştırmak için kullanılabilir. Fakat bu benim terminalimi “devraldı” ve onu stdout
bu özel komutla doldurdu .
Arka planda yalnızca sıfır olmayan bir çıkış kodunda beni bilgilendiren bir komutu nasıl uygularım?
Yanıtlar:
:silent exec "!command"
Komutunuz yürütülürken vim oturumunuzun hala meşgul olacağını unutmayın. Bu Vim'in senkron doğasından kaynaklanmaktadır. CTRL + z tuşlarına basarak (arka plana Vim göndermek için) kabuğuna geri dönebilir ve daha sonra fg
her zamanki komutla vim'e devam edebilirsin .
Eşzamansız işleri yapmak için, eklenti NeoMake'i kullanarak kolayca yararlanabileceğiniz Tim Papa'nın eklenti vim-dispatch veya eşzamansız komut yürütme için yerel desteği olan NeoVim projesine bakın. Vim'in en son sürümü, zaman uyumsuz görevleri de desteklemektedir.
Bakınız : h: sessiz
:silent !ls
) ... 0 olmayan bir çıkış kodunun düzgün bir çıktısını vermeyin ... Korkarım ki kullanmaktan biraz daha fazlası :silent
...
:silent exec "!ls"
ve :silent !ls
gösterilmediğini de belirtmek isterim.
:silent !ls
: i.stack.imgur.com/1XvS6.png ... ^L
Tekrar düzeltmek için basmam gerekiyor ...
Enter mesajını tetiklemeden bir komut uygulamak için,
Devam etmek için ENTER tuşuna basın veya command yazın
aşağıdaki basit örneği deneyin:
:silent !echo Hello
Sonra Vim'e geri döndüğünde ekranı yenilemek için Ctrl+ L(veya :redraw!
) düğmesine basın .
Yenileme ihtiyacını önlemek için, aşağıdakiler gibi kendi özel komutunuzu tanımlayabilirsiniz:
:command! -nargs=1 Silent execute ':silent !'.<q-args> | execute ':redraw!'
Şimdi, bir kabuk komutu çalıştırmak için yeni Vim komutunu kullanabilirsiniz (not: olmadan ! Ve büyük S ile ):
:Silent ps
Kaynak: Vim Wikia sitesinde " Devam etmek için Vur" komutunu kullanmaktan kaçınmak
:Silent ctags -R . > /dev/null &
arka planda çalışacak gibi komutlara izin verir . Stdout komutunu / dev / null öğesine göndermek, çıkışın vim arabelleğinde görünmesini önler.
Bu, arka planda bir işlemi başlatabilir:
:!slow_command_here > /tmp/output 2>&1 &
Fakat Vim'in işlemin ne zaman tamamlandığını ve nasıl bir marker dosyası kullanacağını öğrenmenin bir yoluna ihtiyacı var:
:!(rm -f /tmp/finished; slow_command_here > /tmp/output 2>&1; echo "$?" > /tmp/finished) &
Şimdi Vim'den sürecin tamamlanıp tamamlanmadığını sık sık kontrol etmesini isteyebiliriz:
:augroup WaitForCompletion
:autocmd!
:autocmd CursorHold * if filereadable('/tmp/finished') | exec "augroup WaitForCompletion" | exec "au!" | exec "augroup END" | echo "Process completed with exit code ".readfile('/tmp/finished')[0] | end
:augroup END
Hey, hoş değil, ama işe yarıyor!
Maalesef yukarıdaki autocmd, siz imleci hareket ettirene kadar tetiklemez. Bir kerede birden fazla arka plan işlemi çalıştırmak istiyorsanız, bu dosyalara ve autocmd grup adına benzersiz kimlikler eklemeniz gerekir.
Dolayısıyla, fazladan bir bağımlılığı kaldırabilirseniz, başka bir cevapta belirtilen vim-dispatch eklentisi gibi denenmiş ve test edilmiş bir çözümü kullanarak daha iyi olabilirsiniz.
Sadece çıkış kodundan ziyade sürecin çıktısını görmek istiyorsanız , yukarıdaki final ile değiştirin :echo
silent botright pedit /tmp/output
Bu önizleme penceresini açar. Bunun yerine quickfix hata listesini kullanmak için:
silent cget /tmp/output | copen
Hızlı düzeltme listesi, hataları kullanarak kolayca gezinmenizi sağlar :cnext
. Ancak copen
imleci açıldığında hızlı bir şekilde pencereye götürür, bu muhtemelen şaşırtıcı / can sıkıcı olacaktır.
(Bunun için bir çözüm ile QF penceresini açmak için olacağını :copen
başlangıçta işlemine başlarken, bu yüzden olacak değil sonunda aramak gerekir.)
Bir süreliğine engellenen bir komut çalıştırıyordum ve çıktıyı gerçekten umursamıyordum. Bu, terminale / emülatöre değil, sisteme bağlı işlemi başlatmak ve tüm çıktıyı / dev / null'a yönlendirmekle yapılabilir. Örneğin:
:silent exec "!(espeak 'speaking in background'&) > /dev/null"
(...&)
arka planda çalışır ve > /dev/null
tüm çıkış yönlendirir /dev/null
(hiçbir şey).
Parantez, çıktıyı bir alt kabuğa (ya da onun gibi bir şeye) hapseder, ancak mevcut kabuğa bağlı olmamanın (büyük bir şey değil) yan etkisi vardır.
Sadece eğer fark vardır , aslında, onu haritalama, şöyle bir şey yapabilirsiniz
nnoremap <silent> <leader>e :!$(espeak 'speaking in the background'&) > /dev/null
Yukarıdakiler komut çubuğunda hiçbir şey göstermeyecek ve ek olarak vim dışındaki terminalde hiçbir şey göstermeyecektir. Eşlenir <leader>
eolan \ evarsayılan olarak.
(Başka bir düzenleme - ve belki de en iyisi). Bu seferki olacak görüntülemek çıktı bunu seçerseniz bir komut:
YENİ BİR SEKME İÇİ:
silent exec "!(echo 'hello. I'm a process! :)') > /tmp/vim_process" | :tabedit /tmp/vim_process
DİKEY BİR ÇARPAN İÇİ:
silent exec "!(echo 'hello. I'm a process :)') > /tmp/vim_process" | :vs /tmp/vim_process
YATAY YAYIN İÇERİĞİ:
silent exec "!(echo 'hello. I'm a process :)') > /tmp/vim_process" | :sp /tmp/vim_process
... ne istersen onu yap
Çıkış kodunu umursamıyorsanız, bununla devam edebilirsiniz:
:call system('/usr/bin/zathura using-docker.pdf &')
v:shell_error
değişken size söyleyecektir
Bunun ihtiyaçlarınızı karşılayıp karşılamadığından emin değilsiniz (arka plan işlemlerinde olduğu gibi işlem yapmaz foo &
- “arka planda” derken bunun ne anlama geldiğinden emin değilsiniz ), ancak özel bir komut aşağıdaki gibi kullanılabilir:
fun! s:PraeceptumTacet(cmd)
silent let f = systemlist(a:cmd)
if v:shell_error
echohl Error
echom "ERROR #" . v:shell_error
echohl WarningMsg
for e in f
echom e
endfor
echohl None
endif
endfun
command! -nargs=+ PT call s:PraeceptumTacet(<q-args>)
Ardından, örneğin:
:PT ls -l
:PT foobar
ERROR #127
/bin/bash: foobar: command not found
Basit bir işlemin system()
yapabileceği bir hata mesajına ihtiyacınız yoksa / istemiyorsanız, v:shell_error
örneğin kontrol edin ve rapor verin echo Error!
.
Gönderen yardım v: shell_error :
v:shell_error shell_error-variable
v:shell_error Result of the last shell command. When non-zero, the last
shell command had an error. When zero, there was no problem.
This only works when the shell returns the error code to Vim.
The value -1 is often used when the command could not be
executed. Read-only.
Example: >
:!mv foo bar
:if v:shell_error
: echo 'could not rename "foo" to "bar"!'
:endif
"shell_error" also works, for backwards compatibility.
foo &
” . Q metninden bir bütün olarak onu ya da diye yorumladım. Ya “dış komut AKA arka plan olarak çalıştır” veya “arka plan işlemi olarak dış komut _and_ olarak yürütün.” . Ağırlıklı olarak Q vb. Başlığına dayanarak cevap verdim - ve “Emin değilim…” üzerine bir yorum ekledim .
Vim 8 iş desteği sundu. Biri, eklentilere güvenmeden arka planda harici komutu çalıştırabilir. Örneğin, geçerli konumda bir markdown sunucusu ( markserv ) çalıştırmak ve vim oturumunu engellememek için:
:call job_start('markserv .')
Bu, mevcut vim işleminin bir alt süreci olarak markserv işlemini başlatır. İle bunu doğrulayabilirsiniz pstree
.
Job_start'ı görün
Aşağıdaki kodu kullanıyorum:
command! -nargs=1 Silent call SilentExec(<q-args>)
function! SilentExec(cmd)
let cmd = substitute(a:cmd, '^!', '', '')
let cmd = substitute(cmd, '%', shellescape(expand('%')), '')
call system(cmd)
endfunction
Şimdi aşağıdakileri yazabilirsiniz
:Silent !your_command
Bu silent !
, sermaye hariç, neredeyse Vim'in yerleşik emri gibi görünüyor S
. İsteğe bağlı !
olarak daha da benzer görünmesini sağlar. system()
Kabuk komutunu tamamen susturmak için yapılan çağrı : ekran yanıp sönmez ve yeniden çizilmez.
(ve bir durum koduna ihtiyacınız olursa, v:shell_error
değişkeni kontrol edebilirsiniz , daha fazla bilgi için yardıma bakın)
AsyncRun bunun için tasarlanmış eğer eklenti, bu Vim8 / NeoVim arka planda kabuk komutları çalıştırın ve QuickFix pencerede görüntü çıkışı sağlar.
Sadece !
komutun yerine :
:AsyncRun ls -la /
Çıktıyı tamamen quickfix penceresinde gizleyebilirsiniz:
:AsyncRun -mode=3 ls -la /
İş bittiğinde, AsyncRun bir seçeneği ileterek sizi bilgilendirecektir -post
:
:AsyncRun -post=some_vim_script ls -la /
Tarafından tanımlanan vim betiği -post
iş bittikten sonra çalıştırılacak.