@@ -11,8 +11,8 @@ class Editor:
1111 b"\x1b [F" : 0x03 ,
1212 b"\x1b OF" : 0x03 ,
1313 b"\x1b [4~" : 0x03 ,
14- b"\x1b [5~" : 0x17 ,
15- b"\x1b [6~" : 0x19 ,
14+ b"\x1b [5~" : 0xfff1 ,
15+ b"\x1b [6~" : 0xfff3 ,
1616 b"\x03 " : 0x11 ,
1717 b"\r " : 0x0a ,
1818 b"\x7f " : 0x08 ,
@@ -25,7 +25,7 @@ class Editor:
2525 def __init__ (self , tab_size , undo_limit ):
2626 self .top_line = self .cur_line = self .row = self .col = self .margin = 0
2727 self .tab_size = tab_size
28- self .changed = " "
28+ self .changed = ""
2929 self .message = self .fname = ""
3030 self .content = ["" ]
3131 self .undo = []
@@ -34,6 +34,8 @@ def __init__(self, tab_size, undo_limit):
3434 self .case = "n"
3535 self .autoindent = "y"
3636 self .mark = None
37+ serialcomm = 0
38+ sdev = 0
3739 if sys .platform == "pyboard" :
3840 def wr (self ,s ):
3941 ns = 0
@@ -49,15 +51,15 @@ def rd(self):
4951 return self .serialcomm .read (1 )
5052 def init_tty (self , device , baud ):
5153 import pyb
52- self .sdev = device
53- if self .sdev :
54- self .serialcomm = pyb .UART (device , baud )
54+ Editor .sdev = device
55+ if Editor .sdev :
56+ Editor .serialcomm = pyb .UART (device , baud )
5557 else :
56- self .serialcomm = pyb .USB_VCP ()
57- self .serialcomm .setinterrupt (- 1 )
58+ Editor .serialcomm = pyb .USB_VCP ()
59+ Editor .serialcomm .setinterrupt (- 1 )
5860 def deinit_tty (self ):
59- if not self .sdev :
60- self .serialcomm .setinterrupt (3 )
61+ if not Editor .sdev :
62+ Editor .serialcomm .setinterrupt (3 )
6163 def goto (self , row , col ):
6264 self .wr ("\x1b [{};{}H" .format (row + 1 , col + 1 ))
6365 def clear_to_eol (self ):
@@ -71,17 +73,24 @@ def hilite(self, mode):
7173 self .wr (b"\x1b [43m" )
7274 else :
7375 self .wr (b"\x1b [0m" )
74- def set_screen_parms (self ):
75- self .cursor (False )
76+ def get_screen_size (self ):
7677 self .wr ('\x1b [999;999H\x1b [6n' )
7778 pos = b''
7879 char = self .rd ()
7980 while char != b'R' :
8081 pos += char
8182 char = self .rd ()
82- (self .height , self .width ) = [int (i , 10 ) for i in pos [2 :].split (b';' )]
83- self .height -= 1
84- self .scrbuf = [(False ,"\x00 " )] * self .height
83+ return [int (i , 10 ) for i in pos [2 :].split (b';' )]
84+ def redraw (self , flag ):
85+ self .cursor (False )
86+ Editor .height , Editor .width = self .get_screen_size ()
87+ Editor .height -= 1
88+ Editor .scrbuf = [(False ,"\x00 " )] * Editor .height
89+ self .row = min (Editor .height - 1 , self .row )
90+ if sys .implementation .name == "micropython" :
91+ gc .collect ()
92+ if flag :
93+ self .message = "{} Bytes Memory available" .format (gc .mem_free ())
8594 def get_input (self ):
8695 while True :
8796 in_buffer = self .rd ()
@@ -100,39 +109,39 @@ def get_input(self):
100109 def display_window (self ):
101110 self .cur_line = min (self .total_lines - 1 , max (self .cur_line , 0 ))
102111 self .col = max (0 , min (self .col , len (self .content [self .cur_line ])))
103- if self .col >= self .width + self .margin :
104- self .margin = self .col - self .width + (self .width >> 2 )
112+ if self .col >= Editor .width + self .margin :
113+ self .margin = self .col - Editor .width + (Editor .width >> 2 )
105114 elif self .col < self .margin :
106- self .margin = max (self .col - (self .width >> 2 ), 0 )
107- if not (self .top_line <= self .cur_line < self .top_line + self .height ):
115+ self .margin = max (self .col - (Editor .width >> 2 ), 0 )
116+ if not (self .top_line <= self .cur_line < self .top_line + Editor .height ):
108117 self .top_line = max (self .cur_line - self .row , 0 )
109118 self .row = self .cur_line - self .top_line
110119 self .cursor (False )
111120 i = self .top_line
112- for c in range (self .height ):
121+ for c in range (Editor .height ):
113122 if i == self .total_lines :
114- if self .scrbuf [c ] != (False ,'' ):
123+ if Editor .scrbuf [c ] != (False ,'' ):
115124 self .goto (c , 0 )
116125 self .clear_to_eol ()
117- self .scrbuf [c ] = (False ,'' )
126+ Editor .scrbuf [c ] = (False ,'' )
118127 else :
119128 l = (self .mark != None and (
120129 (self .mark <= i <= self .cur_line ) or (self .cur_line <= i <= self .mark )),
121- self .content [i ][self .margin :self .margin + self .width ])
122- if l != self .scrbuf [c ]:
130+ self .content [i ][self .margin :self .margin + Editor .width ])
131+ if l != Editor .scrbuf [c ]:
123132 self .goto (c , 0 )
124133 if l [0 ]: self .hilite (2 )
125134 self .wr (l [1 ])
126- if len (l [1 ]) < self .width :
135+ if len (l [1 ]) < Editor .width :
127136 self .clear_to_eol ()
128137 if l [0 ]: self .hilite (0 )
129- self .scrbuf [c ] = l
138+ Editor .scrbuf [c ] = l
130139 i += 1
131- self .goto (self .height , 0 )
140+ self .goto (Editor .height , 0 )
132141 self .hilite (1 )
133- self .wr ("[{}] {} Row: {} Col: {} {}" .format (
134- self .total_lines , self .changed , self .cur_line + 1 ,
135- self .col + 1 , self .message [:self .width - 25 ]))
142+ self .wr ("{} {} Row: {}/ {} Col: {} {}" .format (
143+ self .changed , self .fname , self .cur_line + 1 , self . total_lines ,
144+ self .col + 1 , self .message [:Editor .width - 25 - len ( self . fname ) ]))
136145 self .clear_to_eol ()
137146 self .hilite (0 )
138147 self .goto (self .row , self .col - self .margin )
@@ -144,7 +153,7 @@ def line_range(self):
144153 return ((self .mark , self .cur_line + 1 ) if self .mark < self .cur_line else
145154 (self .cur_line , self .mark + 1 ))
146155 def line_edit (self , prompt , default ):
147- self .goto (self .height , 0 )
156+ self .goto (Editor .height , 0 )
148157 self .hilite (1 )
149158 self .wr (prompt )
150159 self .wr (default )
@@ -166,11 +175,11 @@ def line_edit(self, prompt, default):
166175 self .wr ('\b \b ' * len (res ))
167176 res = ''
168177 elif 0x20 <= key < 0xfff0 :
169- if len (prompt ) + len (res ) < self .width - 2 :
178+ if len (prompt ) + len (res ) < Editor .width - 2 :
170179 res += chr (key )
171180 self .wr (chr (key ))
172181 def find_in_file (self , pattern , pos , end ):
173- self .find_pattern = pattern
182+ Editor .find_pattern = pattern
174183 if self .case != "y" :
175184 pattern = pattern .lower ()
176185 spos = pos
@@ -197,7 +206,7 @@ def undo_add(self, lnum, text, key, span = 1):
197206 def delete_lines (self , yank ):
198207 lrange = self .line_range ()
199208 if yank :
200- self .yank_buffer = self .content [lrange [0 ]:lrange [1 ]]
209+ Editor .yank_buffer = self .content [lrange [0 ]:lrange [1 ]]
201210 self .undo_add (lrange [0 ], self .content [lrange [0 ]:lrange [1 ]], 0 , 0 )
202211 del self .content [lrange [0 ]:lrange [1 ]]
203212 if self .content == []:
@@ -241,24 +250,24 @@ def handle_edit_keys(self, key):
241250 self .col = self .spaces (l ) if self .col == 0 else 0
242251 elif key == 0x03 :
243252 self .col = len (l )
244- elif key == 0x17 :
245- self .cur_line -= self .height
246- elif key == 0x19 :
247- self .cur_line += self .height
253+ elif key == 0xfff1 :
254+ self .cur_line -= Editor .height
255+ elif key == 0xfff3 :
256+ self .cur_line += Editor .height
248257 elif key == 0x06 :
249- pat = self .line_edit ("Find: " , self .find_pattern )
258+ pat = self .line_edit ("Find: " , Editor .find_pattern )
250259 if pat :
251260 self .find_in_file (pat , self .col , self .total_lines )
252- self .row = self .height >> 1
261+ self .row = Editor .height >> 1
253262 elif key == 0x0e :
254- if self .find_pattern :
255- self .find_in_file (self .find_pattern , self .col + 1 , self .total_lines )
256- self .row = self .height >> 1
263+ if Editor .find_pattern :
264+ self .find_in_file (Editor .find_pattern , self .col + 1 , self .total_lines )
265+ self .row = Editor .height >> 1
257266 elif key == 0x07 :
258267 line = self .line_edit ("Goto Line: " , "" )
259268 if line :
260269 self .cur_line = int (line ) - 1
261- self .row = self .height >> 1
270+ self .row = Editor .height >> 1
262271 elif key == 0x01 :
263272 self .autoindent = 'y' if self .autoindent != 'y' else 'n'
264273 elif key == 0xfffd :
@@ -321,8 +330,8 @@ def handle_edit_keys(self, key):
321330 if len (self .content [i ]) > 0 :
322331 self .content [i ] = ' ' * (self .tab_size - self .spaces (self .content [i ]) % self .tab_size ) + self .content [i ]
323332 else :
324- self .undo_add (self .cur_line , [l ], 0x09 )
325333 ni = self .tab_size - self .col % self .tab_size
334+ self .undo_add (self .cur_line , [l ], 0x09 )
326335 self .content [self .cur_line ] = l [:self .col ] + ' ' * ni + l [self .col :]
327336 self .col += ni
328337 elif key == 0x15 :
@@ -345,23 +354,22 @@ def handle_edit_keys(self, key):
345354 elif key == 0x04 :
346355 if self .mark != None :
347356 lrange = self .line_range ()
348- self .yank_buffer = self .content [lrange [0 ]:lrange [1 ]]
357+ Editor .yank_buffer = self .content [lrange [0 ]:lrange [1 ]]
349358 self .mark = None
350359 elif key == 0x16 :
351- if self .yank_buffer :
360+ if Editor .yank_buffer :
352361 if self .mark != None :
353362 self .delete_lines (False )
354- self .undo_add (self .cur_line , None , 0 , - len (self .yank_buffer ))
355- self .content [self .cur_line :self .cur_line ] = self .yank_buffer
356- self .total_lines += len (self .yank_buffer )
363+ self .undo_add (self .cur_line , None , 0 , - len (Editor .yank_buffer ))
364+ self .content [self .cur_line :self .cur_line ] = Editor .yank_buffer
365+ self .total_lines += len (Editor .yank_buffer )
357366 elif key == 0x13 :
358- if True :
359- fname = self .line_edit ("Save File: " , self .fname )
360- if fname :
361- self .put_file (fname , 0 , self .total_lines )
362- self .changed = ' '
363- self .undo_zero = len (self .undo )
364- self .fname = fname
367+ fname = self .line_edit ("Save File: " , self .fname )
368+ if fname :
369+ self .put_file (fname )
370+ self .changed = ''
371+ self .undo_zero = len (self .undo )
372+ if not self .fname : self .fname = fname
365373 elif key == 0x1a :
366374 if len (self .undo ) > 0 :
367375 action = self .undo .pop (- 1 )
@@ -376,50 +384,49 @@ def handle_edit_keys(self, key):
376384 else :
377385 del self .content [action [0 ]:action [0 ] - action [1 ]]
378386 self .total_lines = len (self .content )
379- self .changed = ' ' if len (self .undo ) == self .undo_zero else '*'
387+ if len (self .undo ) == self .undo_zero :
388+ self .changed = ''
380389 self .mark = None
390+ elif key == 0x05 :
391+ self .redraw (True )
381392 def edit_loop (self ):
382- if self .content == [] :
393+ if not self .content :
383394 self .content = ["" ]
384395 self .total_lines = len (self .content )
385- key = 0x05
396+ self . redraw ( self . message == "" )
386397 while True :
387398 try :
388- if key == 0x05 :
389- self .set_screen_parms ()
390- self .row = min (self .height - 1 , self .row )
391- if sys .implementation .name == "micropython" :
392- gc .collect ()
393- self .message = "{} Bytes Memory available" .format (gc .mem_free ())
394399 if not self .rd_any ():
395400 self .display_window ()
396401 key = self .get_input ()
397402 self .message = ''
398403 if key == 0x11 :
399- if self .changed != ' ' :
404+ if self .changed != '' :
400405 res = self .line_edit ("Content changed! Quit without saving (y/N)? " , "N" )
401406 if not res or res [0 ].upper () != 'Y' :
402407 continue
403- self .goto (self .height , 0 )
404- self .clear_to_eol ()
405- return None
408+ return (key , "" )
409+ elif key == 0x17 :
410+ return (key , "" )
411+ elif key == 0x0f :
412+ return (key , self .line_edit ("Open file: " , "" ))
406413 else : self .handle_edit_keys (key )
407414 except Exception as err :
408- self .message = "{}" .format (err )
415+ self .message = "{!r }" .format (err )
409416 def get_file (self , fname ):
417+ self .fname = fname
410418 try :
411419 with open (fname ) as f :
412- content = f .readlines ()
420+ self . content = f .readlines ()
413421 except Exception as err :
414- message = 'Could not load {}, {!r}' .format (fname , err )
415- return (None , message )
416- for i in range (len (content )):
417- content [i ] = expandtabs (content [i ].rstrip ('\r \n \t ' ))
418- return (content , "" )
419- def put_file (self , fname , start , stop ):
422+ self .content , self .message = ["" ], "{!r}" .format (err )
423+ else :
424+ for i in range (len (self .content )):
425+ self .content [i ] = expandtabs (self .content [i ].rstrip ('\r \n \t ' ))
426+ def put_file (self , fname ):
420427 import os
421428 with open ("tmpfile.pye" , "w" ) as f :
422- for l in self .content [ start : stop ] :
429+ for l in self .content :
423430 f .write (l + '\n ' )
424431 try : os .unlink (fname )
425432 except : pass
@@ -439,18 +446,38 @@ def expandtabs(s):
439446 return sb .getvalue ()
440447 else :
441448 return s
442- def pye (content = None , tab_size = 4 , undo = 50 , device = 0 , baud = 115200 ):
449+ def pye (* content , tab_size = 4 , undo = 50 , device = 0 , baud = 115200 ):
443450 gc .collect ()
444- e = Editor (tab_size , undo )
445- if type (content ) == str and content :
446- e .fname = content
447- (e .content , e .message ) = e .get_file (e .fname )
448- if e .content == None :
449- print (e .message )
450- return
451- elif type (content ) == list and len (content ) > 0 and type (content [0 ]) == str :
452- e .content = content
453- e .init_tty (device , baud )
454- e .edit_loop ()
455- e .deinit_tty ()
456- return e .content if (e .fname == "" ) else e .fname
451+ if content :
452+ slot = []
453+ index = 0
454+ for f in content :
455+ slot .append (Editor (tab_size , undo ))
456+ if type (f ) == str and f :
457+ slot [index ].get_file (f )
458+ elif type (f ) == list and len (f ) > 0 and type (f [0 ]) == str :
459+ slot [index ].content = f
460+ index += 1
461+ else :
462+ slot = [Editor (tab_size , undo )]
463+ index = 0
464+ slot [0 ].init_tty (device , baud )
465+ while True :
466+ key ,f = slot [index ].edit_loop ()
467+ if key == 0x11 :
468+ if len (slot ) == 1 :
469+ break
470+ del slot [index ]
471+ index %= len (slot )
472+ elif key == 0x0f :
473+ slot .append (Editor (tab_size , undo ))
474+ index = len (slot ) - 1
475+ if f :
476+ slot [index ].get_file (f )
477+ elif key == 0x17 :
478+ index = (index + 1 ) % len (slot )
479+ slot [0 ].goto (slot [0 ].height , 0 )
480+ slot [0 ].clear_to_eol ()
481+ slot [0 ].deinit_tty ()
482+ slot [0 ].undo , Editor .yank_buffer = [],[]
483+ return slot [0 ].content if (slot [0 ].fname == "" ) else slot [0 ].fname
0 commit comments