Skip to content

Commit

Permalink
Minor fixes in File handling
Browse files Browse the repository at this point in the history
  • Loading branch information
robert-hh committed Jan 24, 2016
1 parent 9bd3f09 commit 551b1f7
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 122 deletions.
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:**

Expand All @@ -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**
Expand Down Expand Up @@ -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

25 changes: 15 additions & 10 deletions pye.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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":
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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):
Expand Down Expand Up @@ -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
Expand Down
63 changes: 43 additions & 20 deletions pye2.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"):

Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -697,17 +713,19 @@ 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:
#ifdef INDENT
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:
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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):
Expand Down Expand Up @@ -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
Expand Down
Loading

0 comments on commit 551b1f7

Please sign in to comment.