Come disabilitare il completamento della scheda zsh per le directory NFS?


4

Io uso zshe il suo completamento scheda. Quando premo accidentalmente la scheda in una directory (lenta) NFS, zshimpiega troppo tempo. Ancora peggio, se l'NFS è inattivo, e io premo /mnt/[tab], l'intera shell si blocca.

Come posso disabilitare il zshcompletamento delle schede in queste directory?

Risposte:


2

Per disabilitare completamente il completamento se ci si trova in quelle directory, è possibile utilizzare questo codice:

function restricted-expand-or-complete() {
        if [[ ! $PWD = /mnt/* ]]; then    
                zle expand-or-complete
        else    
                echo -en "\007"
        fi
}
zle -N restricted-expand-or-complete
bindkey "^I" restricted-expand-or-complete

Questo definisce una funzione che controlla se la directory di lavoro inizia con /mnt/. In caso contrario, la funzione di completamento predefinita viene chiamata tramite zle expand-or-completealtrimenti viene emesso un segnale acustico. La funzione è dichiarata come widget ( zle -N) e associata a TAB( bindkey).

Tuttavia, questo è solo un inizio, perché quando fai qualcosa del genere

/foo/bar$ cp hello.c /mnt/[TAB]

ti sei perso di nuovo. Quindi dovevi anche escludere l' /mnt/albero dal sistema di completamento. Secondo il documento che dovrebbe fare il trucco:

zstyle ':completion:*:*files' ignored-patterns '/mnt/*'
zstyle ':completion:*:*directories' ignored-patterns '/mnt/*'

Ma non sono sicuro se ciò impedirà qualsiasi chiamata alla funzione stat /mnt/o rimuoverà solo le partite in seguito. Prova e se c'è ancora un notevole ritardo, estendi la clausola if nella restricted-expand-or-completefunzione a

if [[ ! $PWD = /mnt/* && ! ${${(z)LBUFFER}[-1]} = */mnt/* ]]

[MODIFICARE]

Ho rielaborato questo hack per renderlo più flessibile, ma ha ancora problemi e sono ancora positivo che modificare direttamente le funzioni di completamento (forse _path_files) sarebbe molto più pulito. Però...

Funziona (una sintesi in esempi):

  • ls <TAB>è bloccato all'interno di una dir lenta ( /mnt)
  • ls /mnt/<TAB> è bloccato
  • ls /home/user/symlink_to_mnt/<TAB> è bloccato
  • cd /; ls mnt/<TAB> è bloccato
  • tar --exclude-from=/mnt/<TAB> è bloccato (e anche le altre varianti, link simbolico, percorso relativo)

Questo non funziona:

  • il completamento in-path è ancora completato /m/s/pa/mnt/some/path
  • il completamento delle opzioni di comando è bloccato, se l'opzione non inizia con -, ad es. apt-get inst<TAB>non funzionerà all'interno di / mnt
  • in /comportamenti strani si verifica sotto Cygwin, con Linux va tutto bene

Ed ecco il codice:

function restricted-expand-or-complete() {

   # split into shell words also at "=", if IFS is unset use the default (blank, \t, \n, \0)
   local IFS="${IFS:- \n\t\0}="

   # this word is completed
   local complt

   # if the cursor is following a blank, you are completing in CWD
   # the condition would be much nicer, if it's based on IFS
   if [[ $LBUFFER[-1] = " " || $LBUFFER[-1] = "=" ]]; then
      complt="$PWD"
   else
      # otherwise take the last word of LBUFFER
      complt=${${=LBUFFER}[-1]}
   fi

   # determine the physical path, if $complt is not an option (i.e. beginning with "-")
   [[ $complt[1] = "-" ]] || complt=${complt:A}/

   # activate completion only if the file is on a local filesystem, otherwise produce a beep
   if [[ ! $complt = /mnt/* && ! $complt = /another/nfs-mount/* ]]; then    
      zle expand-or-complete
   else    
      echo -en "\007"
   fi
}
zle -N restricted-expand-or-complete
bindkey "^I" restricted-expand-or-complete

La funzione ha funzionato, lo zstyle no. Ma ci sono ancora modi in cui il completamento viene attivato ma non corrisponde a LBUFFER - e, voglio solo saltare il completamento su quella parte, non su altre cose quando sono in quella directory. C'è un modo per omettere semplicemente il controllo da queste directory, senza usare l'hacker LBUFFER?
SRobertJames,

@SRobertJames: hai ragione, questa soluzione ha alcuni problemi. Non sono a conoscenza della possibilità di escludere completamente una gerarchia di percorsi specifici dal completamento - ciò non significa che non ce ne sia ( /usr/share/zsh/5.0.2/functions/_filespotrebbe essere un punto di partenza). Ho migliorato un po 'l'hack di LBUFFER, quindi il completamento è disabilitato solo se contiene l'ultima parola in LBUFFER */mnt/*.
mpy,

1
Grazie, questa è una soluzione pulita. L'altro problema che ho riscontrato con l'hacking LBUFFER è che ho un link simbolico ~srj/proj1/data(i dati sono su NFS). Mi piacerebbe il completamento delle schede mentre ci sono proj1, ma non per data. C'è una soluzione?
SRobertJames,

@SRobertJames: Ieri avrei detto "no", ma oggi avevo altre idee. Ci sono ancora problemi (ho fatto un elenco con quello che mi è venuto in mente), ma questo è il meglio che puoi ottenere da me;)
mpy

Bene, vado a dare un'occhiata. Dove posso specificare i nomi delle mie directory NFS e dei loro collegamenti simbolici? A proposito, questo problema è unico di zsh o ne soffre anche Bash?
SRobertJames
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.