Virgülle ayrılmış değerler için basmanın tamamlanması


16

Virgülle ayrılmış parametreler listesi için tamamlama kuralı oluşturmak istiyorum. Örneğin sunucu adları listesini alan bir komut var:

myscript -s name1,name2,name3

Şu anda aşağıdaki tamamlamayı yazmayı başardım:

_myscript () {
  local cur prev opts

  _get_comp_words_by_ref cur prev

  opts='-s'

  servers='name1 name2 name3'

  if [[ ${cur} == -* ]] ; then
    COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
  else
    case "${prev}" in
      -s)
        if [[ "$cur" == *,* ]]; then
          local realcur prefix
          realcur=${cur##*,}
          prefix=${cur%,*}
          COMPREPLY=( $(compgen -W "${servers}" -P "${prefix}," -- ${realcur}) )
        else
          COMPREPLY=( $(compgen -W "${servers}" -- ${cur}) )
        fi
        ;;
      *)
        # do nothing
        ;;
    esac
  fi
}

Ancak en az 2 sorunu var:

  1. Mevcut değer için öneriler, öneklerinde önceki tüm değerleri içerir.
  2. Yinelenen değerleri dikkate almaz.

Bu gibi durumlar için en iyi uygulamalar nelerdir? Belki bash tamamlamalarının csv listeleri için bazı işlevleri vardır?


3
Yardımcı olabilecek şey, virgülle ayrılmış değerleri aşağıdaki gibi yinelenebilir bir listeye ayırabilmenizdir: IFS=, LIST=("$VARIABLE")burada $ VARIABLE virgülle ayrılmış değerlerinizi içerir.
Michael Ehrenreich

2
İyi fikir @MichaelEhrenreich, ama alıntı yapmamalısınız $VARIABLE, aksi halde kelime kırılması olmaz. sadece kullanın IFS=, LIST=($VARIABLE).
Guss

Yanıtlar:


6

Temel olarak, tanımladığınız sorunları düzeltmenin bir yolu yoktur, çünkü bash değerleri COMPREPLYdoğrudan ekranda kullanır ve daha sonra kullanıcının metnini değiştirir - istediğinizi elde etmek için önce olası tamamlamaları oluşturmanız gerekir (sadece ek sunucu adları (öneki olmadan) bash için görüntülenir, ardından bash kullanıcı metnini en uzun çakışmayan dizeyle değiştirmek üzereyken, önek içeren metni oluşturmak için komut dosyanızı tekrar çağırmanız gerekir - ve bash bunun için bir tesisi yok.

Gelebileceğim en iyi şey COMPREPLY, tüm öneki ( COMPREPLY=( "${prefix},"$(compgen -W "${servers[@]}" -- ${realcur}) )) içeren sadece ilk kelimeyle oluşturulmasını sağlamaktır , böylece sadece bir olası tamamlama varsa, otomatik olarak doğru bir şekilde tamamlanırken, birden fazla olası tamamlama varsa , daha sonra bash şu ana kadar yazılanları kaldırmaz (çünkü içindeki ilk kelime COMPREPLYtüm ön eke sahiptir ve bu nedenle o anda yazılan metne eşleşir ve kullanıcının metnini değiştirmek için bash tarafından seçilecektir) ve seçenekleri önek olmadan görüntüleyecektir - hariç zaten öneki içeren bir sözcük için, çıktı şu şekilde görünecektir:

$ command -s banana,a
ananas     apricot    banana,apple

"elma" tamamlanma seçeneklerine göre sıralanır, çünkü "b" ile başlayan öneki taşır - çok kafa karıştırıcı. Bu yüzden bunu önermiyorum.

Kopyalarla ilgili olarak - kopyaları göstermemek için, sadece $prefixparçasına girmeniz (easy IFS="," prefix_parts=($prefix):) ve sonra bunları tekrarlamanız ve sadece $serverslistelenmemiş isimleri bırakmanız gerekir . Yazmak için sıkıcı, bu yüzden burada göstermeyeceğim, ancak nispeten önemsiz yani yönetebileceğinizden eminim :-).

Özetlemek gerekirse, en azından bash'ın size tamamlanmasında yardımcı olmasını bekliyorsanız, giriş seçenekleri için virgülle ayrılmış değerler kullanmanız gerektiğini düşünmüyorum.

Bunun gibi bir seçenek biçimini destekleyebilirsiniz: command -s <server> [<server> [..]]ve sonra -sseçenekten hemen sonra giriş dışında bir girişi tamamlamak için , bir seçenek (eşleşen dize ) bulana kadar $COMP_WORDSdiziden geriye doğru tarama yapın ve "-s" sunucu adı tamamlama işlemini yapmanız gerekir.$COMP_CWORD-*

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.