¿Cómo obtengo mis funciones de shell para utilizar el autocompletado existente en zsh?

10

Tengo un par de funciones de shell definidas en mi .zshrcque ahorran al escribir y permiten la integración con la pantalla. Por ejemplo:

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

Sin embargo, cuando uso estas funciones de shell, no puedo aprovechar las funciones integradas de finalización de comandos de zsh. (En el caso de SSH, completar automáticamente los nombres de host basados ​​en known_hosts y ssh_config). ¿Cuál es la forma preferida de conectarse a los mecanismos de finalización existentes para los comandos para los que he creado contenedores?

EDITAR:

Gracias a Gilles por su respuesta a continuación. Usar compdef parece ser la forma de hacerlo, pero curiosamente no parece funcionar de manera uniforme. En este caso, tengo la siguiente configuración:

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

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

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

La finalización de mi función de contenedor 'm' funciona como se esperaba, sin embargo, la finalización de mi función 's' no lo hace; en lugar de intentar completar los nombres de host, parece que retrocede al autocompletado predeterminado al proporcionarme una lista de archivos cuando presiono 'tab'. ¿Hay alguna rareza en la forma en que se maneja la finalización de SSH, lo que significa que necesito hacer algo más?

Murali Suriar
fuente

Respuestas:

9

Utilizo la siguiente función para decir que una función o alias o script de envoltura (por ejemplo s) se debe completar como un comando existente (por ejemplo ssh):

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

Algunos comandos de finalización se aplican a una familia de funciones y leen la primera palabra de la línea de comando para determinar qué comando en particular completar. Por ejemplo, los comandos ssh, scp, sftpy algunos más están completados por la función _ssh. En ese caso, debe indicarle a la función de finalización a qué "servicio" es su función (de manera predeterminada, el servicio es el nombre ejecutable, aquí el nombre de su función).

_s () {
  local service=ssh
  _ssh "$@"
}
compdef _s s
Gilles 'SO- deja de ser malvado'
fuente
Gracias. Supuse que compdef era lo que quería usar. Por interés, ¿hay alguna razón por la que cree una variable local y un cambio, en lugar de hacer referencia a $ 1 y $ 2 en su llamada a compdef?
Murali Suriar el
@Murali: Eso es para que pueda escribir algo así compdefas xterm cxterm uxterm xterm-color.
Gilles 'SO- deja de ser malvado'
1
interesante, así que he definido dos envoltorios, uno para 'man' y otro para 'ssh'. Usando compdef, la finalización de mi contenedor 'man' funciona, pero la finalización de mi contenedor 'ssh' no. ¿Te has encontrado con algún problema como este antes? ¿Hay algo más que deba tocar para que _ssh funcione con mi alias / wrapper?
Murali Suriar