GNU/Linux >> Linux Esercitazione >  >> Ubuntu

Ubuntu:come eseguire correttamente i completamenti Zsh personalizzati "funzionano"?

Per favore perdonami se sto facendo qualcosa di stupido qui, la documentazione è enorme e la ricerca non ha ancora trovato nulla.

Sto cercando di creare completamenti di shell per il mio script personalizzato chiamato fab . Per bash è stato facile, basta rilasciarli in /etc/bash_completion.d e funzionano. Ma oh ragazzo, è zsh una PITA...

Ho la funzione di completamento _fab e funziona bene se abilitato con compdef _fab fab . L'ho messo in /usr/share/zsh/vendor-completions/_fab che era già nel mio $fpath . Il file inizia con #compdef fab e termina con compdef _fab fab . Sembra buono:

$ type _fab
_fab is an autoload shell function

Ma ogni volta che ho avviato una nuova shell, fab i completamenti non hanno funzionato (altre funzioni da vendor-completions , come _docker , stiamo bene). compinit risolto questo problema per quella shell specifica. Ho scoperto che rm ~/.zcompdump ~/.zcompdump-$(hostname)-5.1.1; compinit fallo funzionare in modo permanente (5.1.1 =la mia versione zsh).

Domande:

  1. Cosa e quando legge ~/.zcompdump impostare i completamenti iniziali?
  2. man zshall dice:

    La successiva chiamata di compinit leggerà il file scaricato invece di eseguire un'inizializzazione completa.

    In tal caso, compinit non risolveva i miei completamenti prima di aver eliminato ~/.zcompdump , giusto? Mi sono perso qualcosa?

  3. Cos'è ~/.zcompdump-$(hostname)-5.1.1 e come è correlato a .zcompdump ? L'unica differenza è un completamento che si trova in ~/.oh-my-zsh/completions (perché $ZSH punta a ~/.oh-my-zsh ). È una cosa oh-my-zsh?
  4. Se dovessi impacchettare questi completamenti in un pacchetto ridistribuibile o creare uno script di installazione, dove dovrei inserire i completamenti zsh e cos'altro dovrei fare durante l'installazione per assicurarmi che tutto funzioni correttamente?

Mi rivolgo a Ubuntu 16.04, 18.04 e 19.04, ma sono benvenute informazioni non specifiche per la distribuzione. Lo sto testando su Ubuntu 16.04 con zsh 5.1.1 e recente oh-my-zsh.

Risposta accettata:

TL,DR:Nelle normali operazioni, trascina il file nella directory appropriata. Durante il test, devi rimuovere il file della cache (.zcompdump per impostazione predefinita, ma gli utenti possono metterlo in una posizione diversa e oh-my-zsh lo mette in una posizione diversa).

La semplice risposta è scrivere la funzione di completamento in un file in cui la prima riga è #compdef fab . Il file deve trovarsi in una directory su $fpath .

Il file può contenere il corpo della funzione o una definizione della funzione seguita da una chiamata alla funzione. Cioè, il file contiene qualcosa come

#compdef fab
_arguments …

o

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

Il file deve essere presente su $fpath prima di compinit corre. Ciò significa che devi prestare attenzione all'ordine delle cose in .zshrc :prima aggiungi tutte le directory personalizzate a $fpath , quindi chiama compinit . Se utilizzi un framework come oh-my-zsh, assicurati di aggiungere eventuali directory personalizzate a $fpath prima del codice oh-my-zsh.

compinit è la funzione che inizializza il sistema di completamento. Legge tutti i file in $fpath e controlla la loro prima riga per le direttive magiche #autoload e #compdef .

.zcompdump è un file di cache utilizzato da compinit . ~/.zcompdump è la posizione predefinita; puoi scegliere una posizione diversa durante l'esecuzione di compinit . Oh-my-zsh chiama compinit con il -d opzione per utilizzare un nome di file cache diverso dato dalla variabile ZSH_COMPDUMP , che per impostazione predefinita è

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

Il nome host è incluso per il bene delle persone la cui home directory è condivisa tra macchine e che potrebbero avere software diverso installato su macchine diverse. La versione zsh è inclusa perché il file della cache è incompatibile tra le versioni (include codice che cambia da versione a versione).

Correlati:cosa fa CTRL+V in vim?

Penso che tutti i tuoi problemi siano dovuti a un file di cache obsoleto (e questo ti ha reso eccessivamente complicata la situazione). Sfortunatamente, l'algoritmo di zsh per determinare se il file della cache è obsoleto non è perfetto, presumibilmente nell'interesse della velocità. Non controlla il contenuto o i timestamp dei file su $fpath , li conta. Un .zcompdump il file inizia con una riga come

#files: 858     version: 5.1.1

Se la versione di zsh e il numero di file sono corretti, zsh carica il file della cache.

Il file della cache contiene solo le associazioni tra i nomi dei comandi, non il codice delle funzioni di completamento. Ecco alcuni scenari comuni in cui la cache funziona in modo trasparente:

  • Se aggiungi un nuovo file a $fpath , questo invalida la cache.
  • Più in generale, se aggiungi e rimuovi file su $fpath e il numero totale di file rimossi non è uguale al numero totale di file rimossi, questo invalida la cache.
  • Se sposti un file in una directory diversa in $fpath senza cambiarne il nome, questo non influisce su nulla che sia nella cache, quindi la cache rimane corretta.
  • Se modifichi un file in $fpath senza modificare la sua prima riga, ciò non influisce su nulla che sia nella cache, quindi la cache rimane corretta.

Ecco alcuni scenari comuni in cui la cache diventa non valida, ma zsh non se ne rende conto.

  • Aggiungi alcuni file a $fpath e rimuovi esattamente lo stesso numero di file.
  • Rinomini un file in $fpath .
  • Aggiungi o modifichi il #compdef (o #autoload ) nella parte superiore del file.

Quest'ultimo punto è ciò che tende a mordere durante i test. Se modifichi il #compdef riga, è necessario rimuovere il .zcompdump file e riavvia zsh (o riesegui compinit ).

Se inserisci i completamenti in un pacchetto ridistribuibile, trascina semplicemente il file di completamento in una directory che si trova nel $fpath a livello di sistema . Per un pacchetto Ubuntu, il posto appropriato è /usr/share/zsh/vendor-completions . Per qualcosa installato in /usr/local , è /usr/local/share/zsh/site-functions . Questo è tutto ciò che devi fare.

L'unica cosa che non è trasparente è se devi cambiare il #compdef riga in un aggiornamento o se si rimuovono o si rinominano alcuni file. In questi casi, gli utenti dovranno rimuovere il loro file di cache e non è qualcosa che puoi fare da un pacchetto che viene installato su una macchina multiutente.


Ubuntu
  1. Come aggiungere un file di scambio su Ubuntu

  2. Come installare Oh My Zsh su Ubuntu

  3. Come installare Zsh su Ubuntu 20.04?

  4. Come installare Nagios su Ubuntu 14.04

  5. Come creare un'animazione Splash di avvio personalizzata?

Come eliminare un file in Ubuntu

Come installare CouchPotato su Ubuntu

Come rinominare i file in Ubuntu 20.04

Come installare e rendere Nemo il file manager predefinito in Ubuntu

Come installare ZSH (Z Shell) su Ubuntu 20.04

Come installare OH-MY-ZSH in Ubuntu 21.04