少しひねりを加えて、tcshおよび/またはbash(両方とも私のサイトで使用されています)でディレクトリ補完を設定しようとしています。特定のコマンド「foo」について、補完にカスタム関数を使用して一致させたいと思います/ で区切られた最初の用語を実際のサブツリー ノードに追加し、その後、後続の用語については通常のディレクトリ補完に従います。これは、cdpath と補完の組み合わせのようなものです。または、補完スクリプトによって開始点が制御されるディレクトリ補完の形式だと思います。次のように動作します。
$ foo xxx<TAB>
(custom completion function produces choices it finds at arbitrary levels in the dir tree)
xxxYYY xxxZZZ xxxBLAH ...
foo xxxYYY/<TAB>
(normal directory completion proceeds from this point on, to produce something like:)
foo scene/shot/element/workspace/user/...
私たちは大規模な製品開発ツリー (これは CGI 生産施設です) を持っており、シェルに精通したユーザーが常にナビゲートしたり飛び回ったりしているため、これを行いたいと考えています。不満は、ツリーの上位レベルが扱いにくく冗長であることです。可能な「頭」の選択肢を見つけ、そこからディレクトリ補完を行うために、最初の用語をすばやく検索する必要があります。プログラマブル補完がこれを行う方法を提供できるように思えますが、それはかなりとらえどころのないものであることが判明しています.
これを行うために、カスタムの bash と tcsh の補完を何度か試みましたが、最も近いものは、ユーザーがディレクトリ レベルをスペースを含む個別の単語として扱わなければならない「単語補完」の形式です (例: foo scene/ shot /要素/ワークスペース/ ...)。現在のスクリプトをハッキングし続けることもできますが、何か理解できないことがあるのだろうかと思っていました.これはプログラム補完の最初の試みであり、ドキュメントと例はシェルブックとインターネットでかなり薄いです. . 私を正しい軌道に乗せることができる補完の達人がそこにいるなら、私はそれを感謝します.
FWIW:これが私がこれまでに得たものです(最初にtcshで、次にbashで)。静的ルート「/root/sub1/sub2/sub3」は、さまざまなレベルでさまざまな一致を見つける検索機能の単なるプレースホルダーであることに注意してください。それを機能させることができれば、後で検索機能をサブスクライブできます。繰り返しますが、どちらの例も単語補完を行います。これには、一致する各用語の後にユーザーがスペースを入力する必要があります (実際のパスを構築するために、関数内のスペースも削除する必要があります!)
TCSH の例 (関数は実際には bash スクリプトであることに注意してください):
complete complete_p2 'C@*@`./complete.p2.list.bash $:1 $:2 $:3 $:4 $:5 $:6 $:7 $:8 $:9`@@'
#!/bin/bash --norc
# complete.p2.list.bash - Completion prototype "p2" for shotc command
# Remove spaces from input arguments
ppath=`echo $@ | sed -e 's/ //g'`
# Print basenames (with trailing slashes) of matching dirs for completion
ls -1 -d /root/sub1/sub2/sub3/$ppath* 2>/dev/null | sed -e 's#^.*/##' | awk '{print $1 "/"}'
BASH の例:
_foo()
{
local cur prev opts flist
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
# Get all command words so far (omit command [0] element itself), remove spaces
terms=`echo ${COMP_WORDS[@]:1} | sed -e 's/ //g'`
# Get basenames (with trailing slashes) of matching dirs for completion
flist=`ls -1 -d /root/sub1/sub2/sub3/${terms}* 2>/dev/null | sed -e 's#^.*/##' | awk '{print $1 "/"}' | xargs echo`
COMPREPLY=( $(compgen -W "${flist}" ${cur}) )
return 0
}
complete -F _foo foo