To nie jest idealne, ale z drugiej strony ukończenie bashu jest dość trudne ...
Najprostszy sposób jest oparty na poleceniach, jest nieco bardziej elastyczny niż FIGNOREmożesz:
complete -f -X "/myproject/data/*" vi
To instruuje autouzupełnianie, że uzupełnianie vidotyczy plików i usuwania wzorców pasujących do -Xfiltra. Minusem jest to, że wzorzec nie jest znormalizowany, więc ../dataodmiany nie będą pasować.
Kolejną najlepszą rzeczą może być PROMPT_COMMANDfunkcja niestandardowa :
# 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
To zakończenie wyłącza (całkowicie), gdy jesteś w katalogu, ale nie wyłącza go to dla każdej ścieżki tylko pliki znajdujące się w tym katalogu.
Bardziej ogólnie przydałoby się selektywne wyłączanie tego dla zdefiniowanych ścieżek, ale uważam, że jedynym sposobem jest użycie domyślnej funkcji uzupełniania (bash-4.1 i później z complete -D) i dużo bałaganu.
To powinno pracować dla Ciebie, ale może mieć niezamierzone efekty uboczne (czyli zmiany w przewidywanym zakończeniu w niektórych przypadkach):
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
Działa to do zakończenia vi, w razie potrzeby można dodać inne polecenia. Powinno to zatrzymać uzupełnianie plików w nazwanych katalogach niezależnie od ścieżki lub katalogu roboczego.
Uważam, że ogólne podejście complete -Dpolega na dynamicznym dodawaniu funkcji uzupełniania dla każdego polecenia, jakie napotka. Konieczne może być również dodanie complete -E(uzupełnienie nazwy polecenia, gdy bufor wejściowy jest pusty).
Aktualizacja
Oto hybrydowa wersja PROMPT_COMMANDrozwiązań funkcji uzupełniania i jest nieco łatwiejsza do zrozumienia i zhakowania, jak sądzę:
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
Ta funkcja pytania ustawia nocompletezmienną po wejściu do jednego ze skonfigurowanych katalogów. Zmodyfikowane zachowanie uzupełniania włącza się tylko wtedy, gdy zmienna nie jest pusta i tylko wtedy, gdy próbujesz uzupełnić z pustego łańcucha, umożliwiając w ten sposób uzupełnienie częściowych nazw (usuń -z "$cur"warunek, aby całkowicie nie dopełnić). Skomentuj dwie printflinie dla cichej pracy.
Inne opcje obejmują .noautocompleteplik flag dla katalogu, który można touchw razie potrzeby w katalogu; i zgadywanie rozmiaru katalogu za pomocą GNU stat. Możesz użyć jednej lub wszystkich tych trzech opcji.
( statMetoda jest tylko zgadywaniem , zgłaszany rozmiar katalogu rośnie wraz z jego zawartością, jest to „wysoki znak wodny”, który zwykle nie zmniejsza się, gdy pliki są usuwane bez interwencji administracyjnej. Jest to tańsze niż określenie rzeczywistej zawartości potencjalnie dużej katalog. Precyzyjne zachowanie i przyrost na plik zależy od bazowego systemu plików. Uważam, że jest to wiarygodny wskaźnik przynajmniej w systemach Linux ext2 / 3/4).
bash dodaje dodatkową spację nawet po zwróceniu pustego zakończenia (dzieje się tak tylko po zakończeniu na końcu linii). Możesz dodać -o nospacedo completepolecenia, aby temu zapobiec.
Pozostałym problemem jest to, że jeśli cofniesz kursor na początek tokena i klikniesz kartę, domyślne zakończenie zostanie ponownie uruchomione. Rozważ to jako funkcję ;-)
(Lub możesz przeskakiwać, ${COMP_LINE:$COMP_POINT-1:1}jeśli lubisz nadmierną inżynierię, ale uważam, że sam bash nie ustawia niezawodnie zmiennych zakończenia podczas tworzenia kopii zapasowej i próby ukończenia w środku polecenia.)