Bash-Vervollständigung für durch Kommas getrennte Werte

16

Ich möchte eine Vervollständigungsregel für eine durch Kommas getrennte Parameterliste erstellen. Ich habe zB einen Befehl, der eine Liste von Servernamen empfängt:

myscript -s name1,name2,name3

In diesem Moment habe ich es geschafft folgendes zu schreiben:

_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
}

Es hat aber mindestens 2 Probleme:

  1. Vorschläge für den aktuellen Wert enthalten alle vorherigen Werte in ihrem Präfix.
  2. Es werden keine doppelten Werte berücksichtigt.

Was sind die Best Practices für solche Fälle? Vielleicht hat bash-completions einige gebündelte Funktionen für CSV-Listen?

diffycat
quelle
3
Was helfen könnte, ist, dass Sie kommagetrennte Werte wie folgt in eine iterierbare Liste aufteilen können: IFS=, LIST=("$VARIABLE")wobei $ VARIABLE Ihre kommagetrennten Werte enthält.
Michael Ehrenreich
2
Gute Idee @MichaelEhrenreich, aber das darf man nicht zitieren $VARIABLE, sonst kommt es nicht zum Wortbruch. benutze einfach IFS=, LIST=($VARIABLE).
Guss

Antworten:

6

Grundsätzlich gibt es keine Möglichkeit, die von Ihnen beschriebenen Probleme zu beheben, da bash die Werte COMPREPLYdirekt in der Anzeige verwendet und dann den Text des Benutzers ersetzt. Um das zu erhalten, was Sie möchten, müssen Sie zunächst die möglichen Vervollständigungen (nur die zusätzlichen) generieren Servernamen (ohne Präfix), damit die Bash angezeigt wird. Wenn die Bash den Benutzertext durch die längste nicht in Konflikt stehende Zeichenfolge ersetzen soll, muss das Skript erneut aufgerufen werden, um den Text mit dem Präfix und der Bash zu generieren hat keine möglichkeit dafür.

Das Beste, was ich mir einfallen lassen könnte, ist, dass COMPREPLYnur das erste Wort mit dem gesamten Präfix ( COMPREPLY=( "${prefix},"$(compgen -W "${servers[@]}" -- ${realcur}) )) generiert wird. Wenn es also nur eine mögliche Vervollständigung gibt, wird sie automatisch korrekt vervollständigt, und wenn es mehr als eine mögliche Vervollständigung gibt , dann entfernt bash nicht, was bisher eingegeben wurde (da das erste Wort COMPREPLYdas gesamte Präfix enthält und somit mit dem aktuell eingegebenen Text übereinstimmt und durch bash ausgewählt wird, um den Text des Benutzers zu ersetzen) und zeigt die Optionen ohne das Präfix an - außer Für dieses eine Wort, das bereits das Präfix enthält, sieht die Ausgabe folgendermaßen aus:

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

"apple" als letztes in den Vervollständigungsoptionen sortiert, da es das Präfix trägt, das mit "b" beginnt - sehr verwirrend. Deshalb empfehle ich das nicht.

In Bezug auf die Duplikate - um keine Duplikate anzuzeigen, müssen Sie nur $prefixin ihren Teil einbrechen (easy IFS="," prefix_parts=($prefix):) und dann darüber iterieren und nur $serversdie Namen belassen , die noch nicht aufgeführt sind. Es ist mühsam zu tippen, deshalb werde ich es hier nicht zeigen, aber relativ trivial, also bin ich sicher, dass du es schaffen kannst :-).

Zusammenfassend sollte ich nicht sagen, dass Sie kommagetrennte Werte für die Eingabeoptionen verwenden sollten, zumindest wenn Sie erwarten, dass bash Ihnen beim Abschluss hilft.

Sie können ein Optionsformat wie das folgende unterstützen: Wenn Sie command -s <server> [<server> [..]]andere als die unmittelbar nach der -sOption angegebenen Einträge vervollständigen möchten, durchsuchen Sie das $COMP_WORDSArray einfach von $COMP_CWORDbis Sie eine Option (Zeichenfolge, die übereinstimmt -*) finden und wenn "-s", dann Sie müssen den Servernamen vervollständigen.

Guss
quelle