Problema
Eu tenho o seguinte
git reset HEAD^ half_entered_file_n<Tab>
Neste ponto, gostaria que half_entered_file_name.txt fosse preenchido com guia.
Minha própria investigação
Posso fazer com que o preenchimento da guia funcione se eu escrever
git reset HEAD\^ ...
em vez disso, escapando do "^".
Escrever um "^" como último caractere não parece afetar o preenchimento automático, a menos que HEAD também esteja presente:
#autocomplete works
git reset RANDOM^ half_entered_file_n<Tab> #works
Configuração Zsh
Estou usando Oh-my-zsh. Além do oh-my-zsh, configurei o seguinte que pode ser relevante:
# Let <TAB> auto completion add a slash at the end instead of space (like BASH)
zstyle ':completion:*' special-dirs true
# Unless this option is set, you can't write git checkout HEAD^^ without escaping ^ as \^ in zsh
setopt NO_NOMATCH
# Standard git plugins
plugins=(git git-extras)
Para completar,aqui está minha configuração
Estou executando isso no OSX no iTerm2.
Obrigado!
Atualizar
Encontrei algumas semi-soluções, mas nenhuma que leve ao status de "respondida" ainda, o que basicamente as torna não-soluções.
- definido
compdef -d git
em .zshrccomo proposto por "homem das cavernas"- Resolve: Agora HEAD^ não interrompe mais o preenchimento automático de arquivos.
- Desvantagem: o preenchimento automático do comando git não funciona mais.
- Use oresposta aceita por "ralphtheninja" desta pergunta
- Resolve: Deveria substituir a forma como é gerada a lista de preenchimento de arquivos, o que resolveria o problema.
- Desvantagem: Não funciona. Parece que git-completion.zsh/.bash mudou a sintaxe.
Não conheço scripts de shell bem o suficiente para entender exatamente o que está acontecendo em git-completion.zsh/.bash e se esse é o motivo pelo qual as coisas estão quebrando.
Responder1
Por que você não deve assumir
Por muito tempo eu presumi que a conclusão do git na minha configuração zsh vinha de /usr/local/share/git-core/contrib/completion/
, especificamente de git-completion.zsh
ou mesmo git-completion.bash
. Acho que estava assumindo isso porque a maioria das pesquisas produzirá resultados falando sobre esses arquivos. No entanto, não incluí explicitamente nenhum desses arquivos e, por muito tempo, apenas imaginei que oh-my-zsh os estava incluindo.
Mas...
Não estamos mais no Kansas
Só quando usei o rastreamento do método zsh, habilitado via setopt xtrace
, é que percebi (pesquisando alguns nomes de métodos no Google) que o script que estava sendo usado era de fato /usr/local/share/zsh/functions/_git
. eu já tinha usadoInstrumentos XCode.apppara monitorar quais scripts estavam sendo acessados no sistema de arquivos, mas não descobri então (a saída é bastante tagarela e também mostra acessos de outros aplicativos).
O que está acontecendo?
Os traços mostraram isso (rastros parciais à frente!)
git reset HEAD <TAB>
...
+__git_tree_files:17> tree=HEAD
+__git_tree_files:18> tree_files+=+__git_tree_files:18> _call_program tree-files git ls-tree --name-only -z HEAD ./
+__git_tree_files:18> tree_files+=( first second third )
E
git reset HEAD^ <TAB>
...
+__git_tree_files:17> tree=HEAD^
+__git_tree_files:18> tree_files+=+__git_tree_files:18> _call_program tree-files git ls-tree --name-only -z 'HEAD^' ./
+__git_tree_files:18> tree_files+=( )
Esse vazio tree_files
parece suspeito.
Na linha 6058 /usr/local/share/zsh/functions/_git
encontramos
tree_files+=(${(ps:\0:)"$(_call_program tree-files git ls-tree $extra_args --name-only -z $tree $Path 2>/dev/null)"})
Definitivamente precisamos escapar dessa $tree
variável. Dito e feito:
tree_files+=(${(ps:\0:)"$(_call_program tree-files git ls-tree $extra_args --name-only -z ${(q)tree} $Path 2>/dev/null)"})
Epílogo
Existem mais alguns bugs acontecendo neste script (por exemplo, a lista de arquivos git reset <tree-ish>
é baseada no <tree-ish>
, quando deveria ser baseada no HEAD. Agora eu sei onde corrigi-los!
Atualizar
Também existe a possibilidade de executar os scripts de conclusão do git.Você pode fazer isso seguindo esta resposta.