Как сделать Python, программа командной строки автозаполнения произвольных вещей, НЕ интерпретатор - PullRequest
83 голосов
/ 09 октября 2008

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

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

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

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

Мне не нужно, чтобы он работал на Windows или Mac, просто Linux.

Ответы [ 8 ]

56 голосов
/ 09 октября 2008

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

Вывод на вкладку -> вкладка -> отправить -> вкладка -> вкладка -> f -> вкладка

(Cmd)
help  send
(Cmd) send
foo@bar.com            here@blubb.com         whatever@wherever.org
(Cmd) send foo@bar.com
(Cmd)
55 голосов
/ 09 октября 2008

Использовать привязки 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)

Официальные документы по модулю не намного более подробны, для получения дополнительной информации см. Документацию readline .

34 голосов
/ 13 октября 2008

Поскольку вы говорите «НЕ переводчик» в своем вопросе, я думаю, вам не нужны ответы, включающие чтение строки Python и тому подобное. ( edit : задним числом, это явно не тот случай. Хо-хам. Я думаю, эта информация в любом случае интересна, поэтому я оставлю ее здесь.

Я думаю, вы можете быть после этого .

Речь идет о добавлении завершения на уровне оболочки к произвольным командам, расширении собственного завершения табуляции в 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.

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

21 голосов
/ 30 мая 2014

Я удивлен, что никто не упомянул 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'))
12 голосов
/ 16 октября 2008

Вот полнофункциональная версия кода, которая была предоставлена ​​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
8 голосов
/ 24 октября 2013
# ~/.pythonrc
import rlcompleter, readline
readline.parse_and_bind('tab:complete')

# ~/.bashrc
export PYTHONSTARTUP=~/.pythonrc
1 голос
/ 29 мая 2019

Вы можете попробовать использовать Python Prompt Toolkit , библиотеку для создания интерактивных приложений командной строки в Python.

Библиотека позволяет легко добавлять интерактивные функции автозаполнения, позволяя пользователю использовать клавишу Tab , чтобы визуально переключаться между доступными вариантами выбора. Библиотека является кроссплатформенной (Linux, OS X, FreeBSD, OpenBSD, Windows). Пример:

pgcli - Python Prompt Toolkit

(Источник изображения: pcgli )

0 голосов
/ 30 марта 2019

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

Чтобы установить его, просто запустите: pip install fast-autocomplete

Вот пример:

>>> from fast_autocomplete import AutoComplete
>>> words = {'book': {}, 'burrito': {}, 'pizza': {}, 'pasta':{}}
>>> autocomplete = AutoComplete(words=words)
>>> autocomplete.search(word='b', max_cost=3, size=3)
[['book'], ['burrito']]
>>> autocomplete.search(word='bu', max_cost=3, size=3)
[['burrito']]
>>> autocomplete.search(word='barrito', max_cost=3, size=3)  # mis-spelling
[['burrito']]

Оформить заказ: https://github.com/wearefair/fast-autocomplete для исходного кода.

А вот объяснение того, как это работает: http://zepworks.com/posts/you-autocomplete-me/

Имеется дело с неправильным написанием и, возможно, сортировкой по весу слова. (Допустим, burrito важнее, чем book, тогда вы дадите burrito большее «число», и оно будет отображаться раньше, чем book в результатах.

Слова - это словарь, и каждое слово может иметь контекст. Например, «считать», как отобразить слово, какой-то другой контекст вокруг слова и т. Д. В этом примере слова не имеют никакого контекста.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...