GNU/Linux >> Tutoriales Linux >  >> Ubuntu

Ubuntu:¿cómo hacer correctamente que las terminaciones de Zsh personalizadas "simplemente funcionen"?

Perdóneme si estoy haciendo algo estúpido aquí, la documentación es enorme y la búsqueda no arrojó nada todavía.

Estoy tratando de crear terminaciones de shell para mi script personalizado llamado fab . Para bash fue fácil, simplemente colóquelos en /etc/bash_completion.d y funcionan Pero, vaya, es zsh un PITA...

Tengo la función de finalización _fab y funciona bien cuando está habilitado con compdef _fab fab . Lo puse en /usr/share/zsh/vendor-completions/_fab que ya estaba en mi $fpath . El archivo comienza con #compdef fab y termina con compdef _fab fab . Se ve bien:

$ type _fab
_fab is an autoload shell function

Pero cada vez que comencé un nuevo shell, fab las finalizaciones no funcionaron (otras funciones de vendor-completions , como _docker , Estamos bien). compinit arregló esto para ese shell específico. Descubrí que rm ~/.zcompdump ~/.zcompdump-$(hostname)-5.1.1; compinit hacer que funcione permanentemente (5.1.1 =mi versión zsh).

Preguntas:

  1. Qué y cuándo lee ~/.zcompdump configurar las terminaciones iniciales?
  2. man zshall dice:

    La siguiente invocación de compinit leerá el archivo volcado en lugar de realizar una inicialización completa.

    Si ese fuera el caso, compinit no arreglaría mis finalizaciones antes de eliminar ~/.zcompdump , ¿derecho? ¿Me estoy perdiendo algo?

  3. ¿Qué es ~/.zcompdump-$(hostname)-5.1.1 y cómo se relaciona con .zcompdump ? La única diferencia es una finalización que está en ~/.oh-my-zsh/completions (porque $ZSH apunta a ~/.oh-my-zsh ). ¿Es algo oh-mi-zsh?
  4. Si tuviera que empaquetar estas finalizaciones en un paquete redistribuible o crear un script de instalación, ¿dónde debo colocar las finalizaciones zsh y qué más debo hacer durante la instalación para asegurarme de que todo funciona?

Estoy apuntando a Ubuntu 16.04, 18.04 y 19.04, pero la información no específica de la distribución es bienvenida. Estoy probando esto en Ubuntu 16.04 con zsh 5.1.1 y reciente oh-my-zsh.

Respuesta aceptada:

TL, DR:en operaciones normales, simplemente suelte el archivo en el directorio apropiado. Durante la prueba, debe eliminar el archivo de caché (.zcompdump por defecto, pero los usuarios pueden colocarlo en una ubicación diferente, y oh-my-zsh lo coloca en una ubicación diferente).

La respuesta simple es escribir la función de finalización en un archivo donde la primera línea es #compdef fab . El archivo debe estar en un directorio en $fpath .

El archivo puede contener el cuerpo de la función o una definición de la función seguida de una llamada a la función. Es decir, el archivo contiene algo como

#compdef fab
_arguments …

o

#compdef fab
function _fab {
  _arguments …
}
_fab "[email protected]"

El archivo debe estar presente en $fpath antes de compinit carreras. Eso significa que debe prestar atención al orden de las cosas en .zshrc :primero agregue cualquier directorio personalizado a $fpath , luego llama a compinit . Si usa un marco como oh-my-zsh, asegúrese de agregar directorios personalizados a $fpath antes del código oh-my-zsh.

compinit es la función que inicializa el sistema de finalización. Lee todos los archivos en $fpath y comprueba su primera línea en busca de directivas mágicas #autoload y #compdef .

.zcompdump es un archivo de caché utilizado por compinit . ~/.zcompdump es la ubicación predeterminada; puede elegir una ubicación diferente al ejecutar compinit . Oh-my-zsh llama a compinit con el -d opción para usar un nombre de archivo de caché diferente dado por la variable ZSH_COMPDUMP , que por defecto es

