Как сделать python, программа командной строки автозаполнения произвольных вещей не интерпретатором

Я знаю, как настроить автозаполнение объектов python в интерпретаторе python (в unix).

  • Google показывает много хитов для объяснений о том, как это сделать.
  • к сожалению, есть так много ссылок, что трудно найти то, что мне нужно сделать, что немного отличается.

Мне нужно знать, как включить, tab / auto завершение произвольных элементов в программе командной строки, написанной на python.

мой конкретный случай использования-это программа python командной строки, которая должна отправлять электронные письма. Я хочу иметь возможность автозаполнения адресов электронной почты (у меня есть адреса на диске), когда пользователь вводит его часть (и, возможно, нажимает клавишу TAB).

Мне не нужно, чтобы он работал на windows или mac, просто linux.

6 ответов


использовать в 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 для получения дополнительной информации.


следуя документация 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()

вывод для tab - > tab - > отправить - > tab - > tab - > f - > tab

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

поскольку вы говорите "не интерпретатор" в своем вопросе, я думаю, вы не хотите ответов, связанных с 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.

посмотрите на пример на связанной странице, все это довольно просто.


Я удивлен, что никто не упомянул 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'))

вот полная рабочая версия кода, которая была очень предоставлена 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

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

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