parent
88e0f6b862
commit
e87e02e711
6
README
6
README
|
@ -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.
|
||||||
|
|
||||||
|
@ -92,4 +92,4 @@ Quick Start Guide:
|
||||||
|
|
||||||
b. comments in the source code
|
b. comments in the source code
|
||||||
|
|
||||||
Good luck!
|
Good luck!
|
|
@ -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]
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue