私は独自の完全なコマンドを書こうとしています。完了するには、キー入力コマンドの一部を使用してパス検索を実行する必要があります。
私は次のような行動をとろうとしています。
my_ws/testsの下にフォルダリストを作成すると、完成したリストとしてmy_commad -ws my_ws -t[TAB]
表示されますが、どのように分割するのかわかりません。
以下を試しましたが、見積もりの問題で失敗したようです。
complete my_command 'n@-t@`echo $COMMAND_LINE | perl -ne '/-ws (\w+)/; print $1'`@'
答え1
引用の問題
前述のように、コマンドの問題は、単一引用符の中に単一引用符が含まれているため、エスケープする必要があることです。これを行う方法はいくつかあります。
backslash_quote
シェル変数が設定されている場合は、バックスラッシュを使用して内部単一引用符をエスケープできます。
complete my_command 'n@-t@`echo $COMMAND_LINE | perl -ne \'/-ws (\w+)/; print $1\'`@'
- を実行して1であることを確認できます
echo $?backslash_quote
。 - 設定されていない場合は、以下を実行して設定できます。
set backslash_quote
または、backslash_quote
設定されておらず、それを変更したくない場合は、内部単一引用符をに置き換えることができます'"'"'
。
complete my_command 'n@-t@`echo $COMMAND_LINE | perl -ne '"'"'/-ws (\w+)/; print $1'"'"'`@'
どちらのソリューションも見積もりの問題を解決し、その結果、次のパラメータが-t
あなたのパラメータによって完成します-ws
。
$my_command -ws my_ws -t TABmy_ws
とにかくこれはあなたが達成したいものではありません。あなたはそれを構成したいです「my_ws/testsの下のフォルダのリスト」。
実際の要件に対応
$COMMAND_LINE
より複雑な完了のために変数を解析し、他のタスクを実行するラッパースクリプトを作成することを検討できます。
-t
たとえば、$WS/tests の下のサブディレクトリに次のパラメータを完了させるには、ホームディレクトリに次のようなスクリプトを作成できます。
$ cat $HOME/findtest.sh
#!/bin/sh
ws=$(perl -ne '/-ws (\S+)/; print $1' <<< $@)
find $ws/tests -mindepth 1 -maxdepth 1 -type d 2>/dev/null
その後、コマンドは変数を引数として使用してスクリプトを呼び出しますcomplete
。findtest.sh
$COMMAND_LINE
complete my_command 'n@-t@`$HOME/findtest.sh $COMMAND_LINE`@'
結果:
my_ws/tests
以下に次のフォルダがあるとします。
ls -1 my_ws/tests
test1
test2
test3
その後、パラメータを完了しようとすると、次の-t
結果が得られます。
$my_command -ws my_ws -tTAB my_ws/テスト/テスト1 my_ws/テスト/テスト2 my_ws/テスト/テスト3 $my_command -ws my_ws -t my_ws/test/test
フルパスを表示せず、先行パスなしで以下のディレクトリのみをmy_ws/tests
表示したい場合は、find
スクリプトのコマンドを次のように変更できます。
find $ws/tests -mindepth 1 -maxdepth 1 -type d -printf "%f\n" 2>/dev/null
結果:
$my_command -ws my_ws -tTAB テスト1テスト2テスト3 $my_command -ws my_ws -t テスト
その他の提案
他の機能を追加して完成させることができます。たとえば、
complete my_command 'n@-t@`$HOME/findtest.sh $COMMAND_LINE`@' 'N/-ws/(-t)/' 'n/-ws/d/' 'p/*/(-ws)/'
またはもっと読みやすくするには:
complete my_command \
'n@-t@`$HOME/findtest.sh $COMMAND_LINE`@' \
'N/-ws/(-t)/' \
'n/-ws/d/' \
'p/*/(-ws)/'
説明する:
'p/*/(-ws)/'
- あなた以来どこでもmy_command
完了しようとします-ws
。'n/-ws/d/'
- その後は-ws
ディレクトリだけを完成しようとします。'N/-ws/(-t)/'
-ws
- 予想される次の引数は、行の現在位置の前の2つの単語です-t
。
コマンドに単語が表示される順序tcsh
に従って完了が試みられるので、ここで順序が重要です。たとえば、先頭complete
に移動すると、常に行の残りの部分を完了しようとせずに最後まで完了しようとします。'p/*/(-ws)/'
-ws
結果:
$my_command TAB #が完了しました-ws $my_command-ws $my_command -ws m TAB # 次から始まるディレクトリのリストを完成させます。米 $my_command -ws my_ws/ $ my_command -ws my_ws/ TAB # 完了です。-ティー $my_command -ws my_ws/ -t $ my_command -ws my_ws/ -t TAB # 次のフォルダのリストを完成させます。my_ws/テスト テスト1テスト2テスト3 $my_command -ws my_ws/ -t テスト