Как сделать python, программа командной строки autocomplete произвольные вещи НЕ интерпретатор
Я знаю, как настроить автозаполнение объектов python в интерпретаторе python (в unix).
- Google показывает много просмотров для объяснений, как это сделать.
- К сожалению, есть так много ссылок на то, что трудно найти то, что мне нужно сделать, что немного отличается.
Мне нужно знать, как включить, вкладку/автозаполнение произвольных элементов в программе командной строки, написанной на python.
Мой конкретный вариант использования - это программа python с командной строкой, которая должна отправлять электронные письма. Я хочу иметь возможность автозаполнения адресов электронной почты (у меня есть адреса на диске), когда пользователь набирает часть его (и необязательно нажимает клавишу TAB).
Мне не нужно это работать на windows или mac, просто linux.
Ответы
Ответ 1
Использовать привязки 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)
Официальный модуль docs не намного подробнее, см. readline docs для получения дополнительной информации.
Ответ 2
Следуйте документации cmd, и вы будете в порядке
import cmd
addresses = [
'[email protected]',
'[email protected]',
'[email protected]',
]
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
[email protected] [email protected] [email protected]
(Cmd) send [email protected]
(Cmd)
Ответ 3
Поскольку вы говорите "НЕ интерпретатор" в своем вопросе, я думаю, вам не нужны ответы, связанные с readline python и т.п. (изменить): оглядываясь назад, это, очевидно, не так. Хог гул. Я думаю, что эта информация интересна в любом случае, поэтому я оставлю ее здесь.)
Я думаю, что вы можете после this.
Это о добавлении завершения на уровне оболочки к произвольным командам, расширение 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
.
Посмотрите на пример на связанной странице, все это довольно просто.
Ответ 4
Я удивлен, что никто не упомянул 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'))
Ответ 5
Вот полнофункциональная версия кода, которая была очень снабжена ephemient здесь (спасибо).
import readline
addrs = ['[email protected]', '[email protected]', '[email protected]']
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
Ответ 6
# ~/.pythonrc
import rlcompleter, readline
readline.parse_and_bind('tab:complete')
# ~/.bashrc
export PYTHONSTARTUP=~/.pythonrc