From 551b1f70ef0562081525eb60f43412a22fe5d31d Mon Sep 17 00:00:00 2001 From: Robert HH Date: Sun, 24 Jan 2016 21:24:17 +0100 Subject: [PATCH] Minor fixes in File handling --- README.md | 12 +++- pye.py | 25 +++++--- pye2.py | 63 +++++++++++++------ wipye.py | 179 +++++++++++++++++++++++++++--------------------------- 4 files changed, 157 insertions(+), 122 deletions(-) diff --git a/README.md b/README.md index 3bbf9c2..70a1cdd 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ A small text editor written in Python running on PYBoard and WiPy, allowing to e 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. -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. +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. **Files:** @@ -28,7 +28,7 @@ The editor works also well in a Linux or MAC terminal environment, with both pyt a) find_in_file() supporting regular expressions, b) line_edit() supporting the cursor left/right/home/end keys, and c) expandtabs() and packtabs() with a second argument for tabsize (not for pye, but maybe useful) -- 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. +- 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. - 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. **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 **2.2** Further cleaning and some slight improvements - Moved error catching one level up to the function pye(), catching load-file errors too. - If open file names a directory, the list of files is loaded to the edit buffer. -- Ctrl-V in line edit mode gets the first line of the paste buffer. +- Ctrl-V in line edit mode inserts the first line of the paste buffer - 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. - And of course: update of the doc file +**2.3** Minor fixes +- Catched file not found errors when starting pye, introduced in version 2.2 +- Added a flag to pye2 such that it supports both vertical cursor movement types +- use uos.stat with micropython, since os.stat is not supported on linux-micropython +- When opening a directory, replace the name '.' by the result of os.getcwd(), avoiding error 22 of stat() call on PyBoard and WiPy + diff --git a/pye.py b/pye.py index cf63bec..05b9c9b 100644 --- a/pye.py +++ b/pye.py @@ -460,7 +460,7 @@ def line_edit(self, prompt, default): ## simple one: only 4 fcts res += chr(key) self.wr(chr(key)) - def find_in_file(self, pattern, pos, end): + def find_in_file(self, pattern, pos, end_line): Editor.find_pattern = pattern # remember it if True: #ifndef BASIC @@ -469,7 +469,7 @@ def find_in_file(self, pattern, pos, end): #endif pattern = pattern.lower() spos = pos - for line in range(self.cur_line, end): + for line in range(self.cur_line, end_line): if True: #ifndef BASIC if Editor.case == "y": @@ -863,14 +863,18 @@ def packtabs(self, s): #endif ## Read file into content def get_file(self, fname): - import os + from os import listdir, getcwd + try: from uos import stat + except: from os import stat + if not fname: fname = self.line_edit("Open file: ", "") if fname: - if (os.stat(fname)[0] & 0x4000): ## Dir - self.content = sorted(os.listdir(fname)) + self.fname = fname + if fname == '.': fname = getcwd() + if (stat(fname)[0] & 0x4000): ## Dir + self.content = ["Directory '{}'".format(fname), ""] + sorted(listdir(fname)) else: - self.fname = fname if True: #ifdef LINUX pass @@ -886,7 +890,7 @@ def get_file(self, fname): ## write file def put_file(self, fname): - import os + from os import unlink, rename with open("tmpfile.pye", "w") as f: for l in self.content: #ifndef BASIC @@ -895,9 +899,9 @@ def put_file(self, fname): else: #endif f.write(l + '\n') - try: os.unlink(fname) + try: unlink(fname) except: pass - os.rename("tmpfile.pye", fname) + rename("tmpfile.pye", fname) ## expandtabs: hopefully sometimes replaced by the built-in function def expandtabs(s): @@ -925,7 +929,8 @@ def pye(*content, tab_size = 4, undo = 50, device = 0, baud = 115200): for f in content: if index: slot.append(Editor(tab_size, undo)) if type(f) == str and f: ## String = non-empty Filename - slot[index].get_file(f) + try: slot[index].get_file(f) + except: slot[index].message = "File not found" elif type(f) == list and len(f) > 0 and type(f[0]) == str: slot[index].content = f ## non-empty list of strings -> edit index += 1 diff --git a/pye2.py b/pye2.py index 128828f..c95091f 100644 --- a/pye2.py +++ b/pye2.py @@ -185,6 +185,7 @@ def __init__(self, tab_size, undo_limit): self.undo_zero = 0 self.autoindent = "y" self.mark = None + self.straight = "y" #ifdef LINUX if sys.platform in ("linux", "darwin"): @@ -376,6 +377,9 @@ def display_window(self): ## Update window and status line ## Force cur_line and col to be in the reasonable bounds self.cur_line = min(self.total_lines - 1, max(self.cur_line, 0)) ## Check if Column is out of view, and align margin if needed + if self.straight != "y": + self.col = min(self.col, len(self.content[self.cur_line])) + if self.col < 0: self.col = 0 if self.col >= Editor.width + self.margin: self.margin = self.col - Editor.width + (Editor.width >> 2) elif self.col < self.margin: @@ -509,7 +513,7 @@ def delete_lines(self, yank): ## copy marked lines (opt) and delete them def handle_edit_keys(self, key): ## keys which change content l = self.content[self.cur_line] - jut = self.col - len(l) ## <0: before text end, =0 at text end, >0 beyond text end + jut = self.col - len(l) ## <0: before text end, = 0 at text end, >0 beyond text end if key == KEY_DOWN: #ifdef SCROLL if self.cur_line < self.total_lines - 1: @@ -539,9 +543,19 @@ def handle_edit_keys(self, key): ## keys which change content #endif else: #endif - if self.col > 0: self.col -= 1 + self.col -= 1 elif key == KEY_RIGHT: - self.col += 1 +#ifndef BASIC + if self.straight != "y" and self.col >= len(l) and self.cur_line < self.total_lines - 1: + self.col = 0 + self.cur_line += 1 +#ifdef SCROLL + if self.cur_line == self.top_line + Editor.height: + self.scroll_down(1) +#endif + else: +#endif + self.col += 1 elif key == KEY_DELETE: if self.mark != None: self.delete_lines(False) @@ -558,7 +572,7 @@ def handle_edit_keys(self, key): ## keys which change content if self.mark != None: self.delete_lines(False) elif self.col > 0: - if jut < 0: ## if on solid ground + if jut <= 0: ## if on solid ground self.undo_add(self.cur_line, [l], KEY_BACKSPACE) self.content[self.cur_line] = l[:self.col - 1] + l[self.col:] self.col -= 1 @@ -572,11 +586,10 @@ def handle_edit_keys(self, key): ## keys which change content #endif elif 0x20 <= key < 0xfff0: ## character to be added self.mark = None + self.undo_add(self.cur_line, [l], 0x20 if key == 0x20 else 0x41) if jut < 0: - self.undo_add(self.cur_line, [l], 0x20 if key == 0x20 else 0x41) self.content[self.cur_line] = l[:self.col] + chr(key) + l[self.col:] - elif key != 0x20: - self.undo_add(self.cur_line, [l], 0x41) + else: self.content[self.cur_line] = l + ' ' * jut + chr(key) self.col += 1 elif key == KEY_HOME: @@ -612,13 +625,16 @@ def handle_edit_keys(self, key): ## keys which change content elif key == KEY_TOGGLE: ## Toggle Autoindent/Statusline/Search case if True: #ifndef BASIC - pat = self.line_edit("Case Sensitive Search {}, Autoindent {}, Tab Size {}, Write Tabs {}: ".format(Editor.case, self.autoindent, self.tab_size, Editor.write_tabs), "") + pat = self.line_edit( + "Case Sensitive Search {}, Autoindent {}, Tab Size {}, Write Tabs {}, Straight Cursor {}: ".format( + Editor.case, self.autoindent, self.tab_size, Editor.write_tabs, self.straight), "") try: res = [i.strip().lower() for i in pat.split(",")] if res[0]: Editor.case = 'y' if res[0][0] == 'y' else 'n' if res[1]: self.autoindent = 'y' if res[1][0] == 'y' else 'n' if res[2]: self.tab_size = int(res[2]) if res[3]: Editor.write_tabs = 'y' if res[3][0] == 'y' else 'n' + if res[4]: self.straight = 'y' if res[4][0] == 'y' else 'n' except: pass else: @@ -697,7 +713,7 @@ def handle_edit_keys(self, key): ## keys which change content if self.autoindent == "y": ## Autoindent ni = min(self.spaces(l), self.col) ## query indentation self.cur_line += 1 - self.content[self.cur_line:self.cur_line] = [' ' * ni + l[self.col:]] if jut < 0 else [""] + self.content[self.cur_line:self.cur_line] = [' ' * ni + l[self.col:]] self.total_lines += 1 self.col = ni elif key == KEY_TAB: @@ -705,9 +721,11 @@ def handle_edit_keys(self, key): ## keys which change content if self.mark == None: #endif ni = self.tab_size - self.col % self.tab_size ## determine spaces to add + self.undo_add(self.cur_line, [l], KEY_TAB) if jut < 0: - self.undo_add(self.cur_line, [l], KEY_TAB) self.content[self.cur_line] = l[:self.col] + ' ' * ni + l[self.col:] + else: + self.content[self.cur_line] = l + ' ' * (jut + ni) self.col += ni #ifdef INDENT else: @@ -724,7 +742,7 @@ def handle_edit_keys(self, key): ## keys which change content if self.mark == None: #endif ni = (self.col - 1) % self.tab_size + 1 - if jut < 0: + if jut <= 0: ni = min(ni, self.spaces(l, self.col)) ## determine spaces to drop if ni > 0: self.undo_add(self.cur_line, [l], KEY_BACKTAB) @@ -783,7 +801,7 @@ def handle_edit_keys(self, key): ## keys which change content elif key == KEY_YANK: # delete line or line(s) into buffer if self.mark != None: self.delete_lines(True) elif key == KEY_DUP: # copy line(s) into buffer - if self.mark != None: + if self.mark != None: lrange = self.line_range() Editor.yank_buffer = self.content[lrange[0]:lrange[1]] self.mark = None @@ -864,14 +882,18 @@ def packtabs(self, s): #endif ## Read file into content def get_file(self, fname): - import os + from os import listdir, getcwd + try: from uos import stat + except: from os import stat + if not fname: fname = self.line_edit("Open file: ", "") if fname: - if (os.stat(fname)[0] & 0x4000): - self.content = sorted(os.listdir(fname)) + self.fname = fname + if fname == '.': fname = getcwd() + if (stat(fname)[0] & 0x4000): ## Dir + self.content = ["Directory '{}'".format(fname), ""] + sorted(listdir(fname)) else: - self.fname = fname if True: #ifdef LINUX pass @@ -887,7 +909,7 @@ def get_file(self, fname): ## write file def put_file(self, fname): - import os + from os import unlink, rename with open("tmpfile.pye", "w") as f: for l in self.content: #ifndef BASIC @@ -896,9 +918,9 @@ def put_file(self, fname): else: #endif f.write(l + '\n') - try: os.unlink(fname) + try: unlink(fname) except: pass - os.rename("tmpfile.pye", fname) + rename("tmpfile.pye", fname) ## expandtabs: hopefully sometimes replaced by the built-in function def expandtabs(s): @@ -926,7 +948,8 @@ def pye(*content, tab_size = 4, undo = 50, device = 0, baud = 115200): for f in content: if index: slot.append(Editor(tab_size, undo)) if type(f) == str and f: ## String = non-empty Filename - slot[index].get_file(f) + try: slot[index].get_file(f) + except: slot[index].message = "File not found" elif type(f) == list and len(f) > 0 and type(f[0]) == str: slot[index].content = f ## non-empty list of strings -> edit index += 1 diff --git a/wipye.py b/wipye.py index 3842c61..1121d3e 100644 --- a/wipye.py +++ b/wipye.py @@ -1,23 +1,23 @@ import sys, gc class Editor: - KEYMAP = { + KEYMAP = { b"\x1b[A" : 0x0b, b"\x1b[B" : 0x0d, b"\x1b[D" : 0x1f, b"\x1b[C" : 0x1e, - b"\x1b[H" : 0x10, - b"\x1bOH" : 0x10, - b"\x1b[1~": 0x10, - b"\x1b[F" : 0x03, - b"\x1bOF" : 0x03, - b"\x1b[4~": 0x03, + b"\x1b[H" : 0x10, + b"\x1bOH" : 0x10, + b"\x1b[1~": 0x10, + b"\x1b[F" : 0x03, + b"\x1bOF" : 0x03, + b"\x1b[4~": 0x03, b"\x1b[5~": 0xfff1, b"\x1b[6~": 0xfff2, - b"\x03" : 0x11, + b"\x03" : 0x11, b"\r" : 0x0a, - b"\x7f" : 0x08, + b"\x7f" : 0x08, b"\x1b[3~": 0x7f, - b"\x1b[Z" : 0x15, + b"\x1b[Z" : 0x15, } yank_buffer = [] find_pattern = "" @@ -48,16 +48,16 @@ def clear_to_eol(self): def cursor(self, onoff): self.wr(b"\x1b[?25h" if onoff else b"\x1b[?25l") def hilite(self, mode): - if mode == 1: + if mode == 1: self.wr(b"\x1b[1;47m") - elif mode == 2: + elif mode == 2: self.wr(b"\x1b[43m") - else: + else: self.wr(b"\x1b[0m") def get_screen_size(self): self.wr('\x1b[999;999H\x1b[6n') pos = b'' - char = self.rd() + char = self.rd() while char != b'R': pos += char char = self.rd() @@ -66,15 +66,15 @@ def redraw(self, flag): self.cursor(False) Editor.height, Editor.width = self.get_screen_size() Editor.height -= 1 - Editor.scrbuf = [(False,"\x00")] * Editor.height + Editor.scrbuf = [(False,"\x00")] * Editor.height self.row = min(Editor.height - 1, self.row) if sys.implementation.name == "micropython": gc.collect() if flag: self.message = "{} Bytes Memory available".format(gc.mem_free()) - def get_input(self): + def get_input(self): while True: in_buffer = self.rd() - if in_buffer == b'\x1b': + if in_buffer == b'\x1b': while True: in_buffer += self.rd() c = chr(in_buffer[-1]) @@ -84,22 +84,22 @@ def get_input(self): c = self.KEYMAP[in_buffer] if c != 0x1b: return c - elif len(in_buffer) == 1: + elif len(in_buffer) == 1: return in_buffer[0] - def display_window(self): + def display_window(self): self.cur_line = min(self.total_lines - 1, max(self.cur_line, 0)) self.col = max(0, min(self.col, len(self.content[self.cur_line]))) if self.col >= Editor.width + self.margin: self.margin = self.col - Editor.width + (Editor.width >> 2) elif self.col < self.margin: self.margin = max(self.col - (Editor.width >> 2), 0) - if not (self.top_line <= self.cur_line < self.top_line + Editor.height): + if not (self.top_line <= self.cur_line < self.top_line + Editor.height): self.top_line = max(self.cur_line - self.row, 0) self.row = self.cur_line - self.top_line self.cursor(False) i = self.top_line for c in range(Editor.height): - if i == self.total_lines: + if i == self.total_lines: if Editor.scrbuf[c] != (False,''): self.goto(c, 0) self.clear_to_eol() @@ -108,7 +108,7 @@ def display_window(self): l = (self.mark != None and ( (self.mark <= i <= self.cur_line) or (self.cur_line <= i <= self.mark)), self.content[i][self.margin:self.margin + Editor.width]) - if l != Editor.scrbuf[c]: + if l != Editor.scrbuf[c]: self.goto(c, 0) if l[0]: self.hilite(2) self.wr(l[1]) @@ -122,17 +122,17 @@ def display_window(self): self.wr("{}{} Row: {}/{} Col: {} {}".format( self.changed, self.fname, self.cur_line + 1, self.total_lines, self.col + 1, self.message)[:self.width - 1]) - self.clear_to_eol() + self.clear_to_eol() self.hilite(0) self.goto(self.row, self.col - self.margin) self.cursor(True) - def spaces(self, line, pos = None): - return (len(line) - len(line.lstrip(" ")) if pos == None else + def spaces(self, line, pos = None): + return (len(line) - len(line.lstrip(" ")) if pos == None else len(line[:pos]) - len(line[:pos].rstrip(" "))) def line_range(self): return ((self.mark, self.cur_line + 1) if self.mark < self.cur_line else (self.cur_line, self.mark + 1)) - def line_edit(self, prompt, default): + def line_edit(self, prompt, default): self.goto(Editor.height, 0) self.hilite(1) self.wr(prompt) @@ -140,31 +140,31 @@ def line_edit(self, prompt, default): self.clear_to_eol() res = default while True: - key = self.get_input() - if key in (0x0a, 0x09): + key = self.get_input() + if key in (0x0a, 0x09): self.hilite(0) return res - elif key == 0x11: + elif key == 0x11: self.hilite(0) return None - elif key == 0x08: + elif key == 0x08: if (len(res) > 0): res = res[:len(res)-1] self.wr('\b \b') - elif key == 0x7f: + elif key == 0x7f: self.wr('\b \b' * len(res)) res = '' - elif key == 0x16: + elif key == 0x16: if Editor.yank_buffer: self.wr('\b \b' * len(res)) res = Editor.yank_buffer[0].strip()[:len(prompt) + Editor.width - 2] self.wr(res) - elif 0x20 <= key < 0xfff0: + elif 0x20 <= key < 0xfff0: if len(prompt) + len(res) < Editor.width - 2: res += chr(key) self.wr(chr(key)) def find_in_file(self, pattern, pos, end): - Editor.find_pattern = pattern + Editor.find_pattern = pattern if True: pattern = pattern.lower() spos = pos @@ -184,23 +184,23 @@ def undo_add(self, lnum, text, key, span = 1): self.changed = '*' if self.undo_limit > 0 and ( len(self.undo) == 0 or key == 0 or self.undo[-1][3] != key or self.undo[-1][0] != lnum): - if len(self.undo) >= self.undo_limit: + if len(self.undo) >= self.undo_limit: del self.undo[0] self.undo_zero -= 1 self.undo.append([lnum, span, text, key, self.col]) - def delete_lines(self, yank): + def delete_lines(self, yank): lrange = self.line_range() if yank: Editor.yank_buffer = self.content[lrange[0]:lrange[1]] - self.undo_add(lrange[0], self.content[lrange[0]:lrange[1]], 0, 0) + self.undo_add(lrange[0], self.content[lrange[0]:lrange[1]], 0, 0) del self.content[lrange[0]:lrange[1]] - if self.content == []: - self.content = [""] - self.undo[-1][1] = 1 + if self.content == []: + self.content = [""] + self.undo[-1][1] = 1 self.total_lines = len(self.content) self.cur_line = lrange[0] - self.mark = None - def handle_edit_keys(self, key): + self.mark = None + def handle_edit_keys(self, key): l = self.content[self.cur_line] if key == 0x0d: self.cur_line += 1 @@ -216,7 +216,7 @@ def handle_edit_keys(self, key): elif self.col < len(l): self.undo_add(self.cur_line, [l], 0x7f) self.content[self.cur_line] = l[:self.col] + l[self.col + 1:] - elif (self.cur_line + 1) < self.total_lines: + elif (self.cur_line + 1) < self.total_lines: self.undo_add(self.cur_line, [l, self.content[self.cur_line + 1]], 0) self.content[self.cur_line] = l + self.content.pop(self.cur_line + 1) self.total_lines -= 1 @@ -227,7 +227,7 @@ def handle_edit_keys(self, key): self.undo_add(self.cur_line, [l], 0x08) self.content[self.cur_line] = l[:self.col - 1] + l[self.col:] self.col -= 1 - elif 0x20 <= key < 0xfff0: + elif 0x20 <= key < 0xfff0: self.mark = None self.undo_add(self.cur_line, [l], 0x20 if key == 0x20 else 0x41) self.content[self.cur_line] = l[:self.col] + chr(key) + l[self.col:] @@ -250,14 +250,14 @@ def handle_edit_keys(self, key): if Editor.find_pattern: self.find_in_file(Editor.find_pattern, self.col + 1, self.total_lines) self.row = Editor.height >> 1 - elif key == 0x07: + elif key == 0x07: line = self.line_edit("Goto Line: ", "") if line: self.cur_line = int(line) - 1 self.row = Editor.height >> 1 - elif key == 0x01: + elif key == 0x01: if True: - self.autoindent = 'y' if self.autoindent != 'y' else 'n' + self.autoindent = 'y' if self.autoindent != 'y' else 'n' elif key == 0x0c: self.mark = self.cur_line if self.mark == None else None elif key == 0x0a: @@ -265,71 +265,71 @@ def handle_edit_keys(self, key): self.undo_add(self.cur_line, [l], 0, 2) self.content[self.cur_line] = l[:self.col] ni = 0 - if self.autoindent == "y": - ni = min(self.spaces(l), self.col) + if self.autoindent == "y": + ni = min(self.spaces(l), self.col) self.cur_line += 1 self.content[self.cur_line:self.cur_line] = [' ' * ni + l[self.col:]] self.total_lines += 1 self.col = ni elif key == 0x09: - ni = self.tab_size - self.col % self.tab_size + ni = self.tab_size - self.col % self.tab_size self.undo_add(self.cur_line, [l], 0x09) self.content[self.cur_line] = l[:self.col] + ' ' * ni + l[self.col:] self.col += ni elif key == 0x15: - ni = min((self.col - 1) % self.tab_size + 1, self.spaces(l, self.col)) + ni = min((self.col - 1) % self.tab_size + 1, self.spaces(l, self.col)) if ni > 0: self.undo_add(self.cur_line, [l], 0x15) self.content[self.cur_line] = l[:self.col - ni] + l[self.col:] self.col -= ni - elif key == 0x18: + elif key == 0x18: if self.mark != None: self.delete_lines(True) - elif key == 0x04: + elif key == 0x04: if self.mark != None: lrange = self.line_range() Editor.yank_buffer = self.content[lrange[0]:lrange[1]] self.mark = None - elif key == 0x16: + elif key == 0x16: if Editor.yank_buffer: if self.mark != None: self.delete_lines(False) self.undo_add(self.cur_line, None, 0, -len(Editor.yank_buffer)) - self.content[self.cur_line:self.cur_line] = Editor.yank_buffer + self.content[self.cur_line:self.cur_line] = Editor.yank_buffer self.total_lines += len(Editor.yank_buffer) elif key == 0x13: fname = self.line_edit("Save File: ", self.fname) if fname: self.put_file(fname) - self.changed = '' - self.undo_zero = len(self.undo) - if not self.fname: self.fname = fname + self.changed = '' + self.undo_zero = len(self.undo) + if not self.fname: self.fname = fname elif key == 0x1a: if len(self.undo) > 0: - action = self.undo.pop(-1) + action = self.undo.pop(-1) if not action[3] in (0xfffe, 0xffff): - self.cur_line = action[0] + self.cur_line = action[0] self.col = action[4] - if action[1] >= 0: + if action[1] >= 0: if action[0] < self.total_lines: - self.content[action[0]:action[0] + action[1]] = action[2] + self.content[action[0]:action[0] + action[1]] = action[2] else: self.content += action[2] - else: + else: del self.content[action[0]:action[0] - action[1]] - self.total_lines = len(self.content) + self.total_lines = len(self.content) if len(self.undo) == self.undo_zero: self.changed = '' self.mark = None elif key == 0x05: self.redraw(True) - def edit_loop(self): - if not self.content: + def edit_loop(self): + if not self.content: self.content = [""] self.total_lines = len(self.content) self.redraw(self.message == "") while True: - if not self.rd_any(): - self.display_window() - key = self.get_input() - self.message = '' + if not self.rd_any(): + self.display_window() + key = self.get_input() + self.message = '' if key == 0x11: if self.changed: res = self.line_edit("Content changed! Quit without saving (y/N)? ", "N") @@ -343,35 +343,35 @@ def edit_loop(self): return key else: self.handle_edit_keys(key) def get_file(self, fname): - import os + from os import listdir, getcwd, stat if not fname: fname = self.line_edit("Open file: ", "") if fname: - if (os.stat(fname)[0] & 0x4000): - self.content = sorted(os.listdir(fname)) + self.fname = fname + if fname == '.': fname = getcwd() + if (stat(fname)[0] & 0x4000): + self.content = ["Directory '{}'".format(fname), ""] + sorted(listdir(fname)) else: - self.fname = fname - if True: - with open(fname) as f: - self.content = f.readlines() - for i in range(len(self.content)): + with open(fname) as f: + self.content = f.readlines() + for i in range(len(self.content)): self.content[i] = expandtabs(self.content[i].rstrip('\r\n\t ')) def put_file(self, fname): - import os + from os import unlink, rename with open("tmpfile.pye", "w") as f: for l in self.content: f.write(l + '\n') - try: os.unlink(fname) + try: unlink(fname) except: pass - os.rename("tmpfile.pye", fname) + rename("tmpfile.pye", fname) def expandtabs(s): from _io import StringIO if '\t' in s: sb = StringIO() pos = 0 for c in s: - if c == '\t': - sb.write(" " * (8 - pos % 8)) + if c == '\t': + sb.write(" " * (8 - pos % 8)) pos += 8 - pos % 8 else: sb.write(c) @@ -380,24 +380,25 @@ def expandtabs(s): else: return s def pye(*content, tab_size = 4, undo = 50, device = 0, baud = 115200): - gc.collect() + gc.collect() slot = [Editor(tab_size, undo)] if content: index = 0 for f in content: if index: slot.append(Editor(tab_size, undo)) - if type(f) == str and f: - slot[index].get_file(f) + if type(f) == str and f: + try: slot[index].get_file(f) + except: slot[index].message = "File not found" elif type(f) == list and len(f) > 0 and type(f[0]) == str: - slot[index].content = f + slot[index].content = f index += 1 index = 0 while True: try: index %= len(slot) - key = slot[index].edit_loop() + key = slot[index].edit_loop() if key == 0x11: - if len(slot) == 1: + if len(slot) == 1: break del slot[index] elif key == 0x0f: