Как сделать 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