GNU/Linux >> LINUX-Kenntnisse >  >> Ubuntu

Ubuntu – Wie macht man benutzerdefinierte Zsh-Vervollständigungen richtig „einfach funktionieren“?

Bitte verzeihen Sie mir, wenn ich hier etwas Dummes mache, die Dokumentation ist riesig und die Suche hat noch nichts ergeben.

Ich versuche, Shell-Vervollständigungen für mein benutzerdefiniertes Skript namens fab zu erstellen . Für Bash war es einfach, sie einfach in /etc/bash_completion.d abzulegen und sie funktionieren. Aber oh Mann, ist zsh ein PITA…

Ich habe die Vervollständigungsfunktion _fab und es funktioniert gut, wenn es mit compdef _fab fab aktiviert wird . Ich habe es in /usr/share/zsh/vendor-completions/_fab abgelegt was bereits in meinem $fpath war . Die Datei beginnt mit #compdef fab und endet mit compdef _fab fab . Sieht gut aus:

$ type _fab
_fab is an autoload shell function

Aber immer wenn ich eine neue Shell gestartet habe, fab Vervollständigungen funktionierten nicht (andere Funktionen von vendor-completions , wie _docker , uns geht es gut). compinit dies wurde für diese bestimmte Shell behoben. Ich habe herausgefunden, dass rm ~/.zcompdump ~/.zcompdump-$(hostname)-5.1.1; compinit dauerhaft funktionieren lassen (5.1.1 =meine zsh-Version).

Fragen:

  1. Was und wann liest ~/.zcompdump erste Vervollständigungen einrichten?
  2. man zshall sagt:

    Der nächste Aufruf von compinit wird die ausgegebene Datei lesen, anstatt eine vollständige Initialisierung durchzuführen.

    Wenn das der Fall war, compinit würde meine Vervollständigungen nicht reparieren, bevor ich ~/.zcompdump gelöscht habe , Rechts? Übersehe ich etwas?

  3. Was ist ~/.zcompdump-$(hostname)-5.1.1 und wie hängt es mit .zcompdump zusammen ? Der einzige Unterschied ist eine Vervollständigung, die sich in ~/.oh-my-zsh/completions befindet (weil $ZSH zeigt auf ~/.oh-my-zsh ). Ist es eine Oh-mein-zsh-Sache?
  4. Wenn ich diese Vervollständigungen in ein verteilbares Paket packen oder ein Installationsskript erstellen würde, wo sollte ich zsh-Vervollständigungen platzieren und was sollte ich während der Installation sonst noch tun, um sicherzustellen, dass alles funktioniert?

Ich ziele auf Ubuntu 16.04, 18.04 und 19.04 ab, aber nicht-distrospezifische Informationen sind willkommen. Ich teste dies auf Ubuntu 16.04 mit zsh 5.1.1 und dem aktuellen oh-my-zsh.

Akzeptierte Antwort:

TL,DR:Legen Sie die Datei im normalen Betrieb einfach im entsprechenden Verzeichnis ab. Während des Tests müssen Sie die Cache-Datei (.zcompdump standardmäßig, aber Benutzer können es an einem anderen Ort ablegen, und oh-my-zsh legt es an einem anderen Ort ab).

Die einfache Antwort ist, die Vervollständigungsfunktion in eine Datei zu schreiben, in der die erste Zeile #compdef fab ist . Die Datei muss sich in einem Verzeichnis auf $fpath befinden .

Die Datei kann entweder den Funktionsrumpf oder eine Definition der Funktion gefolgt von einem Aufruf der Funktion enthalten. Das heißt, entweder enthält die Datei etwas wie

#compdef fab
_arguments …

oder

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

Die Datei muss auf $fpath vorhanden sein vor compinit läuft. Das bedeutet, dass Sie auf die Reihenfolge in .zshrc achten müssen :Fügen Sie zuerst alle benutzerdefinierten Verzeichnisse zu $fpath hinzu , dann rufen Sie compinit auf . Wenn Sie ein Framework wie oh-my-zsh verwenden, stellen Sie sicher, dass Sie alle benutzerdefinierten Verzeichnisse zu $fpath hinzufügen vor dem oh-my-zsh-Code.

compinit ist die Funktion, die das Vervollständigungssystem initialisiert. Es liest alle Dateien in $fpath und überprüft ihre erste Zeile auf magische Direktiven #autoload und #compdef .

