Terminal, xargs ile Vim'i çağırdıktan sonra ağladı


30

Bazen Vim'i şu şekilde kullanarak çağırmayı denedim xargs:

find . -name '*.java' | xargs vim

… Hangi tür işler:

  1. Vim başladığında, aşağıdaki uyarının kısa süre yanıp söndüğünü görüyorum:

    Vim: Warning: Input is not from a terminal
    
  2. İşleri düzenleme - :filestüm .javadosyaları beklendiği gibi doğru şekilde sıralar .
  3. Kurtarıp bırakabilirim.

Bununla birlikte, Vim'den çıktıktan sonra terminalim ağladı:

  • Ne olursa olsun kabuk isteminde yankı yazılmaz.
  • Satır başı hiçbir şekilde görünmez ve satır yayınları yalnızca bazen görünür.

Bu reset(1), terminali yeniden başlatmak için bir komut verinceye kadar devam ediyor .

Bu bir Vim hatası mı, yoksa neden böyle bir uçbirimle etkileşime girdiğinin daha tatmin edici bir açıklaması var mı? Linux ve çeşitli Unices sürümlerinde 7.3 sürümüne (sürüm önemli görünmüyor) kadar Vim'de olduğunu gördüm.

Yani bir geçici çözümden haberdarım vim $(find . -name '*.java'). Benim asıl sorum bu olmasa da diğer geçici çözümler memnuniyetle karşılanacaktır.


Bu siteyi olabildiğince fazla soru ile doldurma isteğinizi anlıyorum, ancak… bu soru yıllar boyunca SO / SU ve başka yerlerde onlarca kez cevaplandı: Vim ve sonları tarafından kullanılamayan xargsbir aptal kullanıyor stdinher şey sonra.
romainl,

1
@romainl Bu sitelerde aktif değilim ve orada sordum hiç görmedim - dürüst.
200_success

Related: superuser.com/questions/336016/… - belki birileri en iyi cevapları büyük bir cevaba ulaştırabilir.
muru

2
Büyük soru - bu bana defalarca oldu. Ayrıca, başka hiçbir SO sitesi kullanmıyorum - eğer vim ile ilgiliyse, burada bulmak istiyorum.
craigp

Yanıtlar:


21

Bu, vim çağrıldığında ve terminal yerine önceki boru hattının çıkışına bağlandığında ve beklenmeyen farklı bir giriş aldığında (NUL'lar gibi) gerçekleşir. Çalıştırdığınızda da aynı şey olur:, vim < /dev/nullbu nedenle resetkomut bu durumda yardımcı olur. Bu, süper kullanıcıdaki ağırlık ile iyi açıklanmıştır .

Eğer kullanıyorsanız finddüzenlemek için dosya adları geçmek için de, gerek yok xargs, sadece kullanım -execörneğinde,:

find . -name '*.java' -exec vim {} +

Kullanmak isterseniz xargsUnix üzerinde, / MacOS kullanmanız gerektiğini -o, parametreyi gibi:

find . -name '*.java' | xargs -o vim

-oKomutu çalıştırmadan önce stdin'i alt süreçte / dev / tty olarak yeniden açın. Bu, xargs'ın etkileşimli bir uygulama çalıştırmasını istiyorsanız kullanışlıdır.

veya:

find . -name "*.java" -type f -print0 | xargs -o -0 vim

Not: Dosya adlarını beyaz boşluklarla kullanmak -print0/ -0destekleyecektir.


find+ BSDxargs

Unix / macOS'ta aşağıdaki geçici çözümü deneyebilirsiniz:

find . -name '*.java' | xargs -J% sh -c 'vim < /dev/tty $@'

Örneğin, komut değiştirme sözdizimini de kullanabilirsiniz :

vim $(find . -name '*.java')
vim `find . -name '*.java`

Alternatif olarak , tty tahsisini zorlamak parallelyerine GNU'yu kullanın, xargsörneğin:

find . -name '*.java' | parallel -X --tty vi

Not: parallelUnix / OSX'te farklı parametreleri olduğundan ve tty'yi desteklemediğinden çalışmayacaktır.

İyi (gibi birçok diğer popüler komutlar sözde tty tahsisini sağlayan -tiçinde ssh), bu yüzden yardım edin.

Diğer öneri kullanmak olacaktır:

İlgili:


GNU’mda xargsyok -J. GNU versiyonunda bulunmayan bir MacOS (BSD) seçeneği gibi görünüyor.
sonraki duyuruya kadar duraklatıldı.

12

Geçici çözüm önerisi: bir dosya sistemi gezgini olarak bir arabellek kullanın

vim -Stdin'den bir yol listesini okumak için komutu kullanın . Vim :help --bunu açıklıyor: 1

Stdin'den okunan metinle dolu yeni bir arabelleği düzenlemeye başlayın. Normalde stdin'den okunacak olan komutlar şimdi stderr'den okunacaktır. Örnek:

find . -name "*.c" -print | vim -

Ardından , aynı tampondaki veya sırasıyla yeni bir bölünmüş penceredeki dosyaya gitmek için gfveya öğesini kullanabilirsiniz Ctrl-wCtrl-f.

Geçici çözüm önerisi: bağımsız değişken listesi

Diğer bir harika yol da Vim'in argüman listesini kullanmak. :argadd **/*.javaKomut yinelemeli geçerli dizin içinde bulunan tüm java dosyaları ile Vim'ın argümanı listeyi oluşturacak. Daha sonra dosyalar arasında hareket etmek için :nextve düğmelerini kullanabilirsiniz :prev.


1 İlk -Vim'e yardım için bir komut satırı seçeneği aramak istediğinizi söyler, ikincisi aslında aradığınız komut satırı bayrağıdır. Bunun :help help-contextgibi daha fazla numara için okuyun .


8

Ayrıca reset, deneyebilirsiniz:

stty sane

bu da terminalinizi tekrar kullanılabilir kılmalıdır.

Açıklamalar için buraya bakınız . Ve her nasılsa, bu bir vim yanlış davranış olarak kabul edilebilir, en azından Neovim şu anda bu konuda yok.


Bu soruya tam olarak cevap vermiyor, ama bana yardımcı oldu, yani +1.
Monica iamnotmaynard'ı 18:16

Bu soruya cevap veriyor;) OP'yi okuduktan sonra sanırım resetyapmalıyım.
Sridhar Sarnobat

