Questo non è perfetto, ma poi il completamento bash è piuttosto complicato ...
Il modo più semplice è basato su un comando, è leggermente più flessibile di FIGNORE
, puoi fare:
complete -f -X "/myproject/data/*" vi
Ciò indica il completamento automatico del completamento per i vi
file e la rimozione dei motivi corrispondenti al -X
filtro. Il rovescio della medaglia è che il modello non è normalizzato, quindi le ../data
variazioni non corrispondono.
La prossima cosa migliore potrebbe essere una PROMPT_COMMAND
funzione personalizzata :
# 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
Questo disabilita il completamento (completamente) quando ci si trova nella directory, ma lo disabilita per ogni percorso non solo per i file in quella directory.
Sarebbe più generalmente utile disabilitarlo selettivamente per percorsi definiti, ma credo che l'unico modo sia usare una funzione di completamento predefinita (bash-4.1 e successive con complete -D
) e molti problemi.
Questo dovrebbe funzionare per te, ma potrebbe avere effetti collaterali indesiderati (ad esempio, modifiche al completamento previsto in alcuni casi):
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
Funziona per il completamento di vi
, altri comandi possono essere aggiunti secondo necessità. Dovrebbe interrompere il completamento dei file nelle directory indicate indipendentemente dal percorso o dalla directory di lavoro.
Credo che l'approccio generale complete -D
sia quello di aggiungere dinamicamente funzioni di completamento per ciascun comando quando viene rilevato. Potrebbe anche essere necessario aggiungere complete -E
(completamento del nome del comando quando il buffer di input è vuoto).
Aggiornamento
Ecco una versione ibrida delle PROMPT_COMMAND
soluzioni con funzioni di completamento, è un po 'più facile da capire e hacking penso:
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
Questa funzione di prompt imposta la nocomplete
variabile quando si immette una delle directory configurate. Il comportamento di completamento modificato si attiva solo quando quella variabile non è vuota e solo quando si tenta di completare da una stringa vuota, consentendo così il completamento di nomi parziali (rimuovere la -z "$cur"
condizione per impedirne del tutto il completamento). Commenta le due printf
righe per un funzionamento silenzioso.
Altre opzioni includono un .noautocomplete
file flag per directory che è possibile touch
in una directory secondo necessità; e indovinare la dimensione della directory usando GNU stat
. Puoi usare una o tutte queste tre opzioni.
(Il stat
metodo è solo una supposizione , la dimensione della directory segnalata cresce con il suo contenuto, è un "segno di riferimento" che di solito non si riduce quando i file vengono eliminati senza alcun intervento amministrativo. È più economico che determinare il contenuto reale di un potenzialmente grande directory. Il comportamento preciso e l'incremento per file dipende dal filesystem sottostante. Lo trovo almeno un indicatore affidabile sui sistemi Linux ext2 / 3/4.)
bash aggiunge uno spazio extra anche quando viene restituito un completamento vuoto (ciò si verifica solo quando si completa alla fine di una riga). È possibile aggiungere -o nospace
al complete
comando per impedirlo.
Un altro inconveniente è che se si esegue il backup del cursore all'inizio di un token e si preme la scheda, il completamento predefinito verrà riavviato. Consideralo una caratteristica ;-)
(Oppure potresti andare in giro ${COMP_LINE:$COMP_POINT-1:1}
se ti piace un eccesso di ingegneria, ma trovo che bash stesso non riesca a impostare le variabili di completamento in modo affidabile quando esegui il backup e tenti di completarlo nel mezzo di un comando.)