Skip to content

Commit 29fb9e0

Browse files
committed
Change the way a mark is shown; Safe save
1 parent 67420da commit 29fb9e0

File tree

9 files changed

+166
-114
lines changed

9 files changed

+166
-114
lines changed

Pyboard Editor.doc

-12 KB
Binary file not shown.

Pyboard Editor.pdf

-41.1 KB
Binary file not shown.

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
A small text editor written in Python running on PYBoard and WiPy, allowing to edit files locally. It is based on the editor widget of pfalcon at https://github.com/pfalcon/pyedit. I ported it to PyBoard and WiPy and added a few functions:
66

7-
- Use USB_VCP or UART for input and output.
7+
- Use USB_VCP/Telnet or UART for input and output.
88
- Changed the read keyboard function to comply with slow byte-by-byte input on serial lines.
99
- Added support for Tab, BackTab, Save, Del and Backspace joining lines, Find, Replace, Goto Line, Undo, Get file, Auto-Indent, Set Flags, Copy/Delete & Paste, Indent, Un-Indent
1010
- handling tab (0x09) on reading & writing files,
@@ -116,3 +116,7 @@ c) expandtabs() and packtabs() with a second argument for tabsize (not for pye,
116116
- Except for Delete, Backspace, Cut and Paste, Mark has to be toggled off when not needed any more.
117117
- Right click (Button 2) or Ctrl-Click on the mouse sets/unsets the Mark, left Click extends it, when set.
118118

119+
**1.11** Minor fixes
120+
- Change the way a marked area is highlighted from reverse to a different background color. That works well for black chars on yellow background (code 43). For white chars on black background, the setting for background color in the function hilite() has to be changed, e.g. to blue (code 44).
121+
- Save to a temporary file first, and rename it to the target name when successfully written.
122+

pe.py

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ class Editor:
1818
b"\x7f" : 0x08,
1919
b"\x1b[3~": 0x7f,
2020
b"\x1b[Z" : 0x15,
21-
b"\x1b[3;5~": 0x18,
2221
b"\x11" : 0x11,
2322
b"\n" : 0x0a,
2423
b"\x08" : 0x08,
@@ -35,12 +34,13 @@ class Editor:
3534
b"\x16" : 0x16,
3635
b"\x04" : 0x04,
3736
b"\x0c" : 0x0c,
37+
b"\x14" : 0x14,
38+
b"\x02" : 0x02,
3839
b"\x1b[M" : 0x1b,
3940
b"\x01" : 0x01,
40-
b"\x14" : 0x02,
41-
b"\x02" : 0x14,
42-
b"\x1b[1;5H": 0x02,
43-
b"\x1b[1;5F": 0x14,
41+
b"\x1b[1;5H": 0x14,
42+
b"\x1b[1;5F": 0x02,
43+
b"\x1b[3;5~": 0x18,
4444
b"\x0f" : 0x1e,
4545
}
4646
def __init__(self, tab_size, undo_limit):
@@ -66,6 +66,8 @@ def wr(self,s):
6666
res = self.serialcomm.write(s[ns:])
6767
if res != None:
6868
ns += res
69+
def not_pending(self):
70+
return not self.serialcomm.any()
6971
def rd(self):
7072
while not self.serialcomm.any():
7173
pass
@@ -88,11 +90,11 @@ def clear_to_eol(self):
8890
def cursor(self, onoff):
8991
self.wr(b"\x1b[?25h" if onoff else b"\x1b[?25l")
9092
def hilite(self, mode):
91-
if mode == 1:
93+
if mode == 1:
9294
self.wr(b"\x1b[1m")
93-
if mode == 2:
94-
self.wr(b"\x1b[7m")
95-
else:
95+
elif mode == 2:
96+
self.wr(b"\x1b[43m")
97+
else:
9698
self.wr(b"\x1b[0m")
9799
def mouse_reporting(self, onoff):
98100
self.wr('\x1b[?9h' if onoff else '\x1b[?9l')
@@ -159,7 +161,7 @@ def display_window(self):
159161
i = self.top_line
160162
for c in range(self.height):
161163
if i == self.total_lines:
162-
if self.scrbuf[c][1] != '':
164+
if self.scrbuf[c] != (False,''):
163165
self.goto(c, 0)
164166
self.clear_to_eol()
165167
self.scrbuf[c] = (False,'')
@@ -169,24 +171,20 @@ def display_window(self):
169171
self.content[i][self.margin:self.margin + self.width])
170172
if l != self.scrbuf[c]:
171173
self.goto(c, 0)
172-
if l[0]:
173-
self.hilite(2)
174-
self.wr(l[1])
175-
if l[1] == '': self.wr(' ')
176-
self.hilite(0)
177-
else:
178-
self.wr(l[1])
174+
if l[0]: self.hilite(2)
175+
self.wr(l[1])
179176
if len(l[1]) < self.width:
180177
self.clear_to_eol()
178+
if l[0]: self.hilite(0)
181179
self.scrbuf[c] = l
182180
i += 1
183181
self.goto(self.height, 0)
184182
self.hilite(1)
185183
self.wr("[{}] {} Row: {} Col: {} {}".format(
186184
self.total_lines, self.changed, self.cur_line + 1,
187185
self.col + 1, self.message[:self.width - 25]))
188-
self.hilite(0)
189186
self.clear_to_eol()
187+
self.hilite(0)
190188
self.goto(self.row, self.col - self.margin)
191189
self.cursor(True)
192190
def spaces(self, line, pos = None):
@@ -320,9 +318,9 @@ def handle_cursor_keys(self, key):
320318
if res[3]: self.write_tabs = 'y' if res[3][0] == 'y' else 'n'
321319
except:
322320
pass
323-
elif key == 0x02:
324-
self.cur_line = 0
325321
elif key == 0x14:
322+
self.cur_line = 0
323+
elif key == 0x02:
326324
self.cur_line = self.total_lines - 1
327325
self.row = self.height - 1
328326
else:
@@ -347,6 +345,7 @@ def delete_lines(self, yank):
347345
self.cur_line = lrange[0]
348346
self.mark = None
349347
def handle_edit_key(self, key):
348+
from os import rename, remove
350349
l = self.content[self.cur_line]
351350
if key == 0x0a:
352351
self.mark = None
@@ -481,12 +480,15 @@ def handle_edit_key(self, key):
481480
lrange = (0, self.total_lines)
482481
if fname:
483482
try:
484-
with open(fname, "w") as f:
483+
with open("tmpfile.pye", "w") as f:
485484
for l in self.content[lrange[0]:lrange[1]]:
486485
if self.write_tabs == 'y':
487486
f.write(self.packtabs(l) + '\n')
488487
else:
489488
f.write(l + '\n')
489+
try: remove(fname)
490+
except: pass
491+
rename("tmpfile.pye", fname)
490492
self.changed = ' '
491493
self.undo_zero = len(self.undo)
492494
self.fname = fname
@@ -519,7 +521,8 @@ def edit_loop(self):
519521
self.set_screen_parms()
520522
self.mouse_reporting(True)
521523
while True:
522-
self.display_window()
524+
if self.not_pending():
525+
self.display_window()
523526
key = self.get_input()
524527
self.message = ''
525528
if key == 0x11:

