From e87e02e7116e3617badf7733ac2f6b457fad5de6 Mon Sep 17 00:00:00 2001 From: moculus Date: Fri, 29 Feb 2008 14:39:32 +0000 Subject: [PATCH] methodxx --HG-- branch : pmacs2 --- README | 6 +- method.py => method/__init__.py | 128 ++++++++++++++++++++++++++------ mode/text.py | 2 +- 3 files changed, 108 insertions(+), 28 deletions(-) rename method.py => method/__init__.py (93%) diff --git a/README b/README index 450ddb8..656658f 100644 --- a/README +++ b/README @@ -2,8 +2,8 @@ Pmacs by Erik Osheim -Pmacs is an Emacs-like editor written entirely in Python. It is designed to have -maximally correct and powerful support for syntax highlighting, to support +Pmacs is an Emacs-like editor written entirely in Python. It is designed to +have maximally correct and powerful support for syntax highlighting, to support various methods of automatically indenting lines, and to be extensible in python. @@ -92,4 +92,4 @@ Quick Start Guide: b. comments in the source code -Good luck! +Good luck! \ No newline at end of file diff --git a/method.py b/method/__init__.py similarity index 93% rename from method.py rename to method/__init__.py index 172626c..eb43d82 100644 --- a/method.py +++ b/method/__init__.py @@ -2,8 +2,6 @@ import os, commands, popen2, re, sets, tempfile import buffer, default, dirutil, regex, util, window from point import Point -WHITESPACE = [' ', '\n'] - DATATYPES = { "path": None, "buffer": None, @@ -467,7 +465,7 @@ class DeleteLeftWhitespace(Method): l = w.point_left(p) if l is None: return - while l is not None and w.point_char(l) in WHITESPACE: + while l is not None and w.point_char(l) in (' ', '\n'): p = l l = w.point_left(p) if p < c: @@ -477,7 +475,32 @@ class DeleteRightWhitespace(Method): def _execute(self, w, **vargs): c = w.logical_cursor() p = c - while w.point_char(p) in WHITESPACE: + while w.point_char(p) in (' ', '\n'): + r = w.point_right(p) + if r is None: + break + p = r + if p > c: + w.kill(c, p) +class DeleteLeftSpace(Method): + '''Delete all contiguous spaces left of the cursor''' + def _execute(self, w, **vargs): + c = w.logical_cursor() + p = c + l = w.point_left(p) + if l is None: + return + while l is not None and w.point_char(l) == ' ': + p = l + l = w.point_left(p) + if p < c: + w.kill(p, c) +class DeleteRightSpace(Method): + '''Delete all contiguous spaces under and right of the cursor''' + def _execute(self, w, **vargs): + c = w.logical_cursor() + p = c + while w.point_char(p) == ' ': r = w.point_right(p) if r is None: break @@ -763,33 +786,90 @@ class WrapParagraph(WrapLine): w.buffer.insert_string(Point(len(w.buffer.lines[-1], len(w.buffer.lines) - 1)), '\n') w.goto(Point(x, y)) class WrapParagraph2(Method): - limit = 80 - wrapper = WrapLine - spacer = InsertSpace - empty_re = regex.whitespace + limit = 80 + wrapper = WrapLine + spacer = InsertSpace + empty_re = regex.whitespace prefix_re = None def _execute(self, w, **vargs): - old_cursor = w.logical_cursor() - i = old_cursor.y - while i < len(w.buffer.lines) - 1: - if i < len(w.buffer.lines) and \ - self.empty_re.match(w.buffer.lines[i + 1]): + # we will store the start of our paragaph in p1, and also the original + # cursor position. + p1 = oldc = w.logical_cursor() + cur_offset = 0 + + # see if we are starting in the middle of the paragraph; if so, then + # let's find the actual begining, and update p1 accordingly. + i = p1.y + if i > 1 and w.buffer.lines[i] and not w.buffer.lines[i].startswith(' '): + while i > 1 and w.buffer.lines[i - 1] and not w.buffer.lines[i - 1].startswith(' '): + i -= 1 + p1 = Point(0, i) + + # get the first line; strip it, and put it in our new lines list. + s1 = w.buffer.lines[p1.y][p1.x:] + s2 = s1.rstrip() + if p1.y <= oldc.y: + cur_offset += len(s1) - len(s2) + lines = [s2] + + # ok, so now let's move forward and find the end of the paragraph. + i = p1.y + 1 + while i < len(w.buffer.lines) and w.buffer.lines[i] and not w.buffer.lines[i].startswith(' '): + s1 = w.buffer.lines[i] + s2 = s1.rstrip() + if oldc.y == i: + # once we've adjusted all our previous lines, adjust our + # stored cursor to keep it's X and Y in sync (set Y to the line + # the paragraph started on, increase X by the previous lines + # plus added spaces minus removed whitespace. + x = p1.x + oldc.x + sum([len(x) + 1 for x in lines]) - cur_offset + oldc = Point(x, p1.y) + elif i < oldc.y: + cur_offset += len(s1) - len(s2) + lines.append(s2) + i += 1 + + # stringify our paragraph + s = " ".join(lines) + + # ok, so now we need to find the line breaks + newlines = [] + while s: + # if we have less than the limit left, add it and we're done! + if len(s) < self.limit: + newlines.append(s) break - EndOfLine().execute(w) - self.spacer().execute(w) - DeleteRightWhitespace().execute(w) - w.goto(old_cursor) - self.wrapper().execute(w) - new_cursor = w.logical_cursor() - if new_cursor.y >= len(w.buffer.lines): - while new_cursor.y >= len(w.buffer.lines): - w.buffer.insert_string(Point(len(w.buffer.lines[-1]), len(w.buffer.lines) - 1), "\n") - w.goto(Point(0, new_cursor.y)) + + # look for the rightmost space within our bounds + j = s.rfind(' ', 0, self.limit) + # if we failed to find one, look for the leftmost space + if j == -1: + j = s.find(' ') + # if we failed to find any, use the whole rest of the paragraph + if j == -1: + j = len(s) + # add the next chunk we found and adjust the paragraph + newlines.append(s[:j]) + s = s[j + 1:] + + # translate our cursor according to the line breaks we just did. + (x, y) = oldc.xy() + k = 0 + while x > len(newlines[k]): + x = x - len(newlines[k]) - 1 + y += 1 + k += 1 + #raise Exception, (x, y) + + # kill the old paragraph region, insert the new, and goto the new cursor + w.kill(p1, Point(len(w.buffer.lines[i-1]), i-1)) + w.insert_lines(p1, newlines) + w.goto(Point(x, y)) class JustifyRight(Method): '''Justify text with the previous line right from the cursor by whitespace''' def _execute(self, w, **vargs): - DeleteLeftWhitespace().execute(w) + DeleteLeftSpace().execute(w) cursor = w.logical_cursor() prev_line = w.buffer.lines[cursor.y-1] this_line = w.buffer.lines[cursor.y] diff --git a/mode/text.py b/mode/text.py index 02254e0..c5399a8 100644 --- a/mode/text.py +++ b/mode/text.py @@ -50,7 +50,7 @@ class Text(mode.Fundamental): mode.Fundamental.__init__(self, w) self.add_action_and_bindings(LearnWord(), ('C-c l',)) self.add_action_and_bindings(TextInsertSpace(), ('SPACE',)) - self.add_action_and_bindings(method.WrapParagraph(), ('M-q',)) + self.add_action_and_bindings(method.WrapParagraph2(), ('M-q',)) class TextInsertSpace(method.Method): limit = 80