Завершение табуляции в интерфейсе командной строки Python - как перехватывать события табуляции
Я пишу немного CLI на Python (как расширение для Mercurial) и хотел бы поддержать завершение табуляции. В частности, я хотел бы поймать вкладки в приглашении и показать список подходящих опций (как в bash).
Пример: введите название раздела:
ext*TAB*
extensions
extras
Проблема в том, что я не уверен, как отлавливать события Tab. Я использую ui.prompt()
API Mercurial, который просто звонит raw_input()
под капотом.
Насколько я знаю, raw_input()
возвращается только при вводе, и если пользователь заходит на вкладку, возвращаемая строка просто включает "\t"
,
3 ответа
Для этого вы используете readline
модуль.
Простейший код, который я могу подумать:
import readline
COMMANDS = ['extra', 'extension', 'stuff', 'errors',
'email', 'foobar', 'foo']
def complete(text, state):
for cmd in COMMANDS:
if cmd.startswith(text):
if not state:
return cmd
else:
state -= 1
readline.parse_and_bind("tab: complete")
readline.set_completer(complete)
raw_input('Enter section name: ')
Пример использования:
Enter section name: <tab>
email errors extension extra foo foobar stuff
Enter section name: e<tab>
email errors extension extra
Enter section name: ext<tab>
extension extra
Помимо завершения, readline
предоставляет вам:
- Линия редактирования
- Конфигурация привязки клавиш (включая режимы emacs и vi)
- История (стрелка вверх, чтобы вызвать предыдущие значения)
- Поиск, сохранение и загрузка истории
Отличный пример того, как выполнить завершение табуляции в сотрудничестве с readline, предоставляется в стандартной библиотеке как модуль rlcompleter - вы не можете использовать его как есть (он завершается на основе имен, определенных в настоящее время в основном и встроенном Python), но это показывает, как сделать общую задачу и как подключить ее к readline
,
Вы почти наверняка должны использовать модуль cmd, который уже реализует завершение табуляции и так далее, и, возможно, другие части того, что вы пытаетесь сделать, используя модуль readline и так далее. Нет смысла изобретать велосипед.