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ż FIGNORE
możesz:
complete -f -X "/myproject/data/*" vi
To instruuje autouzupełnianie, że uzupełnianie vi
dotyczy plików i usuwania wzorców pasujących do -X
filtra. Minusem jest to, że wzorzec nie jest znormalizowany, więc ../data
odmiany nie będą pasować.
Kolejną najlepszą rzeczą może być PROMPT_COMMAND
funkcja 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 -D
polega 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_COMMAND
rozwią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 nocomplete
zmienną 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 printf
linie dla cichej pracy.
Inne opcje obejmują .noautocomplete
plik flag dla katalogu, który można touch
w razie potrzeby w katalogu; i zgadywanie rozmiaru katalogu za pomocą GNU stat
. Możesz użyć jednej lub wszystkich tych trzech opcji.
( stat
Metoda 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 nospace
do complete
polecenia, 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.)