Zsh'nin vi modunun bash vi modundaki gibi davranmasını nasıl sağlayabilirim?


24

Genel zsh hızını gerçekten sevdim ama iki şey beni rahatsız ediyor.

  1. Geçmiş araştırmasına ulaşmak için kaçışa vurmakla slash vurmak arasında bir süre beklemek zorundayım (çok hızlı bir şekilde slash vurursa yazıyor zsh: do you wish to see all 514 possibilities (172 lines))
  2. Vuruş nedeniyle ekleme moduna girdikten sonra , aveya Aekleme moduna girdiğim noktadan geriye gidemiyorum.

2'nin klasik vi gibi olduğunu biliyorum ama vim stilini daha çok seviyorum.


Herhangi biri çifte kaçmanın çok can sıkıcı sorununa giriyorsa i, ekleme moduna geri dönmek için iki kez vurmanız gerekebilir , bu düzeltmeyi şiddetle tavsiye ederim !
cchamberlain

Burada iyi bir özet de var: dougblack.io/words/zsh-vi-mode.html
jackcogdill

Yanıtlar:


22

(1). Bazı nedenlerden dolayı, bindkey "/" e geldiğinde garip davranır: <esc>ardından hızlı bir şekilde /yorumlanır <esc-/>. (Bu davranışı geçen gün gözlemledim; neyin sebep olduğuna tam olarak emin değilim.) Bunun bir hata mı yoksa bir özellik mi olduğunu ve eğer devre dışı bırakılabiliyorsa bir özellik olup olmadığını bilmiyorum, ancak oldukça kolay bir şekilde çalışabilirsiniz. .

Bu anahtar combo muhtemelen _history-complete-olderistenmeyen sonuçlara neden olan bağlı - bindkey -Lbu durumda olup olmadığını görmek için kullanabilirsiniz .

Her neyse, sen ödün sakıncası yoksa gerçek <esc-/> bu tipleme böylece (kiriş olarak, birbirine preslenmiş) bağlama, sen o vi modlu geçmiş araması komutuna yeniden bağlanmaktadır edebilir <esc>ardından /herhangi yazarak aynı şeyi yapar hız. =)

Bu bir akor olarak kabul edileceğinden, ilk önce vi komut moduna girme etkisine sahip olmayacağından, ilk önce bunun yapıldığından emin olmalıyız. İlk önce, bir fonksiyon tanımlamanız gerekir; fpatheğer kullanıyorsanız, içine bir yere koyun, yoksa .zshrc'nize koyun:

vi-search-fix() {
zle vi-cmd-mode
zle .vi-history-search-backward
}

Gerisi .zshrc'nizin her ikisine de gider:

autoload vi-search-fix
zle -N vi-search-fix
bindkey -M viins '\e/' vi-search-fix

Gitmek iyi olmalı.

(2). Geri silme tuşunu aşağıdaki gibi düzeltebilirsiniz:

`bindkey "^?" backward-delete-char`

Ayrıca, diğer vi stili komutları için benzer davranışlar istiyorsanız:

bindkey "^W" backward-kill-word 
bindkey "^H" backward-delete-char      # Control-h also deletes the previous char
bindkey "^U" backward-kill-line            

