Como obtenho minhas funções de shell para usar o preenchimento automático existente no zsh?

10

Eu tenho algumas funções de shell definidas no meu, .zshrcque economizam na digitação e permitem a integração com a tela. Por exemplo:

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

No entanto, quando eu uso essas funções do shell, não posso tirar proveito dos recursos de conclusão de comando incorporados do zsh. (No caso do SSH, preenchimento automático de nomes de host com base em known_hosts e ssh_config). Qual é a maneira preferida de conectar-se aos mecanismos de conclusão existentes para comandos para os quais eu criei wrappers?

EDITAR:

Agradecemos a Gilles por sua resposta abaixo. Usar o compdef parece ser a maneira de fazer isso, mas, curiosamente, ele não parece funcionar de maneira uniforme. Nesse caso, tenho a seguinte configuração:

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

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

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

A conclusão da minha função de wrapper 'm' funciona conforme o esperado, mas a conclusão da minha função 's' não; em vez de tentar concluir nomes de host, ele parece voltar ao preenchimento automático padrão, fornecendo-me uma lista de arquivos quando clico em 'tab'. Existe alguma estranheza na maneira como a conclusão do SSH é tratada, o que significa que preciso fazer algo mais?

Murali Suriar
fonte

Respostas:

9

Eu uso a seguinte função para dizer que uma função ou alias ou script de wrapper (por exemplo s) deve ser concluído como um comando existente (por exemplo ssh):

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

Alguns comandos de conclusão se aplicam a uma família de funções e leem a primeira palavra da linha de comando para determinar qual comando específico deve ser concluído. Por exemplo, os comandos ssh, scp, sftpe mais alguns estão todos concluídos pela função _ssh. Nesse caso, você precisa informar à função de conclusão qual é o "serviço" da sua função (por padrão, o serviço é o nome do executável, aqui o nome da sua função).

_s () {
  local service=ssh
  _ssh "$@"
}
compdef _s s
Gilles 'SO- parar de ser mau'
fonte
Obrigado - eu assumi que compdef era o que eu queria usar. Por interesse, existe alguma razão para você criar uma variável local e mudar, em vez de referenciar $ 1 e $ 2 em sua chamada para o compdef?
Murali Suriar
@Murali: É para escrever algo assim compdefas xterm cxterm uxterm xterm-color.
Gilles 'SO- stop be evil'
1
interessante - então eu defini dois wrappers, um para 'man' e outro para 'ssh'. Usando compdef, a conclusão do meu wrapper 'man' funciona, mas a conclusão do meu wrapper 'ssh' não. Você já enfrentou problemas como esse antes? Há algo mais que eu precise cutucar para que o _ssh funcione com meu alias / wrapper?
Murali Suriar