Esto no es perfecto, pero una vez más la finalización de bash es bastante difícil ...
La forma más simple es por orden, es un poco más flexible que FIGNORE
, puedes hacer:
complete -f -X "/myproject/data/*" vi
Esto le indica al autocompletado que la finalización de vi
es para archivos y para eliminar patrones que coincidan con el -X
filtro. La desventaja es que el patrón no está normalizado, así que../data
variaciones no coincidirán.
La siguiente mejor opción podría ser una PROMPT_COMMAND
función 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
Esto desactiva la finalización (completamente) cuando está en el directorio, pero lo desactiva para cada ruta, no solo para los archivos en ese directorio.
Sería más útil en general deshabilitar selectivamente esto para rutas definidas, pero creo que la única forma es usar una función de finalización predeterminada (bash-4.1 y posterior con complete -D
) y un montón de problemas.
Esto debería funcionar para usted, pero puede tener efectos secundarios no deseados (es decir, cambios en la finalización esperada en algunos 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
Esto funciona para completar vi
, se pueden agregar otros comandos según sea necesario. Debe detener la finalización de los archivos en los directorios nombrados, independientemente de la ruta o el directorio de trabajo.
Creo que el enfoque general con complete -D
es agregar dinámicamente funciones de finalización para cada comando a medida que se encuentra. También podría ser necesario agregar complete -E
(completar el nombre del comando cuando el búfer de entrada está vacío).
Actualización
Aquí hay una versión híbrida de las PROMPT_COMMAND
soluciones de función de finalización, creo que es un poco más fácil de entender y piratear:
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 función de solicitud establece la nocomplete
variable cuando ingresa uno de los directorios configurados. El comportamiento de finalización modificado solo se activa cuando esa variable no está en blanco y solo cuando intenta completar desde una cadena vacía, lo que permite completar nombres parciales (elimine la -z "$cur"
condición para evitar que se complete por completo). Comenta los dosprintf
líneas para una operación silenciosa.
Otras opciones incluyen un .noautocomplete
archivo de marca por directorio que puede touch
en un directorio según sea necesario; y adivinar el tamaño del directorio usando GNUstat
. Puede usar cualquiera o todas esas tres opciones.
(El stat
método es solo una suposición , el tamaño del directorio reportado crece con su contenido, es una "marca de límite" que generalmente no se reducirá cuando los archivos se eliminen sin alguna intervención administrativa. Es más barato que determinar el contenido real de un archivo potencialmente grande directorio. El comportamiento preciso y el incremento por archivo dependen del sistema de archivos subyacente. Me parece un indicador confiable en los sistemas Linux ext2 / 3/4 al menos).
bash agrega un espacio adicional incluso cuando se devuelve una finalización vacía (esto solo ocurre cuando se completa al final de una línea). Puede agregar -o nospace
al complete
comando para evitar esto.
Un inconveniente restante es que si retrocede el cursor al comienzo de un token y presiona la pestaña, la finalización predeterminada se activará nuevamente. Considéralo una característica ;-)
(O podría perder el tiempo ${COMP_LINE:$COMP_POINT-1:1}
si le gusta la ingeniería excesiva, pero creo que bash en sí mismo no puede establecer las variables de finalización de manera confiable cuando realiza una copia de seguridad e intenta completarla en medio de un comando).