これは完璧ではありませんが、bashの完了は非常に難しいことです...
最も簡単な方法は、コマンドごとにFIGNORE
行うことです。これは、よりもわずかに柔軟性があります。
complete -f -X "/myproject/data/*" vi
これにより、オートコンプリートvi
はファイルの補完が完了し、-X
フィルターに一致するパターンが削除されます。欠点は、パターンが正規化../data
されていないため、バリエーションが一致しないことです。
次に最適なのは、カスタムPROMPT_COMMAND
関数です。
# 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
この無効完了(完全に)あなたがディレクトリにある、しかし、それだけでそのディレクトリ内のファイルではないすべてのパスのためにそれを無効にします。
定義されたパスに対してこれを選択的に無効にする方が一般的には便利ですが、唯一の方法はデフォルトの補完機能(bash-4.1以降complete -D
)を使用し、多くのことをいじることです。
これはうまくいくはずですが、意図しない副作用がある場合があります(つまり、場合によっては予想される完了への変更)。
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
これはの完了に対してvi
機能し、必要に応じて他のコマンドを追加できます。パスまたは作業ディレクトリに関係なく、指定されたディレクトリ内のファイルの補完を停止する必要があります。
での一般的なアプローチcomplete -D
は、各コマンドに遭遇したときに補完機能を動的に追加することだと思います。追加する必要がある場合もありますcomplete -E
(入力バッファが空の場合のコマンド名の補完)。
更新
ここにPROMPT_COMMAND
、補完機能ソリューションのハイブリッドバージョンがあります。理解し、ハッキングするのが少し簡単だと思います。
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
このプロンプト関数nocomplete
は、構成済みのディレクトリの1つを入力すると変数を設定します。変更された完了動作は、その変数が空白でない場合と空の文字列から完了しようとする場合にのみ起動し、名前の一部の完了を許可します(-z "$cur"
完全に完了しないように条件を削除します)。printf
サイレント操作のために2 行をコメント化します。
他のオプションには、必要に応じてディレクトリ内で使用.noautocomplete
できるディレクトリごとのフラグファイルが含まtouch
れます。GNUを使用したディレクトリサイズの推測stat
。これら3つのオプションのいずれかまたはすべてを使用できます。
(stat
方法は推測に過ぎず、報告されたディレクトリサイズはその内容とともに増加します。管理者の介入なしにファイルが削除されても通常は縮小しない「最高水準点」です。ディレクトリ。ファイルごとの正確な動作と増分は、基礎となるファイルシステムに依存します。Linuxext2 / 3/4システムでは、少なくとも信頼できる指標であると思います。)
bashは、空の完了が返された場合でも余分なスペースを追加します(これは、行の最後で完了する場合にのみ発生します)。あなたは追加することができます-o nospace
しcomplete
、これを防止するためのコマンド。
残っている問題の1つは、カーソルをトークンの先頭にバックアップしてタブを押すと、デフォルトの補完が再び開始されることです。機能と考えてください;-)
(または${COMP_LINE:$COMP_POINT-1:1}
、オーバーエンジニアリングが好きな場合は、いじくり回すことができますが、コマンドの途中でバックアップして完了しようとすると、bash自体が完了変数を確実に設定できません。)