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-complete
altrimenti 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-complete
funzione 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/p
a/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