[Twisted-Python] Embedding manhole interpreter into insults widget.

Maxim Lacrima lacrima.maxim at gmail.com
Wed Aug 6 12:14:20 MDT 2014


Hello,

I have been trying to create a widget that encloses manhole interpreter.
Here is somewhat hacky implementation that I came up with at this moment:

  1 from twisted.conch.insults import insults
  2 from twisted.conch.insults import window
  3 from twisted.conch.insults import helper
  4 from twisted.conch import manhole
  5
  6
  7 class TerminalBufferLastWrite(helper.TerminalBuffer):
  8
  9     lastWrite = ''
 10
 11     def write(self, bytes):
 12         self.lastWrite = bytes
 13         helper.TerminalBuffer.write(self, bytes)
 14
 15 for name, const in zip(insults._KEY_NAMES, insults.FUNCTION_KEYS):
 16     setattr(TerminalBufferLastWrite, name, const)
 17
 18
 19 class ManholeWidget(window.Widget):
 20
 21     def __init__(self, namespace, width, height):
 22         self._buf = TerminalBufferLastWrite()
 23         self._buf.width = width
 24         self._buf.height = height
 25         self._buf.connectionMade()
 26
 27         self.manholeProto = manhole.Manhole(namespace)
 28         self.manholeProto.makeConnection(self._buf)
 29
 30     def keystrokeReceived(self, keyID, modifier):
 31         super(ManholeWidget, self).keystrokeReceived(keyID, modifier)
 32         self.manholeProto.keystrokeReceived(keyID, modifier)
 33         self.repaint()
 34
 35     def render(self, width, height, terminal):
 36         for y, line in enumerate(self._buf.lines[0:height]):
 37             terminal.cursorPosition(0, y)
 38             n = 0
 39             for n, (ch, attr) in enumerate(line[0:width]):
 40                 if ch is self._buf.void:
 41                     ch = ' '
 42                 else:
 43                     cursorRow = y
 44                 terminal.write(ch)
 45             if n < width:
 46                 terminal.write(' ' * (width - n - 1))
 47             terminal.cursorPosition(self.manholeProto.lineBufferIndex +
4,
 48                                     cursorRow)


Basically, I substitute real terminal (`insults.ServerProtocol`) with
slightly extended `TerminalBuffer`, which is used by manhole interpreter to
write its output. `ManholeWidget.render` method is almost entirely reuses
code from `window.Viewport`.

This widget appears to work.

However, here is the problem: if terminal size is large enough (say,
200x50), then there are some io lags (similar to ssh session over slow
internet connection).

The reason is that on each keystroke, the whole terminal buffer is redrawn.
I wonder how I can optimize this. Currently I don't see a solution. Also I
am wondering if I took right approach to embed manhole interpreter into a
widget in the first place, but I don't see a solution, except using
`TerminalBuffer` to capture manhole output.

Thanks.

-- 
Regards,
Maxim
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://twistedmatrix.com/pipermail/twisted-python/attachments/20140806/036ea576/attachment.html>


More information about the Twisted-Python mailing list