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?

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

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.