1

Bunun nedeni ise xargssetleri stdiniçin /dev/null, oysa vimihtiyaçlarına stdinolmak /dev/tty.


BSD xargs(örneğin Mac) çözümü:

echo -e 'file1\nfile2' | xargs -o vim

-ostdinxarg'ın alt sürecini ( vimbu durumda) olarak ayarlar dev/tty.


GNU xargs(örneğin Linux) çözümü:

GNU seçeneğine xargssahip değil -o. Bunun yerine daha karmaşık bir geçici çözüm kullanmak zorunda kalacaksınız. (Not: İzleyen zerodizgeye sahip olmak çok önemlidir , unutma.)

echo -e 'file1\nfile2' | xargs bash -c '</dev/tty vim "$@"' zero

Ayrıca bir takma ad yapabilirsiniz:

alias vimin='xargs bash -c '\''</dev/tty vim "$@"'\'' zero'
echo -e 'file1\nfile2' | vimin

GNU xargs çözümünün ayrıntılı açıklaması

Adım adım parçalayalım:

echo -e 'file1\nfile2' | xargs bash -c '</dev/tty vim "$@"' zero

1. xargsbasitçe ekler stdinböylece, dizenin sonuna kadar xargsbu yürütme edilecektir:

    bash -c '</dev/tty vim "$@"' zero file1 file2

2. biçimi bash -colup bash -c 'COMMAND_STRING' $0 $1 $2 etc.

"$@"konumsal parametrelere genişler "$1", "$2", vb. Bu yüzden zero, yerini almak için kukla dizeyi (herhangi bir dizge olabilir) eklememiz gerekiyor $0. Aksi takdirde, ilk dosyayı kaybedersiniz.

Böylece "$@", genişledikten sonra , sonunda:

    bash -c '</dev/tty vim file1 file2' 

3. bash -cCOMMAND_STRING dosyasını çalıştıracak:

    </dev/tty vim file1 file2 

</dev/ttyayarlar stdiniçin /dev/ttyböylece viminteraktif modda çalışabilir.


+1 Bu, oy sayısının en yüksek olduğu cevabın bir kopyası gibi görünüyor, fakat değil. Yer $0tutucu (burada "sıfır") anahtardır.
sonraki duyuruya kadar duraklatıldı.

0

Tüm bu cevapları eksik buldum. Xargs sorunu ile mücadele ettikten sonra, en basit yolu - benim için! - Bu arama-açma işlemlerini jenerik bir kutuda yapmak:

vim -O `grep -lir mySearchTerm *`

Kullandığım hiçbir sorunu var findolan xargsve grepfakat ben sözdizimi rahatsız edici buluyorum. Üstelik vimIDE olarak kullanan ve terminali kullanan ve sürekli olarak dosyaları araştıran günlük kodlayıcı olarak, kullandığım şey bu.

find . -path ./node_modules -prune -o -name '*.js' | xargs grep -i mySearchTermDosyaları vim ve diğer yöntemlerle açmak için bir zaman ve yer vardır . Benim için bu nadiren olur.

Umarım bu birine yardımcı olur.


2
FWIW, eski backticks gösterimini kullanmamanız ve $(...)yerine kullanmanız önerilir . Komut satırınızdaki bir komut dosyasındaki kadar önemli değil ama bence cevaplarınızda kullanmak daha iyi :) ( burada ve burada referanslar )
statox
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.