From 3f8cd5ab70d1353d8900fede7b725270b11b94b8 Mon Sep 17 00:00:00 2001 From: Lamisator Date: Fri, 4 Aug 2017 20:50:35 +0200 Subject: [PATCH] Initial commit --- src/editorUI.py | 54 +++++++++++++++++++++++++ src/lineWalker.py | 101 ++++++++++++++++++++++++++++++++++++++++++++++ src/main.py | 7 ++++ 3 files changed, 162 insertions(+) create mode 100644 src/editorUI.py create mode 100644 src/lineWalker.py create mode 100755 src/main.py diff --git a/src/editorUI.py b/src/editorUI.py new file mode 100644 index 0000000..da9d3cb --- /dev/null +++ b/src/editorUI.py @@ -0,0 +1,54 @@ +import urwid +from lineWalker import LineWalker +import uuid + + +class EditorUI(object): + + def __init__(self, filename): + + assert open(filename, "a") + + self.filename = filename + + self.footer = urwid.AttrWrap(urwid.Text(" Save as | Close"), "standard") + + self.walker = LineWalker(filename) + self.content = urwid.ListBox(self.walker) + + self.central_frame = urwid.Frame(self.content) + self.central_frame.set_footer(self.footer) + + + + + def main(self): + self.palette = [("standard", "light blue", "black"), + ("warning", "yellow", "black")] + self.loop = urwid.MainLoop(self.central_frame, self.palette, unhandled_input = self.keypress_handler) + self.loop.run() + + def keypress_handler(self, key): + + if key == "meta q": + raise urwid.ExitMainLoop() + + elif key == "meta s": + self.save(self.filename) + + + def save(self, save_filename): + walker = self.walker + + lines = [] + + while walker.file is not None: + lines.append(walker.read_next_line()) + + file_handle = open(save_filename, "w") + + + prefix = "" + for line in lines: + file_handle.write(line) + prefix = "\n" diff --git a/src/lineWalker.py b/src/lineWalker.py new file mode 100644 index 0000000..1753a3f --- /dev/null +++ b/src/lineWalker.py @@ -0,0 +1,101 @@ +import urwid + +class LineWalker: + """ListWalker-compatible class for lazily reading file contents.""" + + def __init__(self, name): + self.file = open(name) + self.lines = [] + self.focus = 0 + + def get_focus(self): + return self._get_at_pos( self.focus ) + + def set_focus(self, focus): + self.focus = focus + + def get_next(self, start_from): + return self._get_at_pos( start_from + 1 ) + + def get_prev(self, start_from): + return self._get_at_pos( start_from - 1 ) + + def read_next_line(self): + """Read another line from the file.""" + + next_line = self.file.readline() + + if not next_line or next_line[-1:] != '\n': + # no newline on last line of file + self.file = None + else: + # trim newline characters + next_line = next_line[:-1] + + expanded = next_line.expandtabs() + + edit = urwid.Edit( "", expanded, allow_tab=True ) + edit.set_edit_pos(0) + edit.original_text = next_line + self.lines.append( edit ) + + return next_line + + + def _get_at_pos(self, pos): + """Return a widget for the line number passed.""" + + if pos < 0: + # line 0 is the start of the file, no more above + return None, None + + if len(self.lines) > pos: + # we have that line so return it + return self.lines[pos], pos + + if self.file is None: + # file is closed, so there are no more lines + return None, None + + assert pos == len(self.lines), "out of order request?" + + self.read_next_line() + + return self.lines[-1], pos + + def split_focus(self): + """Divide the focus edit widget at the cursor location.""" + + focus = self.lines[self.focus] + pos = focus.edit_pos + edit = urwid.Edit("",focus.edit_text[pos:], allow_tab=True ) + edit.original_text = "" + focus.set_edit_text( focus.edit_text[:pos] ) + edit.set_edit_pos(0) + self.lines.insert( self.focus+1, edit ) + + def combine_focus_with_prev(self): + """Combine the focus edit widget with the one above.""" + + above, ignore = self.get_prev(self.focus) + if above is None: + # already at the top + return + + focus = self.lines[self.focus] + above.set_edit_pos(len(above.edit_text)) + above.set_edit_text( above.edit_text + focus.edit_text ) + del self.lines[self.focus] + self.focus -= 1 + + def combine_focus_with_next(self): + """Combine the focus edit widget with the one below.""" + + below, ignore = self.get_next(self.focus) + if below is None: + # already at bottom + return + + focus = self.lines[self.focus] + focus.set_edit_text( focus.edit_text + below.edit_text ) + del self.lines[self.focus+1] diff --git a/src/main.py b/src/main.py new file mode 100755 index 0000000..5a620e3 --- /dev/null +++ b/src/main.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python3 + +import editorUI +from uuid import uuid4 + +ui=editorUI.EditorUI(str(uuid4()) + ".txt") +ui.main()