Как автодополнение кода в python? - PullRequest
32 голосов
/ 19 октября 2011

Я хотел бы написать код автозаполнения в терминале Linux. Код должен работать следующим образом.

Имеется список строк (например, "привет", "привет", "как дела", "до свидания", "здорово", ...).

В терминале пользователь начинает вводить текст и, когда есть некоторая возможность совпадения, он получает подсказку для возможных строк, из которых он может выбрать (аналогично vim editor или инкрементальный поиск google ).

например. он начинает печатать "h" и получает подсказку

ч "ELLO"

_ "i"

_ "ау ты"

И еще лучше, если бы он заканчивал слова не только с самого начала, но и из произвольной части строки.

Спасибо за совет.

Ответы [ 5 ]

45 голосов
/ 19 октября 2011

(я знаю, что это не совсем то, что вы просите, но) Если вас устраивает автозаполнение / предложения, появляющиеся на TAB (как используется во многих оболочках), затем вы можете быстро приступить к работе, используя модуль readline .

Вот краткий пример, основанный на написании Дуга Хеллмана PyMOTW для readline .

import readline

class MyCompleter(object):  # Custom completer

    def __init__(self, options):
        self.options = sorted(options)

    def complete(self, text, state):
        if state == 0:  # on first trigger, build possible matches
            if text:  # cache matches (entries that start with entered text)
                self.matches = [s for s in self.options 
                                    if s and s.startswith(text)]
            else:  # no text entered, all matches possible
                self.matches = self.options[:]

        # return match indexed by state
        try: 
            return self.matches[state]
        except IndexError:
            return None

completer = MyCompleter(["hello", "hi", "how are you", "goodbye", "great"])
readline.set_completer(completer.complete)
readline.parse_and_bind('tab: complete')

input = raw_input("Input: ")
print "You entered", input

Это приводит к следующему поведению (<TAB>, представляющему нажатие клавиши табуляции):

Input: <TAB><TAB>
goodbye      great        hello        hi           how are you

Input: h<TAB><TAB>
hello        hi           how are you

Input: ho<TAB>ow are you

В последней строке ( H O TAB введено), есть только одно возможное совпадение, и целое предложение "как дела" автоматически завершено.

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


"И еще лучше, если бы он заканчивал слова не только с самого начала ... завершение из произвольной части строки."

Это можетбыть достигнуто простым изменением критериев соответствия в завершающей функции, т.е.от:

self.matches = [s for s in self.options 
                   if s and s.startswith(text)]

до чего-то вроде:

self.matches = [s for s in self.options 
                   if text in s]

Это даст вам следующее поведение:

Input: <TAB><TAB>
goodbye      great        hello        hi           how are you

Input: o<TAB><TAB>
goodbye      hello        how are you

Обновления: использование буфера истории(как уже упоминалось в комментариях)

Простой способ создать псевдо-меню для прокрутки / поиска - загрузить ключевые слова в буфер истории.После этого вы сможете прокручивать записи с помощью клавиш со стрелками вверх / вниз, а также использовать Ctrl + R для выполнения обратного поиска.

Дляпопробуйте, внесите следующие изменения:

keywords = ["hello", "hi", "how are you", "goodbye", "great"]
completer = MyCompleter(keywords)
readline.set_completer(completer.complete)
readline.parse_and_bind('tab: complete')
for kw in keywords:
    readline.add_history(kw)

input = raw_input("Input: ")
print "You entered", input

Когда вы запустите скрипт, попробуйте набрать Ctrl + r , а затем a ,Это вернет первое совпадение, которое содержит «а».Введите Ctrl + r еще раз для следующего матча.Чтобы выбрать запись, нажмите ENTER .

Также попробуйте использовать клавиши ВВЕРХ / ВНИЗ для прокрутки ключевых слов.

6 голосов
/ 19 октября 2011

Полагаю, вам понадобится нажать клавишу пользователем.

Вы можете добиться этого (без нажатия клавиши ввода) с помощью метода, подобного следующему:

import termios, os, sys

def getkey():
    fd = sys.stdin.fileno()
    old = termios.tcgetattr(fd)
    new = termios.tcgetattr(fd)
    new[3] = new[3] & ~termios.ICANON & ~termios.ECHO
    new[6][termios.VMIN] = 1
    new[6][termios.VTIME] = 0
    termios.tcsetattr(fd, termios.TCSANOW, new)
    c = None
    try:
        c = os.read(fd, 1)
    finally:
        termios.tcsetattr(fd, termios.TCSAFLUSH, old)
    return c

Тогда, еслиэта клавиша является клавишей табуляции (например, это то, что вам нужно реализовать), а затем отображает все возможности для пользователя.Если это какой-то другой ключ, напечатайте его на stdout.

О, конечно, вам понадобится зациклить getkey (), пока пользователь нажимает ввод.Вы также можете получить метод, такой как raw_input, который будет получать знак целого слова за знаком или отображать все возможности при нажатии на вкладку.

По крайней мере, это элемент, с которого вы можете начать.Если вы решите какие-либо другие проблемы, чем пишите о них.

РЕДАКТИРОВАТЬ 1:

Метод get_word может выглядеть следующим образом:

def get_word():
    s = ""
    while True:
        a = getkey()
        if a == "\n":
            break
        elif a == "\t":
            print "all possibilities"
        else:
            s += a

    return s

word = get_word()
print word

Проблема, с которой я сталкиваюсьПрямо сейчас есть способ отобразить знак, вы только что вошли без каких-либо вводов и пробелов, что делают print a и print a,.

4 голосов
/ 23 сентября 2016

Чтобы включить автозаполнение в оболочке Python, введите:

import rlcompleter, readline
readline.parse_and_bind('tab:complete')

(спасибо http://blog.e -shell.org / 221 )

2 голосов
/ 02 мая 2017

Шаги:

  1. Создайте файл .pythonrc в домашнем каталоге с помощью этой команды: vi .pythonrc

  2. Введите это содержание:

    import rlcompleter, readline  
    readline.parse_and_bind('tab:complete') 
    
  3. Закрыть файл

  4. Теперь запустите

    echo "export PYTHONSTARTUP=~/.pythonrc" >> ~/.bashrc

  5. Перезапустить терминал

1 голос
/ 17 декабря 2013

Для тех (как я), которые в конечном итоге ищут здесь автозаполнение в интерпретаторе:

https://web.archive.org/web/20140214003802/http://conjurecode.com/enable-auto-complete-in-python-interpreter/

Это включает в себя создание файла .pythonrc, изменение .bashrc иimport sys вы должны импортировать каждый раз, когда запускаете интерпретатор Python.

Интересно, может ли последний быть автоматизирован для еще большего выигрыша?

...