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