ZSH_COMPDUMP="${ZDOTDIR:-${HOME}}/.zcompdump-${SHORT_HOST}-${ZSH_VERSION}"

El nombre de host se incluye por el bien de las personas cuyo directorio de inicio se comparte entre máquinas y que pueden tener un software diferente instalado en diferentes máquinas. La versión zsh se incluye porque el archivo de caché es incompatible entre versiones (incluye código que cambia de una versión a otra).

Relacionado:¿Qué hace CTRL+V en vim?

Creo que todos tus problemas se deben a un archivo de caché obsoleto (y eso te ha hecho complicar demasiado la situación). Desafortunadamente, el algoritmo de zsh para determinar si el archivo de caché está obsoleto no es perfecto, presumiblemente en aras de la velocidad. No verifica el contenido o las marcas de tiempo de los archivos en $fpath , solo los cuenta. Un .zcompdump el archivo comienza con una línea como

#files: 858     version: 5.1.1

Si la versión de zsh y el número de archivos son correctos, zsh carga el archivo de caché.

El archivo de caché solo contiene asociaciones entre nombres de comandos, no el código de funciones de finalización. Estos son algunos escenarios comunes en los que la memoria caché funciona de forma transparente:

  • Si agrega un nuevo archivo a $fpath , esto invalida el caché.
  • Más generalmente, si agrega y elimina archivos en $fpath y el número total de archivos eliminados no es el mismo que el número total de archivos eliminados, esto invalida el caché.
  • Si mueve un archivo a un directorio diferente en $fpath sin cambiar su nombre, esto no afecta nada que esté en el caché, por lo que el caché permanece correcto.
  • Si modifica un archivo en $fpath sin cambiar su primera línea, esto no afecta nada que esté en el caché, por lo que el caché permanece correcto.

Estos son algunos escenarios comunes en los que el caché deja de ser válido, pero zsh no se da cuenta.

  • Agrega algunos archivos a $fpath y elimine exactamente la misma cantidad de archivos.
  • Cambia el nombre de un archivo en $fpath .
  • Usted agrega o modifica el #compdef (o #autoload ) en la parte superior del archivo.

Ese último punto es lo que tiende a morder durante las pruebas. Si cambia el #compdef línea, debe eliminar .zcompdump y reinicie zsh (o vuelva a ejecutar compinit ).

Si coloca las finalizaciones en un paquete redistribuible, simplemente suelte el archivo de finalización en un directorio que se encuentra en el $fpath de todo el sistema. . Para un paquete de Ubuntu, el lugar apropiado es /usr/share/zsh/vendor-completions . Para algo instalado bajo /usr/local , eso es /usr/local/share/zsh/site-functions . Eso es todo lo que necesitas hacer.

Lo único que no es transparente es si necesita cambiar el #compdef en una actualización, o si elimina o cambia el nombre de algunos archivos. En tales casos, los usuarios deberán eliminar su archivo de caché, y eso no es algo que pueda hacer desde un paquete que se instala en una máquina multiusuario.


Ubuntu
  1. Cómo agregar un archivo de intercambio en Ubuntu

  2. Cómo instalar Oh My Zsh en Ubuntu

  3. ¿Cómo instalar Zsh en Ubuntu 20.04?

  4. Cómo instalar Nagios en Ubuntu 14.04

  5. ¿Cómo hacer una animación de inicio personalizada?

Cómo eliminar un archivo en Ubuntu

Cómo instalar CouchPotato en Ubuntu

Cómo cambiar el nombre de los archivos en Ubuntu 20.04

Cómo instalar y hacer que Nemo sea el administrador de archivos predeterminado en Ubuntu

Cómo instalar ZSH (Z Shell) en Ubuntu 20.04

Cómo instalar OH-MY-ZSH en Ubuntu 21.04