开发者

stdiodemo and command history

While playing and extending stdiodemo.py, a came up with a thought of开发者_JS百科 adding command line history. Is this possible? Any hints?

Thanks Antonis K.


It's certainly possible. History can be dealt with somewhat independently of input, so ideally you could have an object representing your history with methods like addLine and previousLine and so on. Then you'd glue this to a user-interface of your choice, be it an input box in a Gtk application or something on stdio.

As part of an (unfinished) IRC client, I've written something like this: https://github.com/exarkun/invective/blob/master/invective/history.py

And actually, in the same project, you'll find LineInputWidget which hooks this up to stdio, and also implements things like emacs-style kill and yank, forwards- and backwards-word, etc.

stdiodemo.py can't handle things like up arrow and down arrow, though, which you'll probably want for sensible history navigation. Instead, you need to handle stdio in raw mode with some code that knows how to interpret terminal control sequences. If you've ever run "cat" and hit up arrow or any other function key, then you know there's a special sequence of bytes for each of these. Something in your program needs to interpret these sequences and turn them into something sensible. This is what twisted.conch.insults.insults.ServerProtocol does. It turns a byte transport connected to a terminal into a different, richer kind of transport: a transport that can tell you when bytes have arrived, but also when various special keys are pressed. You can see an example of running a line-based protocol with input history by running:

python -m twisted.conch.stdio

This runs a Python REPL using ServerProtocol and one of the input history classes in Twisted itself (the special thing about this REPL is that it has the reactor running simultaneously with handling your input, something that's challenge to do in the normal Python REPL).

You can find the source for this in twisted/conch/stdio.py. The important stdio hookup code is in the runWithProtocol class. See how it instantiates a ServerProtocol and connects it to stdio with StandardIO (so it's just building more on top of what stdiodemo.py does). ServerProtocol only interprets the bytes from the terminal, though. It doesn't have your application logic. So you need to give it a class that implements your application logic. And that's exactly what invective does.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