git complete con zsh: los nombres de archivo con espacios no se escapan correctamente

20

Finalización de Git:

Tengo dificultades con las autocompletas de nombre de archivo de git en mi sistema. Estoy usando zsh(5.0.5) con git(1.9.3) en OS X (10.9.3). Ambos zshy gitse han instalado a través de homebrew. (La salida de la versión completa se encuentra en la parte inferior de la publicación).

gitLa finalización del nombre de archivo no está insertando espacios como espero. Cuando escribo el nombre de un archivo con un espacio en el nombre, el shell inserta el nombre del archivo sin que escapen espacios. zshLa finalización integrada no hace esto, pero gitla hace.

Aquí hay un ejemplo de lo que estoy viendo.

Tengo un repositorio con algunos archivos con espacios en sus nombres.

% ls -la
test
test four - latest.txt
test three.txt
test two

La barra diagonal inversa del shell escapa a los nombres de archivo como se esperaba cuando uso la finalización de tabulación para insertar el nombre del archivo.

% echo "testing" >> test<tab>

se completa automáticamente después de presionar la pestaña tres veces.

% echo "testing" >> test\ four\ -\ latest.txt
––– file
test                       test\ four\ -\ latest.txt  test\ three.txt            test\ two                

git status muestra estos nombres de archivo entre comillas (comprende totalmente lo que ocurre):

% git status --short
 M test
 M "test four - latest.txt"
 M "test three.txt"
 M "test two"

pero cuando trato de git addautocompletar con pestañas, se va de lado.

% git add test<tab>

resulta en esto después de presionar la pestaña tres veces:

% git add test four - latest.txt
test                    test four - latest.txt  test three.txt          test two

He tratado de regresión de esto un poco: mis dotfiles están en control de versiones, por lo que he probado zsh 4.3.15, git 1.8.3y mis dotfiles desde hace un año, cuando estoy casi seguro que esto funcionó. Extrañamente, esta configuración todavía estaba rota.

Lo he reducido al _gitarchivo de finalización que se obtiene de /usr/local/share/zsh/site-functions:

% echo $FPATH
/usr/local/share/zsh/site-functions:/usr/local/Cellar/zsh/5.0.5/share/zsh/functions
% ls -l /usr/local/share/zsh/site-functions
_git@ -> ../../../Cellar/git/1.9.3/share/zsh/site-functions/_git
_hg@ -> ../../../Cellar/mercurial/3.0/share/zsh/site-functions/_hg
_j@ -> ../../../Cellar/autojump/21.7.1/share/zsh/site-functions/_j
git-completion.bash@ -> ../../../Cellar/git/1.9.3/share/zsh/site-functions/git-completion.bash
go@ -> ../../../Cellar/go/HEAD/share/zsh/site-functions/go

Si cambio manualmente $FPATHantes de mis .zshrcejecuciones compinit(o simplemente elimino el /usr/local/share/zsh/site-functions/_gitenlace simbólico), las terminaciones vuelven zshy funcionan como se esperaba.

La zshfinalización sin _git:

% git add test<tab>

presionar la pestaña tres veces produce resultados correctos:

% git add test\ four\ -\ latest.txt
––– modified file
test                       test\ four\ -\ latest.txt  test\ three.txt            test\ two                

Nota al margen: he intentado eliminar el git-completion.bashenlace, y simplemente rompe totalmente las cosas:

% git add test<tab>

produce esta ruptura:

% git add test__git_zsh_bash_func:9: command not found: __git_aliased_command
    git add test
––– file
test                       test\ four\ -\ latest.txt  test\ three.txt            test\ two                

Yo realmente quiero obtener esta funcionando correctamente: el resto de las _gitterminaciones eran grandes porque son más repo-conscientes que las zshotras, pero necesito los nombres de archivo con espacios u otros caracteres especiales que se escaparon correctamente.


Versiones de software:

% zsh --version
zsh 5.0.5 (x86_64-apple-darwin13.0.0)

% git --version
git version 1.9.3

% sw_vers
ProductName:    Mac OS X
ProductVersion: 10.9.3
BuildVersion:   13D65

He subido los archivos _gity git-completion.bash: git-completar.bash y _git (renombrado para _git.shque CloudApp lo haga visible en el navegador).

cbowns
fuente
2
Para los usuarios que no son OSX en la audiencia, ¿podría vincular a algún lugar donde podamos descargar las terminaciones que se envían con su paquete git?
Gilles 'SO- deja de ser malvado'
2
Claro: _git (renombrado a _git.sh para CloudApp): cl.ly/code/423e0i1X1p29 y git-completar.bash: cl.ly/code/153v2t142i2G
cbowns
3
Le eché un vistazo _git. Las llamadas a compadd -Qverse raro: -Qsignifica "no citar caracteres especiales". Intenta eliminarlo -Qde las compaddllamadas.
Gilles 'SO- deja de ser malvado'
3
Estoy bastante seguro de que el problema se debe al zshcomportamiento predeterminado de los resultados de sustitución de comandos sin división de palabras. De hecho, el \bsescape no es necesario, o es inútil, dependiendo de cómo lo veas. Establezca "SH_WORD_SPLIT" zsh.sourceforge.net/FAQ/zshfaq03.html
mikeserv
44
Alternativamente, edite las funciones de finalización de bash para generar como ${=$(completion)}o lo que sea que devuelvan.
mikeserv

Respuestas:

5

Este error se menciona en la lista de correo .

La solución es editar el archivo git-completion.zshy eliminar la -Qopción desde compaddadentro en __gitcomp_file.

--- i/contrib/completion/git-completion.zsh
+++ w/contrib/completion/git-completion.zsh
@@ -90,7 +90,7 @@ __gitcomp_file ()

    local IFS=$'\n'
    compset -P '*[=:]'
-   compadd -Q -p "${2-}" -f -- ${=1} && _ret=0
+   compadd -p "${2-}" -f -- ${=1} && _ret=0
 }

 __git_zsh_bash_func ()

Este archivo se instala desde el contrib/completiondirectorio y su ruta puede variar con su administrador de paquetes. Si instaló con homebrew en macOS, está ubicado en /usr/local/Cellar/git/2.10.2/share/zsh/site-functions.

copos tostados
fuente
El error __git_aliased_commandse debe a que el directorio compartido cambió su nombre a git-core (al menos en FreeBSD), lo que hace que no se encuentre git-completion.bash. Si cambia la primera ubicación en la línea 33 a una codificada /usr/local/share/git-core/contrib/completion/git-completion.bash, volverá a funcionar.
Melvyn
Hay un echoarchivo en ese archivo justo encima de estas definiciones de funciones, y la falta de apariencia en mi shell (y algún código adyacente cuando se realiza la prueba) sugiere que estas terminaciones ni siquiera se usan:if [[ -n ${ZSH_VERSION-} ]]; then echo "WARNING: this script is deprecated, please see git-completion.zsh" 1>&2
cbowns
1
Esto funcionó para mí (git 2.18, zsh 5.4.2 osx) cuando cambié compadd -Q-> compaddpara todas las instancias en _gity git-completion.bashen la carpeta /usr/local/Cellar/git/2.18.0/share/zsh/site-functions/de mi instalación de brew git. ¡¡¡Gracias!!!
Merlin