pythonコマンドラインのオートコンプリートを行う方法。ただし、文字列の先頭だけではありません。
-
03-07-2019 - |
質問
Python、readlineバインディングにより、優れたコマンドライン自動補完が可能になります(こちら)。
しかし、補完は文字列の先頭でのみ機能するようです。文字列の中央または末尾を一致させたい場合、readlineは機能しません。
使用可能な文字列のリストにある文字列のいずれかと入力した文字列を照合することにより、コマンドラインpythonプログラムで文字列を自動補完します。
- オートコンプリートのタイプの良い例は、Toフィールドに入力したときにGMailで発生するタイプです。連絡先の姓のいずれかを入力すると、名前を入力した場合と同様に表示されます。
- 一致する文字列から選択するために上下矢印またはその他の方法を使用する必要がある場合があり(readlineの場合は不要)、私の場合はこれで問題ありません。
- 私の特定のユースケースは、メールを送信するコマンドラインプログラムです。
- 特定のコード例は非常に役立ちます。
cursesのようなターミナルエミュレータを使用しても問題ありません。 MacまたはWindowsではなく、Linuxでのみ実行する必要があります。
例を次に示します。 リストに次の3つの文字列があるとします
['Paul Eden <paul@domain.com>',
'Eden Jones <ejones@domain.com>',
'Somebody Else <somebody@domain.com>']
「Eden」と入力した後、リストの最初の2つの項目を自動補完し、そのうちの1つを選択できるようにするコードが必要です(すべてキーボードを使用してコマンドラインから)。
解決
問題を理解したかどうかわかりません。 readline.clear_historyとreadline.add_historyを使用して、必要な補完可能な文字列を設定し、control-rを使用して、履歴内のバックワードを検索できます(シェルプロンプトのように)。例:
#!/usr/bin/env python
import readline
readline.clear_history()
readline.add_history('foo')
readline.add_history('bar')
while 1:
print raw_input('> ')
代わりに、独自の完全なバージョンを記述し、適切なキーをそれにバインドすることもできます。このバージョンでは、マッチリストが膨大な場合にキャッシュを使用します。
#!/usr/bin/env python
import readline
values = ['Paul Eden <paul@domain.com>',
'Eden Jones <ejones@domain.com>',
'Somebody Else <somebody@domain.com>']
completions = {}
def completer(text, state):
try:
matches = completions[text]
except KeyError:
matches = [value for value in values
if text.upper() in value.upper()]
completions[text] = matches
try:
return matches[state]
except IndexError:
return None
readline.set_completer(completer)
readline.parse_and_bind('tab: menu-complete')
while 1:
a = raw_input('> ')
print 'said:', a
所属していません StackOverflow