aboutsummaryrefslogtreecommitdiffstats
path: root/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults')
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/__init__.py16
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/client.py138
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/colors.py29
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/helper.py450
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/insults.py1087
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/text.py186
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/window.py868
7 files changed, 0 insertions, 2774 deletions
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/__init__.py
deleted file mode 100755
index c070d4f5..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
-Insults: a replacement for Curses/S-Lang.
-
-Very basic at the moment."""
-
-from twisted.python import deprecate, versions
-
-deprecate.deprecatedModuleAttribute(
- versions.Version("Twisted", 10, 1, 0),
- "Please use twisted.conch.insults.helper instead.",
- __name__, "colors")
-
-deprecate.deprecatedModuleAttribute(
- versions.Version("Twisted", 10, 1, 0),
- "Please use twisted.conch.insults.insults instead.",
- __name__, "client")
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/client.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/client.py
deleted file mode 100755
index 89c79cda..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/client.py
+++ /dev/null
@@ -1,138 +0,0 @@
-"""
-You don't really want to use this module. Try insults.py instead.
-"""
-
-from twisted.internet import protocol
-
-class InsultsClient(protocol.Protocol):
-
- escapeTimeout = 0.2
-
- def __init__(self):
- self.width = self.height = None
- self.xpos = self.ypos = 0
- self.commandQueue = []
- self.inEscape = ''
-
- def setSize(self, width, height):
- call = 0
- if self.width:
- call = 1
- self.width = width
- self.height = height
- if call:
- self.windowSizeChanged()
-
- def dataReceived(self, data):
- from twisted.internet import reactor
- for ch in data:
- if ch == '\x1b':
- if self.inEscape:
- self.keyReceived(ch)
- self.inEscape = ''
- else:
- self.inEscape = ch
- self.escapeCall = reactor.callLater(self.escapeTimeout,
- self.endEscape)
- elif ch in 'ABCD' and self.inEscape:
- self.inEscape = ''
- self.escapeCall.cancel()
- if ch == 'A':
- self.keyReceived('<Up>')
- elif ch == 'B':
- self.keyReceived('<Down>')
- elif ch == 'C':
- self.keyReceived('<Right>')
- elif ch == 'D':
- self.keyReceived('<Left>')
- elif self.inEscape:
- self.inEscape += ch
- else:
- self.keyReceived(ch)
-
- def endEscape(self):
- ch = self.inEscape
- self.inEscape = ''
- self.keyReceived(ch)
-
- def initScreen(self):
- self.transport.write('\x1b=\x1b[?1h')
-
- def gotoXY(self, x, y):
- """Go to a position on the screen.
- """
- self.xpos = x
- self.ypos = y
- self.commandQueue.append(('gotoxy', x, y))
-
- def writeCh(self, ch):
- """Write a character to the screen. If we're at the end of the row,
- ignore the write.
- """
- if self.xpos < self.width - 1:
- self.commandQueue.append(('write', ch))
- self.xpos += 1
-
- def writeStr(self, s):
- """Write a string to the screen. This does not wrap a the edge of the
- screen, and stops at \\r and \\n.
- """
- s = s[:self.width-self.xpos]
- if '\n' in s:
- s=s[:s.find('\n')]
- if '\r' in s:
- s=s[:s.find('\r')]
- self.commandQueue.append(('write', s))
- self.xpos += len(s)
-
- def eraseToLine(self):
- """Erase from the current position to the end of the line.
- """
- self.commandQueue.append(('eraseeol',))
-
- def eraseToScreen(self):
- """Erase from the current position to the end of the screen.
- """
- self.commandQueue.append(('eraseeos',))
-
- def clearScreen(self):
- """Clear the screen, and return the cursor to 0, 0.
- """
- self.commandQueue = [('cls',)]
- self.xpos = self.ypos = 0
-
- def setAttributes(self, *attrs):
- """Set the attributes for drawing on the screen.
- """
- self.commandQueue.append(('attributes', attrs))
-
- def refresh(self):
- """Redraw the screen.
- """
- redraw = ''
- for command in self.commandQueue:
- if command[0] == 'gotoxy':
- redraw += '\x1b[%i;%iH' % (command[2]+1, command[1]+1)
- elif command[0] == 'write':
- redraw += command[1]
- elif command[0] == 'eraseeol':
- redraw += '\x1b[0K'
- elif command[0] == 'eraseeos':
- redraw += '\x1b[OJ'
- elif command[0] == 'cls':
- redraw += '\x1b[H\x1b[J'
- elif command[0] == 'attributes':
- redraw += '\x1b[%sm' % ';'.join(map(str, command[1]))
- else:
- print command
- self.commandQueue = []
- self.transport.write(redraw)
-
- def windowSizeChanged(self):
- """Called when the size of the window changes.
- Might want to redraw the screen here, or something.
- """
-
- def keyReceived(self, key):
- """Called when the user hits a key.
- """
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/colors.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/colors.py
deleted file mode 100755
index c12ab16f..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/colors.py
+++ /dev/null
@@ -1,29 +0,0 @@
-"""
-You don't really want to use this module. Try helper.py instead.
-"""
-
-CLEAR = 0
-BOLD = 1
-DIM = 2
-ITALIC = 3
-UNDERSCORE = 4
-BLINK_SLOW = 5
-BLINK_FAST = 6
-REVERSE = 7
-CONCEALED = 8
-FG_BLACK = 30
-FG_RED = 31
-FG_GREEN = 32
-FG_YELLOW = 33
-FG_BLUE = 34
-FG_MAGENTA = 35
-FG_CYAN = 36
-FG_WHITE = 37
-BG_BLACK = 40
-BG_RED = 41
-BG_GREEN = 42
-BG_YELLOW = 43
-BG_BLUE = 44
-BG_MAGENTA = 45
-BG_CYAN = 46
-BG_WHITE = 47
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/helper.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/helper.py
deleted file mode 100755
index ed645c48..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/helper.py
+++ /dev/null
@@ -1,450 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_helper -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Partial in-memory terminal emulator
-
-@author: Jp Calderone
-"""
-
-import re, string
-
-from zope.interface import implements
-
-from twisted.internet import defer, protocol, reactor
-from twisted.python import log
-
-from twisted.conch.insults import insults
-
-FOREGROUND = 30
-BACKGROUND = 40
-BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, N_COLORS = range(9)
-
-class CharacterAttribute:
- """Represents the attributes of a single character.
-
- Character set, intensity, underlinedness, blinkitude, video
- reversal, as well as foreground and background colors made up a
- character's attributes.
- """
- def __init__(self, charset=insults.G0,
- bold=False, underline=False,
- blink=False, reverseVideo=False,
- foreground=WHITE, background=BLACK,
-
- _subtracting=False):
- self.charset = charset
- self.bold = bold
- self.underline = underline
- self.blink = blink
- self.reverseVideo = reverseVideo
- self.foreground = foreground
- self.background = background
-
- self._subtracting = _subtracting
-
- def __eq__(self, other):
- return vars(self) == vars(other)
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
- def copy(self):
- c = self.__class__()
- c.__dict__.update(vars(self))
- return c
-
- def wantOne(self, **kw):
- k, v = kw.popitem()
- if getattr(self, k) != v:
- attr = self.copy()
- attr._subtracting = not v
- setattr(attr, k, v)
- return attr
- else:
- return self.copy()
-
- def toVT102(self):
- # Spit out a vt102 control sequence that will set up
- # all the attributes set here. Except charset.
- attrs = []
- if self._subtracting:
- attrs.append(0)
- if self.bold:
- attrs.append(insults.BOLD)
- if self.underline:
- attrs.append(insults.UNDERLINE)
- if self.blink:
- attrs.append(insults.BLINK)
- if self.reverseVideo:
- attrs.append(insults.REVERSE_VIDEO)
- if self.foreground != WHITE:
- attrs.append(FOREGROUND + self.foreground)
- if self.background != BLACK:
- attrs.append(BACKGROUND + self.background)
- if attrs:
- return '\x1b[' + ';'.join(map(str, attrs)) + 'm'
- return ''
-
-# XXX - need to support scroll regions and scroll history
-class TerminalBuffer(protocol.Protocol):
- """
- An in-memory terminal emulator.
- """
- implements(insults.ITerminalTransport)
-
- for keyID in ('UP_ARROW', 'DOWN_ARROW', 'RIGHT_ARROW', 'LEFT_ARROW',
- 'HOME', 'INSERT', 'DELETE', 'END', 'PGUP', 'PGDN',
- 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9',
- 'F10', 'F11', 'F12'):
- exec '%s = object()' % (keyID,)
-
- TAB = '\t'
- BACKSPACE = '\x7f'
-
- width = 80
- height = 24
-
- fill = ' '
- void = object()
-
- def getCharacter(self, x, y):
- return self.lines[y][x]
-
- def connectionMade(self):
- self.reset()
-
- def write(self, bytes):
- """
- Add the given printable bytes to the terminal.
-
- Line feeds in C{bytes} will be replaced with carriage return / line
- feed pairs.
- """
- for b in bytes.replace('\n', '\r\n'):
- self.insertAtCursor(b)
-
- def _currentCharacterAttributes(self):
- return CharacterAttribute(self.activeCharset, **self.graphicRendition)
-
- def insertAtCursor(self, b):
- """
- Add one byte to the terminal at the cursor and make consequent state
- updates.
-
- If b is a carriage return, move the cursor to the beginning of the
- current row.
-
- If b is a line feed, move the cursor to the next row or scroll down if
- the cursor is already in the last row.
-
- Otherwise, if b is printable, put it at the cursor position (inserting
- or overwriting as dictated by the current mode) and move the cursor.
- """
- if b == '\r':
- self.x = 0
- elif b == '\n':
- self._scrollDown()
- elif b in string.printable:
- if self.x >= self.width:
- self.nextLine()
- ch = (b, self._currentCharacterAttributes())
- if self.modes.get(insults.modes.IRM):
- self.lines[self.y][self.x:self.x] = [ch]
- self.lines[self.y].pop()
- else:
- self.lines[self.y][self.x] = ch
- self.x += 1
-
- def _emptyLine(self, width):
- return [(self.void, self._currentCharacterAttributes()) for i in xrange(width)]
-
- def _scrollDown(self):
- self.y += 1
- if self.y >= self.height:
- self.y -= 1
- del self.lines[0]
- self.lines.append(self._emptyLine(self.width))
-
- def _scrollUp(self):
- self.y -= 1
- if self.y < 0:
- self.y = 0
- del self.lines[-1]
- self.lines.insert(0, self._emptyLine(self.width))
-
- def cursorUp(self, n=1):
- self.y = max(0, self.y - n)
-
- def cursorDown(self, n=1):
- self.y = min(self.height - 1, self.y + n)
-
- def cursorBackward(self, n=1):
- self.x = max(0, self.x - n)
-
- def cursorForward(self, n=1):
- self.x = min(self.width, self.x + n)
-
- def cursorPosition(self, column, line):
- self.x = column
- self.y = line
-
- def cursorHome(self):
- self.x = self.home.x
- self.y = self.home.y
-
- def index(self):
- self._scrollDown()
-
- def reverseIndex(self):
- self._scrollUp()
-
- def nextLine(self):
- """
- Update the cursor position attributes and scroll down if appropriate.
- """
- self.x = 0
- self._scrollDown()
-
- def saveCursor(self):
- self._savedCursor = (self.x, self.y)
-
- def restoreCursor(self):
- self.x, self.y = self._savedCursor
- del self._savedCursor
-
- def setModes(self, modes):
- for m in modes:
- self.modes[m] = True
-
- def resetModes(self, modes):
- for m in modes:
- try:
- del self.modes[m]
- except KeyError:
- pass
-
-
- def setPrivateModes(self, modes):
- """
- Enable the given modes.
-
- Track which modes have been enabled so that the implementations of
- other L{insults.ITerminalTransport} methods can be properly implemented
- to respect these settings.
-
- @see: L{resetPrivateModes}
- @see: L{insults.ITerminalTransport.setPrivateModes}
- """
- for m in modes:
- self.privateModes[m] = True
-
-
- def resetPrivateModes(self, modes):
- """
- Disable the given modes.
-
- @see: L{setPrivateModes}
- @see: L{insults.ITerminalTransport.resetPrivateModes}
- """
- for m in modes:
- try:
- del self.privateModes[m]
- except KeyError:
- pass
-
-
- def applicationKeypadMode(self):
- self.keypadMode = 'app'
-
- def numericKeypadMode(self):
- self.keypadMode = 'num'
-
- def selectCharacterSet(self, charSet, which):
- self.charsets[which] = charSet
-
- def shiftIn(self):
- self.activeCharset = insults.G0
-
- def shiftOut(self):
- self.activeCharset = insults.G1
-
- def singleShift2(self):
- oldActiveCharset = self.activeCharset
- self.activeCharset = insults.G2
- f = self.insertAtCursor
- def insertAtCursor(b):
- f(b)
- del self.insertAtCursor
- self.activeCharset = oldActiveCharset
- self.insertAtCursor = insertAtCursor
-
- def singleShift3(self):
- oldActiveCharset = self.activeCharset
- self.activeCharset = insults.G3
- f = self.insertAtCursor
- def insertAtCursor(b):
- f(b)
- del self.insertAtCursor
- self.activeCharset = oldActiveCharset
- self.insertAtCursor = insertAtCursor
-
- def selectGraphicRendition(self, *attributes):
- for a in attributes:
- if a == insults.NORMAL:
- self.graphicRendition = {
- 'bold': False,
- 'underline': False,
- 'blink': False,
- 'reverseVideo': False,
- 'foreground': WHITE,
- 'background': BLACK}
- elif a == insults.BOLD:
- self.graphicRendition['bold'] = True
- elif a == insults.UNDERLINE:
- self.graphicRendition['underline'] = True
- elif a == insults.BLINK:
- self.graphicRendition['blink'] = True
- elif a == insults.REVERSE_VIDEO:
- self.graphicRendition['reverseVideo'] = True
- else:
- try:
- v = int(a)
- except ValueError:
- log.msg("Unknown graphic rendition attribute: " + repr(a))
- else:
- if FOREGROUND <= v <= FOREGROUND + N_COLORS:
- self.graphicRendition['foreground'] = v - FOREGROUND
- elif BACKGROUND <= v <= BACKGROUND + N_COLORS:
- self.graphicRendition['background'] = v - BACKGROUND
- else:
- log.msg("Unknown graphic rendition attribute: " + repr(a))
-
- def eraseLine(self):
- self.lines[self.y] = self._emptyLine(self.width)
-
- def eraseToLineEnd(self):
- width = self.width - self.x
- self.lines[self.y][self.x:] = self._emptyLine(width)
-
- def eraseToLineBeginning(self):
- self.lines[self.y][:self.x + 1] = self._emptyLine(self.x + 1)
-
- def eraseDisplay(self):
- self.lines = [self._emptyLine(self.width) for i in xrange(self.height)]
-
- def eraseToDisplayEnd(self):
- self.eraseToLineEnd()
- height = self.height - self.y - 1
- self.lines[self.y + 1:] = [self._emptyLine(self.width) for i in range(height)]
-
- def eraseToDisplayBeginning(self):
- self.eraseToLineBeginning()
- self.lines[:self.y] = [self._emptyLine(self.width) for i in range(self.y)]
-
- def deleteCharacter(self, n=1):
- del self.lines[self.y][self.x:self.x+n]
- self.lines[self.y].extend(self._emptyLine(min(self.width - self.x, n)))
-
- def insertLine(self, n=1):
- self.lines[self.y:self.y] = [self._emptyLine(self.width) for i in range(n)]
- del self.lines[self.height:]
-
- def deleteLine(self, n=1):
- del self.lines[self.y:self.y+n]
- self.lines.extend([self._emptyLine(self.width) for i in range(n)])
-
- def reportCursorPosition(self):
- return (self.x, self.y)
-
- def reset(self):
- self.home = insults.Vector(0, 0)
- self.x = self.y = 0
- self.modes = {}
- self.privateModes = {}
- self.setPrivateModes([insults.privateModes.AUTO_WRAP,
- insults.privateModes.CURSOR_MODE])
- self.numericKeypad = 'app'
- self.activeCharset = insults.G0
- self.graphicRendition = {
- 'bold': False,
- 'underline': False,
- 'blink': False,
- 'reverseVideo': False,
- 'foreground': WHITE,
- 'background': BLACK}
- self.charsets = {
- insults.G0: insults.CS_US,
- insults.G1: insults.CS_US,
- insults.G2: insults.CS_ALTERNATE,
- insults.G3: insults.CS_ALTERNATE_SPECIAL}
- self.eraseDisplay()
-
- def unhandledControlSequence(self, buf):
- print 'Could not handle', repr(buf)
-
- def __str__(self):
- lines = []
- for L in self.lines:
- buf = []
- length = 0
- for (ch, attr) in L:
- if ch is not self.void:
- buf.append(ch)
- length = len(buf)
- else:
- buf.append(self.fill)
- lines.append(''.join(buf[:length]))
- return '\n'.join(lines)
-
-class ExpectationTimeout(Exception):
- pass
-
-class ExpectableBuffer(TerminalBuffer):
- _mark = 0
-
- def connectionMade(self):
- TerminalBuffer.connectionMade(self)
- self._expecting = []
-
- def write(self, bytes):
- TerminalBuffer.write(self, bytes)
- self._checkExpected()
-
- def cursorHome(self):
- TerminalBuffer.cursorHome(self)
- self._mark = 0
-
- def _timeoutExpected(self, d):
- d.errback(ExpectationTimeout())
- self._checkExpected()
-
- def _checkExpected(self):
- s = str(self)[self._mark:]
- while self._expecting:
- expr, timer, deferred = self._expecting[0]
- if timer and not timer.active():
- del self._expecting[0]
- continue
- for match in expr.finditer(s):
- if timer:
- timer.cancel()
- del self._expecting[0]
- self._mark += match.end()
- s = s[match.end():]
- deferred.callback(match)
- break
- else:
- return
-
- def expect(self, expression, timeout=None, scheduler=reactor):
- d = defer.Deferred()
- timer = None
- if timeout:
- timer = scheduler.callLater(timeout, self._timeoutExpected, d)
- self._expecting.append((re.compile(expression), timer, d))
- self._checkExpected()
- return d
-
-__all__ = ['CharacterAttribute', 'TerminalBuffer', 'ExpectableBuffer']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/insults.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/insults.py
deleted file mode 100755
index 721551de..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/insults.py
+++ /dev/null
@@ -1,1087 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_insults -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-VT102 and VT220 terminal manipulation.
-
-@author: Jp Calderone
-"""
-
-from zope.interface import implements, Interface
-
-from twisted.internet import protocol, defer, interfaces as iinternet
-
-class ITerminalProtocol(Interface):
- def makeConnection(transport):
- """Called with an L{ITerminalTransport} when a connection is established.
- """
-
- def keystrokeReceived(keyID, modifier):
- """A keystroke was received.
-
- Each keystroke corresponds to one invocation of this method.
- keyID is a string identifier for that key. Printable characters
- are represented by themselves. Control keys, such as arrows and
- function keys, are represented with symbolic constants on
- L{ServerProtocol}.
- """
-
- def terminalSize(width, height):
- """Called to indicate the size of the terminal.
-
- A terminal of 80x24 should be assumed if this method is not
- called. This method might not be called for real terminals.
- """
-
- def unhandledControlSequence(seq):
- """Called when an unsupported control sequence is received.
-
- @type seq: C{str}
- @param seq: The whole control sequence which could not be interpreted.
- """
-
- def connectionLost(reason):
- """Called when the connection has been lost.
-
- reason is a Failure describing why.
- """
-
-class TerminalProtocol(object):
- implements(ITerminalProtocol)
-
- def makeConnection(self, terminal):
- # assert ITerminalTransport.providedBy(transport), "TerminalProtocol.makeConnection must be passed an ITerminalTransport implementor"
- self.terminal = terminal
- self.connectionMade()
-
- def connectionMade(self):
- """Called after a connection has been established.
- """
-
- def keystrokeReceived(self, keyID, modifier):
- pass
-
- def terminalSize(self, width, height):
- pass
-
- def unhandledControlSequence(self, seq):
- pass
-
- def connectionLost(self, reason):
- pass
-
-class ITerminalTransport(iinternet.ITransport):
- def cursorUp(n=1):
- """Move the cursor up n lines.
- """
-
- def cursorDown(n=1):
- """Move the cursor down n lines.
- """
-
- def cursorForward(n=1):
- """Move the cursor right n columns.
- """
-
- def cursorBackward(n=1):
- """Move the cursor left n columns.
- """
-
- def cursorPosition(column, line):
- """Move the cursor to the given line and column.
- """
-
- def cursorHome():
- """Move the cursor home.
- """
-
- def index():
- """Move the cursor down one line, performing scrolling if necessary.
- """
-
- def reverseIndex():
- """Move the cursor up one line, performing scrolling if necessary.
- """
-
- def nextLine():
- """Move the cursor to the first position on the next line, performing scrolling if necessary.
- """
-
- def saveCursor():
- """Save the cursor position, character attribute, character set, and origin mode selection.
- """
-
- def restoreCursor():
- """Restore the previously saved cursor position, character attribute, character set, and origin mode selection.
-
- If no cursor state was previously saved, move the cursor to the home position.
- """
-
- def setModes(modes):
- """Set the given modes on the terminal.
- """
-
- def resetModes(mode):
- """Reset the given modes on the terminal.
- """
-
-
- def setPrivateModes(modes):
- """
- Set the given DEC private modes on the terminal.
- """
-
-
- def resetPrivateModes(modes):
- """
- Reset the given DEC private modes on the terminal.
- """
-
-
- def applicationKeypadMode():
- """Cause keypad to generate control functions.
-
- Cursor key mode selects the type of characters generated by cursor keys.
- """
-
- def numericKeypadMode():
- """Cause keypad to generate normal characters.
- """
-
- def selectCharacterSet(charSet, which):
- """Select a character set.
-
- charSet should be one of CS_US, CS_UK, CS_DRAWING, CS_ALTERNATE, or
- CS_ALTERNATE_SPECIAL.
-
- which should be one of G0 or G1.
- """
-
- def shiftIn():
- """Activate the G0 character set.
- """
-
- def shiftOut():
- """Activate the G1 character set.
- """
-
- def singleShift2():
- """Shift to the G2 character set for a single character.
- """
-
- def singleShift3():
- """Shift to the G3 character set for a single character.
- """
-
- def selectGraphicRendition(*attributes):
- """Enabled one or more character attributes.
-
- Arguments should be one or more of UNDERLINE, REVERSE_VIDEO, BLINK, or BOLD.
- NORMAL may also be specified to disable all character attributes.
- """
-
- def horizontalTabulationSet():
- """Set a tab stop at the current cursor position.
- """
-
- def tabulationClear():
- """Clear the tab stop at the current cursor position.
- """
-
- def tabulationClearAll():
- """Clear all tab stops.
- """
-
- def doubleHeightLine(top=True):
- """Make the current line the top or bottom half of a double-height, double-width line.
-
- If top is True, the current line is the top half. Otherwise, it is the bottom half.
- """
-
- def singleWidthLine():
- """Make the current line a single-width, single-height line.
- """
-
- def doubleWidthLine():
- """Make the current line a double-width line.
- """
-
- def eraseToLineEnd():
- """Erase from the cursor to the end of line, including cursor position.
- """
-
- def eraseToLineBeginning():
- """Erase from the cursor to the beginning of the line, including the cursor position.
- """
-
- def eraseLine():
- """Erase the entire cursor line.
- """
-
- def eraseToDisplayEnd():
- """Erase from the cursor to the end of the display, including the cursor position.
- """
-
- def eraseToDisplayBeginning():
- """Erase from the cursor to the beginning of the display, including the cursor position.
- """
-
- def eraseDisplay():
- """Erase the entire display.
- """
-
- def deleteCharacter(n=1):
- """Delete n characters starting at the cursor position.
-
- Characters to the right of deleted characters are shifted to the left.
- """
-
- def insertLine(n=1):
- """Insert n lines at the cursor position.
-
- Lines below the cursor are shifted down. Lines moved past the bottom margin are lost.
- This command is ignored when the cursor is outside the scroll region.
- """
-
- def deleteLine(n=1):
- """Delete n lines starting at the cursor position.
-
- Lines below the cursor are shifted up. This command is ignored when the cursor is outside
- the scroll region.
- """
-
- def reportCursorPosition():
- """Return a Deferred that fires with a two-tuple of (x, y) indicating the cursor position.
- """
-
- def reset():
- """Reset the terminal to its initial state.
- """
-
- def unhandledControlSequence(seq):
- """Called when an unsupported control sequence is received.
-
- @type seq: C{str}
- @param seq: The whole control sequence which could not be interpreted.
- """
-
-
-CSI = '\x1b'
-CST = {'~': 'tilde'}
-
-class modes:
- """ECMA 48 standardized modes
- """
-
- # BREAKS YOPUR KEYBOARD MOFO
- KEYBOARD_ACTION = KAM = 2
-
- # When set, enables character insertion. New display characters
- # move old display characters to the right. Characters moved past
- # the right margin are lost.
-
- # When reset, enables replacement mode (disables character
- # insertion). New display characters replace old display
- # characters at cursor position. The old character is erased.
- INSERTION_REPLACEMENT = IRM = 4
-
- # Set causes a received linefeed, form feed, or vertical tab to
- # move cursor to first column of next line. RETURN transmits both
- # a carriage return and linefeed. This selection is also called
- # new line option.
-
- # Reset causes a received linefeed, form feed, or vertical tab to
- # move cursor to next line in current column. RETURN transmits a
- # carriage return.
- LINEFEED_NEWLINE = LNM = 20
-
-
-class privateModes:
- """ANSI-Compatible Private Modes
- """
- ERROR = 0
- CURSOR_KEY = 1
- ANSI_VT52 = 2
- COLUMN = 3
- SCROLL = 4
- SCREEN = 5
- ORIGIN = 6
- AUTO_WRAP = 7
- AUTO_REPEAT = 8
- PRINTER_FORM_FEED = 18
- PRINTER_EXTENT = 19
-
- # Toggle cursor visibility (reset hides it)
- CURSOR_MODE = 25
-
-
-# Character sets
-CS_US = 'CS_US'
-CS_UK = 'CS_UK'
-CS_DRAWING = 'CS_DRAWING'
-CS_ALTERNATE = 'CS_ALTERNATE'
-CS_ALTERNATE_SPECIAL = 'CS_ALTERNATE_SPECIAL'
-
-# Groupings (or something?? These are like variables that can be bound to character sets)
-G0 = 'G0'
-G1 = 'G1'
-
-# G2 and G3 cannot be changed, but they can be shifted to.
-G2 = 'G2'
-G3 = 'G3'
-
-# Character attributes
-
-NORMAL = 0
-BOLD = 1
-UNDERLINE = 4
-BLINK = 5
-REVERSE_VIDEO = 7
-
-class Vector:
- def __init__(self, x, y):
- self.x = x
- self.y = y
-
-def log(s):
- file('log', 'a').write(str(s) + '\n')
-
-# XXX TODO - These attributes are really part of the
-# ITerminalTransport interface, I think.
-_KEY_NAMES = ('UP_ARROW', 'DOWN_ARROW', 'RIGHT_ARROW', 'LEFT_ARROW',
- 'HOME', 'INSERT', 'DELETE', 'END', 'PGUP', 'PGDN', 'NUMPAD_MIDDLE',
- 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9',
- 'F10', 'F11', 'F12',
-
- 'ALT', 'SHIFT', 'CONTROL')
-
-class _const(object):
- """
- @ivar name: A string naming this constant
- """
- def __init__(self, name):
- self.name = name
-
- def __repr__(self):
- return '[' + self.name + ']'
-
-
-FUNCTION_KEYS = [
- _const(_name) for _name in _KEY_NAMES]
-
-class ServerProtocol(protocol.Protocol):
- implements(ITerminalTransport)
-
- protocolFactory = None
- terminalProtocol = None
-
- TAB = '\t'
- BACKSPACE = '\x7f'
- ##
-
- lastWrite = ''
-
- state = 'data'
-
- termSize = Vector(80, 24)
- cursorPos = Vector(0, 0)
- scrollRegion = None
-
- # Factory who instantiated me
- factory = None
-
- def __init__(self, protocolFactory=None, *a, **kw):
- """
- @param protocolFactory: A callable which will be invoked with
- *a, **kw and should return an ITerminalProtocol implementor.
- This will be invoked when a connection to this ServerProtocol
- is established.
-
- @param a: Any positional arguments to pass to protocolFactory.
- @param kw: Any keyword arguments to pass to protocolFactory.
- """
- # assert protocolFactory is None or ITerminalProtocol.implementedBy(protocolFactory), "ServerProtocol.__init__ must be passed an ITerminalProtocol implementor"
- if protocolFactory is not None:
- self.protocolFactory = protocolFactory
- self.protocolArgs = a
- self.protocolKwArgs = kw
-
- self._cursorReports = []
-
- def connectionMade(self):
- if self.protocolFactory is not None:
- self.terminalProtocol = self.protocolFactory(*self.protocolArgs, **self.protocolKwArgs)
-
- try:
- factory = self.factory
- except AttributeError:
- pass
- else:
- self.terminalProtocol.factory = factory
-
- self.terminalProtocol.makeConnection(self)
-
- def dataReceived(self, data):
- for ch in data:
- if self.state == 'data':
- if ch == '\x1b':
- self.state = 'escaped'
- else:
- self.terminalProtocol.keystrokeReceived(ch, None)
- elif self.state == 'escaped':
- if ch == '[':
- self.state = 'bracket-escaped'
- self.escBuf = []
- elif ch == 'O':
- self.state = 'low-function-escaped'
- else:
- self.state = 'data'
- self._handleShortControlSequence(ch)
- elif self.state == 'bracket-escaped':
- if ch == 'O':
- self.state = 'low-function-escaped'
- elif ch.isalpha() or ch == '~':
- self._handleControlSequence(''.join(self.escBuf) + ch)
- del self.escBuf
- self.state = 'data'
- else:
- self.escBuf.append(ch)
- elif self.state == 'low-function-escaped':
- self._handleLowFunctionControlSequence(ch)
- self.state = 'data'
- else:
- raise ValueError("Illegal state")
-
- def _handleShortControlSequence(self, ch):
- self.terminalProtocol.keystrokeReceived(ch, self.ALT)
-
- def _handleControlSequence(self, buf):
- buf = '\x1b[' + buf
- f = getattr(self.controlSequenceParser, CST.get(buf[-1], buf[-1]), None)
- if f is None:
- self.unhandledControlSequence(buf)
- else:
- f(self, self.terminalProtocol, buf[:-1])
-
- def unhandledControlSequence(self, buf):
- self.terminalProtocol.unhandledControlSequence(buf)
-
- def _handleLowFunctionControlSequence(self, ch):
- map = {'P': self.F1, 'Q': self.F2, 'R': self.F3, 'S': self.F4}
- keyID = map.get(ch)
- if keyID is not None:
- self.terminalProtocol.keystrokeReceived(keyID, None)
- else:
- self.terminalProtocol.unhandledControlSequence('\x1b[O' + ch)
-
- class ControlSequenceParser:
- def A(self, proto, handler, buf):
- if buf == '\x1b[':
- handler.keystrokeReceived(proto.UP_ARROW, None)
- else:
- handler.unhandledControlSequence(buf + 'A')
-
- def B(self, proto, handler, buf):
- if buf == '\x1b[':
- handler.keystrokeReceived(proto.DOWN_ARROW, None)
- else:
- handler.unhandledControlSequence(buf + 'B')
-
- def C(self, proto, handler, buf):
- if buf == '\x1b[':
- handler.keystrokeReceived(proto.RIGHT_ARROW, None)
- else:
- handler.unhandledControlSequence(buf + 'C')
-
- def D(self, proto, handler, buf):
- if buf == '\x1b[':
- handler.keystrokeReceived(proto.LEFT_ARROW, None)
- else:
- handler.unhandledControlSequence(buf + 'D')
-
- def E(self, proto, handler, buf):
- if buf == '\x1b[':
- handler.keystrokeReceived(proto.NUMPAD_MIDDLE, None)
- else:
- handler.unhandledControlSequence(buf + 'E')
-
- def F(self, proto, handler, buf):
- if buf == '\x1b[':
- handler.keystrokeReceived(proto.END, None)
- else:
- handler.unhandledControlSequence(buf + 'F')
-
- def H(self, proto, handler, buf):
- if buf == '\x1b[':
- handler.keystrokeReceived(proto.HOME, None)
- else:
- handler.unhandledControlSequence(buf + 'H')
-
- def R(self, proto, handler, buf):
- if not proto._cursorReports:
- handler.unhandledControlSequence(buf + 'R')
- elif buf.startswith('\x1b['):
- report = buf[2:]
- parts = report.split(';')
- if len(parts) != 2:
- handler.unhandledControlSequence(buf + 'R')
- else:
- Pl, Pc = parts
- try:
- Pl, Pc = int(Pl), int(Pc)
- except ValueError:
- handler.unhandledControlSequence(buf + 'R')
- else:
- d = proto._cursorReports.pop(0)
- d.callback((Pc - 1, Pl - 1))
- else:
- handler.unhandledControlSequence(buf + 'R')
-
- def Z(self, proto, handler, buf):
- if buf == '\x1b[':
- handler.keystrokeReceived(proto.TAB, proto.SHIFT)
- else:
- handler.unhandledControlSequence(buf + 'Z')
-
- def tilde(self, proto, handler, buf):
- map = {1: proto.HOME, 2: proto.INSERT, 3: proto.DELETE,
- 4: proto.END, 5: proto.PGUP, 6: proto.PGDN,
-
- 15: proto.F5, 17: proto.F6, 18: proto.F7,
- 19: proto.F8, 20: proto.F9, 21: proto.F10,
- 23: proto.F11, 24: proto.F12}
-
- if buf.startswith('\x1b['):
- ch = buf[2:]
- try:
- v = int(ch)
- except ValueError:
- handler.unhandledControlSequence(buf + '~')
- else:
- symbolic = map.get(v)
- if symbolic is not None:
- handler.keystrokeReceived(map[v], None)
- else:
- handler.unhandledControlSequence(buf + '~')
- else:
- handler.unhandledControlSequence(buf + '~')
-
- controlSequenceParser = ControlSequenceParser()
-
- # ITerminalTransport
- def cursorUp(self, n=1):
- assert n >= 1
- self.cursorPos.y = max(self.cursorPos.y - n, 0)
- self.write('\x1b[%dA' % (n,))
-
- def cursorDown(self, n=1):
- assert n >= 1
- self.cursorPos.y = min(self.cursorPos.y + n, self.termSize.y - 1)
- self.write('\x1b[%dB' % (n,))
-
- def cursorForward(self, n=1):
- assert n >= 1
- self.cursorPos.x = min(self.cursorPos.x + n, self.termSize.x - 1)
- self.write('\x1b[%dC' % (n,))
-
- def cursorBackward(self, n=1):
- assert n >= 1
- self.cursorPos.x = max(self.cursorPos.x - n, 0)
- self.write('\x1b[%dD' % (n,))
-
- def cursorPosition(self, column, line):
- self.write('\x1b[%d;%dH' % (line + 1, column + 1))
-
- def cursorHome(self):
- self.cursorPos.x = self.cursorPos.y = 0
- self.write('\x1b[H')
-
- def index(self):
- self.cursorPos.y = min(self.cursorPos.y + 1, self.termSize.y - 1)
- self.write('\x1bD')
-
- def reverseIndex(self):
- self.cursorPos.y = max(self.cursorPos.y - 1, 0)
- self.write('\x1bM')
-
- def nextLine(self):
- self.cursorPos.x = 0
- self.cursorPos.y = min(self.cursorPos.y + 1, self.termSize.y - 1)
- self.write('\n')
-
- def saveCursor(self):
- self._savedCursorPos = Vector(self.cursorPos.x, self.cursorPos.y)
- self.write('\x1b7')
-
- def restoreCursor(self):
- self.cursorPos = self._savedCursorPos
- del self._savedCursorPos
- self.write('\x1b8')
-
- def setModes(self, modes):
- # XXX Support ANSI-Compatible private modes
- self.write('\x1b[%sh' % (';'.join(map(str, modes)),))
-
- def setPrivateModes(self, modes):
- self.write('\x1b[?%sh' % (';'.join(map(str, modes)),))
-
- def resetModes(self, modes):
- # XXX Support ANSI-Compatible private modes
- self.write('\x1b[%sl' % (';'.join(map(str, modes)),))
-
- def resetPrivateModes(self, modes):
- self.write('\x1b[?%sl' % (';'.join(map(str, modes)),))
-
- def applicationKeypadMode(self):
- self.write('\x1b=')
-
- def numericKeypadMode(self):
- self.write('\x1b>')
-
- def selectCharacterSet(self, charSet, which):
- # XXX Rewrite these as dict lookups
- if which == G0:
- which = '('
- elif which == G1:
- which = ')'
- else:
- raise ValueError("`which' argument to selectCharacterSet must be G0 or G1")
- if charSet == CS_UK:
- charSet = 'A'
- elif charSet == CS_US:
- charSet = 'B'
- elif charSet == CS_DRAWING:
- charSet = '0'
- elif charSet == CS_ALTERNATE:
- charSet = '1'
- elif charSet == CS_ALTERNATE_SPECIAL:
- charSet = '2'
- else:
- raise ValueError("Invalid `charSet' argument to selectCharacterSet")
- self.write('\x1b' + which + charSet)
-
- def shiftIn(self):
- self.write('\x15')
-
- def shiftOut(self):
- self.write('\x14')
-
- def singleShift2(self):
- self.write('\x1bN')
-
- def singleShift3(self):
- self.write('\x1bO')
-
- def selectGraphicRendition(self, *attributes):
- attrs = []
- for a in attributes:
- attrs.append(a)
- self.write('\x1b[%sm' % (';'.join(attrs),))
-
- def horizontalTabulationSet(self):
- self.write('\x1bH')
-
- def tabulationClear(self):
- self.write('\x1b[q')
-
- def tabulationClearAll(self):
- self.write('\x1b[3q')
-
- def doubleHeightLine(self, top=True):
- if top:
- self.write('\x1b#3')
- else:
- self.write('\x1b#4')
-
- def singleWidthLine(self):
- self.write('\x1b#5')
-
- def doubleWidthLine(self):
- self.write('\x1b#6')
-
- def eraseToLineEnd(self):
- self.write('\x1b[K')
-
- def eraseToLineBeginning(self):
- self.write('\x1b[1K')
-
- def eraseLine(self):
- self.write('\x1b[2K')
-
- def eraseToDisplayEnd(self):
- self.write('\x1b[J')
-
- def eraseToDisplayBeginning(self):
- self.write('\x1b[1J')
-
- def eraseDisplay(self):
- self.write('\x1b[2J')
-
- def deleteCharacter(self, n=1):
- self.write('\x1b[%dP' % (n,))
-
- def insertLine(self, n=1):
- self.write('\x1b[%dL' % (n,))
-
- def deleteLine(self, n=1):
- self.write('\x1b[%dM' % (n,))
-
- def setScrollRegion(self, first=None, last=None):
- if first is not None:
- first = '%d' % (first,)
- else:
- first = ''
- if last is not None:
- last = '%d' % (last,)
- else:
- last = ''
- self.write('\x1b[%s;%sr' % (first, last))
-
- def resetScrollRegion(self):
- self.setScrollRegion()
-
- def reportCursorPosition(self):
- d = defer.Deferred()
- self._cursorReports.append(d)
- self.write('\x1b[6n')
- return d
-
- def reset(self):
- self.cursorPos.x = self.cursorPos.y = 0
- try:
- del self._savedCursorPos
- except AttributeError:
- pass
- self.write('\x1bc')
-
- # ITransport
- def write(self, bytes):
- if bytes:
- self.lastWrite = bytes
- self.transport.write('\r\n'.join(bytes.split('\n')))
-
- def writeSequence(self, bytes):
- self.write(''.join(bytes))
-
- def loseConnection(self):
- self.reset()
- self.transport.loseConnection()
-
- def connectionLost(self, reason):
- if self.terminalProtocol is not None:
- try:
- self.terminalProtocol.connectionLost(reason)
- finally:
- self.terminalProtocol = None
-# Add symbolic names for function keys
-for name, const in zip(_KEY_NAMES, FUNCTION_KEYS):
- setattr(ServerProtocol, name, const)
-
-
-
-class ClientProtocol(protocol.Protocol):
-
- terminalFactory = None
- terminal = None
-
- state = 'data'
-
- _escBuf = None
-
- _shorts = {
- 'D': 'index',
- 'M': 'reverseIndex',
- 'E': 'nextLine',
- '7': 'saveCursor',
- '8': 'restoreCursor',
- '=': 'applicationKeypadMode',
- '>': 'numericKeypadMode',
- 'N': 'singleShift2',
- 'O': 'singleShift3',
- 'H': 'horizontalTabulationSet',
- 'c': 'reset'}
-
- _longs = {
- '[': 'bracket-escape',
- '(': 'select-g0',
- ')': 'select-g1',
- '#': 'select-height-width'}
-
- _charsets = {
- 'A': CS_UK,
- 'B': CS_US,
- '0': CS_DRAWING,
- '1': CS_ALTERNATE,
- '2': CS_ALTERNATE_SPECIAL}
-
- # Factory who instantiated me
- factory = None
-
- def __init__(self, terminalFactory=None, *a, **kw):
- """
- @param terminalFactory: A callable which will be invoked with
- *a, **kw and should return an ITerminalTransport provider.
- This will be invoked when this ClientProtocol establishes a
- connection.
-
- @param a: Any positional arguments to pass to terminalFactory.
- @param kw: Any keyword arguments to pass to terminalFactory.
- """
- # assert terminalFactory is None or ITerminalTransport.implementedBy(terminalFactory), "ClientProtocol.__init__ must be passed an ITerminalTransport implementor"
- if terminalFactory is not None:
- self.terminalFactory = terminalFactory
- self.terminalArgs = a
- self.terminalKwArgs = kw
-
- def connectionMade(self):
- if self.terminalFactory is not None:
- self.terminal = self.terminalFactory(*self.terminalArgs, **self.terminalKwArgs)
- self.terminal.factory = self.factory
- self.terminal.makeConnection(self)
-
- def connectionLost(self, reason):
- if self.terminal is not None:
- try:
- self.terminal.connectionLost(reason)
- finally:
- del self.terminal
-
- def dataReceived(self, bytes):
- """
- Parse the given data from a terminal server, dispatching to event
- handlers defined by C{self.terminal}.
- """
- toWrite = []
- for b in bytes:
- if self.state == 'data':
- if b == '\x1b':
- if toWrite:
- self.terminal.write(''.join(toWrite))
- del toWrite[:]
- self.state = 'escaped'
- elif b == '\x14':
- if toWrite:
- self.terminal.write(''.join(toWrite))
- del toWrite[:]
- self.terminal.shiftOut()
- elif b == '\x15':
- if toWrite:
- self.terminal.write(''.join(toWrite))
- del toWrite[:]
- self.terminal.shiftIn()
- elif b == '\x08':
- if toWrite:
- self.terminal.write(''.join(toWrite))
- del toWrite[:]
- self.terminal.cursorBackward()
- else:
- toWrite.append(b)
- elif self.state == 'escaped':
- fName = self._shorts.get(b)
- if fName is not None:
- self.state = 'data'
- getattr(self.terminal, fName)()
- else:
- state = self._longs.get(b)
- if state is not None:
- self.state = state
- else:
- self.terminal.unhandledControlSequence('\x1b' + b)
- self.state = 'data'
- elif self.state == 'bracket-escape':
- if self._escBuf is None:
- self._escBuf = []
- if b.isalpha() or b == '~':
- self._handleControlSequence(''.join(self._escBuf), b)
- del self._escBuf
- self.state = 'data'
- else:
- self._escBuf.append(b)
- elif self.state == 'select-g0':
- self.terminal.selectCharacterSet(self._charsets.get(b, b), G0)
- self.state = 'data'
- elif self.state == 'select-g1':
- self.terminal.selectCharacterSet(self._charsets.get(b, b), G1)
- self.state = 'data'
- elif self.state == 'select-height-width':
- self._handleHeightWidth(b)
- self.state = 'data'
- else:
- raise ValueError("Illegal state")
- if toWrite:
- self.terminal.write(''.join(toWrite))
-
-
- def _handleControlSequence(self, buf, terminal):
- f = getattr(self.controlSequenceParser, CST.get(terminal, terminal), None)
- if f is None:
- self.terminal.unhandledControlSequence('\x1b[' + buf + terminal)
- else:
- f(self, self.terminal, buf)
-
- class ControlSequenceParser:
- def _makeSimple(ch, fName):
- n = 'cursor' + fName
- def simple(self, proto, handler, buf):
- if not buf:
- getattr(handler, n)(1)
- else:
- try:
- m = int(buf)
- except ValueError:
- handler.unhandledControlSequence('\x1b[' + buf + ch)
- else:
- getattr(handler, n)(m)
- return simple
- for (ch, fName) in (('A', 'Up'),
- ('B', 'Down'),
- ('C', 'Forward'),
- ('D', 'Backward')):
- exec ch + " = _makeSimple(ch, fName)"
- del _makeSimple
-
- def h(self, proto, handler, buf):
- # XXX - Handle '?' to introduce ANSI-Compatible private modes.
- try:
- modes = map(int, buf.split(';'))
- except ValueError:
- handler.unhandledControlSequence('\x1b[' + buf + 'h')
- else:
- handler.setModes(modes)
-
- def l(self, proto, handler, buf):
- # XXX - Handle '?' to introduce ANSI-Compatible private modes.
- try:
- modes = map(int, buf.split(';'))
- except ValueError:
- handler.unhandledControlSequence('\x1b[' + buf + 'l')
- else:
- handler.resetModes(modes)
-
- def r(self, proto, handler, buf):
- parts = buf.split(';')
- if len(parts) == 1:
- handler.setScrollRegion(None, None)
- elif len(parts) == 2:
- try:
- if parts[0]:
- pt = int(parts[0])
- else:
- pt = None
- if parts[1]:
- pb = int(parts[1])
- else:
- pb = None
- except ValueError:
- handler.unhandledControlSequence('\x1b[' + buf + 'r')
- else:
- handler.setScrollRegion(pt, pb)
- else:
- handler.unhandledControlSequence('\x1b[' + buf + 'r')
-
- def K(self, proto, handler, buf):
- if not buf:
- handler.eraseToLineEnd()
- elif buf == '1':
- handler.eraseToLineBeginning()
- elif buf == '2':
- handler.eraseLine()
- else:
- handler.unhandledControlSequence('\x1b[' + buf + 'K')
-
- def H(self, proto, handler, buf):
- handler.cursorHome()
-
- def J(self, proto, handler, buf):
- if not buf:
- handler.eraseToDisplayEnd()
- elif buf == '1':
- handler.eraseToDisplayBeginning()
- elif buf == '2':
- handler.eraseDisplay()
- else:
- handler.unhandledControlSequence('\x1b[' + buf + 'J')
-
- def P(self, proto, handler, buf):
- if not buf:
- handler.deleteCharacter(1)
- else:
- try:
- n = int(buf)
- except ValueError:
- handler.unhandledControlSequence('\x1b[' + buf + 'P')
- else:
- handler.deleteCharacter(n)
-
- def L(self, proto, handler, buf):
- if not buf:
- handler.insertLine(1)
- else:
- try:
- n = int(buf)
- except ValueError:
- handler.unhandledControlSequence('\x1b[' + buf + 'L')
- else:
- handler.insertLine(n)
-
- def M(self, proto, handler, buf):
- if not buf:
- handler.deleteLine(1)
- else:
- try:
- n = int(buf)
- except ValueError:
- handler.unhandledControlSequence('\x1b[' + buf + 'M')
- else:
- handler.deleteLine(n)
-
- def n(self, proto, handler, buf):
- if buf == '6':
- x, y = handler.reportCursorPosition()
- proto.transport.write('\x1b[%d;%dR' % (x + 1, y + 1))
- else:
- handler.unhandledControlSequence('\x1b[' + buf + 'n')
-
- def m(self, proto, handler, buf):
- if not buf:
- handler.selectGraphicRendition(NORMAL)
- else:
- attrs = []
- for a in buf.split(';'):
- try:
- a = int(a)
- except ValueError:
- pass
- attrs.append(a)
- handler.selectGraphicRendition(*attrs)
-
- controlSequenceParser = ControlSequenceParser()
-
- def _handleHeightWidth(self, b):
- if b == '3':
- self.terminal.doubleHeightLine(True)
- elif b == '4':
- self.terminal.doubleHeightLine(False)
- elif b == '5':
- self.terminal.singleWidthLine()
- elif b == '6':
- self.terminal.doubleWidthLine()
- else:
- self.terminal.unhandledControlSequence('\x1b#' + b)
-
-
-__all__ = [
- # Interfaces
- 'ITerminalProtocol', 'ITerminalTransport',
-
- # Symbolic constants
- 'modes', 'privateModes', 'FUNCTION_KEYS',
-
- 'CS_US', 'CS_UK', 'CS_DRAWING', 'CS_ALTERNATE', 'CS_ALTERNATE_SPECIAL',
- 'G0', 'G1', 'G2', 'G3',
-
- 'UNDERLINE', 'REVERSE_VIDEO', 'BLINK', 'BOLD', 'NORMAL',
-
- # Protocol classes
- 'ServerProtocol', 'ClientProtocol']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/text.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/text.py
deleted file mode 100755
index e5c8fd12..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/text.py
+++ /dev/null
@@ -1,186 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_text -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Character attribute manipulation API
-
-This module provides a domain-specific language (using Python syntax)
-for the creation of text with additional display attributes associated
-with it. It is intended as an alternative to manually building up
-strings containing ECMA 48 character attribute control codes. It
-currently supports foreground and background colors (black, red,
-green, yellow, blue, magenta, cyan, and white), intensity selection,
-underlining, blinking and reverse video. Character set selection
-support is planned.
-
-Character attributes are specified by using two Python operations:
-attribute lookup and indexing. For example, the string \"Hello
-world\" with red foreground and all other attributes set to their
-defaults, assuming the name twisted.conch.insults.text.attributes has
-been imported and bound to the name \"A\" (with the statement C{from
-twisted.conch.insults.text import attributes as A}, for example) one
-uses this expression::
-
- | A.fg.red[\"Hello world\"]
-
-Other foreground colors are set by substituting their name for
-\"red\". To set both a foreground and a background color, this
-expression is used::
-
- | A.fg.red[A.bg.green[\"Hello world\"]]
-
-Note that either A.bg.green can be nested within A.fg.red or vice
-versa. Also note that multiple items can be nested within a single
-index operation by separating them with commas::
-
- | A.bg.green[A.fg.red[\"Hello\"], " ", A.fg.blue[\"world\"]]
-
-Other character attributes are set in a similar fashion. To specify a
-blinking version of the previous expression::
-
- | A.blink[A.bg.green[A.fg.red[\"Hello\"], " ", A.fg.blue[\"world\"]]]
-
-C{A.reverseVideo}, C{A.underline}, and C{A.bold} are also valid.
-
-A third operation is actually supported: unary negation. This turns
-off an attribute when an enclosing expression would otherwise have
-caused it to be on. For example::
-
- | A.underline[A.fg.red[\"Hello\", -A.underline[\" world\"]]]
-
-@author: Jp Calderone
-"""
-
-from twisted.conch.insults import helper, insults
-
-class _Attribute(object):
- def __init__(self):
- self.children = []
-
- def __getitem__(self, item):
- assert isinstance(item, (list, tuple, _Attribute, str))
- if isinstance(item, (list, tuple)):
- self.children.extend(item)
- else:
- self.children.append(item)
- return self
-
- def serialize(self, write, attrs=None):
- if attrs is None:
- attrs = helper.CharacterAttribute()
- for ch in self.children:
- if isinstance(ch, _Attribute):
- ch.serialize(write, attrs.copy())
- else:
- write(attrs.toVT102())
- write(ch)
-
-class _NormalAttr(_Attribute):
- def serialize(self, write, attrs):
- attrs.__init__()
- super(_NormalAttr, self).serialize(write, attrs)
-
-class _OtherAttr(_Attribute):
- def __init__(self, attrname, attrvalue):
- self.attrname = attrname
- self.attrvalue = attrvalue
- self.children = []
-
- def __neg__(self):
- result = _OtherAttr(self.attrname, not self.attrvalue)
- result.children.extend(self.children)
- return result
-
- def serialize(self, write, attrs):
- attrs = attrs.wantOne(**{self.attrname: self.attrvalue})
- super(_OtherAttr, self).serialize(write, attrs)
-
-class _ColorAttr(_Attribute):
- def __init__(self, color, ground):
- self.color = color
- self.ground = ground
- self.children = []
-
- def serialize(self, write, attrs):
- attrs = attrs.wantOne(**{self.ground: self.color})
- super(_ColorAttr, self).serialize(write, attrs)
-
-class _ForegroundColorAttr(_ColorAttr):
- def __init__(self, color):
- super(_ForegroundColorAttr, self).__init__(color, 'foreground')
-
-class _BackgroundColorAttr(_ColorAttr):
- def __init__(self, color):
- super(_BackgroundColorAttr, self).__init__(color, 'background')
-
-class CharacterAttributes(object):
- class _ColorAttribute(object):
- def __init__(self, ground):
- self.ground = ground
-
- attrs = {
- 'black': helper.BLACK,
- 'red': helper.RED,
- 'green': helper.GREEN,
- 'yellow': helper.YELLOW,
- 'blue': helper.BLUE,
- 'magenta': helper.MAGENTA,
- 'cyan': helper.CYAN,
- 'white': helper.WHITE}
-
- def __getattr__(self, name):
- try:
- return self.ground(self.attrs[name])
- except KeyError:
- raise AttributeError(name)
-
- fg = _ColorAttribute(_ForegroundColorAttr)
- bg = _ColorAttribute(_BackgroundColorAttr)
-
- attrs = {
- 'bold': insults.BOLD,
- 'blink': insults.BLINK,
- 'underline': insults.UNDERLINE,
- 'reverseVideo': insults.REVERSE_VIDEO}
-
- def __getattr__(self, name):
- if name == 'normal':
- return _NormalAttr()
- if name in self.attrs:
- return _OtherAttr(name, True)
- raise AttributeError(name)
-
-def flatten(output, attrs):
- """Serialize a sequence of characters with attribute information
-
- The resulting string can be interpreted by VT102-compatible
- terminals so that the contained characters are displayed and, for
- those attributes which the terminal supports, have the attributes
- specified in the input.
-
- For example, if your terminal is VT102 compatible, you might run
- this for a colorful variation on the \"hello world\" theme::
-
- | from twisted.conch.insults.text import flatten, attributes as A
- | from twisted.conch.insults.helper import CharacterAttribute
- | print flatten(
- | A.normal[A.bold[A.fg.red['He'], A.fg.green['ll'], A.fg.magenta['o'], ' ',
- | A.fg.yellow['Wo'], A.fg.blue['rl'], A.fg.cyan['d!']]],
- | CharacterAttribute())
-
- @param output: Object returned by accessing attributes of the
- module-level attributes object.
-
- @param attrs: A L{twisted.conch.insults.helper.CharacterAttribute}
- instance
-
- @return: A VT102-friendly string
- """
- L = []
- output.serialize(L.append, attrs)
- return ''.join(L)
-
-attributes = CharacterAttributes()
-
-__all__ = ['attributes', 'flatten']
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/window.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/window.py
deleted file mode 100755
index 99013273..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/window.py
+++ /dev/null
@@ -1,868 +0,0 @@
-# -*- test-case-name: twisted.conch.test.test_window -*-
-
-"""
-Simple insults-based widget library
-
-@author: Jp Calderone
-"""
-
-import array
-
-from twisted.conch.insults import insults, helper
-from twisted.python import text as tptext
-
-class YieldFocus(Exception):
- """Input focus manipulation exception
- """
-
-class BoundedTerminalWrapper(object):
- def __init__(self, terminal, width, height, xoff, yoff):
- self.width = width
- self.height = height
- self.xoff = xoff
- self.yoff = yoff
- self.terminal = terminal
- self.cursorForward = terminal.cursorForward
- self.selectCharacterSet = terminal.selectCharacterSet
- self.selectGraphicRendition = terminal.selectGraphicRendition
- self.saveCursor = terminal.saveCursor
- self.restoreCursor = terminal.restoreCursor
-
- def cursorPosition(self, x, y):
- return self.terminal.cursorPosition(
- self.xoff + min(self.width, x),
- self.yoff + min(self.height, y)
- )
-
- def cursorHome(self):
- return self.terminal.cursorPosition(
- self.xoff, self.yoff)
-
- def write(self, bytes):
- return self.terminal.write(bytes)
-
-class Widget(object):
- focused = False
- parent = None
- dirty = False
- width = height = None
-
- def repaint(self):
- if not self.dirty:
- self.dirty = True
- if self.parent is not None and not self.parent.dirty:
- self.parent.repaint()
-
- def filthy(self):
- self.dirty = True
-
- def redraw(self, width, height, terminal):
- self.filthy()
- self.draw(width, height, terminal)
-
- def draw(self, width, height, terminal):
- if width != self.width or height != self.height or self.dirty:
- self.width = width
- self.height = height
- self.dirty = False
- self.render(width, height, terminal)
-
- def render(self, width, height, terminal):
- pass
-
- def sizeHint(self):
- return None
-
- def keystrokeReceived(self, keyID, modifier):
- if keyID == '\t':
- self.tabReceived(modifier)
- elif keyID == '\x7f':
- self.backspaceReceived()
- elif keyID in insults.FUNCTION_KEYS:
- self.functionKeyReceived(keyID, modifier)
- else:
- self.characterReceived(keyID, modifier)
-
- def tabReceived(self, modifier):
- # XXX TODO - Handle shift+tab
- raise YieldFocus()
-
- def focusReceived(self):
- """Called when focus is being given to this widget.
-
- May raise YieldFocus is this widget does not want focus.
- """
- self.focused = True
- self.repaint()
-
- def focusLost(self):
- self.focused = False
- self.repaint()
-
- def backspaceReceived(self):
- pass
-
- def functionKeyReceived(self, keyID, modifier):
- func = getattr(self, 'func_' + keyID.name, None)
- if func is not None:
- func(modifier)
-
- def characterReceived(self, keyID, modifier):
- pass
-
-class ContainerWidget(Widget):
- """
- @ivar focusedChild: The contained widget which currently has
- focus, or None.
- """
- focusedChild = None
- focused = False
-
- def __init__(self):
- Widget.__init__(self)
- self.children = []
-
- def addChild(self, child):
- assert child.parent is None
- child.parent = self
- self.children.append(child)
- if self.focusedChild is None and self.focused:
- try:
- child.focusReceived()
- except YieldFocus:
- pass
- else:
- self.focusedChild = child
- self.repaint()
-
- def remChild(self, child):
- assert child.parent is self
- child.parent = None
- self.children.remove(child)
- self.repaint()
-
- def filthy(self):
- for ch in self.children:
- ch.filthy()
- Widget.filthy(self)
-
- def render(self, width, height, terminal):
- for ch in self.children:
- ch.draw(width, height, terminal)
-
- def changeFocus(self):
- self.repaint()
-
- if self.focusedChild is not None:
- self.focusedChild.focusLost()
- focusedChild = self.focusedChild
- self.focusedChild = None
- try:
- curFocus = self.children.index(focusedChild) + 1
- except ValueError:
- raise YieldFocus()
- else:
- curFocus = 0
- while curFocus < len(self.children):
- try:
- self.children[curFocus].focusReceived()
- except YieldFocus:
- curFocus += 1
- else:
- self.focusedChild = self.children[curFocus]
- return
- # None of our children wanted focus
- raise YieldFocus()
-
-
- def focusReceived(self):
- self.changeFocus()
- self.focused = True
-
-
- def keystrokeReceived(self, keyID, modifier):
- if self.focusedChild is not None:
- try:
- self.focusedChild.keystrokeReceived(keyID, modifier)
- except YieldFocus:
- self.changeFocus()
- self.repaint()
- else:
- Widget.keystrokeReceived(self, keyID, modifier)
-
-
-class TopWindow(ContainerWidget):
- """
- A top-level container object which provides focus wrap-around and paint
- scheduling.
-
- @ivar painter: A no-argument callable which will be invoked when this
- widget needs to be redrawn.
-
- @ivar scheduler: A one-argument callable which will be invoked with a
- no-argument callable and should arrange for it to invoked at some point in
- the near future. The no-argument callable will cause this widget and all
- its children to be redrawn. It is typically beneficial for the no-argument
- callable to be invoked at the end of handling for whatever event is
- currently active; for example, it might make sense to call it at the end of
- L{twisted.conch.insults.insults.ITerminalProtocol.keystrokeReceived}.
- Note, however, that since calls to this may also be made in response to no
- apparent event, arrangements should be made for the function to be called
- even if an event handler such as C{keystrokeReceived} is not on the call
- stack (eg, using C{reactor.callLater} with a short timeout).
- """
- focused = True
-
- def __init__(self, painter, scheduler):
- ContainerWidget.__init__(self)
- self.painter = painter
- self.scheduler = scheduler
-
- _paintCall = None
- def repaint(self):
- if self._paintCall is None:
- self._paintCall = object()
- self.scheduler(self._paint)
- ContainerWidget.repaint(self)
-
- def _paint(self):
- self._paintCall = None
- self.painter()
-
- def changeFocus(self):
- try:
- ContainerWidget.changeFocus(self)
- except YieldFocus:
- try:
- ContainerWidget.changeFocus(self)
- except YieldFocus:
- pass
-
- def keystrokeReceived(self, keyID, modifier):
- try:
- ContainerWidget.keystrokeReceived(self, keyID, modifier)
- except YieldFocus:
- self.changeFocus()
-
-
-class AbsoluteBox(ContainerWidget):
- def moveChild(self, child, x, y):
- for n in range(len(self.children)):
- if self.children[n][0] is child:
- self.children[n] = (child, x, y)
- break
- else:
- raise ValueError("No such child", child)
-
- def render(self, width, height, terminal):
- for (ch, x, y) in self.children:
- wrap = BoundedTerminalWrapper(terminal, width - x, height - y, x, y)
- ch.draw(width, height, wrap)
-
-
-class _Box(ContainerWidget):
- TOP, CENTER, BOTTOM = range(3)
-
- def __init__(self, gravity=CENTER):
- ContainerWidget.__init__(self)
- self.gravity = gravity
-
- def sizeHint(self):
- height = 0
- width = 0
- for ch in self.children:
- hint = ch.sizeHint()
- if hint is None:
- hint = (None, None)
-
- if self.variableDimension == 0:
- if hint[0] is None:
- width = None
- elif width is not None:
- width += hint[0]
- if hint[1] is None:
- height = None
- elif height is not None:
- height = max(height, hint[1])
- else:
- if hint[0] is None:
- width = None
- elif width is not None:
- width = max(width, hint[0])
- if hint[1] is None:
- height = None
- elif height is not None:
- height += hint[1]
-
- return width, height
-
-
- def render(self, width, height, terminal):
- if not self.children:
- return
-
- greedy = 0
- wants = []
- for ch in self.children:
- hint = ch.sizeHint()
- if hint is None:
- hint = (None, None)
- if hint[self.variableDimension] is None:
- greedy += 1
- wants.append(hint[self.variableDimension])
-
- length = (width, height)[self.variableDimension]
- totalWant = sum([w for w in wants if w is not None])
- if greedy:
- leftForGreedy = int((length - totalWant) / greedy)
-
- widthOffset = heightOffset = 0
-
- for want, ch in zip(wants, self.children):
- if want is None:
- want = leftForGreedy
-
- subWidth, subHeight = width, height
- if self.variableDimension == 0:
- subWidth = want
- else:
- subHeight = want
-
- wrap = BoundedTerminalWrapper(
- terminal,
- subWidth,
- subHeight,
- widthOffset,
- heightOffset,
- )
- ch.draw(subWidth, subHeight, wrap)
- if self.variableDimension == 0:
- widthOffset += want
- else:
- heightOffset += want
-
-
-class HBox(_Box):
- variableDimension = 0
-
-class VBox(_Box):
- variableDimension = 1
-
-
-class Packer(ContainerWidget):
- def render(self, width, height, terminal):
- if not self.children:
- return
-
- root = int(len(self.children) ** 0.5 + 0.5)
- boxes = [VBox() for n in range(root)]
- for n, ch in enumerate(self.children):
- boxes[n % len(boxes)].addChild(ch)
- h = HBox()
- map(h.addChild, boxes)
- h.render(width, height, terminal)
-
-
-class Canvas(Widget):
- focused = False
-
- contents = None
-
- def __init__(self):
- Widget.__init__(self)
- self.resize(1, 1)
-
- def resize(self, width, height):
- contents = array.array('c', ' ' * width * height)
- if self.contents is not None:
- for x in range(min(width, self._width)):
- for y in range(min(height, self._height)):
- contents[width * y + x] = self[x, y]
- self.contents = contents
- self._width = width
- self._height = height
- if self.x >= width:
- self.x = width - 1
- if self.y >= height:
- self.y = height - 1
-
- def __getitem__(self, (x, y)):
- return self.contents[(self._width * y) + x]
-
- def __setitem__(self, (x, y), value):
- self.contents[(self._width * y) + x] = value
-
- def clear(self):
- self.contents = array.array('c', ' ' * len(self.contents))
-
- def render(self, width, height, terminal):
- if not width or not height:
- return
-
- if width != self._width or height != self._height:
- self.resize(width, height)
- for i in range(height):
- terminal.cursorPosition(0, i)
- terminal.write(''.join(self.contents[self._width * i:self._width * i + self._width])[:width])
-
-
-def horizontalLine(terminal, y, left, right):
- terminal.selectCharacterSet(insults.CS_DRAWING, insults.G0)
- terminal.cursorPosition(left, y)
- terminal.write(chr(0161) * (right - left))
- terminal.selectCharacterSet(insults.CS_US, insults.G0)
-
-def verticalLine(terminal, x, top, bottom):
- terminal.selectCharacterSet(insults.CS_DRAWING, insults.G0)
- for n in xrange(top, bottom):
- terminal.cursorPosition(x, n)
- terminal.write(chr(0170))
- terminal.selectCharacterSet(insults.CS_US, insults.G0)
-
-
-def rectangle(terminal, (top, left), (width, height)):
- terminal.selectCharacterSet(insults.CS_DRAWING, insults.G0)
-
- terminal.cursorPosition(top, left)
- terminal.write(chr(0154))
- terminal.write(chr(0161) * (width - 2))
- terminal.write(chr(0153))
- for n in range(height - 2):
- terminal.cursorPosition(left, top + n + 1)
- terminal.write(chr(0170))
- terminal.cursorForward(width - 2)
- terminal.write(chr(0170))
- terminal.cursorPosition(0, top + height - 1)
- terminal.write(chr(0155))
- terminal.write(chr(0161) * (width - 2))
- terminal.write(chr(0152))
-
- terminal.selectCharacterSet(insults.CS_US, insults.G0)
-
-class Border(Widget):
- def __init__(self, containee):
- Widget.__init__(self)
- self.containee = containee
- self.containee.parent = self
-
- def focusReceived(self):
- return self.containee.focusReceived()
-
- def focusLost(self):
- return self.containee.focusLost()
-
- def keystrokeReceived(self, keyID, modifier):
- return self.containee.keystrokeReceived(keyID, modifier)
-
- def sizeHint(self):
- hint = self.containee.sizeHint()
- if hint is None:
- hint = (None, None)
- if hint[0] is None:
- x = None
- else:
- x = hint[0] + 2
- if hint[1] is None:
- y = None
- else:
- y = hint[1] + 2
- return x, y
-
- def filthy(self):
- self.containee.filthy()
- Widget.filthy(self)
-
- def render(self, width, height, terminal):
- if self.containee.focused:
- terminal.write('\x1b[31m')
- rectangle(terminal, (0, 0), (width, height))
- terminal.write('\x1b[0m')
- wrap = BoundedTerminalWrapper(terminal, width - 2, height - 2, 1, 1)
- self.containee.draw(width - 2, height - 2, wrap)
-
-
-class Button(Widget):
- def __init__(self, label, onPress):
- Widget.__init__(self)
- self.label = label
- self.onPress = onPress
-
- def sizeHint(self):
- return len(self.label), 1
-
- def characterReceived(self, keyID, modifier):
- if keyID == '\r':
- self.onPress()
-
- def render(self, width, height, terminal):
- terminal.cursorPosition(0, 0)
- if self.focused:
- terminal.write('\x1b[1m' + self.label + '\x1b[0m')
- else:
- terminal.write(self.label)
-
-class TextInput(Widget):
- def __init__(self, maxwidth, onSubmit):
- Widget.__init__(self)
- self.onSubmit = onSubmit
- self.maxwidth = maxwidth
- self.buffer = ''
- self.cursor = 0
-
- def setText(self, text):
- self.buffer = text[:self.maxwidth]
- self.cursor = len(self.buffer)
- self.repaint()
-
- def func_LEFT_ARROW(self, modifier):
- if self.cursor > 0:
- self.cursor -= 1
- self.repaint()
-
- def func_RIGHT_ARROW(self, modifier):
- if self.cursor < len(self.buffer):
- self.cursor += 1
- self.repaint()
-
- def backspaceReceived(self):
- if self.cursor > 0:
- self.buffer = self.buffer[:self.cursor - 1] + self.buffer[self.cursor:]
- self.cursor -= 1
- self.repaint()
-
- def characterReceived(self, keyID, modifier):
- if keyID == '\r':
- self.onSubmit(self.buffer)
- else:
- if len(self.buffer) < self.maxwidth:
- self.buffer = self.buffer[:self.cursor] + keyID + self.buffer[self.cursor:]
- self.cursor += 1
- self.repaint()
-
- def sizeHint(self):
- return self.maxwidth + 1, 1
-
- def render(self, width, height, terminal):
- currentText = self._renderText()
- terminal.cursorPosition(0, 0)
- if self.focused:
- terminal.write(currentText[:self.cursor])
- cursor(terminal, currentText[self.cursor:self.cursor+1] or ' ')
- terminal.write(currentText[self.cursor+1:])
- terminal.write(' ' * (self.maxwidth - len(currentText) + 1))
- else:
- more = self.maxwidth - len(currentText)
- terminal.write(currentText + '_' * more)
-
- def _renderText(self):
- return self.buffer
-
-class PasswordInput(TextInput):
- def _renderText(self):
- return '*' * len(self.buffer)
-
-class TextOutput(Widget):
- text = ''
-
- def __init__(self, size=None):
- Widget.__init__(self)
- self.size = size
-
- def sizeHint(self):
- return self.size
-
- def render(self, width, height, terminal):
- terminal.cursorPosition(0, 0)
- text = self.text[:width]
- terminal.write(text + ' ' * (width - len(text)))
-
- def setText(self, text):
- self.text = text
- self.repaint()
-
- def focusReceived(self):
- raise YieldFocus()
-
-class TextOutputArea(TextOutput):
- WRAP, TRUNCATE = range(2)
-
- def __init__(self, size=None, longLines=WRAP):
- TextOutput.__init__(self, size)
- self.longLines = longLines
-
- def render(self, width, height, terminal):
- n = 0
- inputLines = self.text.splitlines()
- outputLines = []
- while inputLines:
- if self.longLines == self.WRAP:
- wrappedLines = tptext.greedyWrap(inputLines.pop(0), width)
- outputLines.extend(wrappedLines or [''])
- else:
- outputLines.append(inputLines.pop(0)[:width])
- if len(outputLines) >= height:
- break
- for n, L in enumerate(outputLines[:height]):
- terminal.cursorPosition(0, n)
- terminal.write(L)
-
-class Viewport(Widget):
- _xOffset = 0
- _yOffset = 0
-
- def xOffset():
- def get(self):
- return self._xOffset
- def set(self, value):
- if self._xOffset != value:
- self._xOffset = value
- self.repaint()
- return get, set
- xOffset = property(*xOffset())
-
- def yOffset():
- def get(self):
- return self._yOffset
- def set(self, value):
- if self._yOffset != value:
- self._yOffset = value
- self.repaint()
- return get, set
- yOffset = property(*yOffset())
-
- _width = 160
- _height = 24
-
- def __init__(self, containee):
- Widget.__init__(self)
- self.containee = containee
- self.containee.parent = self
-
- self._buf = helper.TerminalBuffer()
- self._buf.width = self._width
- self._buf.height = self._height
- self._buf.connectionMade()
-
- def filthy(self):
- self.containee.filthy()
- Widget.filthy(self)
-
- def render(self, width, height, terminal):
- self.containee.draw(self._width, self._height, self._buf)
-
- # XXX /Lame/
- for y, line in enumerate(self._buf.lines[self._yOffset:self._yOffset + height]):
- terminal.cursorPosition(0, y)
- n = 0
- for n, (ch, attr) in enumerate(line[self._xOffset:self._xOffset + width]):
- if ch is self._buf.void:
- ch = ' '
- terminal.write(ch)
- if n < width:
- terminal.write(' ' * (width - n - 1))
-
-
-class _Scrollbar(Widget):
- def __init__(self, onScroll):
- Widget.__init__(self)
- self.onScroll = onScroll
- self.percent = 0.0
-
- def smaller(self):
- self.percent = min(1.0, max(0.0, self.onScroll(-1)))
- self.repaint()
-
- def bigger(self):
- self.percent = min(1.0, max(0.0, self.onScroll(+1)))
- self.repaint()
-
-
-class HorizontalScrollbar(_Scrollbar):
- def sizeHint(self):
- return (None, 1)
-
- def func_LEFT_ARROW(self, modifier):
- self.smaller()
-
- def func_RIGHT_ARROW(self, modifier):
- self.bigger()
-
- _left = u'\N{BLACK LEFT-POINTING TRIANGLE}'
- _right = u'\N{BLACK RIGHT-POINTING TRIANGLE}'
- _bar = u'\N{LIGHT SHADE}'
- _slider = u'\N{DARK SHADE}'
- def render(self, width, height, terminal):
- terminal.cursorPosition(0, 0)
- n = width - 3
- before = int(n * self.percent)
- after = n - before
- me = self._left + (self._bar * before) + self._slider + (self._bar * after) + self._right
- terminal.write(me.encode('utf-8'))
-
-
-class VerticalScrollbar(_Scrollbar):
- def sizeHint(self):
- return (1, None)
-
- def func_UP_ARROW(self, modifier):
- self.smaller()
-
- def func_DOWN_ARROW(self, modifier):
- self.bigger()
-
- _up = u'\N{BLACK UP-POINTING TRIANGLE}'
- _down = u'\N{BLACK DOWN-POINTING TRIANGLE}'
- _bar = u'\N{LIGHT SHADE}'
- _slider = u'\N{DARK SHADE}'
- def render(self, width, height, terminal):
- terminal.cursorPosition(0, 0)
- knob = int(self.percent * (height - 2))
- terminal.write(self._up.encode('utf-8'))
- for i in xrange(1, height - 1):
- terminal.cursorPosition(0, i)
- if i != (knob + 1):
- terminal.write(self._bar.encode('utf-8'))
- else:
- terminal.write(self._slider.encode('utf-8'))
- terminal.cursorPosition(0, height - 1)
- terminal.write(self._down.encode('utf-8'))
-
-
-class ScrolledArea(Widget):
- """
- A L{ScrolledArea} contains another widget wrapped in a viewport and
- vertical and horizontal scrollbars for moving the viewport around.
- """
- def __init__(self, containee):
- Widget.__init__(self)
- self._viewport = Viewport(containee)
- self._horiz = HorizontalScrollbar(self._horizScroll)
- self._vert = VerticalScrollbar(self._vertScroll)
-
- for w in self._viewport, self._horiz, self._vert:
- w.parent = self
-
- def _horizScroll(self, n):
- self._viewport.xOffset += n
- self._viewport.xOffset = max(0, self._viewport.xOffset)
- return self._viewport.xOffset / 25.0
-
- def _vertScroll(self, n):
- self._viewport.yOffset += n
- self._viewport.yOffset = max(0, self._viewport.yOffset)
- return self._viewport.yOffset / 25.0
-
- def func_UP_ARROW(self, modifier):
- self._vert.smaller()
-
- def func_DOWN_ARROW(self, modifier):
- self._vert.bigger()
-
- def func_LEFT_ARROW(self, modifier):
- self._horiz.smaller()
-
- def func_RIGHT_ARROW(self, modifier):
- self._horiz.bigger()
-
- def filthy(self):
- self._viewport.filthy()
- self._horiz.filthy()
- self._vert.filthy()
- Widget.filthy(self)
-
- def render(self, width, height, terminal):
- wrapper = BoundedTerminalWrapper(terminal, width - 2, height - 2, 1, 1)
- self._viewport.draw(width - 2, height - 2, wrapper)
- if self.focused:
- terminal.write('\x1b[31m')
- horizontalLine(terminal, 0, 1, width - 1)
- verticalLine(terminal, 0, 1, height - 1)
- self._vert.draw(1, height - 1, BoundedTerminalWrapper(terminal, 1, height - 1, width - 1, 0))
- self._horiz.draw(width, 1, BoundedTerminalWrapper(terminal, width, 1, 0, height - 1))
- terminal.write('\x1b[0m')
-
-def cursor(terminal, ch):
- terminal.saveCursor()
- terminal.selectGraphicRendition(str(insults.REVERSE_VIDEO))
- terminal.write(ch)
- terminal.restoreCursor()
- terminal.cursorForward()
-
-class Selection(Widget):
- # Index into the sequence
- focusedIndex = 0
-
- # Offset into the displayed subset of the sequence
- renderOffset = 0
-
- def __init__(self, sequence, onSelect, minVisible=None):
- Widget.__init__(self)
- self.sequence = sequence
- self.onSelect = onSelect
- self.minVisible = minVisible
- if minVisible is not None:
- self._width = max(map(len, self.sequence))
-
- def sizeHint(self):
- if self.minVisible is not None:
- return self._width, self.minVisible
-
- def func_UP_ARROW(self, modifier):
- if self.focusedIndex > 0:
- self.focusedIndex -= 1
- if self.renderOffset > 0:
- self.renderOffset -= 1
- self.repaint()
-
- def func_PGUP(self, modifier):
- if self.renderOffset != 0:
- self.focusedIndex -= self.renderOffset
- self.renderOffset = 0
- else:
- self.focusedIndex = max(0, self.focusedIndex - self.height)
- self.repaint()
-
- def func_DOWN_ARROW(self, modifier):
- if self.focusedIndex < len(self.sequence) - 1:
- self.focusedIndex += 1
- if self.renderOffset < self.height - 1:
- self.renderOffset += 1
- self.repaint()
-
-
- def func_PGDN(self, modifier):
- if self.renderOffset != self.height - 1:
- change = self.height - self.renderOffset - 1
- if change + self.focusedIndex >= len(self.sequence):
- change = len(self.sequence) - self.focusedIndex - 1
- self.focusedIndex += change
- self.renderOffset = self.height - 1
- else:
- self.focusedIndex = min(len(self.sequence) - 1, self.focusedIndex + self.height)
- self.repaint()
-
- def characterReceived(self, keyID, modifier):
- if keyID == '\r':
- self.onSelect(self.sequence[self.focusedIndex])
-
- def render(self, width, height, terminal):
- self.height = height
- start = self.focusedIndex - self.renderOffset
- if start > len(self.sequence) - height:
- start = max(0, len(self.sequence) - height)
-
- elements = self.sequence[start:start+height]
-
- for n, ele in enumerate(elements):
- terminal.cursorPosition(0, n)
- if n == self.renderOffset:
- terminal.saveCursor()
- if self.focused:
- modes = str(insults.REVERSE_VIDEO), str(insults.BOLD)
- else:
- modes = str(insults.REVERSE_VIDEO),
- terminal.selectGraphicRendition(*modes)
- text = ele[:width]
- terminal.write(text + (' ' * (width - len(text))))
- if n == self.renderOffset:
- terminal.restoreCursor()