Adiciona argumentos do comando anterior ao zsh completion

21

No zsh (assim como no bash) você pode usar algumas expansões de palavras do histórico para denotar argumentos de comandos anteriores.

Este exemplo mostra como obter o segundo parâmetro do comando anterior no histórico com !:# expansion:

% echo foo bar baz
foo bar baz
% echo !:2
echo bar
bar

Muitas vezes esqueço exatamente qual parâmetro # é um argumento em particular e digitar !:# nem sempre é tão rápido quando lembro qual é o argumento. Eu sei sobre meta-. para substituir o último argumento, mas às vezes não é o último arg que eu quero.

Gostaria de adicionar os argumentos do comando anterior como sugestões para concluir qualquer comando que eu esteja digitando em zsh.

Consegui descobrir como criar uma função de shell que pode criar uma matriz de argumentos (0..N) a partir do último comando e ligá-lo a um comando específico.

_last_command_args() {
    last_command=$history[$[HISTCMD-1]]
    last_command_array=("${(s/ /)last_command}") 
    _sep_parts last_command_array
}

# trying to get last_command_args to be suggested for any command, this just works for foo
compdef _last_command_args foo

Isso é o que parece ter sido concluído apenas quando eu apertei a tecla tab em <TAB> :

% echo bar baz qux
bar baz qux
% foo <TAB>
bar   baz   echo  qux 

Isso funciona muito bem para concluir o comando "foo", mas gostaria que fossem opções em qualquer expansão zsh que eu fizesse. Eu acho que tem algo a ver com o zstyle completer, mas depois de algumas horas de hacking, percebi que estou fora de profundidade.

Como posso obter os argumentos do meu comando anterior como conclusões sugeridas para qualquer comando em zsh?

Eu tenho meu arquivo de compilação zshrc completo compartilhado no bitbucket se isso ajudar. Muitas delas são extraídas de várias fontes e algumas delas eu mesmo juntei.

ATUALIZAÇÃO:

A resposta de Julien Nicoulaud me aproximou, estou marcando como aceito, já que me levou aonde precisava.

Com minha configuração específica, usando o sugerido:

zstyle ':completion:*' completer _last_command_args _complete

Não funcionou muito bem para mim, pois estava causando o término da tabulação para exibir apenas a lista de argumentos do último comando (embora ele também fosse completo com nomes de arquivos, apenas não os exibisse). Alterar a ordem para _complete _last_command_args fez o inverso. Ele exibiria os nomes de arquivos normais, mas não last_command_args

Eu estou supondo que isso tem algo a ver com a maneira como o completer funciona. Eu acho que só exibe a saída do primeiro método que retorna com sucesso, mas estou tendo problemas para analisar a fonte zsh para entender completamente o que está acontecendo. Consegui ajustar meu método para incluir uma chamada para _complete , de modo que ela mostrasse os dois comandos do último argumento, bem como os itens regulares de autocompletar. Não é tão separado, mas funciona bem o suficiente para mim.

Aqui está a função completa que usei junto com as outras coisas zstyle que eu tenho:

# adds the arguments from the last commadn to the autocomplete list
# I wasn't able to get this to work standalone and still print out both regular
# completion plus the last args, but this works well enough.
_complete_plus_last_command_args() {
    last_command=$history[$[HISTCMD-1]]
    last_command_array=("${(s/ /)last_command}") 
    _sep_parts last_command_array
    _complete 
}


_force_rehash() {
  (( CURRENT == 1 )) && rehash
  return 1  # Because we didn't really complete anything
}

zstyle ':completion:::::' completer _force_rehash _complete_plus_last_command_args _approximate 

Outras linhas zstyle que tenho, não são necessárias para que isso funcione, mas podem afetar o motivo de isso funcionar para mim:

zstyle -e ':completion:*:approximate:*' max-errors 'reply=( $(( ($#PREFIX + $#SUFFIX) / 3 )) )'
zstyle ':completion:*:descriptions' format "- %d -"
zstyle ':completion:*:corrections' format "- %d - (errors %e})"
zstyle ':completion:*:default' list-prompt '%S%M matches%s'
zstyle ':completion:*' group-name ''
zstyle ':completion:*:manuals' separate-sections true
zstyle ':completion:*' menu select
zstyle ':completion:*' verbose yes

Agora, se eu estiver em um diretório com file1.txt e file2.txt , e meu último comando for echo foo bar baz , recebo isso para o preenchimento automático, que é exatamente o que eu queria:

% ls
bar   baz   echo  foo 
- files -
file1.txt   file2.txt 
    
por Ted Naleid 29.12.2010 / 21:34

1 resposta

6

Você pode adicionar seu completer à lista de participantes usados por padrão:

zstyle ':completion:*' completer _last_command_args _complete
    
por 20.01.2011 / 21:54