bash zsh tab-completion

¿Se puede usar un script de finalización de pestaña Bash en zsh?



tab-completion (5)

Tengo una secuencia de comandos de finalización de la pestaña Bash para Hadoop de Apache. Normalmente, uso zsh como mi shell del día a día. Tiende a ser bastante bash cuando necesito que lo sea, pero parece que los sistemas de finalización de pestañas son radicalmente diferentes entre ellos. ¿Existe una forma sencilla de "convertir" las definiciones de finalización de bash-tab existentes para que funcionen en zsh? No quiero invertir mucho tiempo en esto, pero si fuera fácil, ahorraría un esfuerzo moderado.


A partir de esta página (fechada el 2010/01/05):

Zsh puede manejar funciones de finalización de bash. La última versión de desarrollo de zsh tiene una función bashcompinit, que cuando se ejecuta permitirá a zsh leer las especificaciones y funciones de finalización de bash. Esto está documentado en la página del manual de zshcompsys. Para usarlo todo lo que necesita hacer es ejecutar bashcompinit en cualquier momento después de compinit. Definirá funciones completas y compgen correspondientes a los componentes bash.


Estoy ejecutando Antigen como administrador de complementos Oh-My-Zsh. Tuve algunos scripts de finalización de bash escritos por compañeros de trabajo que quería cargar en Zsh con una source /path/to/completion simples.

Tuve algunos problemas, porque parece que tanto Antigen como OMZ (difícil de decir) se preocupan de solo cargar los scripts de finalización de sus complementos. Finalmente bashcompinit esto al bashcompinit automáticamente bashcompinit y compinit después de antigen apply . Simplemente bashcompinit no era suficiente.

source ~/.antigen/antigen.zsh antigen use oh-my-zsh antigen apply autoload -U +X compinit && compinit autoload -U +X bashcompinit && bashcompinit source /path/to/bash_completion

Antigen crea su archivo .zcompdump en $ANTIGEN_COMPDUMP que para mí era ~/.antigen/.zcompdump

La reinvención de compinit y bashcompinit crea un segundo .zcompdump en $HOME/.zcompdump

Parece que todo funciona, porque soy capaz de usar las terminaciones configuradas por /path/to/bash_completion . He eliminado ambos archivos .zcompdump un par de veces para asegurarme de que estén regenerados y que parece que funcionan.

Tuve que reiniciar los archivos .zcompdump varias veces después de reiniciar la máquina debido a los errores que se produjeron al intentar completar la pestaña, pero no estoy seguro de que se deba a esta configuración o algo más. rm ~/.zcompdump && rm $ANTIGEN_COMPDUMP y un nuevo shell lo corrige para mí.

Versiones usadas al momento de escribir:

Antigen = v2.2.3 = d3d4ee0 Oh-my-zsh = c3b072e Zsh = 5.3


Para uso zsh :

  • compdef
  • compadd

Mi ejemplo

# bash completion for bxrun (/home/ecuomo/projects/bashx/bxrun) _bxrun_methods() { grep "^/s*/(function/s/+/)/?__./+()/s*{.*$" "${1}" | while read line ; do echo "$line" | sed "s/()/s*{.*//g" | sed "s//s*/(function/s/+/)/?__//g" done } _bxrun_lst() { if [ -d "/home/ecuomo/projects/bashx/src/actions" ]; then for f in /home/ecuomo/projects/bashx/src/actions/* ; do if [ -f "${f}" ]; then basename "${f}" | sed ''s//..*$//g'' fi done fi _bxrun_methods "/home/ecuomo/projects/bashx/bxrun" _bxrun_methods "/home/ecuomo/projects/bashx/src/bashx.sh" } _bxrun() { local cur COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} COMPREPLY=( $( compgen -W ''$( _bxrun_lst )'' -- $cur ) ) } _bxrun_zsh() { compadd `_bxrun_lst` } if type complete >/dev/null 2>/dev/null; then # bash complete -F _bxrun bxrun else if type compdef >/dev/null 2>/dev/null; then # zsh compdef _bxrun_zsh bxrun fi; fi

Fuente: Mi código https://github.com/reduardo7/bashx


autoload -U +X compinit && compinit autoload -U +X bashcompinit && bashcompinit source /path/to/your/bash_completion_script

Estoy ejecutando zsh zsh 5.0.2 (x86_64-apple-darwin13.0) sin ningún ~ / .zshrc y la secuencia anterior funcionó en una shell zsh recién creada.

Gracias a la secuencia de comandos git-completed.bash por la sugerencia: D

Lectura para más detalles sobre las 3 líneas anteriores:

Bash tiene un impresionante soporte de autocompletado incorporado, pero los scripts de autocompletado de bash no funcionan directamente zsh, ya que el entorno zsh no tiene las funciones de ayuda de autocompletado de bash esenciales como compgen , complete . Lo hace en un esfuerzo por mantener la sesión zsh rápida.

En estos días, zsh se entrega con los scripts de finalización adecuados, como compinit y bashcompinit que tienen las funciones necesarias para admitir los scripts de autocompletado de bash.

autoload <func_name> : autoload <func_name> cuenta que autoload está definido en zsh y no en bash. autoload busca un archivo nombrado en las rutas de directorio devueltas por el comando fpath y marca una función para cargarlo cuando se invoca por primera vez.

  • -U: ignora cualquier alias al cargar una función como compinit o bashcompinit
  • + X: Simplemente carga la función nombrada ahora y no la ejecutes

Por ejemplo, en mi sistema echo $fpath devuelve /usr/share/zsh/site-functions y /usr/share/zsh/5.0.5/functions y compinit y bashcompinit están disponibles en /usr/share/zsh/5.0.5/functions .

También para la mayoría de las personas puede ser que solo se requiera autoload -U +X bashcompinit && bashcompinit se requiere porque algún otro script como git autocompletar o su propio ~/.zshrc puede estar haciendo la autoload -U +X compinit && compinit , pero es seguro ejecutar ambos de ellos.


autoload bashcompinit bashcompinit source /path/to/your/bash_completion_file