Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(322)

Side by Side Diff: third_party/pexpect/screen.py

Issue 11142035: Add pexpect-2.3 to third_party (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: +MIT whitelist for checklicenses on pexpect Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 ANSI class
4 extends this class to add parsing of ANSI escape codes.
5
6 $Id: screen.py 486 2007-07-13 01:04:16Z noah $
7 """
8
9 import copy
10
11 NUL = 0 # Fill character; ignored on input.
12 ENQ = 5 # Transmit answerback message.
13 BEL = 7 # Ring the bell.
14 BS = 8 # Move cursor left.
15 HT = 9 # Move cursor to next tab stop.
16 LF = 10 # Line feed.
17 VT = 11 # Same as LF.
18 FF = 12 # Same as LF.
19 CR = 13 # Move cursor to left margin or newline.
20 SO = 14 # Invoke G1 character set.
21 SI = 15 # Invoke G0 character set.
22 XON = 17 # Resume transmission.
23 XOFF = 19 # Halt transmission.
24 CAN = 24 # Cancel escape sequence.
25 SUB = 26 # Same as CAN.
26 ESC = 27 # Introduce a control sequence.
27 DEL = 127 # Fill character; ignored on input.
28 SPACE = chr(32) # Space or blank character.
29
30 def constrain (n, min, max):
31
32 """This returns a number, n constrained to the min and max bounds. """
33
34 if n < min:
35 return min
36 if n > max:
37 return max
38 return n
39
40 class screen:
41
42 """This object maintains the state of a virtual text screen as a
43 rectangluar array. This maintains a virtual cursor position and handles
44 scrolling as characters are added. This supports most of the methods needed
45 by an ANSI text screen. Row and column indexes are 1-based (not zero-based,
46 like arrays). """
47
48 def __init__ (self, r=24,c=80):
49
50 """This initializes a blank scree of the given dimentions."""
51
52 self.rows = r
53 self.cols = c
54 self.cur_r = 1
55 self.cur_c = 1
56 self.cur_saved_r = 1
57 self.cur_saved_c = 1
58 self.scroll_row_start = 1
59 self.scroll_row_end = self.rows
60 self.w = [ [SPACE] * self.cols for c in range(self.rows)]
61
62 def __str__ (self):
63
64 """This returns a printable representation of the screen. The end of
65 each screen line is terminated by a newline. """
66
67 return '\n'.join ([ ''.join(c) for c in self.w ])
68
69 def dump (self):
70
71 """This returns a copy of the screen as a string. This is similar to
72 __str__ except that lines are not terminated with line feeds. """
73
74 return ''.join ([ ''.join(c) for c in self.w ])
75
76 def pretty (self):
77
78 """This returns a copy of the screen as a string with an ASCII text box
79 around the screen border. This is similar to __str__ except that it
80 adds a box. """
81
82 top_bot = '+' + '-'*self.cols + '+\n'
83 return top_bot + '\n'.join(['|'+line+'|' for line in str(self).split('\n ')]) + '\n' + top_bot
84
85 def fill (self, ch=SPACE):
86
87 self.fill_region (1,1,self.rows,self.cols, ch)
88
89 def fill_region (self, rs,cs, re,ce, ch=SPACE):
90
91 rs = constrain (rs, 1, self.rows)
92 re = constrain (re, 1, self.rows)
93 cs = constrain (cs, 1, self.cols)
94 ce = constrain (ce, 1, self.cols)
95 if rs > re:
96 rs, re = re, rs
97 if cs > ce:
98 cs, ce = ce, cs
99 for r in range (rs, re+1):
100 for c in range (cs, ce + 1):
101 self.put_abs (r,c,ch)
102
103 def cr (self):
104
105 """This moves the cursor to the beginning (col 1) of the current row.
106 """
107
108 self.cursor_home (self.cur_r, 1)
109
110 def lf (self):
111
112 """This moves the cursor down with scrolling.
113 """
114
115 old_r = self.cur_r
116 self.cursor_down()
117 if old_r == self.cur_r:
118 self.scroll_up ()
119 self.erase_line()
120
121 def crlf (self):
122
123 """This advances the cursor with CRLF properties.
124 The cursor will line wrap and the screen may scroll.
125 """
126
127 self.cr ()
128 self.lf ()
129
130 def newline (self):
131
132 """This is an alias for crlf().
133 """
134
135 self.crlf()
136
137 def put_abs (self, r, c, ch):
138
139 """Screen array starts at 1 index."""
140
141 r = constrain (r, 1, self.rows)
142 c = constrain (c, 1, self.cols)
143 ch = str(ch)[0]
144 self.w[r-1][c-1] = ch
145
146 def put (self, ch):
147
148 """This puts a characters at the current cursor position.
149 """
150
151 self.put_abs (self.cur_r, self.cur_c, ch)
152
153 def insert_abs (self, r, c, ch):
154
155 """This inserts a character at (r,c). Everything under
156 and to the right is shifted right one character.
157 The last character of the line is lost.
158 """
159
160 r = constrain (r, 1, self.rows)
161 c = constrain (c, 1, self.cols)
162 for ci in range (self.cols, c, -1):
163 self.put_abs (r,ci, self.get_abs(r,ci-1))
164 self.put_abs (r,c,ch)
165
166 def insert (self, ch):
167
168 self.insert_abs (self.cur_r, self.cur_c, ch)
169
170 def get_abs (self, r, c):
171
172 r = constrain (r, 1, self.rows)
173 c = constrain (c, 1, self.cols)
174 return self.w[r-1][c-1]
175
176 def get (self):
177
178 self.get_abs (self.cur_r, self.cur_c)
179
180 def get_region (self, rs,cs, re,ce):
181
182 """This returns a list of lines representing the region.
183 """
184
185 rs = constrain (rs, 1, self.rows)
186 re = constrain (re, 1, self.rows)
187 cs = constrain (cs, 1, self.cols)
188 ce = constrain (ce, 1, self.cols)
189 if rs > re:
190 rs, re = re, rs
191 if cs > ce:
192 cs, ce = ce, cs
193 sc = []
194 for r in range (rs, re+1):
195 line = ''
196 for c in range (cs, ce + 1):
197 ch = self.get_abs (r,c)
198 line = line + ch
199 sc.append (line)
200 return sc
201
202 def cursor_constrain (self):
203
204 """This keeps the cursor within the screen area.
205 """
206
207 self.cur_r = constrain (self.cur_r, 1, self.rows)
208 self.cur_c = constrain (self.cur_c, 1, self.cols)
209
210 def cursor_home (self, r=1, c=1): # <ESC>[{ROW};{COLUMN}H
211
212 self.cur_r = r
213 self.cur_c = c
214 self.cursor_constrain ()
215
216 def cursor_back (self,count=1): # <ESC>[{COUNT}D (not confused with down)
217
218 self.cur_c = self.cur_c - count
219 self.cursor_constrain ()
220
221 def cursor_down (self,count=1): # <ESC>[{COUNT}B (not confused with back)
222
223 self.cur_r = self.cur_r + count
224 self.cursor_constrain ()
225
226 def cursor_forward (self,count=1): # <ESC>[{COUNT}C
227
228 self.cur_c = self.cur_c + count
229 self.cursor_constrain ()
230
231 def cursor_up (self,count=1): # <ESC>[{COUNT}A
232
233 self.cur_r = self.cur_r - count
234 self.cursor_constrain ()
235
236 def cursor_up_reverse (self): # <ESC> M (called RI -- Reverse Index)
237
238 old_r = self.cur_r
239 self.cursor_up()
240 if old_r == self.cur_r:
241 self.scroll_up()
242
243 def cursor_force_position (self, r, c): # <ESC>[{ROW};{COLUMN}f
244
245 """Identical to Cursor Home."""
246
247 self.cursor_home (r, c)
248
249 def cursor_save (self): # <ESC>[s
250
251 """Save current cursor position."""
252
253 self.cursor_save_attrs()
254
255 def cursor_unsave (self): # <ESC>[u
256
257 """Restores cursor position after a Save Cursor."""
258
259 self.cursor_restore_attrs()
260
261 def cursor_save_attrs (self): # <ESC>7
262
263 """Save current cursor position."""
264
265 self.cur_saved_r = self.cur_r
266 self.cur_saved_c = self.cur_c
267
268 def cursor_restore_attrs (self): # <ESC>8
269
270 """Restores cursor position after a Save Cursor."""
271
272 self.cursor_home (self.cur_saved_r, self.cur_saved_c)
273
274 def scroll_constrain (self):
275
276 """This keeps the scroll region within the screen region."""
277
278 if self.scroll_row_start <= 0:
279 self.scroll_row_start = 1
280 if self.scroll_row_end > self.rows:
281 self.scroll_row_end = self.rows
282
283 def scroll_screen (self): # <ESC>[r
284
285 """Enable scrolling for entire display."""
286
287 self.scroll_row_start = 1
288 self.scroll_row_end = self.rows
289
290 def scroll_screen_rows (self, rs, re): # <ESC>[{start};{end}r
291
292 """Enable scrolling from row {start} to row {end}."""
293
294 self.scroll_row_start = rs
295 self.scroll_row_end = re
296 self.scroll_constrain()
297
298 def scroll_down (self): # <ESC>D
299
300 """Scroll display down one line."""
301
302 # Screen is indexed from 1, but arrays are indexed from 0.
303 s = self.scroll_row_start - 1
304 e = self.scroll_row_end - 1
305 self.w[s+1:e+1] = copy.deepcopy(self.w[s:e])
306
307 def scroll_up (self): # <ESC>M
308
309 """Scroll display up one line."""
310
311 # Screen is indexed from 1, but arrays are indexed from 0.
312 s = self.scroll_row_start - 1
313 e = self.scroll_row_end - 1
314 self.w[s:e] = copy.deepcopy(self.w[s+1:e+1])
315
316 def erase_end_of_line (self): # <ESC>[0K -or- <ESC>[K
317
318 """Erases from the current cursor position to the end of the current
319 line."""
320
321 self.fill_region (self.cur_r, self.cur_c, self.cur_r, self.cols)
322
323 def erase_start_of_line (self): # <ESC>[1K
324
325 """Erases from the current cursor position to the start of the current
326 line."""
327
328 self.fill_region (self.cur_r, 1, self.cur_r, self.cur_c)
329
330 def erase_line (self): # <ESC>[2K
331
332 """Erases the entire current line."""
333
334 self.fill_region (self.cur_r, 1, self.cur_r, self.cols)
335
336 def erase_down (self): # <ESC>[0J -or- <ESC>[J
337
338 """Erases the screen from the current line down to the bottom of the
339 screen."""
340
341 self.erase_end_of_line ()
342 self.fill_region (self.cur_r + 1, 1, self.rows, self.cols)
343
344 def erase_up (self): # <ESC>[1J
345
346 """Erases the screen from the current line up to the top of the
347 screen."""
348
349 self.erase_start_of_line ()
350 self.fill_region (self.cur_r-1, 1, 1, self.cols)
351
352 def erase_screen (self): # <ESC>[2J
353
354 """Erases the screen with the background color."""
355
356 self.fill ()
357
358 def set_tab (self): # <ESC>H
359
360 """Sets a tab at the current position."""
361
362 pass
363
364 def clear_tab (self): # <ESC>[g
365
366 """Clears tab at the current position."""
367
368 pass
369
370 def clear_all_tabs (self): # <ESC>[3g
371
372 """Clears all tabs."""
373
374 pass
375
376 # Insert line Esc [ Pn L
377 # Delete line Esc [ Pn M
378 # Delete character Esc [ Pn P
379 # Scrolling region Esc [ Pn(top);Pn(bot) r
380
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698