Skip to content

Commit 551b1f7

Browse files
committed
Minor fixes in File handling
1 parent 9bd3f09 commit 551b1f7

File tree

4 files changed

+157
-122
lines changed

4 files changed

+157
-122
lines changed

README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ A small text editor written in Python running on PYBoard and WiPy, allowing to e
1313

1414
The editor assumes a VT100 terminal. It works in Insert mode. Cursor Keys, Home, End, PgUp, PgDn, Del and Backspace work as you would expect. The additional functions like FIND etc. are available with Ctrl-Keys. On reading files, tab characters are expanded to spaces with a tab size of 8, and trailing white space on a line will be discarded. The orginal state of tabs will not be restored when the file is written. Optionally, tabs can be written when saving the file, replacing spaces with tabs when possible. The screen size is determined, when the editor is started or when the Redraw-key (Ctrl-E) is hit.
1515

16-
The editor works also well in a Linux or MAC terminal environment, with both python3 and micropython. For that purpose, a small main() section is embedded, which when called with CPython also accepts data from a pipe or redirection.
16+
The editor works also well in a Linux or MAC terminal environment (and also in some terminal apps of Android - tested with Termux), with both python3 and micropython. For that purpose, a small main() section is embedded, which when called with CPython also accepts data from a pipe or redirection.
1717

1818
**Files:**
1919

@@ -28,7 +28,7 @@ The editor works also well in a Linux or MAC terminal environment, with both pyt
2828
a) find_in_file() supporting regular expressions,
2929
b) line_edit() supporting the cursor left/right/home/end keys, and
3030
c) expandtabs() and packtabs() with a second argument for tabsize (not for pye, but maybe useful)
31-
- strip.sh: sample Shell script which creates the different variants out of pye.py using cpp, including variants of wipye.py with either speed up scrolling or support replace or support got bracket.
31+
- strip.sh: sample Shell script which creates the different variants out of pye.py using cpp, including all variants of wipye.py with either speed up scrolling or support replace or support goto bracket or support indent/un-indent or support mouse.
3232
- pye_vt.py: a variant of pye.py, where all directly screen related functions are placed into a separate class. That's a better style, however it uses more memory. This file is just given as exmaple and not maintained.
3333

3434
**Short Version History**
@@ -161,7 +161,13 @@ The final code saving is just a few hundred bytes, so it's still not clear to me
161161
**2.2** Further cleaning and some slight improvements
162162
- Moved error catching one level up to the function pye(), catching load-file errors too.
163163
- If open file names a directory, the list of files is loaded to the edit buffer.
164-
- Ctrl-V in line edit mode gets the first line of the paste buffer.
164+
- Ctrl-V in line edit mode inserts the first line of the paste buffer
165165
- The WiPy version does not support undo for Indent/Un-indent, even if Indent is enabled. It is too memory consuming at runtime. It's questionable whether this is needed at all.
166166
- And of course: update of the doc file
167167

168+
**2.3** Minor fixes
169+
- Catched file not found errors when starting pye, introduced in version 2.2
170+
- Added a flag to pye2 such that it supports both vertical cursor movement types
171+
- use uos.stat with micropython, since os.stat is not supported on linux-micropython
172+
- When opening a directory, replace the name '.' by the result of os.getcwd(), avoiding error 22 of stat() call on PyBoard and WiPy
173+

pye.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ def line_edit(self, prompt, default): ## simple one: only 4 fcts
460460
res += chr(key)
461461
self.wr(chr(key))
462462

463-
def find_in_file(self, pattern, pos, end):
463+
def find_in_file(self, pattern, pos, end_line):
464464
Editor.find_pattern = pattern # remember it
465465
if True:
466466
#ifndef BASIC
@@ -469,7 +469,7 @@ def find_in_file(self, pattern, pos, end):
469469
#endif
470470
pattern = pattern.lower()
471471
spos = pos
472-
for line in range(self.cur_line, end):
472+
for line in range(self.cur_line, end_line):
473473
if True:
474474
#ifndef BASIC
475475
if Editor.case == "y":
@@ -863,14 +863,18 @@ def packtabs(self, s):
863863
#endif
864864
## Read file into content
865865
def get_file(self, fname):
866-
import os
866+
from os import listdir, getcwd
867+
try: from uos import stat
868+
except: from os import stat
869+
867870
if not fname:
868871
fname = self.line_edit("Open file: ", "")
869872
if fname:
870-
if (os.stat(fname)[0] & 0x4000): ## Dir
871-
self.content = sorted(os.listdir(fname))
873+
self.fname = fname
874+
if fname == '.': fname = getcwd()
875+
if (stat(fname)[0] & 0x4000): ## Dir
876+
self.content = ["Directory '{}'".format(fname), ""] + sorted(listdir(fname))
872877
else:
873-
self.fname = fname
874878
if True:
875879
#ifdef LINUX
876880
pass
@@ -886,7 +890,7 @@ def get_file(self, fname):
886890

