Ich habe eine Funktion namens load_pg, die wie folgt definiert ist:
load_pg () {
pg_restore --verbose --clean --no-acl --no-owner -h localhost -U $1 -d $2 $3
}
Und ich versuche, jeden Parameter mit dem folgenden Code automatisch zu vervollständigen:
#compdef load_pg
_arguments -s \
"1::_ldpguser" \
"2::_ldpgdb" \
"3::_ldpgfile"
_ldpguser () {
compadd $USER
}
_ldpgdb () {
compadd $(cat config/database.yml | grep -i database | awk '{print $2}')
}
_ldpgfile () {
compadd $(ls *.dump*)
}
Leider passiert nichts, wenn ich TAB drücke. Was mache ich falsch? Ich habe versucht, Code aus demfolgende Antwort
Antwort1
Erste Hürde: Die Syntax eines Arguments to _arguments
is where darf nicht leer sein. Wenn Sie eine Nachricht hinzufügen, sehen Sie einige Fortschritte:n:message:action
message
_arguments -s \
"1:username:_ldpguser" \
"2:database:_ldpgdb" \
"3:dump file:_ldpgfile"
Die nächste Hürde besteht darin, dass die Hilfsfunktionen nach _arguments
den Ausführungen definiert werden. Wenn Sie also die Argumente zum ersten Mal vervollständigen, erhalten Sie eine Fehlermeldung, die besagt, dass eine der Funktionen nicht existiert. Definieren Sie die Funktionen, bevor Sie sie verwenden. Besser ist es, die Definition der _load_pg
Funktion explizit zu machen und sie am Ende der automatisch geladenen Datei aufzurufen. Das sieht umständlich aus, aber so sind die meisten mit zsh gelieferten Multifunktionsvervollständigungsfunktionen geschrieben.
#compdef load_pg
_ldpguser () {
compadd $USER
}
_ldpgdb () {
compadd $(cat config/database.yml | grep -i database | awk '{print $2}')
}
_ldpgfile () {
compadd $(ls *.dump*)
}
_load_pg () {
_arguments -s \
"1:user:_ldpguser" \
"2:database:_ldpgdb" \
"3:dump file:_ldpgfile"
}
_load_pg "$@"
Damit erhalten Sie den Kern der Funktion. Anschließend möchten Sie die einzelnen Funktionen bereinigen. Zumindest:
compadd $USER
scheint sinnlos: Wenn Sie die Funktion immer nur mit Ihrem Benutzernamen aufrufen möchten, warum bauen Sie sie dann nicht ein? Um Benutzernamen zu vervollständigen, rufen Sie auf_users
.- Befehlsersetzung ersetzt alle Leerzeichen. Um Zeilen zu teilen, verwenden Sie die
@
undf
Parametererweiterungsflags. Sie sollten Ihren Befehl wahrscheinlich auchgrep
präziser formulieren und ihn möglicherweise mit kombinierengrep
. - Wenn Sie
compadd
eine Aktion von aufrufen_arguments
, übergeben Sie ihr die kontextbezogenen Optionen in$expl
. - Sie können eine Beschreibung für Abschlüsse mit angeben
_describe
. $(ls *.dump*)
ist eine komplizierte Art*.dump*
, „und wenn es keine Übereinstimmung gibt, tun Sie etwas, das von den aktuellen Shell-Einstellungen abhängt“ zu schreiben.Analysieren Sie nicht die Ausgabe vonls
, mmm, okay? Du könntestN
Glob-Qualifiziererum eine leere Liste von Vervollständigungen zu erhalten, wenn es keine Übereinstimmung gibt. Sie sollten jedoch stattdessen_files
das sich unter anderem um die Vervollständigung von Dateien in Unterverzeichnissen kümmert.
#compdef load_pg
_ldpgdb () {
compadd $expl[@] -- "${(@f)$(<config/database.yml grep -i database | awk '{print $2}')}"
}
_load_pg () {
_arguments -s \
'1:user:_users' \
'2:database:_ldpgdb' \
'3:dump file:_files -g "*.dump*"'
}
_load_pg "$@"