Comment puis-je obtenir mes fonctions shell pour utiliser l'auto-complétion existante dans zsh?

10

J'ai quelques fonctions de shell définies dans mon .zshrcqui économisent sur la frappe et permettent l'intégration avec l'écran. Par exemple:

function s()
{
     screen -t "$1" ssh "$@"
}

Cependant, lorsque j'utilise ces fonctions shell, je ne peux pas profiter des fonctionnalités intégrées de complétion de commande de zsh. (Dans le cas de SSH, compléter automatiquement les noms d'hôte sur la base de known_hosts et ssh_config). Quelle est la meilleure façon de se connecter aux mécanismes de complétion existants pour les commandes pour lesquelles j'ai créé des wrappers?

ÉDITER:

Merci à Gilles pour sa réponse ci-dessous. L'utilisation de compdef semble être le moyen de le faire, mais il est intéressant de noter que cela ne semble pas fonctionner de manière uniforme. Dans ce cas, j'ai la configuration suivante:

function s()
{
    screen -t "$1" ssh "$@"
}

function m()
{
    screen -t "man.$1" man "$1"
}

compdef $_comps[man] m
compdef $_comps[ssh] s

L'achèvement de ma fonction wrapper 'm' fonctionne comme prévu, mais l'achèvement de ma fonction 's' ne fonctionne pas; plutôt que d'essayer de compléter les noms d'hôte, il semble revenir à la saisie semi-automatique par défaut en me fournissant une liste de fichiers lorsque je clique sur "tab". Y a-t-il une bizarrerie dans la façon dont l'achèvement de SSH est géré, ce qui signifie que je dois faire quelque chose de plus?

Murali Suriar
la source

Réponses:

9

J'utilise la fonction suivante pour dire qu'une fonction ou un alias ou un script wrapper (par exemple s) doit être complété comme une commande existante (par exemple ssh):

compdefas () {
  local a
  a="$1"
  shift
  compdef "$_comps[$a]" "${(@)*}=$a"
}
compdefas xterm cxterm uxterm xterm-color

Certaines commandes d'achèvement s'appliquent à une famille de fonctions et lisent le premier mot de la ligne de commande pour déterminer la commande particulière à exécuter. Par exemple, les commandes ssh, scp, sftpet quelques autres sont tous terminés par la fonction _ssh. Dans ce cas, vous devez indiquer à la fonction d'achèvement à quel «service» votre fonction est similaire (par défaut, le service est le nom de l'exécutable, ici le nom de votre fonction).

_s () {
  local service=ssh
  _ssh "$@"
}
compdef _s s
Gilles 'SO- arrête d'être méchant'
la source
Merci - j'ai supposé que compdef était ce que je voulais utiliser. Par intérêt, y a-t-il une raison pour laquelle vous créez une variable locale et un décalage, plutôt que de référencer $ 1 et $ 2 dans votre appel à compdef?
Murali Suriar
@Murali: C'est pour que je puisse écrire quelque chose comme compdefas xterm cxterm uxterm xterm-color.
Gilles 'SO- arrête d'être méchant'
1
intéressant - j'ai donc défini deux wrappers, un pour «man» et un pour «ssh». En utilisant compdef, l'achèvement pour mon wrapper 'man' fonctionne, mais pas l'achèvement pour mon wrapper 'ssh'. Avez-vous déjà rencontré des problèmes comme celui-ci? Y a-t-il autre chose que je dois pousser pour que _ssh fonctionne avec mon alias / wrapper?
Murali Suriar