887891
## write file
888892
def put_file(self, fname):
889-
import os
893+
from os import unlink, rename
890894
with open("tmpfile.pye", "w") as f:
891895
for l in self.content:
892896
#ifndef BASIC
@@ -895,9 +899,9 @@ def put_file(self, fname):
895899
else:
896900
#endif
897901
f.write(l + '\n')
898-
try: os.unlink(fname)
902+
try: unlink(fname)
899903
except: pass
900-
os.rename("tmpfile.pye", fname)
904+
rename("tmpfile.pye", fname)
901905

902906
## expandtabs: hopefully sometimes replaced by the built-in function
903907
def expandtabs(s):
@@ -925,7 +929,8 @@ def pye(*content, tab_size = 4, undo = 50, device = 0, baud = 115200):
925929
for f in content:
926930
if index: slot.append(Editor(tab_size, undo))
927931
if type(f) == str and f: ## String = non-empty Filename
928-
slot[index].get_file(f)
932+
try: slot[index].get_file(f)
933+
except: slot[index].message = "File not found"
929934
elif type(f) == list and len(f) > 0 and type(f[0]) == str:
930935
slot[index].content = f ## non-empty list of strings -> edit
931936
index += 1

pye2.py

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ def __init__(self, tab_size, undo_limit):
185185
self.undo_zero = 0
186186
self.autoindent = "y"
187187
self.mark = None
188+
self.straight = "y"
188189
#ifdef LINUX
189190
if sys.platform in ("linux", "darwin"):
190191

@@ -376,6 +377,9 @@ def display_window(self): ## Update window and status line
376377
## Force cur_line and col to be in the reasonable bounds
377378
self.cur_line = min(self.total_lines - 1, max(self.cur_line, 0))
378379
## Check if Column is out of view, and align margin if needed
380+
if self.straight != "y":
381+
self.col = min(self.col, len(self.content[self.cur_line]))
382+
if self.col < 0: self.col = 0
379383
if self.col >= Editor.width + self.margin:
380384
self.margin = self.col - Editor.width + (Editor.width >> 2)
381385
elif self.col < self.margin:
@@ -509,7 +513,7 @@ def delete_lines(self, yank): ## copy marked lines (opt) and delete them
509513

