引用の問題

引用の問題

私は独自の完全なコマンドを書こうとしています。完了するには、キー入力コマンドの一部を使用してパス検索を実行する必要があります。

私は次のような行動をとろうとしています。

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

その後、コマンドは変数を引数として使用してスクリプトを呼び出しますcompletefindtest.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 テスト

関連情報