diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2016-01-06 20:12:03 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2016-01-06 20:12:03 +0000 | 
| commit | 9e6d35490a6542f9c97607f93c2ef8ca8e03cbcc (patch) | |
| tree | dd2a1ddf0476664c2b823409c36cbccd52662ca7 /third_party/Python/module/pexpect-2.4/screen.py | |
| parent | 3bd2e91faeb9eeec1aae82c64a3253afff551cfd (diff) | |
Notes
Diffstat (limited to 'third_party/Python/module/pexpect-2.4/screen.py')
| -rw-r--r-- | third_party/Python/module/pexpect-2.4/screen.py | 380 | 
1 files changed, 380 insertions, 0 deletions
| diff --git a/third_party/Python/module/pexpect-2.4/screen.py b/third_party/Python/module/pexpect-2.4/screen.py new file mode 100644 index 000000000000..13699f93b5b5 --- /dev/null +++ b/third_party/Python/module/pexpect-2.4/screen.py @@ -0,0 +1,380 @@ +"""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 ANSI class +extends this class to add parsing of ANSI escape codes. + +$Id: screen.py 486 2007-07-13 01:04:16Z noah $ +""" + +import copy + +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 = chr(32) # Space or blank character. + +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 +    rectangluar 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). """ + +    def __init__ (self, r=24,c=80): + +        """This initializes a blank scree of the given dimentions.""" + +        self.rows = r +        self.cols = c +        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 c in range(self.rows)] + +    def __str__ (self): + +        """This returns a printable representation of the screen. The end of +        each screen line is terminated by a newline. """ + +        return '\n'.join ([ ''.join(c) for c in self.w ]) + +    def dump (self): + +        """This returns a copy of the screen as a string. This is similar to +        __str__ except that lines are not terminated with line feeds. """ + +        return ''.join ([ ''.join(c) for c in self.w ]) + +    def pretty (self): + +        """This returns a copy of the screen as a string with an ASCII text box +        around the screen border. This is similar to __str__ except that it +        adds a box. """ + +        top_bot = '+' + '-'*self.cols + '+\n' +        return top_bot + '\n'.join(['|'+line+'|' for line in str(self).split('\n')]) + '\n' + top_bot + +    def fill (self, ch=SPACE): + +        self.fill_region (1,1,self.rows,self.cols, ch) + +    def fill_region (self, rs,cs, re,ce, ch=SPACE): + +        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) +        ch = str(ch)[0] +        self.w[r-1][c-1] = ch + +    def put (self, ch): + +        """This puts a characters at the current cursor position. +        """ + +        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. +        """ + +        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): + +        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 = '' +            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 + | 