510514
def handle_edit_keys(self, key): ## keys which change content
511515
l = self.content[self.cur_line]
512-
jut = self.col - len(l) ## <0: before text end, =0 at text end, >0 beyond text end
516+
jut = self.col - len(l) ## <0: before text end, = 0 at text end, >0 beyond text end
513517
if key == KEY_DOWN:
514518
#ifdef SCROLL
515519
if self.cur_line < self.total_lines - 1:
@@ -539,9 +543,19 @@ def handle_edit_keys(self, key): ## keys which change content
539543
#endif
540544
else:
541545
#endif
542-
if self.col > 0: self.col -= 1
546+
self.col -= 1
543547
elif key == KEY_RIGHT:
544-
self.col += 1
548+
#ifndef BASIC
549+
if self.straight != "y" and self.col >= len(l) and self.cur_line < self.total_lines - 1:
550+
self.col = 0
551+
self.cur_line += 1
552+
#ifdef SCROLL
553+
if self.cur_line == self.top_line + Editor.height:
554+
self.scroll_down(1)
555+
#endif
556+
else:
557+
#endif
558+
self.col += 1
545559
elif key == KEY_DELETE:
546560
if self.mark != None:
547561
self.delete_lines(False)
@@ -558,7 +572,7 @@ def handle_edit_keys(self, key): ## keys which change content
558572
if self.mark != None:
559573
self.delete_lines(False)
560574
elif self.col > 0:
561-
if jut < 0: ## if on solid ground
575+
if jut <= 0: ## if on solid ground
562576
self.undo_add(self.cur_line, [l], KEY_BACKSPACE)
563577
self.content[self.cur_line] = l[:self.col - 1] + l[self.col:]
564578
self.col -= 1
@@ -572,11 +586,10 @@ def handle_edit_keys(self, key): ## keys which change content
572586
#endif
573587
elif 0x20 <= key < 0xfff0: ## character to be added
574588
self.mark = None
589+
self.undo_add(self.cur_line, [l], 0x20 if key == 0x20 else 0x41)
575590
if jut < 0:
576-
self.undo_add(self.cur_line, [l], 0x20 if key == 0x20 else 0x41)
577591
self.content[self.cur_line] = l[:self.col] + chr(key) + l[self.col:]
578-
elif key != 0x20:
579-
self.undo_add(self.cur_line, [l], 0x41)
592+
else:
580593
self.content[self.cur_line] = l + ' ' * jut + chr(key)
581594
self.col += 1
582595
elif key == KEY_HOME:
@@ -612,13 +625,16 @@ def handle_edit_keys(self, key): ## keys which change content
612625
elif key == KEY_TOGGLE: ## Toggle Autoindent/Statusline/Search case
613626
if True:
614627
#ifndef BASIC
615-
pat = self.line_edit("Case Sensitive Search {}, Autoindent {}, Tab Size {}, Write Tabs {}: ".format(Editor.case, self.autoindent, self.tab_size, Editor.write_tabs), "")
628+
pat = self.line_edit(
629+
"Case Sensitive Search {}, Autoindent {}, Tab Size {}, Write Tabs {}, Straight Cursor {}: ".format(
630+
Editor.case, self.autoindent, self.tab_size, Editor.write_tabs, self.straight), "")
616631
try:
617632
res = [i.strip().lower() for i in pat.split(",")]
618633
if res[0]: Editor.case = 'y' if res[0][0] == 'y' else 'n'
619634
if res[1]: self.autoindent = 'y' if res[1][0] == 'y' else 'n'
620635
if res[2]: self.tab_size = int(res[2])
621636
if res[3]: Editor.write_tabs = 'y' if res[3][0] == 'y' else 'n'
637+
if res[4]: self.straight = 'y' if res[4][0] == 'y' else 'n'
622638
except:
623639
pass
624640
else:
@@ -697,17 +713,19 @@ def handle_edit_keys(self, key): ## keys which change content
697713
if self.autoindent == "y": ## Autoindent
698714
ni = min(self.spaces(l), self.col) ## query indentation
699715
self.cur_line += 1
700-
self.content[self.cur_line:self.cur_line] = [' ' * ni + l[self.col:]] if jut < 0 else [""]
716+
self.content[self.cur_line:self.cur_line] = [' ' * ni + l[self.col:]]
701717
self.total_lines += 1
702718
self.col = ni
703719
elif key == KEY_TAB:
704720
#ifdef INDENT
705721
if self.mark == None:
706722
#endif
707723
ni = self.tab_size - self.col % self.tab_size ## determine spaces to add
724+
self.undo_add(self.cur_line, [l], KEY_TAB)
708725
if jut < 0:
709-
self.undo_add(self.cur_line, [l], KEY_TAB)
710726
self.content[self.cur_line] = l[:self.col] + ' ' * ni + l[self.col:]
727+
else:
728+
self.content[self.cur_line] = l + ' ' * (jut + ni)
711729
self.col += ni
712730
#ifdef INDENT
713731
else:
@@ -724,7 +742,7 @@ def handle_edit_keys(self, key): ## keys which change content
724742
if self.mark == None:
725743
#endif
726744
ni = (self.col - 1) % self.tab_size + 1
727-
if jut < 0:
745+
if jut <= 0:
728746
ni = min(ni, self.spaces(l, self.col)) ## determine spaces to drop
729747
if ni > 0:
730748
self.undo_add(self.cur_line, [l], KEY_BACKTAB)
@@ -783,7 +801,7 @@ def handle_edit_keys(self, key): ## keys which change content
783801
elif key == KEY_YANK: # delete line or line(s) into buffer
784802
if self.mark != None: self.delete_lines(True)
785803
elif key == KEY_DUP: # copy line(s) into buffer
786-
if self.mark != None:
804+
if self.mark != None:
787805
lrange = self.line_range()
788806
Editor.yank_buffer = self.content[lrange[0]:lrange[1]]
789807
self.mark = None
@@ -864,14 +882,18 @@ def packtabs(self, s):
864882
#endif
865883
## Read file into content
866884
def get_file(self, fname):
867-
import os
885+
from os import listdir, getcwd
886+
try: from uos import stat
887+
except: from os import stat
888+
868889
if not fname:
869890
fname = self.line_edit("Open file: ", "")
870891
if fname:
871-
if (os.stat(fname)[0] & 0x4000):
872-
self.content = sorted(os.listdir(fname))
892+
self.fname = fname
893+
if fname == '.': fname = getcwd()
894+
if (stat(fname)[0] & 0x4000): ## Dir
895+
self.content = ["Directory '{}'".format(fname), ""] + sorted(listdir(fname))
873896
else:
874-
self.fname = fname
875897
if True:
876898
#ifdef LINUX
877899
pass
@@ -887,7 +909,7 @@ def get_file(self, fname):
887909

888910
## write file
889911
def put_file(self, fname):
890-
import os
912+
from os import unlink, rename
891913
with open("tmpfile.pye", "w") as f:
892914
for l in self.content:
893915
#ifndef BASIC
@@ -896,9 +918,9 @@ def put_file(self, fname):
896918
else:
897919
#endif
898920
f.write(l + '\n')
899-
try: os.unlink(fname)
921+
try: unlink(fname)
900922
except: pass
901-
os.rename("tmpfile.pye", fname)
923+
rename("tmpfile.pye", fname)
902924

903925
## expandtabs: hopefully sometimes replaced by the built-in function
904926
def expandtabs(s):
@@ -926,7 +948,8 @@ def pye(*content, tab_size = 4, undo = 50, device = 0, baud = 115200):
926948
for f in content:
927949
if index: slot.append(Editor(tab_size, undo))
928950
if type(f) == str and f: ## String = non-empty Filename
929-
slot[index].get_file(f)
951+
try: slot[index].get_file(f)
952+
except: slot[index].message = "File not found"
930953
elif type(f) == list and len(f) > 0 and type(f[0]) == str:
931954
slot[index].content = f ## non-empty list of strings -> edit
932955
index += 1

0 commit comments

Comments
 (0)