Скрученная интеграция Python с модулем Cmd
мне нравится в Python Twisted и Cmd. Я хочу использовать их вместе.
у меня есть некоторые вещи, но до сих пор я не понял, как заставить tab-completion работать, потому что я не вижу, как получить события Tab keypres сразу (без нажатия Enter) в LineReceiver Twisted.
вот мой код до сих пор:
#!/usr/bin/env python
from cmd import Cmd
from twisted.internet import reactor
from twisted.internet.stdio import StandardIO
from twisted.protocols.basic import LineReceiver
class CommandProcessor(Cmd):
def do_EOF(self, line):
return True
class LineProcessor(LineReceiver):
from os import linesep as delimiter # makes newline work
def __init__(self):
self.processor = CommandProcessor()
self.setRawMode()
def connectionMade(self):
self.transport.write('>>> ')
def rawDataReceived(self, data):
self.processor.onecmd(data)
self.transport.write('>>> ')
StandardIO(LineProcessor())
reactor.run()
помимо завершения вкладки, это несколько работает. Я могу ввести команду "help" и Cmd модуль печати результатов. Но я потерял отличную вкладку-полную функциональность модуля Cmd, потому что Twisted буферизует одну строку за раз. Я попытался установить LineProcessor.delimiter
к пустой строке, безрезультатно. Может быть, мне нужно найти какой-то другой кусок скрученного, чтобы использовать вместо LineReceiver? Или может есть более простой подход, который позволит избежать необходимости обрабатывать каждый символ по одному?
Я не могу использовать Cmd в одиночку, потому что я хочу сделать это сетевое приложение, где некоторые команды приведут к отправке данных, а получение данных из сети произойдет асинхронно (и будет отображаться пользователю).
Итак, начнем ли мы с приведенного выше кода или что-то совершенно другое, я хотел бы создать хорошее, дружественное терминальное приложение в Python, которое реагирует на сетевые события, а также на завершение вкладки. Надеюсь, я смогу использовать то, что уже есть, и не придется слишком много реализовывать.
1 ответов
у вас есть несколько трудностей с этим подходом:
-
Cmd.onecmd
не собирается выполнять обработку вкладок. - даже если это так, ваш терминал должен быть в режиме cbreak, чтобы отдельные нажатия клавиш могли попасть в интерпретатор Python (
tty.setcbreak
может позаботиться об этом). - как известно,
Cmd.cmdloop
не знает реактор и будет блокировать ожидание ввода. - тем не менее, чтобы получить все крутое редактирование строк, которое вы хотите, Cmd (на самом деле readline) должен иметь прямой доступ к stdin и stdout.
учитывая все эти трудности, вы можете захотеть посмотреть, как запустить CommandProcessor в своем собственном потоке. Например:
#!/usr/bin/env python
from cmd import Cmd
from twisted.internet import reactor
class CommandProcessor(Cmd):
def do_EOF(self, line):
return True
def do_YEP(self, line):
reactor.callFromThread(on_main_thread, "YEP")
def do_NOPE(self, line):
reactor.callFromThread(on_main_thread, "NOPE")
def on_main_thread(item):
print "doing", item
def heartbeat():
print "heartbeat"
reactor.callLater(1.0, heartbeat)
reactor.callLater(1.0, heartbeat)
reactor.callInThread(CommandProcessor().cmdloop)
reactor.run()