Add venv
This commit is contained in:
431
venv/lib/python3.6/site-packages/pexpect/screen.py
Normal file
431
venv/lib/python3.6/site-packages/pexpect/screen.py
Normal file
@@ -0,0 +1,431 @@
|
||||
'''This implements a virtual screen. This is used to support ANSI terminal
|
||||
emulation. The screen representation and state is implemented in this class.
|
||||
Most of the methods are inspired by ANSI screen control codes. The
|
||||
:class:`~pexpect.ANSI.ANSI` class extends this class to add parsing of ANSI
|
||||
escape codes.
|
||||
|
||||
PEXPECT LICENSE
|
||||
|
||||
This license is approved by the OSI and FSF as GPL-compatible.
|
||||
http://opensource.org/licenses/isc-license.txt
|
||||
|
||||
Copyright (c) 2012, Noah Spurrier <noah@noah.org>
|
||||
PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY
|
||||
PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE
|
||||
COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES.
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
'''
|
||||
|
||||
import codecs
|
||||
import copy
|
||||
import sys
|
||||
|
||||
import warnings
|
||||
|
||||
warnings.warn(("pexpect.screen and pexpect.ANSI are deprecated. "
|
||||
"We recommend using pyte to emulate a terminal screen: "
|
||||
"https://pypi.python.org/pypi/pyte"),
|
||||
stacklevel=2)
|
||||
|
||||
NUL = 0 # Fill character; ignored on input.
|
||||
ENQ = 5 # Transmit answerback message.
|
||||
BEL = 7 # Ring the bell.
|
||||
BS = 8 # Move cursor left.
|
||||
HT = 9 # Move cursor to next tab stop.
|
||||
LF = 10 # Line feed.
|
||||
VT = 11 # Same as LF.
|
||||
FF = 12 # Same as LF.
|
||||
CR = 13 # Move cursor to left margin or newline.
|
||||
SO = 14 # Invoke G1 character set.
|
||||
SI = 15 # Invoke G0 character set.
|
||||
XON = 17 # Resume transmission.
|
||||
XOFF = 19 # Halt transmission.
|
||||
CAN = 24 # Cancel escape sequence.
|
||||
SUB = 26 # Same as CAN.
|
||||
ESC = 27 # Introduce a control sequence.
|
||||
DEL = 127 # Fill character; ignored on input.
|
||||
SPACE = u' ' # Space or blank character.
|
||||
|
||||
PY3 = (sys.version_info[0] >= 3)
|
||||
if PY3:
|
||||
unicode = str
|
||||
|
||||
def constrain (n, min, max):
|
||||
|
||||
'''This returns a number, n constrained to the min and max bounds. '''
|
||||
|
||||
if n < min:
|
||||
return min
|
||||
if n > max:
|
||||
return max
|
||||
return n
|
||||
|
||||
class screen:
|
||||
'''This object maintains the state of a virtual text screen as a
|
||||
rectangular array. This maintains a virtual cursor position and handles
|
||||
scrolling as characters are added. This supports most of the methods needed
|
||||
by an ANSI text screen. Row and column indexes are 1-based (not zero-based,
|
||||
like arrays).
|
||||
|
||||
Characters are represented internally using unicode. Methods that accept
|
||||
input characters, when passed 'bytes' (which in Python 2 is equivalent to
|
||||
'str'), convert them from the encoding specified in the 'encoding'
|
||||
parameter to the constructor. Methods that return screen contents return
|
||||
unicode strings, with the exception of __str__() under Python 2. Passing
|
||||
``encoding=None`` limits the API to only accept unicode input, so passing
|
||||
bytes in will raise :exc:`TypeError`.
|
||||
'''
|
||||
def __init__(self, r=24, c=80, encoding='latin-1', encoding_errors='replace'):
|
||||
'''This initializes a blank screen of the given dimensions.'''
|
||||
|
||||
self.rows = r
|
||||
self.cols = c
|
||||
self.encoding = encoding
|
||||
self.encoding_errors = encoding_errors
|
||||
if encoding is not None:
|
||||
self.decoder = codecs.getincrementaldecoder(encoding)(encoding_errors)
|
||||
else:
|
||||
self.decoder = None
|
||||
self.cur_r = 1
|
||||
self.cur_c = 1
|
||||
self.cur_saved_r = 1
|
||||
self.cur_saved_c = 1
|
||||
self.scroll_row_start = 1
|
||||
self.scroll_row_end = self.rows
|
||||
self.w = [ [SPACE] * self.cols for _ in range(self.rows)]
|
||||
|
||||
def _decode(self, s):
|
||||
'''This converts from the external coding system (as passed to
|
||||
the constructor) to the internal one (unicode). '''
|
||||
if self.decoder is not None:
|
||||
return self.decoder.decode(s)
|
||||
else:
|
||||
raise TypeError("This screen was constructed with encoding=None, "
|
||||
"so it does not handle bytes.")
|
||||
|
||||
def _unicode(self):
|
||||
'''This returns a printable representation of the screen as a unicode
|
||||
string (which, under Python 3.x, is the same as 'str'). The end of each
|
||||
screen line is terminated by a newline.'''
|
||||
|
||||
return u'\n'.join ([ u''.join(c) for c in self.w ])
|
||||
|
||||
if PY3:
|
||||
__str__ = _unicode
|
||||
else:
|
||||
__unicode__ = _unicode
|
||||
|
||||
def __str__(self):
|
||||
'''This returns a printable representation of the screen. The end of
|
||||
each screen line is terminated by a newline. '''
|
||||
encoding = self.encoding or 'ascii'
|
||||
return self._unicode().encode(encoding, 'replace')
|
||||
|
||||
def dump (self):
|
||||
'''This returns a copy of the screen as a unicode string. This is similar to
|
||||
__str__/__unicode__ except that lines are not terminated with line
|
||||
feeds.'''
|
||||
|
||||
return u''.join ([ u''.join(c) for c in self.w ])
|
||||
|
||||
def pretty (self):
|
||||
'''This returns a copy of the screen as a unicode string with an ASCII
|
||||
text box around the screen border. This is similar to
|
||||
__str__/__unicode__ except that it adds a box.'''
|
||||
|
||||
top_bot = u'+' + u'-'*self.cols + u'+\n'
|
||||
return top_bot + u'\n'.join([u'|'+line+u'|' for line in unicode(self).split(u'\n')]) + u'\n' + top_bot
|
||||
|
||||
def fill (self, ch=SPACE):
|
||||
|
||||
if isinstance(ch, bytes):
|
||||
ch = self._decode(ch)
|
||||
|
||||
self.fill_region (1,1,self.rows,self.cols, ch)
|
||||
|
||||
def fill_region (self, rs,cs, re,ce, ch=SPACE):
|
||||
|
||||
if isinstance(ch, bytes):
|
||||
ch = self._decode(ch)
|
||||
|
||||
rs = constrain (rs, 1, self.rows)
|
||||
re = constrain (re, 1, self.rows)
|
||||
cs = constrain (cs, 1, self.cols)
|
||||
ce = constrain (ce, 1, self.cols)
|
||||
if rs > re:
|
||||
rs, re = re, rs
|
||||
if cs > ce:
|
||||
cs, ce = ce, cs
|
||||
for r in range (rs, re+1):
|
||||
for c in range (cs, ce + 1):
|
||||
self.put_abs (r,c,ch)
|
||||
|
||||
def cr (self):
|
||||
'''This moves the cursor to the beginning (col 1) of the current row.
|
||||
'''
|
||||
|
||||
self.cursor_home (self.cur_r, 1)
|
||||
|
||||
def lf (self):
|
||||
'''This moves the cursor down with scrolling.
|
||||
'''
|
||||
|
||||
old_r = self.cur_r
|
||||
self.cursor_down()
|
||||
if old_r == self.cur_r:
|
||||
self.scroll_up ()
|
||||
self.erase_line()
|
||||
|
||||
def crlf (self):
|
||||
'''This advances the cursor with CRLF properties.
|
||||
The cursor will line wrap and the screen may scroll.
|
||||
'''
|
||||
|
||||
self.cr ()
|
||||
self.lf ()
|
||||
|
||||
def newline (self):
|
||||
'''This is an alias for crlf().
|
||||
'''
|
||||
|
||||
self.crlf()
|
||||
|
||||
def put_abs (self, r, c, ch):
|
||||
'''Screen array starts at 1 index.'''
|
||||
|
||||
r = constrain (r, 1, self.rows)
|
||||
c = constrain (c, 1, self.cols)
|
||||
if isinstance(ch, bytes):
|
||||
ch = self._decode(ch)[0]
|
||||
else:
|
||||
ch = ch[0]
|
||||
self.w[r-1][c-1] = ch
|
||||
|
||||
def put (self, ch):
|
||||
'''This puts a characters at the current cursor position.
|
||||
'''
|
||||
|
||||
if isinstance(ch, bytes):
|
||||
ch = self._decode(ch)
|
||||
|
||||
self.put_abs (self.cur_r, self.cur_c, ch)
|
||||
|
||||
def insert_abs (self, r, c, ch):
|
||||
'''This inserts a character at (r,c). Everything under
|
||||
and to the right is shifted right one character.
|
||||
The last character of the line is lost.
|
||||
'''
|
||||
|
||||
if isinstance(ch, bytes):
|
||||
ch = self._decode(ch)
|
||||
|
||||
r = constrain (r, 1, self.rows)
|
||||
c = constrain (c, 1, self.cols)
|
||||
for ci in range (self.cols, c, -1):
|
||||
self.put_abs (r,ci, self.get_abs(r,ci-1))
|
||||
self.put_abs (r,c,ch)
|
||||
|
||||
def insert (self, ch):
|
||||
|
||||
if isinstance(ch, bytes):
|
||||
ch = self._decode(ch)
|
||||
|
||||
self.insert_abs (self.cur_r, self.cur_c, ch)
|
||||
|
||||
def get_abs (self, r, c):
|
||||
|
||||
r = constrain (r, 1, self.rows)
|
||||
c = constrain (c, 1, self.cols)
|
||||
return self.w[r-1][c-1]
|
||||
|
||||
def get (self):
|
||||
|
||||
self.get_abs (self.cur_r, self.cur_c)
|
||||
|
||||
def get_region (self, rs,cs, re,ce):
|
||||
'''This returns a list of lines representing the region.
|
||||
'''
|
||||
|
||||
rs = constrain (rs, 1, self.rows)
|
||||
re = constrain (re, 1, self.rows)
|
||||
cs = constrain (cs, 1, self.cols)
|
||||
ce = constrain (ce, 1, self.cols)
|
||||
if rs > re:
|
||||
rs, re = re, rs
|
||||
if cs > ce:
|
||||
cs, ce = ce, cs
|
||||
sc = []
|
||||
for r in range (rs, re+1):
|
||||
line = u''
|
||||
for c in range (cs, ce + 1):
|
||||
ch = self.get_abs (r,c)
|
||||
line = line + ch
|
||||
sc.append (line)
|
||||
return sc
|
||||
|
||||
def cursor_constrain (self):
|
||||
'''This keeps the cursor within the screen area.
|
||||
'''
|
||||
|
||||
self.cur_r = constrain (self.cur_r, 1, self.rows)
|
||||
self.cur_c = constrain (self.cur_c, 1, self.cols)
|
||||
|
||||
def cursor_home (self, r=1, c=1): # <ESC>[{ROW};{COLUMN}H
|
||||
|
||||
self.cur_r = r
|
||||
self.cur_c = c
|
||||
self.cursor_constrain ()
|
||||
|
||||
def cursor_back (self,count=1): # <ESC>[{COUNT}D (not confused with down)
|
||||
|
||||
self.cur_c = self.cur_c - count
|
||||
self.cursor_constrain ()
|
||||
|
||||
def cursor_down (self,count=1): # <ESC>[{COUNT}B (not confused with back)
|
||||
|
||||
self.cur_r = self.cur_r + count
|
||||
self.cursor_constrain ()
|
||||
|
||||
def cursor_forward (self,count=1): # <ESC>[{COUNT}C
|
||||
|
||||
self.cur_c = self.cur_c + count
|
||||
self.cursor_constrain ()
|
||||
|
||||
def cursor_up (self,count=1): # <ESC>[{COUNT}A
|
||||
|
||||
self.cur_r = self.cur_r - count
|
||||
self.cursor_constrain ()
|
||||
|
||||
def cursor_up_reverse (self): # <ESC> M (called RI -- Reverse Index)
|
||||
|
||||
old_r = self.cur_r
|
||||
self.cursor_up()
|
||||
if old_r == self.cur_r:
|
||||
self.scroll_up()
|
||||
|
||||
def cursor_force_position (self, r, c): # <ESC>[{ROW};{COLUMN}f
|
||||
'''Identical to Cursor Home.'''
|
||||
|
||||
self.cursor_home (r, c)
|
||||
|
||||
def cursor_save (self): # <ESC>[s
|
||||
'''Save current cursor position.'''
|
||||
|
||||
self.cursor_save_attrs()
|
||||
|
||||
def cursor_unsave (self): # <ESC>[u
|
||||
'''Restores cursor position after a Save Cursor.'''
|
||||
|
||||
self.cursor_restore_attrs()
|
||||
|
||||
def cursor_save_attrs (self): # <ESC>7
|
||||
'''Save current cursor position.'''
|
||||
|
||||
self.cur_saved_r = self.cur_r
|
||||
self.cur_saved_c = self.cur_c
|
||||
|
||||
def cursor_restore_attrs (self): # <ESC>8
|
||||
'''Restores cursor position after a Save Cursor.'''
|
||||
|
||||
self.cursor_home (self.cur_saved_r, self.cur_saved_c)
|
||||
|
||||
def scroll_constrain (self):
|
||||
'''This keeps the scroll region within the screen region.'''
|
||||
|
||||
if self.scroll_row_start <= 0:
|
||||
self.scroll_row_start = 1
|
||||
if self.scroll_row_end > self.rows:
|
||||
self.scroll_row_end = self.rows
|
||||
|
||||
def scroll_screen (self): # <ESC>[r
|
||||
'''Enable scrolling for entire display.'''
|
||||
|
||||
self.scroll_row_start = 1
|
||||
self.scroll_row_end = self.rows
|
||||
|
||||
def scroll_screen_rows (self, rs, re): # <ESC>[{start};{end}r
|
||||
'''Enable scrolling from row {start} to row {end}.'''
|
||||
|
||||
self.scroll_row_start = rs
|
||||
self.scroll_row_end = re
|
||||
self.scroll_constrain()
|
||||
|
||||
def scroll_down (self): # <ESC>D
|
||||
'''Scroll display down one line.'''
|
||||
|
||||
# Screen is indexed from 1, but arrays are indexed from 0.
|
||||
s = self.scroll_row_start - 1
|
||||
e = self.scroll_row_end - 1
|
||||
self.w[s+1:e+1] = copy.deepcopy(self.w[s:e])
|
||||
|
||||
def scroll_up (self): # <ESC>M
|
||||
'''Scroll display up one line.'''
|
||||
|
||||
# Screen is indexed from 1, but arrays are indexed from 0.
|
||||
s = self.scroll_row_start - 1
|
||||
e = self.scroll_row_end - 1
|
||||
self.w[s:e] = copy.deepcopy(self.w[s+1:e+1])
|
||||
|
||||
def erase_end_of_line (self): # <ESC>[0K -or- <ESC>[K
|
||||
'''Erases from the current cursor position to the end of the current
|
||||
line.'''
|
||||
|
||||
self.fill_region (self.cur_r, self.cur_c, self.cur_r, self.cols)
|
||||
|
||||
def erase_start_of_line (self): # <ESC>[1K
|
||||
'''Erases from the current cursor position to the start of the current
|
||||
line.'''
|
||||
|
||||
self.fill_region (self.cur_r, 1, self.cur_r, self.cur_c)
|
||||
|
||||
def erase_line (self): # <ESC>[2K
|
||||
'''Erases the entire current line.'''
|
||||
|
||||
self.fill_region (self.cur_r, 1, self.cur_r, self.cols)
|
||||
|
||||
def erase_down (self): # <ESC>[0J -or- <ESC>[J
|
||||
'''Erases the screen from the current line down to the bottom of the
|
||||
screen.'''
|
||||
|
||||
self.erase_end_of_line ()
|
||||
self.fill_region (self.cur_r + 1, 1, self.rows, self.cols)
|
||||
|
||||
def erase_up (self): # <ESC>[1J
|
||||
'''Erases the screen from the current line up to the top of the
|
||||
screen.'''
|
||||
|
||||
self.erase_start_of_line ()
|
||||
self.fill_region (self.cur_r-1, 1, 1, self.cols)
|
||||
|
||||
def erase_screen (self): # <ESC>[2J
|
||||
'''Erases the screen with the background color.'''
|
||||
|
||||
self.fill ()
|
||||
|
||||
def set_tab (self): # <ESC>H
|
||||
'''Sets a tab at the current position.'''
|
||||
|
||||
pass
|
||||
|
||||
def clear_tab (self): # <ESC>[g
|
||||
'''Clears tab at the current position.'''
|
||||
|
||||
pass
|
||||
|
||||
def clear_all_tabs (self): # <ESC>[3g
|
||||
'''Clears all tabs.'''
|
||||
|
||||
pass
|
||||
|
||||
# Insert line Esc [ Pn L
|
||||
# Delete line Esc [ Pn M
|
||||
# Delete character Esc [ Pn P
|
||||
# Scrolling region Esc [ Pn(top);Pn(bot) r
|
||||
|
Reference in New Issue
Block a user