Как выполнить автодополнение командной строки Python, но НЕ только в начале строки
-
03-07-2019 - |
Вопрос
Python, благодаря привязкам строки чтения, обеспечивает отличное автодополнение командной строки (как описано в здесь).
Но завершение, похоже, работает только в начале строк.Если вы хотите сопоставить середину или конец строки, строка чтения не работает.
Я хотел бы автозаполнять строки в программе Python с командной строкой, сопоставляя то, что я набираю, с любой строкой в списке доступных строк.
- Хорошим примером типа автозаполнения, который мне хотелось бы иметь, является тип, который происходит в GMail, когда вы вводите текст в поле «Кому».Если вы наберете фамилию одного из ваших контактов, она появится так же хорошо, как если бы вы набрали ее имя.
- Может потребоваться использование стрелок вверх и вниз или какой-либо другой метод выбора из совпадающих строк (и не требуется в случае readline), и в моем случае это нормально.
- Мой конкретный вариант использования — это программа командной строки, которая отправляет электронные письма.
- Конкретные примеры кода были бы очень полезны.
Было бы неплохо использовать эмуляторы терминала, такие как проклятия.Он должен работать только на Linux, а не на Mac или Windows.
Вот пример:Скажем, у меня есть следующие три строки в списке
['Paul Eden <paul@domain.com>',
'Eden Jones <ejones@domain.com>',
'Somebody Else <somebody@domain.com>']
Мне нужен код, который будет автоматически заполнять первые два элемента в списке после того, как я наберу «Эден», а затем позволит мне выбрать один из них (все через командную строку с помощью клавиатуры).
Решение
Я не уверен, что понимаю проблему.Вы можете использовать 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