Isso não é perfeito, mas a conclusão do bash é bem complicada ...
A maneira mais simples é por comando, é um pouco mais flexível que FIGNORE
, você pode fazer:
complete -f -X "/myproject/data/*" vi
Isso instrui o preenchimento automático de que a conclusão de vi
é para arquivos e para remover padrões correspondentes ao filtro -X
. A desvantagem é que o padrão não é normalizado, portanto, ../data
e variações não corresponderão.
A próxima melhor coisa pode ser uma função PROMPT_COMMAND
personalizada:
# associative arrays of non-autocomplete directories
declare -A noacdirs=([/myproject/data]=1 )
function _myprompt {
[[ -n "${noacdirs[$PWD]}" ]] && {
echo autocomplete off
bind 'set disable-completion on'
} || {
echo autocomplete on
bind 'set disable-completion off'
}
}
PROMPT_COMMAND=_myprompt
Esta desativa a conclusão (completamente) quando você está no diretório, mas desativa-o para todos os caminhos, não apenas arquivos naquele diretório.
Seria mais útil desativar isso seletivamente para caminhos definidos, mas acredito que a única maneira é usar uma função de conclusão padrão (bash-4.1 e posterior com complete -D
) e muita confusão.
Isso deve funcionar para você, mas pode ter efeitos colaterais indesejados (ou seja, alterações na conclusão esperada em alguns casos):
declare -A noacdirs=([/myproject/data]=1 )
_xcomplete() {
local cur=${COMP_WORDS[COMP_CWORD]} # the current token
name=$(readlink -f "${cur:-./}") # poor man's path canonify
dirname=$(dirname "$name/.")
[[ -n "${noacdirs[$dirname]}" ]] && {
COMPREPLY=( "" ) # dummy to prevent completion
return
}
# let default kick in
COMPREPLY=()
}
complete -o bashdefault -o default -F _xcomplete vi
Isso funciona para a conclusão de vi
, outros comandos podem ser adicionados conforme necessário. Deve parar a conclusão de arquivos nos diretórios nomeados, independentemente do caminho ou diretório de trabalho.
Eu acredito que a abordagem geral com complete -D
é adicionar dinamicamente funções de conclusão para cada comando conforme ele é encontrado. Também é necessário adicionar complete -E
(conclusão do nome do comando quando o buffer de entrada estiver vazio).
Atualizar
Aqui está uma versão híbrida das soluções PROMPT_COMMAND
e função de conclusão, é um pouco mais fácil de entender e hackear, eu acho:
declare -A noacdirs=([/myproject/data]=1 [/project2/bigdata]=1)
_xcomplete() {
local cmd=${COMP_WORDS[0]}
local cur=${COMP_WORDS[COMP_CWORD]} # the current token
[[ -z "$cur" && -n "$nocomplete" ]] && {
printf "\n(restricted completion for $cmd in $nocomplete)\n"
printf "$PS2 $COMP_LINE"
COMPREPLY=( "" ) # dummy to prevent completion
return
}
COMPREPLY=() # let default kick in
}
function _myprompt {
nocomplete=
# uncomment next line for hard-coded list of directories
[[ -n "${noacdirs[$PWD]}" ]] && nocomplete=$PWD
# uncomment next line for per-directory ".noautocomplete"
# [[ -f ./.noautocomplete ]] && nocomplete=$PWD
# uncomment next line for size-based guessing of large directories
# [[ $(stat -c %s .) -gt 512*1024 ]] && nocomplete=$PWD
}
PROMPT_COMMAND=_myprompt
complete -o bashdefault -o default -F _xcomplete vi cp scp diff
Esta função de prompt define a variável nocomplete
quando você insere um dos diretórios configurados. O comportamento de conclusão modificado só entra em ação quando essa variável não estiver em branco e apenas quando você tentar concluir uma string vazia, permitindo a conclusão de nomes parciais (remova a condição -z "$cur"
para evitar a conclusão completamente) . Comente as duas linhas printf
para operação silenciosa.
Outras opções incluem um arquivo% flag .noautocomplete
por diretório, que você pode usar touch
em um diretório, conforme necessário; e adivinhando o tamanho do diretório usando o GNU stat
. Você pode usar qualquer uma ou todas essas três opções.
(O método stat
é apenas um palpite , o tamanho do diretório relatado aumenta com o seu conteúdo, é um "limite máximo" que normalmente não diminui quando os arquivos são excluídos sem algum procedimento administrativo É mais barato do que determinar o conteúdo real de um diretório potencialmente grande.Comportamento preciso e incremento por arquivo depende do sistema de arquivos subjacente.Eu acho um indicador confiável em sistemas linux ext2 / 3/4, pelo menos.
bash adiciona um espaço extra, mesmo quando uma conclusão vazia é retornada (isso ocorre apenas ao completar no final de uma linha). Você pode adicionar -o nospace
ao comando complete
para evitar isso.
Uma coisinha remanescente é que, se você fizer o backup do cursor para o início de um token e clicar na guia, a conclusão padrão será ativada novamente. Considere isso como um recurso; -)
(Ou você pode andar com ${COMP_LINE:$COMP_POINT-1:1}
se você gosta de engenharia excessiva, mas acho que o próprio bash falha em definir as variáveis de conclusão de forma confiável quando você faz backup e tenta completar no meio de um comando.)