Wie kann ich meine Shell-Funktionen dazu bringen, die vorhandene automatische Vervollständigung in zsh zu nutzen?

10

In meinem sind einige Shell-Funktionen definiert, .zshrcdie beim Tippen sparen und die Integration in den Bildschirm ermöglichen. Zum Beispiel:

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

Wenn ich diese Shell-Funktionen verwende, kann ich jedoch die integrierten Befehlsvervollständigungsfunktionen von zsh nicht nutzen. (Bei SSH werden Hostnamen basierend auf bekannten_Hosts und ssh_config automatisch vervollständigt.) Was ist die bevorzugte Methode, um sich an die vorhandenen Vervollständigungsmechanismen für Befehle anzuschließen, für die ich Wrapper erstellt habe?

BEARBEITEN:

Vielen Dank an Gilles für seine Antwort unten. Die Verwendung von compdef scheint der Weg zu sein, aber interessanterweise scheint es nicht einheitlich zu funktionieren. In diesem Fall habe ich folgendes Setup:

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

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

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

Die Vervollständigung für meine Wrapper-Funktion 'm' funktioniert wie erwartet, die Vervollständigung für meine Funktion 's' jedoch nicht. Anstatt zu versuchen, Hostnamen zu vervollständigen, scheint es auf die standardmäßige automatische Vervollständigung zurückzugreifen, indem mir eine Liste von Dateien zur Verfügung gestellt wird, wenn ich auf "Tab" drücke. Gibt es eine Kuriosität in der Art und Weise, wie die SSH-Fertigstellung gehandhabt wird, was bedeutet, dass ich etwas weiter tun muss?

Murali Suriar
quelle

Antworten:

9

Ich benutze die folgende Funktion, um zu sagen, dass eine Funktion oder ein Alias ​​oder ein Wrapper-Skript (z. B. s) wie ein vorhandener Befehl (z. B. ssh) ausgeführt werden soll:

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

Einige Vervollständigungsbefehle gelten für eine Familie von Funktionen und lesen das erste Wort der Befehlszeile, um zu bestimmen, welcher bestimmte Befehl ausgeführt werden soll. Zum Beispiel können die Befehle ssh, scp, sftpund ein paar mehr werden alle durch die Funktion beendet _ssh. In diesem Fall müssen Sie der Abschlussfunktion mitteilen, wie „Dienst“ Ihre Funktion ist (standardmäßig ist der Dienst der Name der ausführbaren Datei, hier der Name Ihrer Funktion).

_s () {
  local service=ssh
  _ssh "$@"
}
compdef _s s
Gilles 'SO - hör auf böse zu sein'
quelle
Danke - ich nahm an, dass compdef das war, was ich verwenden wollte. Gibt es aus Interesse einen Grund, warum Sie eine lokale Variable erstellen und verschieben, anstatt in Ihrem Aufruf von compdef auf $ 1 und $ 2 zu verweisen?
Murali Suriar
@Murali: So kann ich so etwas schreiben compdefas xterm cxterm uxterm xterm-color.
Gilles 'SO - hör auf böse zu sein'
1
interessant - also habe ich zwei Wrapper definiert, einen für 'man' und einen für 'ssh'. Mit compdef funktioniert die Vervollständigung für meinen 'man'-Wrapper, die Vervollständigung für meinen' ssh'-Wrapper jedoch nicht. Haben Sie schon einmal solche Probleme gehabt? Muss ich noch etwas stupsen, damit _ssh mit meinem Alias ​​/ Wrapper funktioniert?
Murali Suriar