.zcompdump ist eine Cache-Datei, die von compinit verwendet wird . ~/.zcompdump ist der Standardspeicherort; Sie können beim Ausführen von compinit einen anderen Speicherort auswählen . Oh-my-zsh ruft compinit auf mit dem -d Option, einen anderen Cache-Dateinamen zu verwenden, der durch die Variable ZSH_COMPDUMP angegeben wird , die standardmäßig

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

Der Hostname ist für Personen enthalten, deren Home-Verzeichnis von mehreren Computern gemeinsam genutzt wird und die möglicherweise unterschiedliche Software auf verschiedenen Computern installiert haben. Die zsh-Version ist enthalten, weil die Cache-Datei zwischen den Versionen nicht kompatibel ist (sie enthält Code, der sich von Version zu Version ändert).

Verwandte:Was macht STRG + V in vim?

Ich denke, alle Ihre Probleme sind auf eine veraltete Cache-Datei zurückzuführen (und das hat Sie die Situation zu kompliziert gemacht). Leider ist der Algorithmus von zsh, um festzustellen, ob die Cache-Datei veraltet ist, nicht perfekt, vermutlich im Interesse der Geschwindigkeit. Es überprüft nicht den Inhalt oder die Zeitstempel der Dateien auf $fpath , es zählt sie einfach. Ein .zcompdump Datei beginnt mit einer Zeile wie

#files: 858     version: 5.1.1

Wenn die zsh-Version und die Anzahl der Dateien korrekt sind, lädt zsh die Cache-Datei.

Die Cache-Datei enthält nur Zuordnungen zwischen Befehlsnamen, nicht den Code von Abschlussfunktionen. Hier sind einige gängige Szenarien, in denen der Cache transparent arbeitet:

  • Wenn Sie $fpath eine neue Datei hinzufügen , dadurch wird der Cache ungültig.
  • Allgemeiner gesagt, wenn Sie Dateien auf $fpath hinzufügen und entfernen , und die Gesamtzahl der entfernten Dateien nicht mit der Gesamtzahl der entfernten Dateien übereinstimmt, macht dies den Cache ungültig.
  • Wenn Sie eine Datei in $fpath in ein anderes Verzeichnis verschieben ohne seinen Namen zu ändern, wirkt sich dies nicht auf alles aus, was sich im Cache befindet, sodass der Cache korrekt bleibt.
  • Wenn Sie eine Datei in $fpath ändern ohne die erste Zeile zu ändern, wirkt sich dies nicht auf den Cache aus, sodass der Cache korrekt bleibt.

Hier sind einige häufige Szenarien, in denen der Cache ungültig wird, aber zsh es nicht bemerkt.

  • Sie fügen einige Dateien zu $fpath hinzu und genau die gleiche Anzahl von Dateien entfernen.
  • Sie benennen eine Datei in $fpath um .
  • Sie fügen den #compdef hinzu oder ändern ihn (oder #autoload ) Zeile am Anfang der Datei.

Dieser letzte Punkt neigt dazu, beim Testen zu beißen. Wenn Sie die #compdef ändern müssen Sie die .zcompdump entfernen Datei und starten Sie zsh neu (oder führen Sie compinit erneut aus ).

Wenn Sie Vervollständigungen in ein verteilbares Paket packen, legen Sie die Vervollständigungsdatei einfach in einem Verzeichnis ab, das sich im systemweiten $fpath befindet . Für ein Ubuntu-Paket ist der geeignete Ort /usr/share/zsh/vendor-completions . Für etwas, das unter /usr/local installiert ist , das ist /usr/local/share/zsh/site-functions . Das ist alles, was Sie tun müssen.

Das einzige, was nicht transparent ist, ist, ob Sie #compdef ändern müssen bei einem Upgrade oder wenn Sie einige Dateien entfernen oder umbenennen. In solchen Fällen müssen Benutzer ihre Cache-Datei entfernen, und das können Sie nicht mit einem Paket tun, das auf einem Mehrbenutzer-Computer installiert wird.


Ubuntu
  1. Wie installiere ich Zsh unter Ubuntu 20.04?

  2. So installieren Sie Nagios unter Ubuntu 14.04

  3. Wie erstelle ich eine benutzerdefinierte Start-Splash-Animation?

  4. So installieren Sie g ++ unter Ubuntu

  5. So installieren Sie ZSH unter Ubuntu 20.04

So löschen Sie eine Datei in Ubuntu

So installieren Sie CouchPotato auf Ubuntu

So benennen Sie Dateien in Ubuntu 20.04 um

So installieren und machen Sie Nemo zum Standard-Dateimanager in Ubuntu

So installieren Sie ZSH (Z Shell) unter Ubuntu 20.04

So installieren Sie OH-MY-ZSH in Ubuntu 21.04