Skip to content

Commit 4905ff6

Browse files
committed
Further improvement of Mark
1 parent 301affa commit 4905ff6

File tree

8 files changed

+311
-359
lines changed

8 files changed

+311
-359
lines changed

Pyboard Editor.doc

12.5 KB
Binary file not shown.

Pyboard Editor.pdf

41.2 KB
Binary file not shown.

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,9 @@ c) expandtabs() and packtabs() with a second argument for tabsize (not for pye,
110110
- Removed UART mode on WiPy. Not stable yet. UART mode can be achieved by redirecting REPL.
111111
- A variant of pye.py, called pye2.py, keeps the cursor column even if the cursor is moved beyond the text in a line, instead of moving to the end of text if a line is shorter than the actual cursor column. Another variant, pye3, tries to go back to the cursor column which once was set by a horizontal move. That's more how gedit works. Not sure which I like better.
112112

113+
**1.10** Further refinement of Mark
114+
- When the mark is set, the whole area affected is now highlighted instead of just the line with the mark.
115+
- Paste, Delete and Backspace now also take notice of the line Mark. You can Mark a line range and delete it (or cut it). Implicit deleting marked lines when pressing the Enter or character key was considered but rejected (easy - just 3 lines of code).
116+
- Except for Delete, Backspace, Cut and Paste, Mark has to be toggled off when not needed any more.
117+
- Right click (Button 2) or Ctrl-Click on the mouse sets/unsets the Mark, left Click extends it, when set.
118+

pe.py

Lines changed: 58 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,7 @@ def __init__(self, tab_size, undo_limit):
5656
self.case = "n"
5757
self.autoindent = "y"
5858
self.yank_buffer = []
59-
self.mark = -1
60-
self.check_mark = -1
61-
self.mark_tab = False
62-
self.msg_find = "Find: "
59+
self.mark = None
6360
self.replc_pattern = ""
6461
self.write_tabs = "n"
6562
if sys.platform == "pyboard":
@@ -89,10 +86,7 @@ def goto(self, row, col):
8986
def clear_to_eol(self):
9087
self.wr(b"\x1b[0K")
9188
def cursor(self, onoff):
92-
if onoff:
93-
self.wr(b"\x1b[?25h")
94-
else:
95-
self.wr(b"\x1b[?25l")
89+
self.wr(b"\x1b[?25h" if onoff else b"\x1b[?25l")
9690
def hilite(self, mode):
9791
if mode == 1:
9892
self.wr(b"\x1b[1m")
@@ -101,15 +95,9 @@ def hilite(self, mode):
10195
else:
10296
self.wr(b"\x1b[0m")
10397
def mouse_reporting(self, onoff):
104-
if onoff:
105-
self.wr('\x1b[?9h')
106-
else:
107-
self.wr('\x1b[?9l')
98+
self.wr('\x1b[?9h' if onoff else '\x1b[?9l')
10899
def scroll_region(self, stop):
109-
if stop:
110-
self.wr('\x1b[1;{}r'.format(stop))
111-
else:
112-
self.wr('\x1b[r')
100+
self.wr('\x1b[1;{}r'.format(stop) if stop else '\x1b[r')
113101
def scroll_up(self, scrolling):
114102
self.scrbuf[scrolling:] = self.scrbuf[:-scrolling]
115103
self.scrbuf[:scrolling] = [''] * scrolling
@@ -130,7 +118,7 @@ def set_screen_parms(self):
130118
char = self.rd()
131119
(self.height, self.width) = [int(i, 10) for i in pos[2:].split(b';')]
132120
self.height -= 1
133-
self.scrbuf = ["\x01"] * self.height
121+
self.scrbuf = [(False,"\x00")] * self.height
134122
self.scroll_region(self.height)
135123
def get_input(self):
136124
while True:
@@ -146,12 +134,12 @@ def get_input(self):
146134
if c != 0x1b:
147135
return c
148136
else:
149-
mf = ord((self.rd()))
137+
self.mouse_fct = ord((self.rd()))
150138
self.mouse_x = ord(self.rd()) - 33
151139
self.mouse_y = ord(self.rd()) - 33
152-
if mf == 0x61:
140+
if self.mouse_fct == 0x61:
153141
return 0x1d
154-
elif mf == 0x60:
142+
elif self.mouse_fct == 0x60:
155143
return 0x1c
156144
else:
157145
return 0x1b
@@ -171,23 +159,24 @@ def display_window(self):
171159
i = self.top_line
172160
for c in range(self.height):
173161
if i == self.total_lines:
174-
if self.scrbuf[c] != '':
162+
if self.scrbuf[c][1] != '':
175163
self.goto(c, 0)
176164
self.clear_to_eol()
177-
self.scrbuf[c] = ''
165+
self.scrbuf[c] = (False,'')
178166
else:
179-
l = self.content[i][self.margin:self.margin + self.width]
180-
if l != self.scrbuf[c] or i == self.check_mark:
167+
l = (self.mark != None and (
168+
(self.mark <= i <= self.cur_line) or (self.cur_line <= i <= self.mark)),
169+
self.content[i][self.margin:self.margin + self.width])
170+
if l != self.scrbuf[c]:
181171
self.goto(c, 0)
182-
if i == self.mark:
172+
if l[0]:
183173
self.hilite(2)
184-
self.wr(l)
185-
if l == "": self.wr(' ')
174+
self.wr(l[1])
175+
if l[1] == '': self.wr(' ')
186176
self.hilite(0)
187177
else:
188-
self.wr(l)
189-
if i == self.check_mark: self.check_mark = -1
190-
if len(l) < self.width:
178+
self.wr(l[1])
179+
if len(l[1]) < self.width:
191180
self.clear_to_eol()
192181
self.scrbuf[c] = l
193182
i += 1
@@ -201,18 +190,11 @@ def display_window(self):
201190
self.goto(self.row, self.col - self.margin)
202191
self.cursor(True)
203192
def spaces(self, line, pos = None):
204-
if pos == None:
205-
return len(line) - len(line.lstrip(" "))
206-
else:
207-
return len(line[:pos]) - len(line[:pos].rstrip(" "))
193+
return (len(line) - len(line.lstrip(" ")) if pos == None else
194+
len(line[:pos]) - len(line[:pos].rstrip(" ")))
208195
def line_range(self):
209-
if self.mark < 0:
210-
return (self.cur_line, self.cur_line + 1)
211-
else:
212-
if self.mark < self.cur_line:
213-
return (self.mark, self.cur_line + 1)
214-
else:
215-
return (self.cur_line, self.mark + 1)
196+
return ((self.mark, self.cur_line + 1) if self.mark < self.cur_line else
197+
(self.cur_line, self.mark + 1))
216198
def line_edit(self, prompt, default):
217199
self.goto(self.height, 0)
218200
self.hilite(1)
@@ -294,7 +276,7 @@ def handle_cursor_keys(self, key):
294276
elif key == 0x19:
295277
self.cur_line += self.height
296278
elif key == 0x06:
297-
pat = self.line_edit(self.msg_find, self.find_pattern)
279+
pat = self.line_edit("Find: ", self.find_pattern)
298280
if pat:
299281
self.find_in_file(pat, self.col, self.total_lines)
300282
self.row = self.height >> 1
@@ -314,6 +296,8 @@ def handle_cursor_keys(self, key):
314296
if self.mouse_y < self.height:
315297
self.col = self.mouse_x + self.margin
316298
self.cur_line = self.mouse_y + self.top_line
299+
if self.mouse_fct in (0x22, 0x30):
300+
self.mark = self.cur_line if self.mark == None else None
317301
elif key == 0x1c:
318302
if self.top_line > 0:
319303
self.top_line = max(self.top_line - 3, 0)
@@ -352,9 +336,20 @@ def undo_add(self, lnum, text, key, span = 1):
352336
del self.undo[0]
353337
self.undo_zero -= 1
354338
self.undo.append((lnum, span, text, key, self.col))
339+
def delete_lines(self, yank):
340+
lrange = self.line_range()
341+
if yank: self.yank_buffer = self.content[lrange[0]:lrange[1]]
342+
self.undo_add(lrange[0], self.content[lrange[0]:lrange[1]], 0, 0)
343+
del self.content[lrange[0]:lrange[1]]
344+
if self.content == []:
345+
self.content = [""]
346+
self.total_lines = len(self.content)
347+
self.cur_line = lrange[0]
348+
self.mark = None
355349
def handle_edit_key(self, key):
356350
l = self.content[self.cur_line]
357351
if key == 0x0a:
352+
self.mark = None
358353
self.undo_add(self.cur_line, [l], 0, 2)
359354
self.content[self.cur_line] = l[:self.col]
360355
ni = 0
@@ -368,7 +363,9 @@ def handle_edit_key(self, key):
368363
self.total_lines += 1
369364
self.col = ni
370365
elif key == 0x08:
371-
if self.col > 0:
366+
if self.mark != None:
367+
self.delete_lines(False)
368+
elif self.col > 0:
372369
self.undo_add(self.cur_line, [l], 0x08)
373370
self.content[self.cur_line] = l[:self.col - 1] + l[self.col:]
374371
self.col -= 1
@@ -379,16 +376,17 @@ def handle_edit_key(self, key):
379376
self.cur_line -= 1
380377
self.total_lines -= 1
381378
elif key == 0x7f:
382-
if self.col < len(l):
379+
if self.mark != None:
380+
self.delete_lines(False)
381+
elif self.col < len(l):
383382
self.undo_add(self.cur_line, [l], 0x7f)
384383
self.content[self.cur_line] = l[:self.col] + l[self.col + 1:]
385384
elif (self.cur_line + 1) < self.total_lines:
386385
self.undo_add(self.cur_line, [l, self.content[self.cur_line + 1]], 0)
387386
self.content[self.cur_line] = l + self.content.pop(self.cur_line + 1)
388387
self.total_lines -= 1
389388
elif key == 0x09:
390-
if self.mark >= 0:
391-
self.mark_tab = True
389+
if self.mark != None:
392390
lrange = self.line_range()
393391
self.undo_add(lrange[0], self.content[lrange[0]:lrange[1]], 0xffff, lrange[1] - lrange[0])
394392
for i in range(lrange[0],lrange[1]):
@@ -400,8 +398,7 @@ def handle_edit_key(self, key):
400398
self.content[self.cur_line] = l[:self.col] + ' ' * ni + l[self.col:]
401399
self.col += ni
402400
elif key == 0x15:
403-
if self.mark >= 0:
404-
self.mark_tab = True
401+
if self.mark != None:
405402
lrange = self.line_range()
406403
self.undo_add(lrange[0], self.content[lrange[0]:lrange[1]], 0xffff, lrange[1] - lrange[0])
407404
for i in range(lrange[0],lrange[1]):
@@ -416,13 +413,13 @@ def handle_edit_key(self, key):
416413
self.col -= ni
417414
elif key == 0x12:
418415
count = 0
419-
pat = self.line_edit(self.msg_find, self.find_pattern)
416+
pat = self.line_edit("Find: ", self.find_pattern)
420417
if pat:
421418
rpat = self.line_edit("Replace with: ", self.replc_pattern)
422419
if rpat != None:
423420
self.replc_pattern = rpat
424421
q = ''
425-
if self.mark >= 0:
422+
if self.mark != None:
426423
lrange = self.line_range()
427424
self.cur_line = lrange[0]
428425
else:
@@ -456,36 +453,26 @@ def handle_edit_key(self, key):
456453
self.content[self.cur_line:self.cur_line] = content
457454
self.total_lines = len(self.content)
458455
elif key == 0x0c:
459-
if self.mark < 0:
460-
self.mark = self.check_mark = self.cur_line
461-
self.mark_tab = False
462-
else:
463-
self.mark = -1
456+
self.mark = self.cur_line if self.mark == None else None
464457
elif key == 0x18:
465-
lrange = self.line_range()
466-
self.yank_buffer = self.content[lrange[0]:lrange[1]]
467-
self.undo_add(lrange[0], self.content[lrange[0]:lrange[1]], 0, 0)
468-
del self.content[lrange[0]:lrange[1]]
469-
if self.content == []:
470-
self.content = [""]
471-
self.total_lines = len(self.content)
472-
self.cur_line = lrange[0]
473-
self.mark = -1
458+
if self.mark != None:
459+
self.delete_lines(True)
474460
elif key == 0x04:
475-
lrange = self.line_range()
476-
self.yank_buffer = self.content[lrange[0]:lrange[1]]
477-
self.mark = -1
461+
if self.mark != None:
462+
lrange = self.line_range()
463+
self.yank_buffer = self.content[lrange[0]:lrange[1]]
478464
elif key == 0x16:
479465
if self.yank_buffer:
466+
if self.mark != None:
467+
self.delete_lines(False)
480468
self.undo_add(self.cur_line, None, 0, -len(self.yank_buffer))
481469
self.content[self.cur_line:self.cur_line] = self.yank_buffer
482470
self.total_lines += len(self.yank_buffer)
483471
elif key == 0x13:
484472
if False: pass
485-
elif self.mark >= 0:
473+
elif self.mark != None:
486474
fname = self.line_edit("Save Mark: ", "")
487475
lrange = self.line_range()
488-
self.mark = -1
489476
else:
490477
fname = self.fname
491478
if fname == None:
@@ -521,11 +508,12 @@ def handle_edit_key(self, key):
521508
self.total_lines = len(self.content)
522509
self.changed = ' ' if len(self.undo) == self.undo_zero else '*'
523510
elif key >= 0x20:
511+
self.mark = None
524512
self.undo_add(self.cur_line, [l], 0x20 if key == 0x20 else 0x41)
525513
self.content[self.cur_line] = l[:self.col] + chr(key) + l[self.col:]
526514
self.col += 1
527515
def edit_loop(self):
528-
if len(self.content) == 0:
516+
if self.content == []:
529517
self.content = [""]
530518
self.total_lines = len(self.content)
531519
self.set_screen_parms()
@@ -534,8 +522,6 @@ def edit_loop(self):
534522
self.display_window()
535523
key = self.get_input()
536524
self.message = ''
537-
if self.mark_tab and key != 0x09 and key != 0x15:
538-
self.mark = -1
539525
if key == 0x11:
540526
if self.changed != ' ':
541527
res = self.line_edit("Content changed! Quit without saving (y/N)? ", "N")

0 commit comments

Comments
 (0)