bash がディレクトリ名を補完する方法を設定することは可能ですか?

bash がディレクトリ名を補完する方法を設定することは可能ですか?

特定のディレクトリ名に対して特別な方法を使用して補完を実行するように bash に指示したいと思います。たとえば、パスが「$$」で始まる場合は bash が私のプログラムを呼び出して補完を実行し、それ以外の場合は通常の補完を実行します。

これは本当に可能ですか? どのように実装しますか?

賞金: その質問にお答えいただければ幸いです。目標はオートジャンプユーザーが特定のプレフィックスを付けてコマンドを開始したときに、すべてのコマンドのパスを補完します。たとえば、遠いディレクトリからファイルをコピーする場合は、次のように入力できます。

cp $$patern + <Tab>

自動ジャンプが完了すると

cp /home/user/CompliCatedDireCTOry/long/path/bla/bla

そして、ファイルを配置する場所を追加するだけです。もちろん、ott のコメントを使用して、いくつかの特定のコマンドに追加することもできますが、もっと良いアイデアをお持ちの方がいらっしゃいましたら、大変ありがたく思います。

答え1

これは、TAB(^i) のデフォルトのバインディングをオーバーライドすることで実行できます。まず、TAB バインディングをオーバーライドし、次にコマンドを呼び出す関数を作成し、最後にそのコマンドからの出力を取得して、現在のコマンド ラインを含む変数を更新する必要があります。

この関数は、現在のコマンド ラインの最後の 2 文字を 'huugs' に変更します。

function my_awesome_tab_completion_function () {
  set -- $READLINE_LINE
  command="$1"
  shift
  argument="$*"
  argument_length=$(echo -n $argument | wc -c)
  if echo $argument | grep '^$$' >/dev/null 2>&1; then
    new_argument=$(echo $argument | sed 's/..$/huugs/') # put your autojump here
  else
    new_argument=$(compgen -d $argument)
  fi
  new_argument_length=$(echo -n $new_argument | wc -c)
  READLINE_POINT=$(( $new_argument_length - $argument_length + $READLINE_POINT ))
  READLINE_LINE="$command $new_argument"
}

たとえば、new_argument 行を次のように変更すると良いでしょう。

  new_argument=$(autojump $argument)

ここで、^i バインディングをオーバーライドします。

$ bind -x '"\C-i"':'my_awesome_tab_completion_function'

動作するかテストします。

$ cd /ro<TAB>
changes my command to:
$ cd /root

通常の補完は引き続き機能するので、cd $$などを実行して$$部分をテストできます。

問題が発生した場合は、詳細モードをオンにしてください。

$ set -x

関数が実行しているすべての内容を出力します。

私はこれを、bash 4.2.8(1)-release (デフォルト) を使用して Ubuntu 11 でテストしました。

答え2

bash 補完ルーチンはシェル スクリプトとしてプログラムできます。

以下は、特定のコマンドに対してのみ、かつパラメータが正確に "$$" である場合にのみ、$$[Tab]任意のパラメータを に置き換えるシェル スクリプトの例です。my replacement stringmycommand

_mycomplete()
{
        if [ ${COMP_WORDS[COMP_CWORD]} == \$\$ ]
        then
                COMPREPLY='my replacement string'
        fi
}
complete -o default -o bashdefault -F _mycomplete mycommand

source <file-name>スクリプトを実行するには、(またはドット コマンドを使用して) bash にスクリプトをソースとして渡し、次の操作を実行する必要があります。

mycommand $$[Tab] -> mycommand my replacement string
mycommand $$$[Tab] -> mycommand $$$ (beep)
mycommand whatever[Tab] -> (will complete "whatever" in the normal bash manner)

一部またはすべてのユーザーに対して常に機能させるには、これをbash プロファイルルーチン

このコマンドの問題点completeは、パラメータとして指定された 1 つ以上のコマンド名に対してのみ機能することです。ユーザーが使用する可能性のあるすべてのコマンドのリストを単に指定するか、緊急の場合は展開することができます/bin/* /usr/bin/* ~/bin/*

CentOS 5.5 でテスト済み。

このシンプルなスクリプトは、私が他の回答でリストしたソースに基づいています。これは、モデレーターの studiohack によって削除されたものです。興味がある場合は、彼に削除を取り消すように依頼してください。

関連情報