[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / lldb / third_party / Python / module / pexpect-4.6 / pexpect / screen.py
blob5ab45b946795bec5c9f010cf6242bfb80bc7d29c
1 '''This implements a virtual screen. This is used to support ANSI terminal
2 emulation. The screen representation and state is implemented in this class.
3 Most of the methods are inspired by ANSI screen control codes. The
4 :class:`~pexpect.ANSI.ANSI` class extends this class to add parsing of ANSI
5 escape codes.
7 PEXPECT LICENSE
9 This license is approved by the OSI and FSF as GPL-compatible.
10 http://opensource.org/licenses/isc-license.txt
12 Copyright (c) 2012, Noah Spurrier <noah@noah.org>
13 PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY
14 PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE
15 COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES.
16 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
17 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
18 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
19 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
22 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 '''
26 import codecs
27 import copy
28 import sys
30 import warnings
32 warnings.warn(("pexpect.screen and pexpect.ANSI are deprecated. "
33 "We recommend using pyte to emulate a terminal screen: "
34 "https://pypi.python.org/pypi/pyte"),
35 stacklevel=2)
37 NUL = 0 # Fill character; ignored on input.
38 ENQ = 5 # Transmit answerback message.
39 BEL = 7 # Ring the bell.
40 BS = 8 # Move cursor left.
41 HT = 9 # Move cursor to next tab stop.
42 LF = 10 # Line feed.
43 VT = 11 # Same as LF.
44 FF = 12 # Same as LF.
45 CR = 13 # Move cursor to left margin or newline.
46 SO = 14 # Invoke G1 character set.
47 SI = 15 # Invoke G0 character set.
48 XON = 17 # Resume transmission.
49 XOFF = 19 # Halt transmission.
50 CAN = 24 # Cancel escape sequence.
51 SUB = 26 # Same as CAN.
52 ESC = 27 # Introduce a control sequence.
53 DEL = 127 # Fill character; ignored on input.
54 SPACE = u' ' # Space or blank character.
56 PY3 = (sys.version_info[0] >= 3)
57 if PY3:
58 unicode = str
60 def constrain (n, min, max):
62 '''This returns a number, n constrained to the min and max bounds. '''
64 if n < min:
65 return min
66 if n > max:
67 return max
68 return n
70 class screen:
71 '''This object maintains the state of a virtual text screen as a
72 rectangular array. This maintains a virtual cursor position and handles
73 scrolling as characters are added. This supports most of the methods needed
74 by an ANSI text screen. Row and column indexes are 1-based (not zero-based,
75 like arrays).
77 Characters are represented internally using unicode. Methods that accept
78 input characters, when passed 'bytes' (which in Python 2 is equivalent to
79 'str'), convert them from the encoding specified in the 'encoding'
80 parameter to the constructor. Methods that return screen contents return
81 unicode strings, with the exception of __str__() under Python 2. Passing
82 ``encoding=None`` limits the API to only accept unicode input, so passing
83 bytes in will raise :exc:`TypeError`.
84 '''
85 def __init__(self, r=24, c=80, encoding='latin-1', encoding_errors='replace'):
86 '''This initializes a blank screen of the given dimensions.'''
88 self.rows = r
89 self.cols = c
90 self.encoding = encoding
91 self.encoding_errors = encoding_errors
92 if encoding is not None:
93 self.decoder = codecs.getincrementaldecoder(encoding)(encoding_errors)
94 else:
95 self.decoder = None
96 self.cur_r = 1
97 self.cur_c = 1
98 self.cur_saved_r = 1
99 self.cur_saved_c = 1
100 self.scroll_row_start = 1
101 self.scroll_row_end = self.rows
102 self.w = [ [SPACE] * self.cols for _ in range(self.rows)]
104 def _decode(self, s):
105 '''This converts from the external coding system (as passed to
106 the constructor) to the internal one (unicode). '''
107 if self.decoder is not None:
108 return self.decoder.decode(s)
109 else:
110 raise TypeError("This screen was constructed with encoding=None, "
111 "so it does not handle bytes.")
113 def _unicode(self):
114 '''This returns a printable representation of the screen as a unicode
115 string (which, under Python 3.x, is the same as 'str'). The end of each
116 screen line is terminated by a newline.'''
118 return u'\n'.join ([ u''.join(c) for c in self.w ])
120 if PY3:
121 __str__ = _unicode
122 else:
123 __unicode__ = _unicode
125 def __str__(self):
126 '''This returns a printable representation of the screen. The end of
127 each screen line is terminated by a newline. '''
128 encoding = self.encoding or 'ascii'
129 return self._unicode().encode(encoding, 'replace')
131 def dump (self):
132 '''This returns a copy of the screen as a unicode string. This is similar to
133 __str__/__unicode__ except that lines are not terminated with line
134 feeds.'''
136 return u''.join ([ u''.join(c) for c in self.w ])
138 def pretty (self):
139 '''This returns a copy of the screen as a unicode string with an ASCII
140 text box around the screen border. This is similar to
141 __str__/__unicode__ except that it adds a box.'''
143 top_bot = u'+' + u'-'*self.cols + u'+\n'
144 return top_bot + u'\n'.join([u'|'+line+u'|' for line in unicode(self).split(u'\n')]) + u'\n' + top_bot
146 def fill (self, ch=SPACE):
148 if isinstance(ch, bytes):
149 ch = self._decode(ch)
151 self.fill_region (1,1,self.rows,self.cols, ch)
153 def fill_region (self, rs,cs, re,ce, ch=SPACE):
155 if isinstance(ch, bytes):
156 ch = self._decode(ch)
158 rs = constrain (rs, 1, self.rows)
159 re = constrain (re, 1, self.rows)
160 cs = constrain (cs, 1, self.cols)
161 ce = constrain (ce, 1, self.cols)
162 if rs > re:
163 rs, re = re, rs
164 if cs > ce:
165 cs, ce = ce, cs
166 for r in range (rs, re+1):
167 for c in range (cs, ce + 1):
168 self.put_abs (r,c,ch)
170 def cr (self):
171 '''This moves the cursor to the beginning (col 1) of the current row.
174 self.cursor_home (self.cur_r, 1)
176 def lf (self):
177 '''This moves the cursor down with scrolling.
180 old_r = self.cur_r
181 self.cursor_down()
182 if old_r == self.cur_r:
183 self.scroll_up ()
184 self.erase_line()
186 def crlf (self):
187 '''This advances the cursor with CRLF properties.
188 The cursor will line wrap and the screen may scroll.
191 self.cr ()
192 self.lf ()
194 def newline (self):
195 '''This is an alias for crlf().
198 self.crlf()
200 def put_abs (self, r, c, ch):
201 '''Screen array starts at 1 index.'''
203 r = constrain (r, 1, self.rows)
204 c = constrain (c, 1, self.cols)
205 if isinstance(ch, bytes):
206 ch = self._decode(ch)[0]
207 else:
208 ch = ch[0]
209 self.w[r-1][c-1] = ch
211 def put (self, ch):
212 '''This puts a characters at the current cursor position.
215 if isinstance(ch, bytes):
216 ch = self._decode(ch)
218 self.put_abs (self.cur_r, self.cur_c, ch)
220 def insert_abs (self, r, c, ch):
221 '''This inserts a character at (r,c). Everything under
222 and to the right is shifted right one character.
223 The last character of the line is lost.
226 if isinstance(ch, bytes):
227 ch = self._decode(ch)
229 r = constrain (r, 1, self.rows)
230 c = constrain (c, 1, self.cols)
231 for ci in range (self.cols, c, -1):
232 self.put_abs (r,ci, self.get_abs(r,ci-1))
233 self.put_abs (r,c,ch)
235 def insert (self, ch):
237 if isinstance(ch, bytes):
238 ch = self._decode(ch)
240 self.insert_abs (self.cur_r, self.cur_c, ch)
242 def get_abs (self, r, c):
244 r = constrain (r, 1, self.rows)
245 c = constrain (c, 1, self.cols)
246 return self.w[r-1][c-1]
248 def get (self):
250 self.get_abs (self.cur_r, self.cur_c)
252 def get_region (self, rs,cs, re,ce):
253 '''This returns a list of lines representing the region.
256 rs = constrain (rs, 1, self.rows)
257 re = constrain (re, 1, self.rows)
258 cs = constrain (cs, 1, self.cols)
259 ce = constrain (ce, 1, self.cols)
260 if rs > re:
261 rs, re = re, rs
262 if cs > ce:
263 cs, ce = ce, cs
264 sc = []
265 for r in range (rs, re+1):
266 line = u''
267 for c in range (cs, ce + 1):
268 ch = self.get_abs (r,c)
269 line = line + ch
270 sc.append (line)
271 return sc
273 def cursor_constrain (self):
274 '''This keeps the cursor within the screen area.
277 self.cur_r = constrain (self.cur_r, 1, self.rows)
278 self.cur_c = constrain (self.cur_c, 1, self.cols)
280 def cursor_home (self, r=1, c=1): # <ESC>[{ROW};{COLUMN}H
282 self.cur_r = r
283 self.cur_c = c
284 self.cursor_constrain ()
286 def cursor_back (self,count=1): # <ESC>[{COUNT}D (not confused with down)
288 self.cur_c = self.cur_c - count
289 self.cursor_constrain ()
291 def cursor_down (self,count=1): # <ESC>[{COUNT}B (not confused with back)
293 self.cur_r = self.cur_r + count
294 self.cursor_constrain ()
296 def cursor_forward (self,count=1): # <ESC>[{COUNT}C
298 self.cur_c = self.cur_c + count
299 self.cursor_constrain ()
301 def cursor_up (self,count=1): # <ESC>[{COUNT}A
303 self.cur_r = self.cur_r - count
304 self.cursor_constrain ()
306 def cursor_up_reverse (self): # <ESC> M (called RI -- Reverse Index)
308 old_r = self.cur_r
309 self.cursor_up()
310 if old_r == self.cur_r:
311 self.scroll_up()
313 def cursor_force_position (self, r, c): # <ESC>[{ROW};{COLUMN}f
314 '''Identical to Cursor Home.'''
316 self.cursor_home (r, c)
318 def cursor_save (self): # <ESC>[s
319 '''Save current cursor position.'''
321 self.cursor_save_attrs()
323 def cursor_unsave (self): # <ESC>[u
324 '''Restores cursor position after a Save Cursor.'''
326 self.cursor_restore_attrs()
328 def cursor_save_attrs (self): # <ESC>7
329 '''Save current cursor position.'''
331 self.cur_saved_r = self.cur_r
332 self.cur_saved_c = self.cur_c
334 def cursor_restore_attrs (self): # <ESC>8
335 '''Restores cursor position after a Save Cursor.'''
337 self.cursor_home (self.cur_saved_r, self.cur_saved_c)
339 def scroll_constrain (self):
340 '''This keeps the scroll region within the screen region.'''
342 if self.scroll_row_start <= 0:
343 self.scroll_row_start = 1
344 if self.scroll_row_end > self.rows:
345 self.scroll_row_end = self.rows
347 def scroll_screen (self): # <ESC>[r
348 '''Enable scrolling for entire display.'''
350 self.scroll_row_start = 1
351 self.scroll_row_end = self.rows
353 def scroll_screen_rows (self, rs, re): # <ESC>[{start};{end}r
354 '''Enable scrolling from row {start} to row {end}.'''
356 self.scroll_row_start = rs
357 self.scroll_row_end = re
358 self.scroll_constrain()
360 def scroll_down (self): # <ESC>D
361 '''Scroll display down one line.'''
363 # Screen is indexed from 1, but arrays are indexed from 0.
364 s = self.scroll_row_start - 1
365 e = self.scroll_row_end - 1
366 self.w[s+1:e+1] = copy.deepcopy(self.w[s:e])
368 def scroll_up (self): # <ESC>M
369 '''Scroll display up one line.'''
371 # Screen is indexed from 1, but arrays are indexed from 0.
372 s = self.scroll_row_start - 1
373 e = self.scroll_row_end - 1
374 self.w[s:e] = copy.deepcopy(self.w[s+1:e+1])
376 def erase_end_of_line (self): # <ESC>[0K -or- <ESC>[K
377 '''Erases from the current cursor position to the end of the current
378 line.'''
380 self.fill_region (self.cur_r, self.cur_c, self.cur_r, self.cols)
382 def erase_start_of_line (self): # <ESC>[1K
383 '''Erases from the current cursor position to the start of the current
384 line.'''
386 self.fill_region (self.cur_r, 1, self.cur_r, self.cur_c)
388 def erase_line (self): # <ESC>[2K
389 '''Erases the entire current line.'''
391 self.fill_region (self.cur_r, 1, self.cur_r, self.cols)
393 def erase_down (self): # <ESC>[0J -or- <ESC>[J
394 '''Erases the screen from the current line down to the bottom of the
395 screen.'''
397 self.erase_end_of_line ()
398 self.fill_region (self.cur_r + 1, 1, self.rows, self.cols)
400 def erase_up (self): # <ESC>[1J
401 '''Erases the screen from the current line up to the top of the
402 screen.'''
404 self.erase_start_of_line ()
405 self.fill_region (self.cur_r-1, 1, 1, self.cols)
407 def erase_screen (self): # <ESC>[2J
408 '''Erases the screen with the background color.'''
410 self.fill ()
412 def set_tab (self): # <ESC>H
413 '''Sets a tab at the current position.'''
415 pass
417 def clear_tab (self): # <ESC>[g
418 '''Clears tab at the current position.'''
420 pass
422 def clear_all_tabs (self): # <ESC>[3g
423 '''Clears all tabs.'''
425 pass
427 # Insert line Esc [ Pn L
428 # Delete line Esc [ Pn M
429 # Delete character Esc [ Pn P
430 # Scrolling region Esc [ Pn(top);Pn(bot) r