GNU/Linux >> Tutoriels Linux >  >> Ubuntu

Ubuntu - Comment faire correctement pour que les complétions Zsh personnalisées « fonctionnent » ?

Veuillez m'excuser si je fais quelque chose de stupide ici, la documentation est énorme et la recherche n'a encore rien donné.

J'essaie de créer des complétions shell pour mon script personnalisé appelé fab . Pour bash, c'était facile, il suffit de les déposer dans /etc/bash_completion.d et ils fonctionnent. Mais oh boy, est-ce que zsh est un PITA…

J'ai la fonction de complétion _fab et cela fonctionne bien lorsqu'il est activé avec compdef _fab fab . Je l'ai mis dans /usr/share/zsh/vendor-completions/_fab qui était déjà dans mon $fpath . Le fichier commence par #compdef fab et se termine par compdef _fab fab . Ça a l'air bien :

$ type _fab
_fab is an autoload shell function

Mais chaque fois que je démarrais un nouveau shell, fab les complétions ne fonctionnaient pas (autres fonctions de vendor-completions , comme _docker , nous allons bien). compinit corrigé cela pour ce shell spécifique. J'ai compris que rm ~/.zcompdump ~/.zcompdump-$(hostname)-5.1.1; compinit faites-le fonctionner en permanence (5.1.1 =ma version zsh).

Questions :

  1. Quand et quoi lit ~/.zcompdump configurer les complétions initiales ?
  2. man zshall dit :

    La prochaine invocation de compinit lira le fichier vidé au lieu d'effectuer une initialisation complète.

    Si tel était le cas, compinit ne corrigeait pas mes complétions avant de supprimer ~/.zcompdump , à droite? Ai-je raté quelque chose ?

  3. Qu'est-ce que ~/.zcompdump-$(hostname)-5.1.1 et comment est-il lié à .zcompdump ? La seule différence est une complétion qui se trouve dans ~/.oh-my-zsh/completions (parce que $ZSH pointe vers ~/.oh-my-zsh ). Est-ce un truc oh-my-zsh ?
  4. Si je devais regrouper ces complétions dans un package redistribuable ou créer un script d'installation, où dois-je placer les complétions zsh et que dois-je faire d'autre pendant l'installation pour m'assurer que tout fonctionne correctement ?

Je cible Ubuntu 16.04, 18.04 et 19.04, mais les informations non spécifiques à la distribution sont les bienvenues. Je teste cela sur Ubuntu 16.04 avec zsh 5.1.1 et le récent oh-my-zsh.

Réponse acceptée :

TL,DR :Dans les opérations normales, déposez simplement le fichier dans le répertoire approprié. Pendant le test, vous devez supprimer le fichier cache (.zcompdump par défaut, mais les utilisateurs peuvent le placer dans un emplacement différent, et oh-my-zsh le place dans un emplacement différent).

La réponse simple est d'écrire la fonction de complétion dans un fichier où la première ligne est #compdef fab . Le fichier doit être dans un répertoire sur $fpath .

Le fichier peut soit contenir le corps de la fonction, soit une définition de la fonction suivie d'un appel à la fonction. Autrement dit, soit le fichier contient quelque chose comme

#compdef fab
_arguments …

ou

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

Le fichier doit être présent sur $fpath avant compinit court. Cela signifie que vous devez faire attention à l'ordre des choses dans .zshrc  :ajoutez d'abord tous les répertoires personnalisés à $fpath , puis appelez compinit . Si vous utilisez un framework tel que oh-my-zsh, assurez-vous d'ajouter tous les répertoires personnalisés à $fpath avant le code oh-my-zsh.

compinit est la fonction qui initialise le système de complétion. Il lit tous les fichiers dans $fpath et vérifie leur première ligne pour les directives magiques #autoload et #compdef .

