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:
- Vorschläge für den aktuellen Wert enthalten alle vorherigen Werte in ihrem Präfix.
- 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?
bash
autocomplete
diffycat
quelle
quelle
IFS=, LIST=("$VARIABLE")
wobei $ VARIABLE Ihre kommagetrennten Werte enthält.$VARIABLE
, sonst kommt es nicht zum Wortbruch. benutze einfachIFS=, LIST=($VARIABLE)
.Antworten:
Grundsätzlich gibt es keine Möglichkeit, die von Ihnen beschriebenen Probleme zu beheben, da bash die Werte
COMPREPLY
direkt 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
COMPREPLY
nur 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 WortCOMPREPLY
das 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:"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
$prefix
in ihren Teil einbrechen (easyIFS="," prefix_parts=($prefix)
:) und dann darüber iterieren und nur$servers
die 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-s
Option angegebenen Einträge vervollständigen möchten, durchsuchen Sie das$COMP_WORDS
Array einfach von$COMP_CWORD
bis Sie eine Option (Zeichenfolge, die übereinstimmt-*
) finden und wenn "-s", dann Sie müssen den Servernamen vervollständigen.quelle