Önceki komuttan zsh tamamlamaya bağımsız değişkenler ekleme


21

Zsh (hem bash), önceki komutlardan gelen argümanları göstermek için bazı tarihçe kelime açılımlarını kullanabilirsiniz.

Bu örnek, bir önceki komuttan 2. parametrenin !:#genişleme ile alındığını gösterir :

% echo foo bar baz
foo bar baz
% echo !:2
echo bar
bar

Belirli bir argümanın ne kadar # parametresini sık sık unuturum ve hangi argüman olduğunu !:#hatırladığımda yazmak her zaman o kadar hızlı olmaz. meta-.Son argümanı değiştirmeyi biliyorum ama bazen istediğim son argüman değil.

Önceki komuttan argümanları, zsh ile yazdığım herhangi bir komutu tamamlamak için öneri olarak eklemek istiyorum.

Son komuttan bir dizi argüman (0..N) yaratabilen ve belirli bir komuta bağlayabilen bir kabuk fonksiyonunun nasıl oluşturulduğunu çözebildim.

_last_command_args() {
    last_command=$history[$[HISTCMD-1]]
    last_command_array=("${(s/ /)last_command}") 
    _sep_parts last_command_array
}

# trying to get last_command_args to be suggested for any command, this just works for foo
compdef _last_command_args foo

Sekme tuşuna bastığım yerdeyken sadece foo'yu tamamlıyor gibiyim <TAB>:

% echo bar baz qux
bar baz qux
% foo <TAB>
bar   baz   echo  qux 

Bu "foo" komutunu tamamlamak için harika çalışıyor, ancak bunların yaptığım herhangi bir zsh genişlemesinde seçenek olmasını istiyorum. Zstyle tamamlayıcısıyla bir ilgisi olduğunu düşünüyorum, ancak birkaç saatlik hacklemeden sonra derinliğimin düştüğünü anladım.

Önceki komutumdan, zsh içindeki herhangi bir komut için önerilen tamamlamalar gibi argümanları nasıl alabilirim?

Eğer yardımcı olursa, tam zshrc compinstall dosyamı bitbucket'te paylaşmıştım. Birçoğu çeşitli kaynaklardan toplanmış ve bir kısmı kendimi hackledim.

GÜNCELLEŞTİRME:

@Julien Nicoulaud'un cevabı beni yaklaştırdı, almam gereken yere ulaştığını kabul ediyorum.

Özel yapılandırma ile önerilenleri kullanarak:

zstyle ':completion:*' completer _last_command_args _complete

Sekme tamamlamanın yalnızca son komuttaki bağımsız değişkenlerin listesini görüntülemesine neden olduğu için pek çalışmadı (aslında dosya adlarıyla da tamamlandı, ancak bunları görüntülemiyordu). Sırasını değiştirme sırasını _complete _last_command_argsyaptı. Normal dosya isimlerini gösterirdi, fakat last_command_args değil

Bunun, tamamlayıcının çalışmasıyla bir ilgisi olduğunu tahmin ediyorum. Sanırım sadece başarılı bir şekilde geri dönen ilk yöntemden elde edilen çıktıyı gösteriyor, ama tam olarak ne olduğunu anlamak için zsh kaynağını ayrıştırmakta güçlük çekiyorum. _completeHem son argüman komutlarını hem de normal otomatik tamamlama öğelerini gösterecek şekilde bir çağrı eklemek için yöntemimi ayarlayabildim. Tam olarak değil, ama benim için yeterince iyi çalışıyor.

İşte sahip olduğum diğer zstyle eşyaları ile birlikte kullandığım tam işlev:

# adds the arguments from the last commadn to the autocomplete list
# I wasn't able to get this to work standalone and still print out both regular
# completion plus the last args, but this works well enough.
_complete_plus_last_command_args() {
    last_command=$history[$[HISTCMD-1]]
    last_command_array=("${(s/ /)last_command}") 
    _sep_parts last_command_array
    _complete 
}


_force_rehash() {
  (( CURRENT == 1 )) && rehash
  return 1  # Because we didn't really complete anything
}

zstyle ':completion:::::' completer _force_rehash _complete_plus_last_command_args _approximate 

Diğer zstyle çizgileri var, bunun çalışması için gerekli değil, bunun neden benim için işe yaradığını etkileyebilir:

zstyle -e ':completion:*:approximate:*' max-errors 'reply=( $(( ($#PREFIX + $#SUFFIX) / 3 )) )'
zstyle ':completion:*:descriptions' format "- %d -"
zstyle ':completion:*:corrections' format "- %d - (errors %e})"
zstyle ':completion:*:default' list-prompt '%S%M matches%s'
zstyle ':completion:*' group-name ''
zstyle ':completion:*:manuals' separate-sections true
zstyle ':completion:*' menu select
zstyle ':completion:*' verbose yes

Şimdi, eğer file1.txtve ile bir dizindeysem ve file2.txtson echo foo bar bazemrim buydu, tam istediğim şey olan otomatik tamamlama için bunu alıyorum:

% ls
bar   baz   echo  foo 
- files -
file1.txt   file2.txt 

2
Bu muhteşem bir fikir
Michael Mrozek

2
Takviye ^[ .( insert-last-word), copy-earlier-wordhangi hatların ulaştığı arasında kelimeler arasında geçiş yapmayı seviyorum insert-last-word. Senin için .zshrc:autoload copy-earlier-word && zle -N copy-earlier-word && bindkey '^[,' copy-earlier-word
Gilles 'SO-'

@Gilles teşekkürler! Tam otomatik tamamlama işlemini başaramazsam, bu beni işlevsellikten daha fazla yaklaştırır. Zamanın ~% 80'i, eğer son argüman değilse, istediğim 2. son argüman ve C-. + C-, oldukça iyi.
Ted Naleid,

Yanıtlar:


6

Tamamlayıcıyı varsayılan olarak kullanılan tamamlayıcılar listesine ekleyebilirsiniz:

zstyle ':completion:*' completer _last_command_args _complete

1
Herhangi bir _last_command_argstamamlama varsa , diğerleri gösterilmez. Alışılmış olanlara ek olarak onları nasıl elde edersiniz?
Gilles 'SO- kötülük'

1
Cevabınız için teşekkürler, bu benim için bir şeylerin çalışmasını sağlayacak kadar yaklaşmamı sağladı, bu yüzden kabul ediyorum. Farklı yaptığım, yukarıdaki soruya bir güncelleme olarak kaydedildi. Çözümünüz hem son komuttaki argümanları hem de normal tamamlayıcıdaki dosyaları vb. _completeOluşturduğum fonksiyonun içinde besteledim ve istediğim gibi çalışıyor.
Ted Naleid

Haklısın, cevabım doğru değil.
nicoulaj
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.