52

argparsePythonスクリプトで シェルタブ補完を連携させる方法は?

#!/usr/bin/env python
import argparse

def main(**args):
    pass

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('positional', choices=['spam', 'eggs'])
    parser.add_argument('--optional', choices=['foo1', 'foo2', 'bar'])
    args = parser.parse_args()
    main(**vars(args))

.pyファイルに実行可能フラグを設定すると、期待される結果は次のようになります。

$ ./example.py sp<tab>             
   ->  completes to "./example.py spam"
$ ./example.py --op<tab> 
   ->  completes to "./example.py --optional"
$ ./example.py --optional b<tab>
   ->  completes to "./example.py --optional bar"
$ ./example.py --optional f<tab>   
   ->  completes to "./example.py --optional foo"
       and, additionally, prints  "foo1  foo2"  choices on stdout on a new line
4

2 に答える 2

76

AndreyKislyukによるargcompleteをご覧ください。

次のコマンドでインストールします。

pip install argcomplete

モジュールをインポートし、呼び出す前にソースに1行追加しますparser.parse_args()

#!/usr/bin/env python

import argparse as ap
import argcomplete

def main(**args):
  pass

if __name__ == '__main__':
  parser = ap.ArgumentParser()
  parser.add_argument('positional', choices=['spam', 'eggs'])
  parser.add_argument('--optional', choices=['foo1', 'foo2', 'bar'])
  argcomplete.autocomplete(parser)
  args = parser.parse_args()
  main(**vars(args))

そして、bashがこのスクリプトを認識していることを確認するには、次を使用します。

eval "$(register-python-argcomplete your_script)"

その行を自分のドキュメントに入れる~/.bashrcか、argcompleteのドキュメントに従って、「グローバル」補完をアクティブにする必要があります。

その後、完了は要求どおりに機能します。

これが機能する方法は、eval行が_python_argcomleteを使用して登録される関数を作成することcompleteです。register-python-argcomplete your_script(何がbashに評価されるかを確認するために実行します)。オートコンプリート関数は、bash補完メカニズムによって設定された環境変数を探して、動作する必要があるかどうかを確認します。動作する場合は、プログラムを終了します。それが機能しない場合、これはプログラムへの通常の呼び出しであり、関数は何もせず、プログラムの通常のフローが続行されます。

于 2013-03-08T07:41:05.593 に答える
4

オートコンプリートを機能させるには、可能なオプションを生成するためのbash関数が必要です。次に、実行する必要があります。complete -F <function_name> <program_name>

これを行う最良の方法は、重複を避けるために、プログラムに独自の解析アルゴリズムに基づいて完了関数を生成させることです。ただし、argparseを一目見ただけでは、内部構造にアクセスする方法が見つかりませんでしたが、探すことをお勧めします。

上記のプログラムに対して実行するbash関数は次のとおりです。

function _example_auto() {
    local cur=${COMP_WORDS[COMP_CWORD]}
    local prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
    --optional ) 
        COMPREPLY=( $(compgen -W "foo1 foo2 bar" -- $cur) )
        return 0
        ;;
    *)
        COMPREPLY=( $(compgen -W "--optional spam eggs" -- $cur) )
        return 0
        ;;
    esac
}
于 2013-03-06T11:06:38.957 に答える