Bash完了スクリプトを設定しようとしていますが、問題が発生しています。
リストされている補完が特定の拡張子に一致するファイル、またはディレクトリ(その拡張子のファイルが含まれている場合と含まれていない場合があります)のいずれかになるように設定したいと思います。
私が抱えている問題は、ファイルを含む補完を取得する唯一の方法およびディレクトリは-o plusdirs -f -X '!*.txt'
のようなものを使用することですが、bashにディレクトリの1つを補完させるとスラッシュではなく、末尾にスペースを追加するだけです。
_xyz()
{
local cur=${COMP_WORDS[COMP_CWORD]}
local prev=${COMP_WORDS[COMP_CWORD-1]}
#COMPREPLY=( $( compgen -f -X '!*.txt' -- $cur ) )
#COMPREPLY=( $( compgen -f -G '*.txt' -- $cur ) )
#COMPREPLY=( $( compgen -o filenames -f -X '!*.txt' -- $cur ) )
#COMPREPLY=( $( compgen -o dirnames -f -X '!*.txt' -- $cur ) )
COMPREPLY=( $( compgen -o plusdirs -f -X '!*.txt' -- $cur ) )
return 0
}
complete -F _xyz xyz
コメントアウトされた行もすべて試しましたが、ディレクトリも拡張されていません。
テストのために、これを1つの.txtファイルと1つのディレクトリ "dir"があるディレクトリで実行しました(.txtファイルが含まれていますが、まだ問題ではありません)。この関数でxyz <TAB>
と入力すると、ディレクトリと.txtファイルが一覧表示されますが、xyz d<TAB>
と入力すると、xyz dir
に展開されます(「dir」の後にスペースが付きます)。
/ etc/bash_completionの関数_cd()
を見ると、末尾にスラッシュ自体が追加されていることがわかります。 completeは、cdのオプション-o nospace
で呼び出されます。
xyzについても同じことができますが、見つかった一致がディレクトリ(ある場合はスラッシュを追加)かファイル(スラッシュを追加)かを個別に確認する必要がありますその場合は、スペースを追加します)。これは、見つかったすべての一致を処理するためにforループで実行する必要があります。
また、スペースを含むパスを適切に処理するには、内部ファイル区切り文字を改行のみに設定し、スペースをエスケープする必要があります。 IFS=$'\n'
をprintf %q
と組み合わせて使用すると、ほぼすべての文字で完了が機能します。1 後続スペースから逃げないように特別な注意を払う必要があります。
以下が機能するはずです。
_xyz ()
{
local IFS=$'\n'
local LASTCHAR=' '
COMPREPLY=($(compgen -o plusdirs -f -X '!*.txt' \
-- "${COMP_WORDS[COMP_CWORD]}"))
if [ ${#COMPREPLY[@]} = 1 ]; then
[ -d "$COMPREPLY" ] && LASTCHAR=/
COMPREPLY=$(printf %q%s "$COMPREPLY" "$LASTCHAR")
else
for ((i=0; i < ${#COMPREPLY[@]}; i++)); do
[ -d "${COMPREPLY[$i]}" ] && COMPREPLY[$i]=${COMPREPLY[$i]}/
done
fi
return 0
}
complete -o nospace -F _xyz xyz
1 改行文字は内部のファイル区切り文字であるため、ここでは明らかな例外です。
この単純な解決策は、次の点で機能すると思います。
.txt
で終わるディレクトリとファイルに一致しますキーは完了するために-o filenames
を渡していました。これは、RHEL 5.3のGNU bash 3.2.25およびosxのGNU bash 4.3.18でテストされました。
_xyz()
{
local cur=${COMP_WORDS[COMP_CWORD]}
local IFS=$'\n'
COMPREPLY=( $( compgen -o plusdirs -f -X '!*.txt' -- $cur ) )
}
complete -o filenames -F _xyz xyz