Para desativar a conclusão completamente se você estiver nesses diretórios, você pode usar este código:
function restricted-expand-or-complete() {
if [[ ! $PWD = /mnt/* ]]; then
zle expand-or-complete
else
echo -en "/foo/bar$ cp hello.c /mnt/[TAB]
7"
fi
}
zle -N restricted-expand-or-complete
bindkey "^I" restricted-expand-or-complete
Isso define uma função que verifica se o seu diretório de trabalho começa com /mnt/
. Caso contrário, a função de conclusão padrão é chamada via zle expand-or-complete
, caso contrário, um bipe é produzido.
A função é declarada como um widget ( zle -N
) e vinculada a TAB ( bindkey
).
No entanto, isso é apenas um começo, porque quando você faz algo assim
zstyle ':completion:*:*files' ignored-patterns '/mnt/*'
zstyle ':completion:*:*directories' ignored-patterns '/mnt/*'
você está perdido novamente. Então você também teve que excluir a árvore /mnt/
do sistema de conclusão. De acordo com o documento que deve fazer o truque:
if [[ ! $PWD = /mnt/* && ! ${${(z)LBUFFER}[-1]} = */mnt/* ]]
Mas não tenho certeza se isso impedirá qualquer chamada de função stat para /mnt/
ou somente removerá as correspondências posteriormente. Por favor, tente e se ainda houver um atraso perceptível, estenda a cláusula if na função restricted-expand-or-complete
para
function restricted-expand-or-complete() {
# split into shell words also at "=", if IFS is unset use the default (blank, \t, \n, function restricted-expand-or-complete() {
if [[ ! $PWD = /mnt/* ]]; then
zle expand-or-complete
else
echo -en "/foo/bar$ cp hello.c /mnt/[TAB]
7"
fi
}
zle -N restricted-expand-or-complete
bindkey "^I" restricted-expand-or-complete
)
local IFS="${IFS:- \n\tzstyle ':completion:*:*files' ignored-patterns '/mnt/*'
zstyle ':completion:*:*directories' ignored-patterns '/mnt/*'
}="
# 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 "if [[ ! $PWD = /mnt/* && ! ${${(z)LBUFFER}[-1]} = */mnt/* ]]
7"
fi
}
zle -N restricted-expand-or-complete
bindkey "^I" restricted-expand-or-complete
[EDITAR]
Eu reformulei este hack para ser mais flexível, mas ainda tem problemas e ainda estou positivo modificando diretamente as funções de conclusão (talvez _path_files
) seria muito mais limpo. No entanto ...
Isso funciona (um resumo nos exemplos):
-
ls <TAB>
está bloqueado em um diretório lento (/mnt
) -
ls /mnt/<TAB>
está bloqueado -
ls /home/user/symlink_to_mnt/<TAB>
está bloqueado -
cd /; ls mnt/<TAB>
está bloqueado -
tar --exclude-from=/mnt/<TAB>
está bloqueado (também as outras variantes, symlink, caminho relativo)
Isso não funciona:
-
A conclusão no caminho
- ainda completa
/m/s/p
a/mnt/some/path
- a conclusão das opções de comando é bloqueada, se a opção não começar com
-
, por ex.apt-get inst<TAB>
não funciona dentro de / mnt - em
/
o comportamento estranho ocorre no Cygwin, com o Linux tudo está bem
E aqui está o código:
function restricted-expand-or-complete() {
# split into shell words also at "=", if IFS is unset use the default (blank, \t, \n, %pre%)
local IFS="${IFS:- \n\t%pre%}="
# 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 "%pre%7"
fi
}
zle -N restricted-expand-or-complete
bindkey "^I" restricted-expand-or-complete