Skip to content

Commit caa0434

Browse files
committed
Fixing an inconsistency in the Save command
1 parent 6fe3489 commit caa0434

File tree

10 files changed

+539
-568
lines changed

10 files changed

+539
-568
lines changed

Pyboard Editor.doc

0 Bytes
Binary file not shown.

Pyboard Editor.pdf

-210 Bytes
Binary file not shown.

README.md

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ c) expandtabs() and packtabs() with a second argument for tabsize (not for pye,
3434

3535
**1.0** Initial release with all the basic functions
3636

37-
**1.1** Same function set, but simplified keyboard mapping.
37+
**1.1** Same function set, but simplified keyboard mapping.
3838
- Removed the duplicated definitions for cursor motion keys.
39-
- Allowed both \r and \n for ENTER, and both \x08 and \x7f for BACKSPACE, which avoid some hazzle with terminal settings.
39+
- Allowed both \r and \n for ENTER, and both \x08 and \x7f for BACKSPACE, which avoid some hazzle with terminal settings.
4040
- Removed auto-indent from the minimal version.
4141

4242
**1.2** Mouse support added, as well as some other minor changes.
@@ -61,16 +61,16 @@ c) expandtabs() and packtabs() with a second argument for tabsize (not for pye,
6161
- Support for WiPy added. WiPy runs only the minimal version.
6262
- Aligned function set of the minimal version, in order to comply with WiPy. Dropped Mouse support, GET file, Line number column, and write tabs; but included Tab, Backtab, the buffer functions Yank, Dup & ZAP and scrolling optimization.
6363
- LEFT and RIGHT move to the adjacent line if needed
64-
- When used with Linux **and** CPython, a terminal window resize cause redrawing the screen content. The REDRAW key (Ctrl-E) stays functional and is required for all other use cases, when the window size is changed.
64+
- When used with Linux **and** CPython, a terminal window resize cause redrawing the screen content. The REDRAW key (Ctrl-E) stays functional and is required for all other use cases, when the window size is changed.
6565
- HOME toggles again between start-of-line and start-of-text. END moves always to end-of-line
66-
- Dropped context sensitive behaviour of Tab, Backtab, Backspace and Delete. Too confusing.
66+
- Dropped context sensitive behaviour of Tab, Backtab, Backspace and Delete. Too confusing.
6767
- Dropped the line number column, and made the status line permanent in all modes.
6868
- Rearranged the code such that any platform related sections are grouped together.
6969

7070
**1.6** WiPy fixes and further trimming:
7171
- Making rarely used small functions inline again, which saves some space. Important for WiPy.
7272
- Catch Ctrl-C on WiPy. Not really nice yet, since the next input byte is lost.
73-
- Tab Size can be set with the Ctrl-A command (if available).
73+
- Tab Size can be set with the Ctrl-A command (if available).
7474
- Simplified Linux main(). No calling options any more.
7575
- Always ask when leaving w/o saving after the content was changed.
7676

@@ -99,7 +99,7 @@ c) expandtabs() and packtabs() with a second argument for tabsize (not for pye,
9999
**1.8** Clean Copy & Paste, Indent, Un-Indent
100100
- Added a Mark Line key for Line Delete, Line Copy, Indent and Un-Indent
101101
- Changed Line Delete, Line Copy and Buffer Insert into a cleaner Copy & Paste mode
102-
- Added a cleaner Indent and Un-Indent method; for WiPy too
102+
- Added a cleaner Indent and Un-Indent method; for WiPy too
103103
- Removed the attempt to recover from out-of-memory situations: did not work.
104104
- Still runs on WiPy, but really at it's limit
105105

@@ -121,8 +121,15 @@ c) expandtabs() and packtabs() with a second argument for tabsize (not for pye,
121121
- Lazy screen update: defer screen update, until all chars from the keyboard are processed. Not provided for WiPY, even if needed there most. WiPy has no way to tell if more chars are waiting in the input or at least a read with timeout.
122122

123123
**1.12** Bracket Match and Minor changes
124-
- Ctrl-K causes the cursor set to the matching bracket, if any. Pretty raw, not elegant. Brackets in comments and strings are counting as well.
124+
- Ctrl-K causes the cursor set to the matching bracket, if any. Pretty raw, not elegant.
125+
Brackets in comments and strings are counting as well.
125126
- On Copy the mark will be cleared, since it is assumed that the just copied lines will not be overwritten.
126127
- High level try/except catching internal errors (mostly coding errors)
127128
- Separate cpp options for including scroll optimization, replace or bracket match into the minimal version. Changes in strip.sh script to generate the minimal wipye version too.
128-
- Some editorial changes and fixign of tyops.
129+
- Some editorial changes and fixing of typos.
130+
131+
132+
**1.12b** Fixing a inconsistency in the Save command
133+
- Fixing a inconsistency in the Save command, which caused the change flag being reset when writing just a block
134+
- Squeezing a few lines out of the source code
135+

pe.py

Lines changed: 67 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ def wr(self,s):
6767
res = self.serialcomm.write(s[ns:])
6868
if res != None:
6969
ns += res
70-
def not_pending(self):
71-
return not self.serialcomm.any()
70+
def rd_any(self):
71+
return self.serialcomm.any()
7272
def rd(self):
7373
while not self.serialcomm.any():
7474
pass
@@ -215,7 +215,7 @@ def line_edit(self, prompt, default):
215215
elif key == 0x7f:
216216
self.wr('\b \b' * len(res))
217217
res = ''
218-
elif key >= 0x20:
218+
elif 0x20 <= key < 0xfff0:
219219
if len(prompt) + len(res) < self.width - 2:
220220
res += chr(key)
221221
self.wr(chr(key))
@@ -286,22 +286,17 @@ def handle_cursor_keys(self, key):
286286
elif key == 0x07:
287287
line = self.line_edit("Goto Line: ", "")
288288
if line:
289-
try:
290-
self.cur_line = int(line) - 1
291-
self.row = self.height >> 1
292-
except:
293-
pass
289+
self.cur_line = int(line) - 1
290+
self.row = self.height >> 1
294291
elif key == 0x01:
295-
296-
292+
self.autoindent = 'y' if self.autoindent != 'y' else 'n'
293+
self.autoindent = 'y' if self.autoindent != 'y' else 'n'
297294
pat = self.line_edit("Case Sensitive Search {}, Autoindent {}, Tab Size {}, Write Tabs {}: ".format(self.case, self.autoindent, self.tab_size, self.write_tabs), "")
298295
try:
299296
res = [i.strip().lower() for i in pat.split(",")]
300297
if res[0]: self.case = 'y' if res[0][0] == 'y' else 'n'
301298
if res[1]: self.autoindent = 'y' if res[1][0] == 'y' else 'n'
302-
if res[2]:
303-
try: self.tab_size = int(res[2])
304-
except: pass
299+
if res[2]: self.tab_size = int(res[2])
305300
if res[3]: self.write_tabs = 'y' if res[3][0] == 'y' else 'n'
306301
except:
307302
pass
@@ -341,8 +336,7 @@ def handle_cursor_keys(self, key):
341336
for c in range(pos, len(self.content[i])):
342337
if self.content[i][c] == match:
343338
if level == 0:
344-
self.cur_line = i
345-
self.col = c
339+
self.cur_line, self.col = i, c
346340
return True
347341
else:
348342
level -= 1
@@ -358,8 +352,7 @@ def handle_cursor_keys(self, key):
358352
for c in range(pos, -1, -1):
359353
if self.content[i][c] == match:
360354
if level == 0:
361-
self.cur_line = i
362-
self.col = c
355+
self.cur_line, self.col = i, c
363356
return True
364357
else:
365358
level -= 1
@@ -391,23 +384,23 @@ def delete_lines(self, yank):
391384
self.total_lines = len(self.content)
392385
self.cur_line = lrange[0]
393386
self.mark = None
394-
def handle_edit_key(self, key):
395-
from os import rename, unlink
387+
def handle_edit_keys(self, key):
396388
l = self.content[self.cur_line]
397-
if key == 0x0a:
389+
if key == 0x7f:
390+
if self.mark != None:
391+
self.delete_lines(False)
392+
elif self.col < len(l):
393+
self.undo_add(self.cur_line, [l], 0x7f)
394+
self.content[self.cur_line] = l[:self.col] + l[self.col + 1:]
395+
elif (self.cur_line + 1) < self.total_lines:
396+
self.undo_add(self.cur_line, [l, self.content[self.cur_line + 1]], 0)
397+
self.content[self.cur_line] = l + self.content.pop(self.cur_line + 1)
398+
self.total_lines -= 1
399+
elif 0x20 <= key < 0xfff0:
398400
self.mark = None
399-
self.undo_add(self.cur_line, [l], 0, 2)
400-
self.content[self.cur_line] = l[:self.col]
401-
ni = 0
402-
if self.autoindent == "y":
403-
ni = min(self.spaces(l), self.col)
404-
r = l.partition("\x23")[0].rstrip()
405-
if r and r[-1] == ':' and self.col >= len(r):
406-
ni += self.tab_size
407-
self.cur_line += 1
408-
self.content[self.cur_line:self.cur_line] = [' ' * ni + l[self.col:]]
409-
self.total_lines += 1
410-
self.col = ni
401+
self.undo_add(self.cur_line, [l], 0x20 if key == 0x20 else 0x41)
402+
self.content[self.cur_line] = l[:self.col] + chr(key) + l[self.col:]
403+
self.col += 1
411404
elif key == 0x08:
412405
if self.mark != None:
413406
self.delete_lines(False)
@@ -421,16 +414,20 @@ def handle_edit_key(self, key):
421414
self.content[self.cur_line - 1] += self.content.pop(self.cur_line)
422415
self.cur_line -= 1
423416
self.total_lines -= 1
424-
elif key == 0x7f:
425-
if self.mark != None:
426-
self.delete_lines(False)
427-
elif self.col < len(l):
428-
self.undo_add(self.cur_line, [l], 0x7f)
429-
self.content[self.cur_line] = l[:self.col] + l[self.col + 1:]
430-
elif (self.cur_line + 1) < self.total_lines:
431-
self.undo_add(self.cur_line, [l, self.content[self.cur_line + 1]], 0)
432-
self.content[self.cur_line] = l + self.content.pop(self.cur_line + 1)
433-
self.total_lines -= 1
417+
elif key == 0x0a:
418+
self.mark = None
419+
self.undo_add(self.cur_line, [l], 0, 2)
420+
self.content[self.cur_line] = l[:self.col]
421+
ni = 0
422+
if self.autoindent == "y":
423+
ni = min(self.spaces(l), self.col)
424+
r = l.partition("\x23")[0].rstrip()
425+
if r and r[-1] == ':' and self.col >= len(r):
426+
ni += self.tab_size
427+
self.cur_line += 1
428+
self.content[self.cur_line:self.cur_line] = [' ' * ni + l[self.col:]]
429+
self.total_lines += 1
430+
self.col = ni
434431
elif key == 0x09:
435432
if self.mark != None:
436433
lrange = self.line_range()
@@ -520,28 +517,16 @@ def handle_edit_key(self, key):
520517
if self.mark != None:
521518
fname = self.line_edit("Save Mark: ", "")
522519
lrange = self.line_range()
520+
self.put_file(fname, lrange[0], lrange[1])
523521
else:
524522
fname = self.fname
525523
if fname == None:
526524
fname = ""
527525
fname = self.line_edit("Save File: ", fname)
528-
lrange = (0, self.total_lines)
529-
if fname:
530-
try:
531-
with open("tmpfile.pye", "w") as f:
532-
for l in self.content[lrange[0]:lrange[1]]:
533-
if self.write_tabs == 'y':
534-
f.write(self.packtabs(l) + '\n')
535-
else:
536-
f.write(l + '\n')
537-
try: unlink(fname)
538-
except: pass
539-
rename("tmpfile.pye", fname)
526+
self.put_file(fname, 0, self.total_lines)
540527
self.changed = ' '
541528
self.undo_zero = len(self.undo)
542529
self.fname = fname
543-
except Exception as err:
544-
self.message = 'Could not save {}, {!r}'.format(fname, err)
545530
elif key == 0x1a:
546531
if len(self.undo) > 0:
547532
action = self.undo.pop(-1)
@@ -558,24 +543,25 @@ def handle_edit_key(self, key):
558543
self.total_lines = len(self.content)
559544
self.changed = ' ' if len(self.undo) == self.undo_zero else '*'
560545
self.mark = None
561-
elif key >= 0x20:
562-
self.mark = None
563-
self.undo_add(self.cur_line, [l], 0x20 if key == 0x20 else 0x41)
564-
self.content[self.cur_line] = l[:self.col] + chr(key) + l[self.col:]
565-
self.col += 1
566546
def edit_loop(self):
567547
if self.content == []:
568548
self.content = [""]
569549
self.total_lines = len(self.content)
570-
self.set_screen_parms()
571550
self.mouse_reporting(True)
572-
self.scroll_region(self.height)
551+
key = 0x05
573552
while True:
574-
if self.not_pending():
575-
self.display_window()
576-
key = self.get_input()
577-
self.message = ''
578553
try:
554+
if key == 0x05:
555+
self.set_screen_parms()
556+
self.row = min(self.height - 1, self.row)
557+
self.scroll_region(self.height)
558+
if sys.implementation.name == "micropython":
559+
gc.collect()
560+
self.message = "{} Bytes Memory available".format(gc.mem_free())
561+
if not self.rd_any():
562+
self.display_window()
563+
key = self.get_input()
564+
self.message = ''
579565
if key == 0x11:
580566
if self.changed != ' ':
581567
res = self.line_edit("Content changed! Quit without saving (y/N)? ", "N")
@@ -586,17 +572,11 @@ def edit_loop(self):
586572
self.goto(self.height, 0)
587573
self.clear_to_eol()
588574
return None
589-
elif key == 0x05:
590-
self.set_screen_parms()
591-
self.row = min(self.height - 1, self.row)
592-
if sys.implementation.name == "micropython":
593-
gc.collect()
594-
self.message = "{} Bytes Memory available".format(gc.mem_free())
595575
elif self.handle_cursor_keys(key):
596576
pass
597-
else: self.handle_edit_key(key)
577+
else: self.handle_edit_keys(key)
598578
except Exception as err:
599-
self.message = "Internal error: {}".format(err)
579+
self.message = "{}".format(err)
600580
def packtabs(self, s):
601581
from _io import StringIO
602582
sb = StringIO()
@@ -618,6 +598,18 @@ def get_file(self, fname):
618598
for i in range(len(content)):
619599
content[i] = expandtabs(content[i].rstrip('\r\n\t '))
620600
return (content, "")
601+
def put_file(self, fname, start, stop):
602+
from os import rename, unlink
603+
if fname:
604+
with open("tmpfile.pye", "w") as f:
605+
for l in self.content[start:stop]:
606+
if self.write_tabs == 'y':
607+
f.write(self.packtabs(l) + '\n')
608+
else:
609+
f.write(l + '\n')
610+
try: unlink(fname)
611+
except: pass
612+
rename("tmpfile.pye", fname)
621613
def expandtabs(s):
622614
from _io import StringIO
623615
if '\t' in s:

0 commit comments

Comments
 (0)