Como desabilitar a conclusão da guia zsh para diretórios NFS?

4

Eu uso zsh e sua conclusão de tabulação. Quando acidentalmente clico em uma guia NFS (lenta), zsh demora muito. Pior ainda, se o NFS estiver inativo e eu atingir /mnt/[tab] , todo o meu shell trava.

Como posso desativar a conclusão da guia zsh nesses diretórios?

    
por SRobertJames 21.04.2013 / 04:02

1 resposta

2

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\t
zstyle ':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
    
por 22.04.2013 / 15:39

Tags