Wie kann ich jeden Parameter anders automatisch vervollständigen?

Wie kann ich jeden Parameter anders automatisch vervollständigen?

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 _argumentsis where darf nicht leer sein. Wenn Sie eine Nachricht hinzufügen, sehen Sie einige Fortschritte:n:message:actionmessage

_arguments -s \
  "1:username:_ldpguser" \
  "2:database:_ldpgdb" \
  "3:dump file:_ldpgfile"

Die nächste Hürde besteht darin, dass die Hilfsfunktionen nach _argumentsden 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_pgFunktion 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 $USERscheint 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 auch greppräziser formulieren und ihn möglicherweise mit kombinieren grep.
  • Wenn Sie compaddeine 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_filesdas 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 "$@"

verwandte Informationen