pemin.py

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ class Editor:
1818
b"\x7f" : 0x08,
1919
b"\x1b[3~": 0x7f,
2020
b"\x1b[Z" : 0x15,
21-
b"\x1b[3;5~": 0x18,
2221
}
2322
def __init__(self, tab_size, undo_limit):
2423
self.top_line = self.cur_line = self.row = self.col = self.margin = 0
@@ -41,6 +40,8 @@ def wr(self,s):
4140
res = self.serialcomm.write(s[ns:])
4241
if res != None:
4342
ns += res
43+
def not_pending(self):
44+
return not self.serialcomm.any()
4445
def rd(self):
4546
while not self.serialcomm.any():
4647
pass
@@ -63,11 +64,11 @@ def clear_to_eol(self):
6364
def cursor(self, onoff):
6465
self.wr(b"\x1b[?25h" if onoff else b"\x1b[?25l")
6566
def hilite(self, mode):
66-
if mode == 1:
67+
if mode == 1:
6768
self.wr(b"\x1b[1m")
68-
if mode == 2:
69-
self.wr(b"\x1b[7m")
70-
else:
69+
elif mode == 2:
70+
self.wr(b"\x1b[43m")
71+
else:
7172
self.wr(b"\x1b[0m")
7273
def scroll_region(self, stop):
7374
self.wr('\x1b[1;{}r'.format(stop) if stop else '\x1b[r')
@@ -122,7 +123,7 @@ def display_window(self):
122123
i = self.top_line
123124
for c in range(self.height):
124125
if i == self.total_lines:
125-
if self.scrbuf[c][1] != '':
126+
if self.scrbuf[c] != (False,''):
126127
self.goto(c, 0)
127128
self.clear_to_eol()
128129
self.scrbuf[c] = (False,'')
@@ -132,24 +133,20 @@ def display_window(self):
132133
self.content[i][self.margin:self.margin + self.width])
133134
if l != self.scrbuf[c]:
134135
self.goto(c, 0)
135-
if l[0]:
136-
self.hilite(2)
137-
self.wr(l[1])
138-
if l[1] == '': self.wr(' ')
139-
self.hilite(0)
140-
else:
141-
self.wr(l[1])
136+
if l[0]: self.hilite(2)
137+
self.wr(l[1])
142138
if len(l[1]) < self.width:
143139
self.clear_to_eol()
140+
if l[0]: self.hilite(0)
144141
self.scrbuf[c] = l
145142
i += 1
146143
self.goto(self.height, 0)
147144
self.hilite(1)
148145
self.wr("[{}] {} Row: {} Col: {} {}".format(
149146
self.total_lines, self.changed, self.cur_line + 1,
150147
self.col + 1, self.message[:self.width - 25]))
151-
self.hilite(0)
152148
self.clear_to_eol()
149+
self.hilite(0)
153150
self.goto(self.row, self.col - self.margin)
154151
self.cursor(True)
155152
def spaces(self, line, pos = None):
@@ -243,6 +240,11 @@ def handle_cursor_keys(self, key):
243240
self.row = self.height >> 1
244241
except:
245242
pass
243+
elif key == 0x14:
244+
self.cur_line = 0
245+
elif key == 0x02:
246+
self.cur_line = self.total_lines - 1
247+
self.row = self.height - 1
246248
else:
247249
return False
248250
return True
@@ -265,6 +267,7 @@ def delete_lines(self, yank):
265267
self.cur_line = lrange[0]
266268
self.mark = None
267269
def handle_edit_key(self, key):
270+
from os import rename, remove
268271
l = self.content[self.cur_line]
269272
if key == 0x0a:
270273
self.mark = None
@@ -346,9 +349,12 @@ def handle_edit_key(self, key):
346349
lrange = (0, self.total_lines)
347350
if fname:
348351
try:
349-
with open(fname, "w") as f:
352+
with open("tmpfile.pye", "w") as f:
350353
for l in self.content[lrange[0]:lrange[1]]:
351354
f.write(l + '\n')
355+
try: remove(fname)
356+
except: pass
357+
rename("tmpfile.pye", fname)
352358
self.changed = ' '
353359
self.undo_zero = len(self.undo)
354360
self.fname = fname
@@ -380,7 +386,8 @@ def edit_loop(self):
380386
self.total_lines = len(self.content)
381387
self.set_screen_parms()
382388
while True:
383-
self.display_window()
389+
if self.not_pending():
390+
self.display_window()
384391
key = self.get_input()
385392
self.message = ''
386393
if key == 0x11:

0 commit comments

Comments
 (0)