.zcompdump est un fichier cache utilisé par compinit . ~/.zcompdump est l'emplacement par défaut ; vous pouvez choisir un emplacement différent lors de l'exécution de compinit . Oh-my-zsh appelle compinit avec le -d option pour utiliser un nom de fichier de cache différent donné par la variable ZSH_COMPDUMP , qui par défaut est

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

Le nom d'hôte est inclus pour le bien des personnes dont le répertoire personnel est partagé entre les machines et qui peuvent avoir différents logiciels installés sur différentes machines. La version zsh est incluse car le fichier cache est incompatible entre les versions (il inclut du code qui change d'une version à l'autre).

Connexe :Que fait CTRL+V dans vim ?

Je pense que tous vos problèmes sont dus à un fichier de cache obsolète (et cela vous a compliqué la situation). Malheureusement, l'algorithme de zsh pour déterminer si le fichier cache est obsolète n'est pas parfait, probablement dans l'intérêt de la vitesse. Il ne vérifie pas le contenu ou les horodatages des fichiers sur $fpath , il ne fait que les compter. Un .zcompdump le fichier commence par une ligne comme

#files: 858     version: 5.1.1

Si la version de zsh et le nombre de fichiers sont corrects, zsh charge le fichier cache.

Le fichier cache ne contient que des associations entre les noms de commande, pas le code des fonctions de complétion. Voici quelques scénarios courants dans lesquels le cache fonctionne de manière transparente :

  • Si vous ajoutez un nouveau fichier à $fpath , cela invalide le cache.
  • Plus généralement, si vous ajoutez et supprimez des fichiers sur $fpath , et que le nombre total de fichiers supprimés n'est pas le même que le nombre total de fichiers supprimés, cela invalide le cache.
  • Si vous déplacez un fichier vers un autre répertoire dans $fpath sans changer son nom, cela n'affecte rien de ce qui se trouve dans le cache, donc le cache reste correct.
  • Si vous modifiez un fichier dans $fpath sans changer sa première ligne, cela n'affecte rien de ce qui est dans le cache, donc le cache reste correct.

Voici quelques scénarios courants où le cache devient invalide, mais zsh ne s'en rend pas compte.

  • Vous ajoutez des fichiers à $fpath et supprimer exactement le même nombre de fichiers.
  • Vous renommez un fichier en $fpath .
  • Vous ajoutez ou modifiez le #compdef (ou #autoload ) ligne en haut du fichier.

Ce dernier point est ce qui a tendance à mordre lors des tests. Si vous modifiez le #compdef ligne, vous devez supprimer le .zcompdump fichier et redémarrez zsh (ou relancez compinit ).

Si vous placez des complétions dans un package redistribuable, déposez simplement le fichier de complétion dans un répertoire qui se trouve dans le système $fpath . Pour un paquet Ubuntu, l'endroit approprié est /usr/share/zsh/vendor-completions . Pour quelque chose installé sous /usr/local , c'est /usr/local/share/zsh/site-functions . C'est tout ce que vous avez à faire.

La seule chose qui n'est pas transparente, c'est si vous devez changer le #compdef ligne dans une mise à niveau, ou si vous supprimez ou renommez certains fichiers. Dans de tels cas, les utilisateurs devront supprimer leur fichier de cache, et ce n'est pas quelque chose que vous pouvez faire à partir d'un package installé sur une machine multi-utilisateur.


Ubuntu
  1. Comment ajouter un fichier d'échange sur Ubuntu

  2. Comment installer Oh My Zsh sur Ubuntu

  3. Comment installer Zsh sur Ubuntu 20.04 ?

  4. Comment installer Nagios sur Ubuntu 14.04

  5. Comment créer une animation Splash de démarrage personnalisée ?

Comment supprimer un fichier dans Ubuntu

Comment installer CouchPotato sur Ubuntu

Comment renommer des fichiers dans Ubuntu 20.04

Comment installer et faire de Nemo le gestionnaire de fichiers par défaut dans Ubuntu

Comment installer ZSH (Z Shell) sur Ubuntu 20.04

Comment installer OH-MY-ZSH dans Ubuntu 21.04