Как сделать Python, программу командной строки автозаполнением произвольных вещей НЕ интерпретатором

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

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

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

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

Мне он не нужен для работы на windows или mac, только linux.

Этот блог должен делать трюки с конфигурацией файла .pythonrc.

LF00 10.06.2017 04:53
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
103
1
59 885
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Ответ принят как подходящий

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

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

заметьте, что если вы пишете свою командную строку с помощью модуля cmd, есть лучшие способы сделать это.

Florian Bösch 09.10.2008 19:17

Обратите внимание, что readline не работает в Windows. pyreadline, похоже, не подходит для замены, но он не работает с Linux.

Samuel 23.12.2020 18:33

Вы можете просто поставить условие в начале вашего файла python, который проверяет ОС и импортирует либо readline, либо pyreadline.

Paul Rooney 15.02.2021 05:27

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

Есть ли способ контролировать, как строка чтения выводит вывод в столбцы? Итак, скажем, я бы хотел, чтобы он располагался в столбцах с двумя пробелами между каждым элементом.

Fnord 24.11.2013 19:55

Когда я запускаю этот код, вкладки просто печатаются в командной строке. На самом деле это верно независимо от того, использую ли я cmd или прямую строку чтения.

Hack Saw 16.09.2016 07:01

Я вижу много ссылок на чтение в документации по cmd. Это работает в оболочке Windows?

Samuel 23.12.2020 18:35

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

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

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

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

На самом деле я приехал сюда из-за этого

user1767754 03.06.2017 14:30

Спасибо, это именно то, что я искал!

Teekeks 26.02.2020 13:49

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

Обратите внимание, что readline не работает в Windows, по крайней мере, в Python 2.7.18. pyreadline, похоже, в основном заменяет собой, за исключением того, что вам нужно заменить raw_input () на readline.readline (),

Samuel 23.12.2020 18:38

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

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

Для mac os замените readline.parse_and_bind('tab:complete') на readline.parse_and_bind ("bind ^I rl_complete")

Mani 29.08.2019 06:25

Это круто. Работал у меня. Спасибо, что поделился.

Ajay Ahuja 03.10.2019 00:11

@Mani Я застрял в этом надолго. Большое спасибо

AnaS Kayed 27.08.2020 10:31

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

Это старый пост, может, argcomplete тогда еще не было? Спасибо, что упомянули об этом, я думаю, это именно то, что нужно моему проекту!

FrustratedWithFormsDesigner 02.10.2015 17:14

Очень красиво в сочетании с argparse!

AstroFloyd 16.02.2020 23:11

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

Чтобы установить его, просто запустите: 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/seperman/fast-autocomplete для исходного кода.

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

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

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

Работает ли он с оболочками Windows и Linux?

Samuel 23.12.2020 18:39

@Samuel Я слышал от людей, которые используют его в Windows. Единственное, что не работает в Windows, - это интерактивный режим, который предназначен только для демонстрационных целей.

Seperman 31.12.2020 11:26

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

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

pgcli - Python Prompt Toolkit

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

Другие вопросы по теме