Bu mükemmel değil, ama sonra tekrar bash tamamlanması oldukça zor bir şey ...
En basit yol, komut başına esasında, FIGNORE
yapabileceğinizden biraz daha esnektir :
complete -f -X "/myproject/data/*" vi
Bu, tamamlamanın vi
dosyalar için olduğunu ve -X
filtreyle eşleşen kalıpları kaldırmasını otomatik olarak tamamlar . Dezavantajı, desenin normalleştirilmemesi ../data
ve varyasyonların eşleşmemesidir.
Bir sonraki en iyi şey özel bir PROMPT_COMMAND
işlev olabilir :
# 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
Bu , dizinde olduğunuzda tamamlamayı (tamamen) devre dışı bırakır , ancak yalnızca bu dizindeki dosyalar için değil, her yol için devre dışı bırakır.
Tanımlı yollar için bunu seçici olarak devre dışı bırakmak daha genel olarak yararlı olacaktır, ancak tek yolun varsayılan tamamlama işlevini (bash-4.1 ve üstü ile complete -D
) ve çok fazla karışıklık kullanmak olduğuna inanıyorum .
Bu gerektiğini sizin için çalışacak, ama bu olabilir istenmeyen yan etkilere (yani bazı durumlarda beklenen tamamlanma değiştirir) vardır:
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
Bu vi
işlemin tamamlanması için çalışır , gerektiğinde diğer komutlar eklenebilir. Yoldan veya çalışma dizininden bağımsız olarak, adlandırılmış dizinlerdeki dosyaların tamamlanmasını durdurmalıdır.
Genel yaklaşım ile complete -D
karşılaşılan her komut için dinamik olarak tamamlama işlevleri eklemek olduğuna inanıyorum . Birinin de eklenmesi gerekebilir complete -E
(giriş arabelleği boş olduğunda komut adının tamamlanması).
Güncelleme
İşte PROMPT_COMMAND
ve tamamlama fonksiyonu çözümlerinin hibrit bir versiyonu, bence anlamak ve kesmek biraz daha kolay:
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
Bu komut istemi işlevi nocomplete
, yapılandırılmış dizinlerden birini girdiğinizde değişkeni ayarlar . Değiştirilen tamamlama davranışı yalnızca bu değişken boş olmadığında ve yalnızca boş bir dizeden tamamlamaya çalıştığınızda devreye girer ve böylece kısmi adların tamamlanmasına izin verir ( -z "$cur"
tamamlamayı tamamen önlemek için koşulu kaldırın ). printf
Sessiz çalışma için iki satırı yorumlayın.
Diğer seçenekler arasında , bir dizinde gerektiğinde .noautocomplete
yapabileceğiniz dizin başına bayrak dosyası touch
; ve GNU kullanarak dizin boyutunun tahmin edilmesi stat
. Bu üç seçenekten herhangi birini veya tümünü kullanabilirsiniz.
( stat
Yöntem sadece bir tahmindir , rapor edilen dizin boyutu içeriği ile birlikte büyür, bazı idari müdahaleler olmadan dosyalar silindiğinde genellikle küçülmeyen bir "yüksek su işareti" dir. Potansiyel olarak büyük bir dosyanın gerçek içeriğini belirlemek daha ucuz Dosya başına kesin davranış ve artış, altta yatan dosya sistemine bağlıdır. En azından linux ext2 / 3/4 sistemlerinde güvenilir bir gösterge buluyorum.)
bash, boş bir tamamlama döndürülse bile fazladan bir boşluk ekler (bu yalnızca bir satırın sonunda tamamlandığında oluşur). Bunu önlemek -o nospace
için complete
komuta ekleyebilirsiniz .
Kalan bir ince eleyip, imleci bir token ve hit sekmesinin başlangıcına yedeklerseniz, varsayılan tamamlamanın tekrar başlayacağı yönündedir. Bir özellik olarak düşünün ;-)
(Veya ${COMP_LINE:$COMP_POINT-1:1}
aşırı mühendislikten hoşlanıyorsanız etrafta dolaşabilirsiniz , ancak yedeklediğinizde ve bir komutun ortasında tamamlamayı denediğinizde bash'ın kendisinin tamamlama değişkenlerini güvenilir bir şekilde ayarlayamadığını görüyorum.)