Ce n'est pas parfait, mais encore une fois, l'achèvement de bash est assez difficile ...
La manière la plus simple est sur une base par commande, elle est légèrement plus flexible que FIGNORE
, vous pouvez le faire:
complete -f -X "/myproject/data/*" vi
Cela indique à la saisie semi-automatique que la complétion vi
est pour les fichiers et à supprimer les modèles correspondant au -X
filtre. L'inconvénient est que le modèle n'est pas normalisé, donc les ../data
variations ne correspondent pas.
La prochaine meilleure chose pourrait être une PROMPT_COMMAND
fonction personnalisée :
# 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
Cela désactive l'achèvement (complètement) lorsque vous êtes dans le répertoire, mais il le désactive pour chaque chemin, pas seulement pour les fichiers de ce répertoire.
Il serait plus généralement utile de désactiver cela de manière sélective pour des chemins définis, mais je crois que la seule façon est d'utiliser une fonction de complétion par défaut (bash-4.1 et ultérieur avec complete -D
) et beaucoup de déconner.
Cela devrait fonctionner pour vous, mais cela peut avoir des effets secondaires imprévus (c'est-à-dire des changements à la fin attendue dans certains cas):
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
Cela fonctionne pour l'achèvement de vi
, d'autres commandes peuvent être ajoutées au besoin. Il doit arrêter l'achèvement des fichiers dans les répertoires nommés, quel que soit le chemin ou le répertoire de travail.
Je pense que l'approche générale complete -D
consiste à ajouter dynamiquement des fonctions d'achèvement pour chaque commande au fur et à mesure qu'elle se produit. Il peut également être nécessaire d'ajouter complete -E
(achèvement du nom de la commande lorsque le tampon d'entrée est vide).
Mise à jour
Voici une version hybride des PROMPT_COMMAND
solutions de fonction et de complétion, c'est un peu plus facile à comprendre et à pirater je pense:
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
Cette fonction d'invite définit la nocomplete
variable lorsque vous entrez dans l'un des répertoires configurés. Le comportement de complétion modifié n'intervient que lorsque cette variable n'est pas vide et uniquement lorsque vous essayez de terminer à partir d'une chaîne vide, permettant ainsi la complétion des noms partiels (supprimez la -z "$cur"
condition pour empêcher complètement la complétion). Commentez les deux printf
lignes pour un fonctionnement silencieux.
Les autres options incluent un .noautocomplete
fichier indicateur par répertoire que vous pouvez touch
dans un répertoire selon vos besoins; et deviner la taille du répertoire en utilisant GNU stat
. Vous pouvez utiliser l'une ou l'ensemble de ces trois options.
(La stat
méthode n'est qu'une supposition , la taille du répertoire signalé augmente avec son contenu, c'est un «high water mark» qui ne rétrécit généralement pas lorsque les fichiers sont supprimés sans intervention administrative. C'est moins cher que de déterminer le contenu réel d'un fichier potentiellement volumineux Le comportement précis et l'incrémentation par fichier dépendent du système de fichiers sous-jacent. Je le trouve au moins un indicateur fiable sur les systèmes linux ext2 / 3/4.)
bash ajoute un espace supplémentaire même quand un achèvement vide est retourné (cela ne se produit que lors de l'achèvement à la fin d'une ligne). Vous pouvez ajouter -o nospace
à la complete
commande pour éviter cela.
Un inconvénient restant est que si vous sauvegardez le curseur au début d'un jeton et appuyez sur l'onglet, l'achèvement par défaut se déclenchera à nouveau. Considérez cela comme une fonctionnalité ;-)
(Ou vous pouvez essayer ${COMP_LINE:$COMP_POINT-1:1}
si vous aimez la sur-ingénierie, mais je trouve que bash lui-même ne parvient pas à définir les variables d'achèvement de manière fiable lorsque vous sauvegardez et tentez l'achèvement au milieu d'une commande.)