Pregunta Zsh / git: Tab autocompletar no funciona si "HEAD ^" está al lado de la última palabra en la fila de entrada


Problema

Tengo lo siguiente

git reset HEAD^ half_entered_file_n<Tab>

En este punto, me gustaría que half_entered_file_name.txt se complete con pestañas.

Mi propia investigación

Puedo completar la tabulación para que funcione si escribo

git reset HEAD\^ ...

en cambio, escapando del "^".

Escribir un "^" como el último carácter no parece afectar el autocompletado, a menos que HEAD también esté presente:

#autocomplete works
git reset RANDOM^ half_entered_file_n<Tab> #works

Configuración Zsh

Estoy usando Oh-my-zsh. Además de oh-my-zsh, configuré lo siguiente que puede 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)

Por completitud, aquí está mi configuración

Estoy ejecutando esto en OSX en iTerm2.

¡Gracias!

Actualizar

He encontrado algunas semi-soluciones, pero ninguna que conduzca a un estado de "respuesta" todavía, lo que básicamente las convierte en no soluciones.

  1. conjunto compdef -d git en .zshrc según lo propuesto por "hombre de las cavernas"
    • Resuelve: Ahora HEAD ^ ya no rompe la autocompletación de archivos.
    • Desventaja: la autocompletación del comando git ya no funciona.
  2. Utilizar el respuesta aceptada por "ralphtheninja" de esta pregunta
    • Resuelve: debe reemplazar la forma en que se genera la lista de finalización de archivos, lo que resolvería el problema.
    • Drawback: no funciona. Parece que git-completion.zsh / .bash ha cambiado la sintaxis.

No conozco los guiones de shell lo suficientemente bien como para entender exactamente lo que está pasando en git-completion.zsh / .bash, y si esa es la razón por la que las cosas se están rompiendo.


2


origen




Respuestas:


Por qué no debes asumir

Durante mucho tiempo, asumí que la finalización de git en mi configuración de zsh venía de /usr/local/share/git-core/contrib/completion/, específicamente de git-completion.zsh o incluso git-completion.bash. Supongo que estaba asumiendo esto porque la mayoría de las búsquedas producirán resultados hablando de estos archivos. Sin embargo, no incluí explícitamente ninguno de estos archivos y por mucho tiempo solo estaba adivinando que oh-my-zsh los incluía.

Pero...

Ya no estamos en Kansas

No fue hasta que usé zsh method tracing, habilitado a través de setopt xtrace, que me di cuenta (al buscar en Google algunos nombres de métodos) que la secuencia de comandos que se usaba era, de hecho, /usr/local/share/zsh/functions/_git. Yo había usado previamente XCode Instruments.app para controlar a qué scripts se accedía en el sistema de archivos, pero no lo resolvió (la salida es bastante hablante y muestra los accesos de otras aplicaciones también).

¿Que esta pasando?

Las huellas mostraron esto (huellas parciales adelante!)

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 )

Y

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+=( )

Eso vacio tree_files parece sospechoso

En la línea 6058 en /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 necesitamos escapar de eso $tree variable. Dicho y hecho:

tree_files+=(${(ps:\0:)"$(_call_program tree-files git ls-tree $extra_args --name-only -z ${(q)tree} $Path 2>/dev/null)"}) 

Epílogo

Hay más errores en este script (por ejemplo, la lista de archivos para git reset <tree-ish> se basa en el <tree-ish>, cuando debería basarse en HEAD. ¡Ahora sé dónde arreglarlos!

Actualizar

También existe la posibilidad de ejecutar los scripts de finalización de git en su lugar. Puedes hacer eso siguiendo esta respuesta.


1



Puedo sugerir un informe de error para sourceforge.net/p/zsh/bugs para que pueda ser arreglado aguas arriba? - Raniz