Avfs sahte dizinlerini zsh ile tamamlamak


37

Bazı durumlarda “sahte” dosyaları tamamlamak için zsh'nin tamamlama sistemini nasıl ayarlayabilirim?

Daha doğrusu, AVFS dosya sistemi her arşivin yanında bir "sahte dizin" oluşturarak arşivleri dizin olarak gösterir. Varsayılan olarak, tüm dizin hiyerarşisini bağlama noktasının altında çoğaltır ~/.avfs. Ayrıca, ~/.avfsarşiv dosyası gibi her arşiv dosyası /tmp/foo.zipiçin arşivin içeriğini gösteren ~/.avfs/tmp/foo.zipbir dizin vardır ~/.avfs/tmp/foo.zip#. Ancak bu fazladan dizin aşağıdaki listede görünmemektedir ~/.avfs/tmp: yalnızca açıkça talep edildiğinde bulunur. (Bu, bazı otomatik sayaçların nasıl çalıştığına benzer.)

mountavfs
cd ~/.avfs/tmp/foo.zip\#

Yukarıdaki gibi bir komut yazdığımda , böyle bir dizin olmadığı için foo.zip#altında tamamlama olarak görünmüyor ~/.avfs/tmp/. Zsh'ye, tam yolu ¹ ile $arceşleşen bir dosya ~/.avfs/**/*.(tgz|zip)olduğunda, adı verilen bir dizin olduğunu varsayması gerektiğini nasıl söyleyebilirim ${arc}#?

(Tamamlamanın , yalnızca komut için değil, her çağrıyla _filesveya istemesiyle çalışmasını istediğimi unutmayın . Mümkünse , işlev kodunu çoğaltmamam gerektiğini tercih ederim .)_dirscd_files

¹ ve tüm uzantıları


~ / .Avfs, tüm dosya sisteminin bir "kopyasını" içeriyor mu?
ctrl-alt-delor

@richard Evet, herkes /path/to/foogörünür ~/.avfs/path/to/foo.
Gilles 'SO- kötülük olmayı bırak'

Bu düzeltilmesi daha kolay olabilir avfs. #Desteklediği dizelerle eşleşen herhangi bir dosya için varsayılan dizin girişini sunmuşsa veya sihir bile bir #giriş olması gereken dosyaları bir dizindeki dosyaları sınamışsa, tamamlanma işe yarayacaktır. Sanırım findşimdi sıkıştırılmış dosyalar arasında dolanacak gibi bir şey için bir performans vurgusu olacaktı.
Matt

Yanıtlar:


1

Sahte bir cevap bu sahte soru için yetersiz görünüyor; automount dizinleri için zsh yerleşik desteği fake-files dir:names, içindeki dosya düzenlerinde değil, dizinlerde ( ) çalışır . Bu uygun olabilir bir dizin, belirli adlandırılmış dosyaları eklemek için kullanışlıdır automountveya sshfsveya NetApp .snapshottip kurulumları nerede dizin-to-be-monteli olan bilinen statik isim, ALAS.

autoload -U compinit
compinit
zstyle ':completion:*' fake-files $HOME/.avfs:'ALAS POOR YORICK'