Altında ^[/değildi \e/, ama ikisi de kaçmanın söylemenin geçerli yolları. Değişim mükemmel çalışıyor. Şimdi onunla daha fazla oynayacağıma göre, zsh'nin vi modu bash ile karşılaştırıldığında berbat görünüyor (ya da en azından varsayılan olarak tamamen yapılandırılmamış). Bunun bir örneği, arama geçmişinden sonra sizi ekleme moduna bırakmasıdır. Bir sonraki arama öğesini bulmak için n 'ye basmak için komut moduna geri dönmem gerekiyor.
Chas. Owens

1
Başka örneklerin var mı bilmiyorum, ama bahsettiğin şey benim suçum, zsh'in değil. =) Olan şey şu ki vi insert modunda bir vi-cmd modu editörü komutu bağladım - komut kabuğu zaten cmd modunda bekler ve buna göre davranır. Önce "cmd moduna girin" komutunu çağıran ve sonra yürüten bir editör komutu yazmamız gerekir .vi-history-search-backward. Yazacağım ve cevabımı düzenleyeceğim - bugün daha sonra tekrar kontrol edin.
Marshall Eubanks

Tamam, cevabımı güncelledim. Denemek.
Marshall Eubanks,

(2) ile ilgili olarak bindkey | grep <searchterm>, terimlerden herhangi birini yaptığımda , hepsi tarafından eklenir vi-. bindkeyÖneki olmayan komutlar ayarlamam gerekir vi-mi?
adam_0 13.03.2013

1
Teşekkür ederim. Bu hackler (ve altındaki wjv'ler) zsh'nin vi modunu kullanılamaz durumdan mükemmel hale getirmektedir. Size oy kullanabilmem için bir süper kullanıcı hesabı oluşturdum. :-)
ctrueden

14

Ben sadece soruyu ele alacağım (1).

Senin problemin KEYTIMEOUT. Zshzle'dan (1) alıntı yapıyorum:

ZLE, terminalden bir komut okurken, bazı komuta bağlı olan ve aynı zamanda daha uzun ciltli bir dizenin öneki olan bir sekans okuyabilir. Bu durumda ZLE, daha fazla karakterin yazılıp yazılmadığını görmek için belirli bir süre bekleyecek ve eğer değilse (veya daha uzun bir dizeyle eşleşmiyorsa), ciltleme işlemini yürütecektir. Bu zaman aşımı KEYTIMEOUT parametresi tarafından tanımlanır; varsayılan değeri 0,4 sn'dir. Önek dizgisinin kendisi bir komuta bağlı değilse zaman aşımı olmaz.

Bu 0,4'ler ESC'ye çarptıktan sonra yaşadığınız gecikmedir. Düzeltme, KEYTIMEOUT'u, kabuk başlangıç ​​dosyalarından birinde 0.01 saniye olarak ayarlamaktır:

export KEYTIMEOUT=1

Maalesef bunun etki yaratma etkisi var: Başka şeyler ters gitmeye başlıyor…

Öncelikle, vi komut kipinde şimdi bir sorun var: ESC yazmak imlecin askıda kalmasına neden olur ve daha sonra yazdığınız karakter yutulur. Bunun nedeni, ESC'nin vi komut modunda varsayılan olarak hiçbir şeye bağlı olmamasıdır, ancak ESC ile başlayan çoklu karakter widget'ları vardır (imleç tuşları!). ESC'ye bastığınızda, ZLE bir sonraki karakteri bekler… ve sonra onu tüketir.

Düzeltme için ESC bağlamak olduğunu şey böylece sağlanması, komut modunda bir şey $ KEYTIMEOUT centiseconds sonra zle geçirilir. Şimdi ESC ile başlayan ciltleri bu kötü etkiler olmadan komut modunda tutabiliriz. ESC'yi, kendi kendine eklemekten daha az müdahaleci bulduğu zil karakterine bağlarım (ve kabuğum susturuldu):

bindkey -sM vicmd '^[' '^G'

2017 Güncellemesi:

undefined-keyWidget - ESC'yi bağlamak için daha iyi bir çözüm buldum . Bu cevabı başlangıçta yazdığımda bu widgetın zsh ile hazır olup olmadığından emin değilim.

bindkey -M vicmd '^[' undefined-key

Sonraki sorun: Varsayılan olarak, vi ekleme modunda ^ X ile başlayan bazı iki anahtarlı widget'lar vardır; $ KEYTIMEOUT tamamen ayarlanmışsa bunlar kullanılamaz hale gelir. Yaptığım, vi ekleme modunda ^ X bağlantısını açmak (varsayılan olarak kendi kendine eklenir); bu, iki anahtar widget'ın çalışmaya devam etmesini sağlar.

bindkey -rM viins '^X'

Kendiliğinden geçme bağını kaybedersiniz, ancak elbette başka bir şeye bağlayabilirsiniz. (Bilmiyorum, çünkü faydasım yok.)

Son sorun (Şimdiye kadar buldum): $ KEYTIMEOUT ayarını yaptığımız için "kaybettiğimiz" bazı varsayılan tuş bağları var, bunun yerine, imleç tuşları olmayan vi insert modunda ESC ile başlayanlar . Ben şahsen ^ X ile başlamak için onları yeniden bağlarım:

bindkey -M viins '^X,' _history-complete-newer \
                 '^X/' _history-complete-older \
                 '^X`' _bash_complete-word

2018 Güncellemesi:

Yukarıdaki bölümün tamamını (“Güncelleme 2017” den sonra) mutlaka gerekli değildir. META tuşunu kullanarak klavye eşlemelerinde ESC'ye eşdeğer olacak şekilde ayarlamak mümkündür:

bindkey -mv

Bu nedenle mümkün değildir bir lider yerine (Modern klavyelerde ALT veya OPT) olarak META basarak ESC başlayacak keybinding ^ X unbind için ve erişim.

Kiddle ve arkadaşlarının Bash'den Z Shell'e kitabına erişiminiz varsa , ESB ve META'nın klavyelerdeki denkliği sayfa 78-79'daki Bölüm 4 kenar çubuğunda tartışılmaktadır.


Teşekkür ederim. Bu hackler (ve yukarıdaki marshaul'lular da) zsh'nin vi modunu kullanılamaz durumdan mükemmel hale getirmektedir. Size oy kullanabilmem için bir süper kullanıcı hesabı oluşturdum. :-)
ctrueden

1
Teşekkürler! Tüm bunlardan sonra, temelde bir zsh işlevselliğini kullanılabilir kılmak için esasen bir kesmek ve bir geçici çözüm olan şeye ihtiyacımız olduğuna biraz endişe duyuyorum!
WJV
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.