Skip to content

Commit 1e1a97e

Browse files
committed
WiPy too
1 parent 7e1badc commit 1e1a97e

File tree

2 files changed

+110
-125
lines changed

2 files changed

+110
-125
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ anyhow called one after the other, resulting in a enormous long function handlin
145145
- Some editorial changes
146146

147147
**2.0** Edit muliple files
148-
- Support for editing mutiple files and copy/paste between them
148+
- Support for editing mutiple files at once and copy/paste between them
149149
- Ctrl-W steps through the list of files/buffers
150150
- Ctrl-O opens a new file/buffer.
151151

wipye.py

Lines changed: 109 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,20 @@ class Editor:
1111
b"\x1b[F" : 0x03,
1212
b"\x1bOF" : 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,
1919
b"\x1b[3~": 0x7f,
2020
b"\x1b[Z" : 0x15,
21-
b"\x0b" : 0xfffd,
2221
}
2322
yank_buffer = []
2423
find_pattern = ""
2524
def __init__(self, tab_size, undo_limit):
2625
self.top_line = self.cur_line = self.row = self.col = self.margin = 0
2726
self.tab_size = tab_size
28-
self.changed = " "
27+
self.changed = ""
2928
self.message = self.fname = ""
3029
self.content = [""]
3130
self.undo = []
@@ -58,17 +57,24 @@ def hilite(self, mode):
5857
self.wr(b"\x1b[43m")
5958
else:
6059
self.wr(b"\x1b[0m")
61-
def set_screen_parms(self):
62-
self.cursor(False)
60+
def get_screen_size(self):
6361
self.wr('\x1b[999;999H\x1b[6n')
6462
pos = b''
6563
char = self.rd()
6664
while char != b'R':
6765
pos += char
6866
char = self.rd()
69-
(self.height, self.width) = [int(i, 10) for i in pos[2:].split(b';')]
70-
self.height -= 1
71-
self.scrbuf = [(False,"\x00")] * self.height
67+
return [int(i, 10) for i in pos[2:].split(b';')]
68+
def redraw(self, flag):
69+
self.cursor(False)
70+
Editor.height, Editor.width = self.get_screen_size()
71+
Editor.height -= 1
72+
Editor.scrbuf = [(False,"\x00")] * Editor.height
73+
self.row = min(Editor.height - 1, self.row)
74+
if sys.implementation.name == "micropython":
75+
gc.collect()
76+
if flag:
77+
self.message = "{} Bytes Memory available".format(gc.mem_free())
7278
def get_input(self):
7379
while True:
7480
in_buffer = self.rd()
@@ -87,39 +93,39 @@ def get_input(self):
8793
def display_window(self):
8894
self.cur_line = min(self.total_lines - 1, max(self.cur_line, 0))
8995
self.col = max(0, min(self.col, len(self.content[self.cur_line])))
90-
if self.col >= self.width + self.margin:
91-
self.margin = self.col - self.width + (self.width >> 2)
96+
if self.col >= Editor.width + self.margin:
97+
self.margin = self.col - Editor.width + (Editor.width >> 2)
9298
elif self.col < self.margin:
93-
self.margin = max(self.col - (self.width >> 2), 0)
94-
if not (self.top_line <= self.cur_line < self.top_line + self.height):
99+
self.margin = max(self.col - (Editor.width >> 2), 0)
100+
if not (self.top_line <= self.cur_line < self.top_line + Editor.height):
95101
self.top_line = max(self.cur_line - self.row, 0)
96102
self.row = self.cur_line - self.top_line
97103
self.cursor(False)
98104
i = self.top_line
99-
for c in range(self.height):
105+
for c in range(Editor.height):
100106
if i == self.total_lines:
101-
if self.scrbuf[c] != (False,''):
107+
if Editor.scrbuf[c] != (False,''):
102108
self.goto(c, 0)
103109
self.clear_to_eol()
104-
self.scrbuf[c] = (False,'')
110+
Editor.scrbuf[c] = (False,'')
105111
else:
106112
l = (self.mark != None and (
107113
(self.mark <= i <= self.cur_line) or (self.cur_line <= i <= self.mark)),
108-
self.content[i][self.margin:self.margin + self.width])
109-
if l != self.scrbuf[c]:
114+
self.content[i][self.margin:self.margin + Editor.width])
115+
if l != Editor.scrbuf[c]:
110116
self.goto(c, 0)
111117
if l[0]: self.hilite(2)
112118
self.wr(l[1])
113-
if len(l[1]) < self.width:
119+
if len(l[1]) < Editor.width:
114120
self.clear_to_eol()
115121
if l[0]: self.hilite(0)
116-
self.scrbuf[c] = l
122+
Editor.scrbuf[c] = l
117123
i += 1
118-
self.goto(self.height, 0)
124+
self.goto(Editor.height, 0)
119125
self.hilite(1)
120-
self.wr("[{}] {} Row: {} Col: {} {}".format(
121-
self.total_lines, self.changed, self.cur_line + 1,
122-
self.col + 1, self.message[:self.width - 25]))
126+
self.wr("{}{} Row: {}/{} Col: {} {}".format(
127+
self.changed, self.fname, self.cur_line + 1, self.total_lines,
128+
self.col + 1, self.message[:Editor.width - 25 - len(self.fname)]))
123129
self.clear_to_eol()
124130
self.hilite(0)
125131
self.goto(self.row, self.col - self.margin)
@@ -131,7 +137,7 @@ def line_range(self):
131137
return ((self.mark, self.cur_line + 1) if self.mark < self.cur_line else
132138
(self.cur_line, self.mark + 1))
133139
def line_edit(self, prompt, default):
134-
self.goto(self.height, 0)
140+
self.goto(Editor.height, 0)
135141
self.hilite(1)
136142
self.wr(prompt)
137143
self.wr(default)
@@ -153,11 +159,11 @@ def line_edit(self, prompt, default):
153159
self.wr('\b \b' * len(res))
154160
res = ''
155161
elif 0x20 <= key < 0xfff0:
156-
if len(prompt) + len(res) < self.width - 2:
162+
if len(prompt) + len(res) < Editor.width - 2:
157163
res += chr(key)
158164
self.wr(chr(key))
159165
def find_in_file(self, pattern, pos, end):
160-
self.find_pattern = pattern
166+
Editor.find_pattern = pattern
161167
if self.case != "y":
162168
pattern = pattern.lower()
163169
spos = pos
@@ -184,7 +190,7 @@ def undo_add(self, lnum, text, key, span = 1):
184190
def delete_lines(self, yank):
185191
lrange = self.line_range()
186192
if yank:
187-
self.yank_buffer = self.content[lrange[0]:lrange[1]]
193+
Editor.yank_buffer = self.content[lrange[0]:lrange[1]]
188194
self.undo_add(lrange[0], self.content[lrange[0]:lrange[1]], 0, 0)
189195
del self.content[lrange[0]:lrange[1]]
190196
if self.content == []:
@@ -228,65 +234,26 @@ def handle_edit_keys(self, key):
228234
self.col = self.spaces(l) if self.col == 0 else 0
229235
elif key == 0x03:
230236
self.col = len(l)
231-
elif key == 0x17:
232-
self.cur_line -= self.height
233-
elif key == 0x19:
234-
self.cur_line += self.height
237+
elif key == 0xfff1:
238+
self.cur_line -= Editor.height
239+
elif key == 0xfff3:
240+
self.cur_line += Editor.height
235241
elif key == 0x06:
236-
pat = self.line_edit("Find: ", self.find_pattern)
242+
pat = self.line_edit("Find: ", Editor.find_pattern)
237243
if pat:
238244
self.find_in_file(pat, self.col, self.total_lines)
239-
self.row = self.height >> 1
245+
self.row = Editor.height >> 1
240246
elif key == 0x0e:
241-
if self.find_pattern:
242-
self.find_in_file(self.find_pattern, self.col + 1, self.total_lines)
243-
self.row = self.height >> 1
247+
if Editor.find_pattern:
248+
self.find_in_file(Editor.find_pattern, self.col + 1, self.total_lines)
249+
self.row = Editor.height >> 1
244250
elif key == 0x07:
245251
line = self.line_edit("Goto Line: ", "")
246252
if line:
247253
self.cur_line = int(line) - 1
248-
self.row = self.height >> 1
254+
self.row = Editor.height >> 1
249255
elif key == 0x01:
250256
self.autoindent = 'y' if self.autoindent != 'y' else 'n'
251-
elif key == 0xfffd:
252-
if self.col < len(l):
253-
opening = "([{<"
254-
closing = ")]}>"
255-
level = 0
256-
pos = self.col
257-
srch = l[pos]
258-
i = opening.find(srch)
259-
if i >= 0:
260-
pos += 1
261-
match = closing[i]
262-
for i in range(self.cur_line, self.total_lines):
263-
for c in range(pos, len(self.content[i])):
264-
if self.content[i][c] == match:
265-
if level == 0:
266-
self.cur_line, self.col = i, c
267-
return True
268-
else:
269-
level -= 1
270-
elif self.content[i][c] == srch:
271-
level += 1
272-
pos = 0
273-
else:
274-
i = closing.find(srch)
275-
if i >= 0:
276-
pos -= 1
277-
match = opening[i]
278-
for i in range(self.cur_line, -1, -1):
279-
for c in range(pos, -1, -1):
280-
if self.content[i][c] == match:
281-
if level == 0:
282-
self.cur_line, self.col = i, c
283-
return True
284-
else:
285-
level -= 1
286-
elif self.content[i][c] == srch:
287-
level += 1
288-
if i > 0:
289-
pos = len(self.content[i - 1]) - 1
290257
elif key == 0x0c:
291258
self.mark = self.cur_line if self.mark == None else None
292259
elif key == 0x0a:
@@ -308,8 +275,8 @@ def handle_edit_keys(self, key):
308275
if len(self.content[i]) > 0:
309276
self.content[i] = ' ' * (self.tab_size - self.spaces(self.content[i]) % self.tab_size) + self.content[i]
310277
else:
311-
self.undo_add(self.cur_line, [l], 0x09)
312278
ni = self.tab_size - self.col % self.tab_size
279+
self.undo_add(self.cur_line, [l], 0x09)
313280
self.content[self.cur_line] = l[:self.col] + ' ' * ni + l[self.col:]
314281
self.col += ni
315282
elif key == 0x15:
@@ -332,23 +299,22 @@ def handle_edit_keys(self, key):
332299
elif key == 0x04:
333300
if self.mark != None:
334301
lrange = self.line_range()
335-
self.yank_buffer = self.content[lrange[0]:lrange[1]]
302+
Editor.yank_buffer = self.content[lrange[0]:lrange[1]]
336303
self.mark = None
337304
elif key == 0x16:
338-
if self.yank_buffer:
305+
if Editor.yank_buffer:
339306
if self.mark != None:
340307
self.delete_lines(False)
341-
self.undo_add(self.cur_line, None, 0, -len(self.yank_buffer))
342-
self.content[self.cur_line:self.cur_line] = self.yank_buffer
343-
self.total_lines += len(self.yank_buffer)
308+
self.undo_add(self.cur_line, None, 0, -len(Editor.yank_buffer))
309+
self.content[self.cur_line:self.cur_line] = Editor.yank_buffer
310+
self.total_lines += len(Editor.yank_buffer)
344311
elif key == 0x13:
345-
if True:
346-
fname = self.line_edit("Save File: ", self.fname)
347-
if fname:
348-
self.put_file(fname, 0, self.total_lines)
349-
self.changed = ' '
350-
self.undo_zero = len(self.undo)
351-
self.fname = fname
312+
fname = self.line_edit("Save File: ", self.fname)
313+
if fname:
314+
self.put_file(fname)
315+
self.changed = ''
316+
self.undo_zero = len(self.undo)
317+
if not self.fname: self.fname = fname
352318
elif key == 0x1a:
353319
if len(self.undo) > 0:
354320
action = self.undo.pop(-1)
@@ -363,50 +329,49 @@ def handle_edit_keys(self, key):
363329
else:
364330
del self.content[action[0]:action[0] - action[1]]
365331
self.total_lines = len(self.content)
366-
self.changed = ' ' if len(self.undo) == self.undo_zero else '*'
332+
if len(self.undo) == self.undo_zero:
333+
self.changed = ''
367334
self.mark = None
335+
elif key == 0x05:
336+
self.redraw(True)
368337
def edit_loop(self):
369-
if self.content == []:
338+
if not self.content:
370339
self.content = [""]
371340
self.total_lines = len(self.content)
372-
key = 0x05
341+
self.redraw(self.message == "")
373342
while True:
374343
try:
375-
if key == 0x05:
376-
self.set_screen_parms()
377-
self.row = min(self.height - 1, self.row)
378-
if sys.implementation.name == "micropython":
379-
gc.collect()
380-
self.message = "{} Bytes Memory available".format(gc.mem_free())
381344
if not self.rd_any():
382345
self.display_window()
383346
key = self.get_input()
384347
self.message = ''
385348
if key == 0x11:
386-
if self.changed != ' ':
349+
if self.changed != '':
387350
res = self.line_edit("Content changed! Quit without saving (y/N)? ", "N")
388351
if not res or res[0].upper() != 'Y':
389352
continue
390-
self.goto(self.height, 0)
391-
self.clear_to_eol()
392-
return None
353+
return (key, "")
354+
elif key == 0x17:
355+
return (key, "")
356+
elif key == 0x0f:
357+
return (key, self.line_edit("Open file: ", ""))
393358
else: self.handle_edit_keys(key)
394359
except Exception as err:
395-
self.message = "{}".format(err)
360+
self.message = "{!r}".format(err)
396361
def get_file(self, fname):
362+
self.fname = fname
397363
try:
398364
with open(fname) as f:
399-
content = f.readlines()
365+
self.content = f.readlines()
400366
except Exception as err:
401-
message = 'Could not load {}, {!r}'.format(fname, err)
402-
return (None, message)
403-
for i in range(len(content)):
404-
content[i] = expandtabs(content[i].rstrip('\r\n\t '))
405-
return (content, "")
406-
def put_file(self, fname, start, stop):
367+
self.content, self.message = [""], "{!r}".format(err)
368+
else:
369+
for i in range(len(self.content)):
370+
self.content[i] = expandtabs(self.content[i].rstrip('\r\n\t '))
371+
def put_file(self, fname):
407372
import os
408373
with open("tmpfile.pye", "w") as f:
409-
for l in self.content[start:stop]:
374+
for l in self.content:
410375
f.write(l + '\n')
411376
try: os.unlink(fname)
412377
except: pass
@@ -426,16 +391,36 @@ def expandtabs(s):
426391
return sb.getvalue()
427392
else:
428393
return s
429-
def pye(content = None, tab_size = 4, undo = 50, device = 0, baud = 115200):
394+
def pye(*content, tab_size = 4, undo = 50, device = 0, baud = 115200):
430395
gc.collect()
431-
e = Editor(tab_size, undo)
432-
if type(content) == str and content:
433-
e.fname = content
434-
(e.content, e.message) = e.get_file(e.fname)
435-
if e.content == None:
436-
print (e.message)
437-
return
438-
elif type(content) == list and len(content) > 0 and type(content[0]) == str:
439-
e.content = content
440-
e.edit_loop()
441-
return e.content if (e.fname == "") else e.fname
396+
if content:
397+
slot = []
398+
index = 0
399+
for f in content:
400+
slot.append(Editor(tab_size, undo))
401+
if type(f) == str and f:
402+
slot[index].get_file(f)
403+
elif type(f) == list and len(f) > 0 and type(f[0]) == str:
404+
slot[index].content = f
405+
index += 1
406+
else:
407+
slot = [Editor(tab_size, undo)]
408+
index = 0
409+
while True:
410+
key,f = slot[index].edit_loop()
411+
if key == 0x11:
412+
if len(slot) == 1:
413+
break
414+
del slot[index]
415+
index %= len(slot)
416+
elif key == 0x0f:
417+
slot.append(Editor(tab_size, undo))
418+
index = len(slot) - 1
419+
if f:
420+
slot[index].get_file(f)
421+
elif key == 0x17:
422+
index = (index + 1) % len(slot)
423+
slot[0].goto(slot[0].height, 0)
424+
slot[0].clear_to_eol()
425+
slot[0].undo, Editor.yank_buffer = [],[]
426+
return slot[0].content if (slot[0].fname == "") else slot[0].fname

0 commit comments

Comments
 (0)