Özel komutlar için dinamik zsh otomatik tamamlama


19

Yazdığım bazı özel işlevler için tamamlama işlevleri yazmaya çalışıyorum, ancak en temel işlevlerle bile gerçekten mücadele ediyor gibi görünüyor.

Örnek bir fonksiyon:

function eb_instances() {
    if [ "$#" -ne 2 ]; then
        echo "Usage eb_instances <aws profile name> <environment name>"
        echo "e.g.:"
        echo " eb_instances production kraken-prod-api"
        return 1
    fi

    aws ec2 describe-instances --filters  "Name=instance-state-name,Values=running"   "Name=tag:Name,Values=$2" --profile=$1 --output=json | jq -r ".Reservations[].Instances[].PrivateIpAddress"
}

Bunun iki konumsal argümanı vardır <aws profile name>ve<environment name>

Tamamlama seçeneklerini <aws profile name>çalıştırarak dinamik olarak kullanılabilir olmasını sed -n -E 's/\[([a-zA-Z0-9_\-]+)\]/\1/p' ~/.aws/credentials | tr \\n ' 've tamamladığım <environment name>başka bir işlevi çalıştırarak tamamlanmasını dinamik olarak kullanılabilir olmasını istiyorum eb_names.

Belgeleri oldukça seyrek ve takip etmesi zor buluyorum. Ben de benzer komutlar için zsh-completions repo gördüm ama ihtiyacım olana benzer bir şey bulmak gibi görünmüyor.

Başlamak için herhangi bir yardım çok takdir edilecektir!

Güncelleme

@ Cuonglm cevabına dayanarak kullandım:

#compdef ebinstances

_ebinstances() {
  local state

  _arguments \
    '1: :->aws_profile'\
    '*: :->eb_name'

  case $state in
    (aws_profile) _arguments '1:profiles:($(sed -n -E "s/\[([a-zA-Z0-9_\-]+)\]/\1/p" ~/.aws/credentials | tr \\n " "))' ;;
              (*) compadd "$@" foo bar
  esac
}

_ebinstances "$@"

Orijinal soruda bahsetmeyi unuttuğum şey, aynı zamanda ikinci argümanın tamamlanmasının ilkine (her ikisi de bazı kodları yürüten dinamik tabanlı) bağımlı olmasını istediğimdi:

$ eb_instances <cursor>TAB
cuonglm  test

istediğim tamamlamaları alır. Birini seçtikten sonra ilkini söyleyin ve otomatik tamamlamayı deneyin:

$ eb_instances cuonglm <cursor>TAB

Ben yürüterek tamamlama seçeneklerini oluşturmak istiyorum eb_names cuonglmve doğru aday olup olmadığını, mümkünse de, örneğin tamamlama üzerinde ayrıntılı inceleme foo-bar,

$ eb_instances cuonglm foo<cursor>TAB

Tamamlama seçeneklerini yürüterek oluşturmak istiyorum eb_names cuonglm foo

Yanıtlar:


23

İlk defa, zsh Tamamlama Sistemi çok karmaşık ve anlaşılması zor görünüyor. Bir örnek deneyelim.

Bilmeniz gereken ilk şey, zshtamamlama sisteminden tamamlama işlevlerini yükleyecektir $fpath. Tamamlama dizininizin şu konumda görüntülendiğinden emin olun:

print -rl -- $fpath

(Eğer oh-my-zsh kullandıysanız , orada .oh-my-zsh/completionsvar $fpath, sadece oluşturabilir ve tamamlama işlevlerinizi oraya koyabilirsiniz)

Şimdi, işleviniz için bir tamamlama dosyası oluşturmanız gerekir, adı alt çizgi _ile ve işlev adınızla başlamalıdır . Sizin durumunuzda adı _eb_instances.

Bu _eb_instancesdosyalara şu satırları ekleyin :

#compdef eb_instances

_eb_instances() {
  local state

  _arguments \
    '1: :->aws_profile'\
    '*: :->eb_name'

  case $state in
    (aws_profile) _arguments '1:profiles:(cuonglm test)' ;;
              (*) compadd "$@" prod staging dev
  esac
}

_eb_instances "$@"

Bitirdiniz. Dosyayı kaydedin ve tamamlamayı test etmek için yeni bir oturum başlatın. Bunun gibi bir şey göreceksiniz:

$ eb_instances <cursor>TAB
cuonglm  test

$ eb_instances cuonglm <cursor>TAB
dev      prod     staging

_argumentsİşlev, statedeğişken hakkında zsh tamamlama sistemi belgelerini okuyabilirsiniz . Ayrıca değiştirmeniz gereken (cuonglm test)sizin ile sedkomuta ve değişim prod staging devsizin için eb_namesişleve.

1. bağımsız değişkeni geçen 2. bağımsız değişken tabanını oluşturmak istiyorsanız, $words[2]değişkeni kullanabilirsiniz :

case $state in
  (aws_profile) _arguments '1:profiles:(cuonglm test)' ;;
            (*) compadd "$@" $(echo $words[2]) ;;
esac

echoGerçek işlevinizle değiştirin , sizin durumunuzda, öyle $(eb_names $words[2]).

Hala bunu gerçekleştirmek zor düşünüyorsanız, sadece tanımlamak _eb_instancesve eb_instancessizin de .zshrcolduğu gibi daha sonra çağrı tamamlama:

compdef _eb_instances eb_instances

Tamamlama sistemini aşağıdakilerle başlatmanız gerekir:

autoload -U compinit
compinit

(Kullandıysanız oh-my-zsh, yüklendi)


Ayrıntılı yanıt için çok teşekkürler. Yapmak için iyi belgelenmiş bir yol bulamıyorum gibi olsa da, tamamlama seçeneklerim cuonglm testsed -n -E 's/\[([a-zA-Z0-9_\-]+)\]/\1/p' ~/.aws/credentials | tr \\n ' '
dinamikse

@zsquare: Sadece değiştirmek (cuonglm test)ile ($(sed -n -E 's/\[([a-zA-Z0-9_\-]+)\]/\1/p' ~/.aws/credentials | tr \\n ' '))değişim, compadd "$@" prod staging deviçin compadd "$@" $(eb_names).
cuonglm

bu biraz gergin olabilir, ama, eb_namesilk argümanı geçmesi gerektiğini söylemeyi unuttum , yani, productionya da stagingnasıl yapabilirim? Çok teşekkürler, bununla ilgili birkaç şey aldım.
zsquare

Yani eb_names'e geçmek için ilk argümanı kullanmak istemedim. Ben referans çalıştı $1ya $2, ama nafile.
zsquare

2
Sen bir büyücüsün Harry.
cambunctious
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.