Python、コマンドラインプログラムをインタープリターではなく任意のものにオートコンプリートさせる方法


92

Pythonインタープリター(UNIX上)でPythonオブジェクトのオートコンプリートを設定する方法を知っています。

  • Googleはこれを行う方法の説明について多くのヒットを示しています。
  • 残念ながら、参照先が非常に多いため、やらなければならないことを見つけるのが難しいため、少し異なります。

Pythonで書かれたコマンドラインプログラムで任意の項目のタブ/オートコンプリートを有効にする方法を知る必要があります。

私の具体的な使用例は、メールを送信する必要があるコマンドラインのpythonプログラムです。ユーザーがメールアドレスの一部を入力したとき(およびオプションでTabキーを押したとき)に、電子メールアドレス(ディスクにアドレスを持っている)をオートコンプリートできるようにしたい。

私はそれがウィンドウズやマックで動くのに必要ではなく、リナックスだけです。


このブログは.pythonrcファイルを設定してトリックを行う必要があります。
Kris Roofe 2017年

回答:


63

Pythonのreadlineバインディングを使用します。例えば、

import readline

def completer(text, state):
    options = [i for i in commands if i.startswith(text)]
    if state < len(options):
        return options[state]
    else:
        return None

readline.parse_and_bind("tab: complete")
readline.set_completer(completer)

公式モジュールのドキュメントはそれほど詳細ではありません。詳細については、readlineのドキュメントを参照してください。


1
cmdモジュールを使用してコマンドラインを作成する場合、より適切な方法があることに注意してください。
FlorianBösch

60

cmdのドキュメントに従ってください。問題はありません。

import cmd

addresses = [
    'here@blubb.com',
    'foo@bar.com',
    'whatever@wherever.org',
]

class MyCmd(cmd.Cmd):
    def do_send(self, line):
        pass

    def complete_send(self, text, line, start_index, end_index):
        if text:
            return [
                address for address in addresses
                if address.startswith(text)
            ]
        else:
            return addresses


if __name__ == '__main__':
    my_cmd = MyCmd()
    my_cmd.cmdloop()

タブの出力->タブ->送信->タブ->タブ-> f->タブ

(Cmd)
help  send
(Cmd) send
foo@bar.com            here@blubb.com         whatever@wherever.org
(Cmd) send foo@bar.com
(Cmd)

readlineが出力を列化する方法を制御する方法はありますか?それで、各項目の間に2つのスペースを入れて列化したいとします。
2013年

このコードを実行すると、タブがコマンドラインに出力されます。実際、これは、cmdを使用するか、readlineを使用するかに関係なく当てはまります。
ハックソー

38

質問で「インタプリタではない」と言っているので、python readlineなどを含む回答は望まないでしょう。(編集:後から考えて、それは明らかにそうではありません。ほんとう。この情報はとにかく面白いと思うので、ここに残しておきます。

あなたはこの後かもしれないと思います。

これは、bash自体のタブ補完を拡張して、任意のコマンドにシェルレベルの補完を追加することです。

簡単に言うと、補完候補を生成するシェル関数を含むファイルを作成し、それをに保存/etc/bash_completion.d/して、コマンドで登録しcompleteます。リンクされたページのスニペットは次のとおりです。

_foo() 
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts="--help --verbose --version"

    if [[ ${cur} == -* ]] ; then
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
    fi
}
complete -F _foo foo

この場合は、タイピングがfoo --[TAB]あなたに変数の値を与えるopts、すなわち--help--verbose--version。あなたの目的のために、あなたは本質的にに入れられる値をカスタマイズしたいと思うでしょうopts

リンク先のページの例をご覧ください。すべて簡単です。


10
実際私はそのためにここに来ました
user1767754

ありがとう、これはまさに私が探していたものです!
Teekeks

27

argcompleteについて誰も言及していないことに驚いています。これはドキュメントの例です:

from argcomplete.completers import ChoicesCompleter

parser.add_argument("--protocol", choices=('http', 'https', 'ssh', 'rsync', 'wss'))
parser.add_argument("--proto").completer=ChoicesCompleter(('http', 'https', 'ssh', 'rsync', 'wss'))

それは古い投稿です、おそらくargcompleteは当時存在していませんでしたか?それについて言及してくれてありがとう、私はそれがまさに私のプロジェクトに必要なものだと思います!
FrustratedWithFormsDesigner 2015年

argparseとの組み合わせもとても良いです!
AstroFloyd

13

ここにephemient から非常に提供された完全に機能するバージョンのコードがあります(ありがとうございます)。

import readline

addrs = ['angela@domain.com', 'michael@domain.com', 'david@test.com']

def completer(text, state):
    options = [x for x in addrs if x.startswith(text)]
    try:
        return options[state]
    except IndexError:
        return None

readline.set_completer(completer)
readline.parse_and_bind("tab: complete")

while 1:
    a = raw_input("> ")
    print "You entered", a

10
# ~/.pythonrc
import rlcompleter, readline
readline.parse_and_bind('tab:complete')

# ~/.bashrc
export PYTHONSTARTUP=~/.pythonrc

1
マックOSの場合は、交換するreadline.parse_and_bind('tab:complete')readline.parse_and_bind ("bind ^I rl_complete")
マニ

これはすごいです。私のために働いた。共有いただきありがとうございます。
Ajay Ahuja

@マニ私はこれに長い間立ち往生していました。どうもありがとうございました
AnaS Kayed

5

あなたはPython Prompt Toolkitを使ってみることができますインタラクティブなコマンドラインアプリケーションを構築するためのライブラリで。

ライブラリにより、インタラクティブなオートコンプリート機能を簡単に追加でき、ユーザーは Tabキーをて、利用可能な選択肢を視覚的に循環できます。ライブラリはクロスプラットフォームです(Linux、OS X、FreeBSD、OpenBSD、Windows)。例:

pgcli-Pythonプロンプトツールキット

(画像ソース:pcgli


1

投稿された回答は問題なく機能しますが、私は職場で書いたオートコンプリートライブラリをオープンソース化しました。私たちはこれを本番で使用しており、高速で安定していて使いやすいです。デモモードも備えているので、単語を入力したときに何が得られるかをすばやくテストできます。

それをインストールするには、単に実行します: pip install fast-autocomplete

次に例を示します。

>>> from fast_autocomplete import AutoComplete
>>> words = {'book': {}, 'burrito': {}, 'pizza': {}, 'pasta':{}}
>>> autocomplete = AutoComplete(words=words)
>>> autocomplete.search(word='b', max_cost=3, size=3)
[['book'], ['burrito']]
>>> autocomplete.search(word='bu', max_cost=3, size=3)
[['burrito']]
>>> autocomplete.search(word='barrito', max_cost=3, size=3)  # mis-spelling
[['burrito']]

チェックアウト:https : //github.com/wearefair/fast-autocompleteソースコードの。

そして、これがどのように機能するかの説明です: http //zepworks.com/posts/you-autocomplete-me/

スペルミスを処理し、単語の重みでオプションで並べ替えます。(burritoがより重要であるとしましょうbook。そうするとburrito、より高い「カウント」を与えると、それが最初に表示されます。bookられ、結果のにれます。

単語は辞書であり、各単語はコンテキストを持つことができます。たとえば、「カウント」、単語の表示方法、単語の周りの他のコンテキストなど。この例では、単語にはコンテキストがありませんでした。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.