zshall(1)"isimler" dizgedir ve deneyler meta karakterleri (örneğin #veya \#veya '*(e:"echo hi":)') "çeşitli şekillerde" çalışmadığını "gösterir, bu yüzden fake-filesifadenin isimleri kısmına bir küre sokmak için bildiğim hiçbir yol yoktur . (Geçmek Src/Zle/computil.c, adların tam olarak ne olduğunu ortaya çıkarabilir, ancak bu daha işe yarayabilir.) (Ayrıca, arşiv dosyalarını adlandırmak için dizin konumunda özyinelemeli glob'lar kullanmak uçmadı, ancak yine de ne kadar fake-filesizin verdiğini görmek için C dalışı sürecek uzaklaş.)

İle compdef, tek listeleyebilirsiniz .avfsdizin tamamlama:

compdef '_files -g $HOME/.avfs/\*' -p \^
function andthehash {
  reply=($REPLY $REPLY\#)
}
compdef "_files -g $HOME/.avfs/'*(+andthehash)'" -p \^

Bu başarısız olmadıkça, sadece #önemli olmadığında dosyaları göstereceği için ve böylece onları tamamlayamaz. (Bu durum için olmasa da, bu formun verimli kullanımları vardır.)

Kullanmak zstyle, aşağıdakilerle sizi daha da yakınlaştırır .zshrc:

autoload -U compinit
compinit

function UnderAVFS {
  local pdir
  [[ -z $1 ]] && return 1
  pdir=$1:a
  [[ ! -d $pdir ]] && pdir=$pdir:h
  [[ ! -d $pdir || $pdir == . ]] && return 1
  while [[ $pdir != / ]]; do
    [[ $pdir == $HOME/.avfs ]] && return 0
    pdir=$pdir:h
  done
  return 1
}

function AVFSExtras {
  if UnderAVFS $REPLY; then
    reply=($REPLY)
    # TODO embiggen list of archive suffixes
    [[ $REPLY == *.(bz2|tbz2) ]] && reply+=($REPLY\#)
  fi
}

# Try to match avfs, otherwise the default pattern. Probably could greatly
# benefit from caching, to avoid hits on UnderAVFS function.
zstyle ':completion:*' file-patterns '*(+AVFSExtras):avfs-files' '%p:all-files'

Bununla birlikte, yalnızca \#/bite kadar tamamlayabilir (varsayılan bir avfs kurulumuyla bir debian sıkma üzerinde), ancak bir arşiv için sanal dosya sistemine giremez, bu yüzden arşivleri tamamlamak için ek bir çalışma gerekir. Var olmayan dizinlerin inandığına inanmanın daha zarif bir yolu olmadığı sürece, _call_program ... lsbitirme için bu satırlar boyunca veya bir şeyle tahmin ediyorum .\#zsh

Kötü haber! Tamamlama _path_filessahte dizinler için yapmaz ; Bunun zsh globbing ile ilgili olduğundan şüpheleniyorum. Hem zsh 4. üzerinde bir şey var hem de zsh 5.0.8 bu sorunu ortaya koyuyor. Bu yüzden, tam bir düzeltmenin yamalar _path_filesya da bu sahte dirsekler üzerinde tamamlanan farklı bir şeyler yazmaları gerekeceğinden şüpheleniyorum . Biri, bunun nedeninin başarısız olduğunu araştırmak istiyorsa ls /root/.avfs/root/sometar.gz\#/, o yazmanın sonunda ve sonunda yazarak control-xve sonra da varsa ?, bindkey -ebu _complete_debugkeycombo'ya bağlı olduğunu varsayarak ve tamamlayarak hata ayıklama izi oluşturulabilir .


0

Zsh içerisinde compctl -K, kendi işlevinizi üretim tamamlama seçeneklerine kaydetmek için kullanabilirsiniz . Örneğin:

compctl -f -c -u -r -K myAVFScompletion "*" -tn

O zaman kendi işlevinizi tanımlamanız gerekir:

myAVFScompletion () {
    read -c COMMAND ARGS

    # Decide what paths you want to suggest completion for
    # by looking inside the ~/.avfs folder.

    # Place your suggestions into an array:
    reply=( a_path b_path ... )
}

Açıkçası, yukarıdakilerin biraz daha fazla çalışmaya ihtiyacı var ama başlaması gereken bir şey var.

Benzer bir (ancak farklı) özel tamamlama işlevi bash için kaydedilebilir.

İşte bash ve zsh için yapılan uygulamalara bir örnek . (Komutun kılavuz sayfasından seçenekleri kapatarak komut satırı seçeneklerinin tamamlanmasını sağlar.)

Ve işte tamamlama işleviniz içinde işe yarayabilecek şeyler hakkında hızlı tahminler:

if [[ -d "$ARGS#" ]]
then reply=( "$ARGS#" )
else reply=
fi

Ya da belki bu:

reply=( $(find ~/.avfs -type f -name "*.tgz" -or -name "*.zip" | sed 's+$+#+') )

İyi şanslar!


Tamamlama işlevini nasıl yazacağımı biliyorum, çok teşekkür ederim. Sorun, dosyalar için mevcut tamamlama mekanizmasının nasıl değiştirileceğidir. "Yeni" tamamlama mekanizmasını kullandığımı unutmayın compctl, yani ne yaptığını değiştirmek istiyorum _files. Cevabınız hiç yardımcı değil.
Gilles 'SO- kötülük' dur

@Gilles Alev savaşı başlatmamak ve yanlış çıkma riski altında, en azından denedi ... Bu cevapsız "tavan arasına" oturmuş 2 yıl artı ... +1 t .
eyoung100

@ eyoung100 Lütfen çaba için +1 vermeyin (bu çaba burada görünmez). Faydalı olmayan yanıtları kaldırmak siteye zarar verir.
Gilles 'SO- kötülük yapmayı bırak'
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.