--HG--
branch : pmacs2
This commit is contained in:
moculus 2008-02-29 14:39:32 +00:00
parent 88e0f6b862
commit e87e02e711
3 changed files with 108 additions and 28 deletions

4
README
View File

@ -2,8 +2,8 @@ Pmacs
by Erik Osheim <erik@osheim.org> by Erik Osheim <erik@osheim.org>
Pmacs is an Emacs-like editor written entirely in Python. It is designed to have Pmacs is an Emacs-like editor written entirely in Python. It is designed to
maximally correct and powerful support for syntax highlighting, to support have maximally correct and powerful support for syntax highlighting, to support
various methods of automatically indenting lines, and to be extensible in various methods of automatically indenting lines, and to be extensible in
python. python.

View File

@ -2,8 +2,6 @@ import os, commands, popen2, re, sets, tempfile
import buffer, default, dirutil, regex, util, window import buffer, default, dirutil, regex, util, window
from point import Point from point import Point
WHITESPACE = [' ', '\n']
DATATYPES = { DATATYPES = {
"path": None, "path": None,
"buffer": None, "buffer": None,
@ -467,7 +465,7 @@ class DeleteLeftWhitespace(Method):
l = w.point_left(p) l = w.point_left(p)
if l is None: if l is None:
return 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 p = l
l = w.point_left(p) l = w.point_left(p)
if p < c: if p < c:
@ -477,7 +475,32 @@ class DeleteRightWhitespace(Method):
def _execute(self, w, **vargs): def _execute(self, w, **vargs):
c = w.logical_cursor() c = w.logical_cursor()
p = c 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) r = w.point_right(p)
if r is None: if r is None:
break 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.buffer.insert_string(Point(len(w.buffer.lines[-1], len(w.buffer.lines) - 1)), '\n')
w.goto(Point(x, y)) w.goto(Point(x, y))
class WrapParagraph2(Method): class WrapParagraph2(Method):
limit = 80 limit = 80
wrapper = WrapLine wrapper = WrapLine
spacer = InsertSpace spacer = InsertSpace
empty_re = regex.whitespace empty_re = regex.whitespace
prefix_re = None prefix_re = None
def _execute(self, w, **vargs): def _execute(self, w, **vargs):
old_cursor = w.logical_cursor() # we will store the start of our paragaph in p1, and also the original
i = old_cursor.y # cursor position.
while i < len(w.buffer.lines) - 1: p1 = oldc = w.logical_cursor()
if i < len(w.buffer.lines) and \ cur_offset = 0
self.empty_re.match(w.buffer.lines[i + 1]):
# 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 break
EndOfLine().execute(w)
self.spacer().execute(w) # look for the rightmost space within our bounds
DeleteRightWhitespace().execute(w) j = s.rfind(' ', 0, self.limit)
w.goto(old_cursor) # if we failed to find one, look for the leftmost space
self.wrapper().execute(w) if j == -1:
new_cursor = w.logical_cursor() j = s.find(' ')
if new_cursor.y >= len(w.buffer.lines): # if we failed to find any, use the whole rest of the paragraph
while new_cursor.y >= len(w.buffer.lines): if j == -1:
w.buffer.insert_string(Point(len(w.buffer.lines[-1]), len(w.buffer.lines) - 1), "\n") j = len(s)
w.goto(Point(0, new_cursor.y)) # 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): class JustifyRight(Method):
'''Justify text with the previous line right from the cursor by whitespace''' '''Justify text with the previous line right from the cursor by whitespace'''
def _execute(self, w, **vargs): def _execute(self, w, **vargs):
DeleteLeftWhitespace().execute(w) DeleteLeftSpace().execute(w)
cursor = w.logical_cursor() cursor = w.logical_cursor()
prev_line = w.buffer.lines[cursor.y-1] prev_line = w.buffer.lines[cursor.y-1]
this_line = w.buffer.lines[cursor.y] this_line = w.buffer.lines[cursor.y]

View File

@ -50,7 +50,7 @@ class Text(mode.Fundamental):
mode.Fundamental.__init__(self, w) mode.Fundamental.__init__(self, w)
self.add_action_and_bindings(LearnWord(), ('C-c l',)) self.add_action_and_bindings(LearnWord(), ('C-c l',))
self.add_action_and_bindings(TextInsertSpace(), ('SPACE',)) 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): class TextInsertSpace(method.Method):
limit = 80 limit = 80