sort of for real

--HG--
branch : pmacs2
This commit is contained in:
moculus 2007-06-14 12:41:55 +00:00
parent 5ae3d1ef45
commit e8f015574c
6 changed files with 204 additions and 174 deletions

View File

@ -87,7 +87,7 @@ class Application(object):
# 'nasm': mode_nasm.Nasm,
'perl': mode_perl.Perl,
'python': mode_python.Python,
# 'replace': mode_replace.Replace,
'replace': mode_replace.Replace,
'search': mode_search.Search,
# 'sh': mode_sh.Sh,
# 'text': mode_text.Text,
@ -211,7 +211,7 @@ class Application(object):
assert n >= 0 and n < len(self.bufferlist.slots), \
"invalid slot: %r (%r)" % (n, len(self.bufferlist.slots))
self.bufferlist.remove_slot(n)
if self.active_slot > slotname:
if self.active_slot > n:
self.active_slot = max(0, self.active_slot - 1) #XYZ
def single_slot(self):
while len(self.bufferlist.slots) > 1:

View File

@ -67,16 +67,13 @@ class BufferList:
# manipulate slots
def add_slot(self):
assert len(self.slots) == 0, "fuck"
self.slots.append(Slot(self.height, self.width, 0))
self.fit_slots()
return len(self.slots) - 1
def empty_slot(self, i):
assert len(self.slots) == 0, "fuck"
assert i > -1 and i < len(self.slots), "slot %d does not exist" % i
return self.slots[i].is_empty()
def unset_slot(self, i):
assert len(self.slots) == 1, "fuck"
assert i > -1 and i < len(self.slots), "slot %d does not exist" % i
old_w = self.slots[i].unset()
if old_w is not None:
@ -87,7 +84,6 @@ class BufferList:
old_b.remove_window(old_w)
def set_slot(self, i, b):
assert len(self.slots) == 1, "fuck"
assert i > -1 and i < len(self.slots), "slot %d does not exist" % i
assert b in self.buffers, "buffer %s does not exist" % (b.name())
slot = self.slots[i]
@ -103,7 +99,6 @@ class BufferList:
slot.set(w)
def remove_slot(self, i):
assert False, "fuck"
assert i > -1 and i < len(self.slots), "slot %d does not exist" % i
self.unset_slot(i)
del self.slots[i]

View File

@ -160,7 +160,6 @@ class Highlighter:
def update_del(self, lines, y1, x1, y2, x2):
assert y1 >= 0
assert y1 <= y2
assert y2 < len(lines)
# first let's delete any token who falls in the range of the change (or,
# in the case of child tokens, whose parent is being deleted).

242
method.py
View File

@ -2,6 +2,8 @@ import os, commands, popen2, re
import buffer2, default, regex, util, window2
from point2 import Point
WHITESPACE = [' ', '\n']
DATATYPES = {
"path": None,
"buffer": None,
@ -220,7 +222,7 @@ class OpenAesFile(Method):
if not w.application.has_buffer_name(path):
b = buffer2.AesBuffer(path, password)
b.open()
window.Window(b, a, height=0, width=0)
window2.Window(b, a, height=0, width=0)
w.application.add_buffer(b)
SwitchBuffer().execute(w, buffername=path)
class SwitchBuffer(Method):
@ -261,6 +263,10 @@ class KillBuffer(Method):
b.close()
class ForceKillBuffer(KillBuffer):
force=True
def _args(self):
return [Argument('buffername', datatype="buffer",
prompt="Force Kill Buffer: ",
default=default.current_buffer)]
class ListBuffers(Method):
'''List all open buffers in a new buffer'''
def _execute(self, w, **vargs):
@ -284,8 +290,11 @@ class SaveBufferAs(Method):
w.application.set_error("buffer for %r is already open" % path)
return
w.application.file_buffer(path, data, switch_to=True)
w.application.methods['kill-buffer'].execute(w, buffername=curr_buffer_name)
#w.application.set_error('Wrote %r' % path)
if curr_buffer_name != '*Scratch*':
w.application.methods['kill-buffer'].execute(w, buffername=curr_buffer_name)
else:
curr_buffer.set_data('')
w.application.set_error('Wrote %r' % path)
class SaveBuffer(Method):
'''Save the contents of a buffer'''
def _execute(self, w, **vargs):
@ -421,30 +430,28 @@ class DeleteRightWord(Method):
class DeleteLeftWhitespace(Method):
'''Delete all contiguous of whitespace left of the cursor'''
def _execute(self, w, **vargs):
cursor = w.logical_cursor()
cursor_offset = w.get_cursor_offset()
left_offset = cursor_offset - 1
s = w.buffer.make_string()
while left_offset >= 0 and (s[left_offset] == ' ' or
s[left_offset] == '\n'):
left_offset -= 1
left_offset += 1
if left_offset < cursor_offset - 1:
left_point = w.buffer.get_offset_point(left_offset)
w.kill(left_point, cursor)
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) in WHITESPACE:
p = l
l = w.point_left(p)
if p < c:
w.kill(p, c)
class DeleteRightWhitespace(Method):
'''Delete all contiguous of whitespace under and right of the cursor'''
def _execute(self, w, **vargs):
cursor = w.logical_cursor()
cursor_offset = w.get_cursor_offset()
right_offset = cursor_offset
s = w.buffer.make_string()
while right_offset < len(s) and (s[right_offset] == ' ' or
s[right_offset] == '\n'):
right_offset += 1
if right_offset > cursor_offset:
right_point = w.buffer.get_offset_point(right_offset)
w.kill(cursor, right_point)
c = w.logical_cursor()
p = c
while w.point_char(p) in WHITESPACE:
r = w.point_right(p)
if r is None:
break
p = r
if p > c:
w.kill(c, p)
# random stuff
class DumpTokens(Method):
@ -487,77 +494,78 @@ class ToggleMargins(Method):
a.margins_visible = not a.margins_visible
class CenterView(Method):
'''Move view to center on cursor'''
def _execute(self, window, **vargs):
window.center_view()
def _execute(self, w, **vargs):
w.center_view()
class SetMark(Method):
'''Set the mark to the current cursor location'''
def _execute(self, window, **vargs):
window.set_mark()
def _execute(self, w, **vargs):
w.set_mark()
class SwitchMark(Method):
'''Switch the mark and the cursor locations'''
def _execute(self, window, **vargs):
window.switch_mark()
def _execute(self, w, **vargs):
w.switch_mark()
# insertion methods
class InsertNewline(Method):
'''Insert newline into buffer at the cursor'''
def _execute(self, window, **vargs):
window.insert_string_at_cursor('\n')
def _execute(self, w, **vargs):
w.insert_string_at_cursor('\n')
class InsertSpace(Method):
'''Insert space into buffer at the cursor'''
def _execute(self, window, **vargs):
window.insert_string_at_cursor(' ')
def _execute(self, w, **vargs):
w.insert_string_at_cursor(' ')
class InsertTab(Method):
'''Insert tab into buffer, or tabbify line, depending on mode'''
def _execute(self, window, **vargs):
cursor = window.logical_cursor()
#i = window.mode.get_indentation_level(cursor.y)
#XYZ
def _execute(self, w, **vargs):
cursor = w.logical_cursor()
#i = w.mode.get_indentation_level(cursor.y)
i = None
if i is None:
window.insert_string_at_cursor(' ')
w.insert_string_at_cursor(' ')
else:
j = window.buffer.count_leading_whitespace(cursor.y)
j = w.buffer.count_leading_whitespace(cursor.y)
if i != j:
KillWhitespace().execute(window)
window.insert(Point(0, cursor.y), ' ' * i)
KillWhitespace().execute(w)
w.insert(Point(0, cursor.y), ' ' * i)
else:
window.goto(Point(j, cursor.y))
w.goto(Point(j, cursor.y))
class KillWhitespace(Method):
'''Delete leading whitespace on current line'''
def _execute(self, window, **vargs):
cursor = window.logical_cursor()
i = window.buffer.count_leading_whitespace(cursor.y)
def _execute(self, w, **vargs):
cursor = w.logical_cursor()
i = w.buffer.count_leading_whitespace(cursor.y)
if i > 0:
window.kill(Point(0, cursor.y),
w.kill(Point(0, cursor.y),
Point(i, cursor.y))
# tabification
class TabBuffer(Method):
'''Tabbify every line in the current buffer'''
def _execute(self, window, **vargs):
y = window.logical_cursor().y
def _execute(self, w, **vargs):
y = w.logical_cursor().y
it = InsertTab()
for i in range(0, len(window.buffer.lines)):
window.goto_line(i)
it.execute(window)
window.goto_line(y)
for i in range(0, len(w.buffer.lines)):
w.goto_line(i)
it.execute(w)
w.goto_line(y)
# commenting
class CommentRegion(Method):
'''Prepend a comment to every line in the current buffer'''
def _execute(self, window, **vargs):
cursor = window.logical_cursor()
if cursor < window.mark:
def _execute(self, w, **vargs):
cursor = w.logical_cursor()
if cursor < w.mark:
p1 = cursor
p2 = window.mark
elif window.mark < cursor:
p1 = window.mark
p2 = w.mark
elif w.mark < cursor:
p1 = w.mark
p2 = cursor
else:
window.input_line = "Empty kill region"
w.input_line = "Empty kill region"
return
for y in range(p1.y, p2.y):
window.buffer.insert_string_at_cursor(Point(0, y), "#")
w.buffer.insert_string_at_cursor(Point(0, y), "#")
class UncommentRegion(Method):
'''Remove a comment from every line in the current buffer'''
def _execute(self, w, **vargs):
@ -579,33 +587,33 @@ class UncommentRegion(Method):
class WrapLine(Method):
'''Wrap the current line at 80 characters by word'''
limit = 80
def _execute(self, window, **vargs):
cursor = window.logical_cursor()
def _execute(self, w, **vargs):
cursor = w.logical_cursor()
old_cursor = cursor.copy()
i = cursor.y
move_old_cursor = old_cursor.x > self.limit
while len(window.buffer.lines[i]) > self.limit:
if ' ' in window.buffer.lines[i][:self.limit]:
j = window.buffer.lines[i][:self.limit].rindex(' ')
elif ' ' in window.buffer.lines[i][self.limit:]:
j = window.buffer.lines[i][self.limit:].index(' ')
while len(w.buffer.lines[i]) > self.limit:
if ' ' in w.buffer.lines[i][:self.limit]:
j = w.buffer.lines[i][:self.limit].rindex(' ')
elif ' ' in w.buffer.lines[i][self.limit:]:
j = w.buffer.lines[i][self.limit:].index(' ')
else:
break
if move_old_cursor:
move_old_cursor = False
old_cursor.x -= j + 1
old_cursor.y += 1
window.goto(Point(j, i))
window.right_delete()
window.insert_string_at_cursor('\n')
w.goto(Point(j, i))
w.right_delete()
w.insert_string_at_cursor('\n')
i += 1
l = len(window.buffer.lines[old_cursor.y])
l = len(w.buffer.lines[old_cursor.y])
if l > old_cursor.x:
window.goto(old_cursor)
w.goto(old_cursor)
else:
window.goto(Point(l, old_cursor.y))
w.goto(Point(l, old_cursor.y))
class WrapParagraph(Method):
limit = 80
wrapper = WrapLine
@ -624,11 +632,11 @@ class WrapParagraph(Method):
class JustifyRight(Method):
'''Justify text with the previous line right from the cursor by whitespace'''
def _execute(self, window, **vargs):
DeleteLeftWhitespace().execute(window)
cursor = window.logical_cursor()
prev_line = window.buffer.lines[cursor.y-1]
this_line = window.buffer.lines[cursor.y]
def _execute(self, w, **vargs):
DeleteLeftWhitespace().execute(w)
cursor = w.logical_cursor()
prev_line = w.buffer.lines[cursor.y-1]
this_line = w.buffer.lines[cursor.y]
if cursor.y <= 0:
return
if cursor.x >= len(prev_line):
@ -643,14 +651,14 @@ class JustifyRight(Method):
if i >= len(prev_line):
return
s = ' ' * (i - cursor.x)
window.insert_string_at_cursor(s)
w.insert_string_at_cursor(s)
class JustifyLeft(Method):
'''Justify text with the previous line left from the cursor by whitespace'''
def _execute(self, window, **vargs):
DeleteRightWhitespace().execute(window)
cursor = window.logical_cursor()
prev_line = window.buffer.lines[cursor.y-1]
this_line = window.buffer.lines[cursor.y]
def _execute(self, w, **vargs):
DeleteRightWhitespace().execute(w)
cursor = w.logical_cursor()
prev_line = w.buffer.lines[cursor.y-1]
this_line = w.buffer.lines[cursor.y]
if cursor.y <= 0:
return
if cursor.x <= 0:
@ -674,73 +682,73 @@ class JustifyLeft(Method):
return
if this_line[i] != ' ':
return
window.buffer.delete_string(Point(i, cursor.y), cursor)
w.buffer.delete_string(Point(i, cursor.y), cursor)
# undo/redo
class Undo(Method):
'''Undo last action'''
def _execute(self, window, **vargs):
def _execute(self, w, **vargs):
try:
window.buffer.undo()
w.buffer.undo()
except Exception, e:
window.application.set_error("%s" % (e))
w.application.set_error("%s" % (e))
class Redo(Method):
'''Redo last undone action'''
def _execute(self, window, **vargs):
def _execute(self, w, **vargs):
try:
window.buffer.redo()
w.buffer.redo()
except Exception, e:
window.application.set_error("%s" % (e))
w.application.set_error("%s" % (e))
# window navigation methods
# w navigation methods
class StartOfLine(Method):
'''Move the cursor to the start of the current line'''
def _execute(self, window, **vargs):
window.start_of_line()
def _execute(self, w, **vargs):
w.start_of_line()
class EndOfLine(Method):
'''Move the cursor to the end of the current line'''
def _execute(self, window, **vargs):
window.end_of_line()
def _execute(self, w, **vargs):
w.end_of_line()
class Forward(Method):
'''Move the cursor right one character'''
def _execute(self, window, **vargs):
window.forward()
def _execute(self, w, **vargs):
w.forward()
class Backward(Method):
'''Move the cursor left one character'''
def _execute(self, window, **vargs):
window.backward()
def _execute(self, w, **vargs):
w.backward()
class NextLine(Method):
'''Move the cursor down one line'''
def _execute(self, window, **vargs):
window.next_line()
def _execute(self, w, **vargs):
w.next_line()
class PreviousLine(Method):
'''Move the cursor up one line'''
def _execute(self, window, **vargs):
window.previous_line()
def _execute(self, w, **vargs):
w.previous_line()
class PageUp(Method):
'''Move the cursor up one page'''
def _execute(self, window, **vargs):
window.page_up()
def _execute(self, w, **vargs):
w.page_up()
class PageDown(Method):
'''Move the cursor down one page'''
def _execute(self, window, **vargs):
window.page_down()
def _execute(self, w, **vargs):
w.page_down()
class GotoBeginning(Method):
'''Move the cursor to the beginning of the buffer'''
def _execute(self, window, **vargs):
window.goto_beginning()
def _execute(self, w, **vargs):
w.goto_beginning()
class GotoEnd(Method):
'''Move the cursor to the end of the buffer'''
def _execute(self, window, **vargs):
window.goto_end()
def _execute(self, w, **vargs):
w.goto_end()
class RightWord(Method):
'''Move the cursor to the start of the word to the right'''
def _execute(self, window, **vargs):
window.right_word()
def _execute(self, w, **vargs):
w.right_word()
class LeftWord(Method):
'''Move the cursor to the start of the word to the left'''
def _execute(self, window, **vargs):
window.left_word()
def _execute(self, w, **vargs):
w.left_word()
class NextSection(Method):
'''Move the cursor to the next section'''
def _execute(self, w, **vargs):
@ -862,7 +870,7 @@ class OpenConsole(Method):
if not a.has_buffer_name('*Console*'):
a.add_buffer(buffer2.ConsoleBuffer())
b = a.bufferlist.get_buffer_by_name('*Console*')
if a.window().buffer is not b:
if a.w().buffer is not b:
a.switch_buffer(b)
f = lambda x: None
w.application.open_mini_buffer('>>> ', f, self, None, 'console')

View File

@ -11,13 +11,14 @@ class Replace(mode2.Fundamental):
self.actions = {}
self.bindings = {}
default_actions = ((ReplaceAll(), ('a', '!',)),
(ReplaceOne(), ('y', 'SPACE',)),
(SkipReplace(), ('n', 'DELETE',)),
(CancelReplace(), ('q', 'RETURN', 'C-]', 'C-n',
'C-p', 'C-a', 'C-e', 'C-f',
'C-b')))
default_actions = (
(ReplaceAll(), ('a', '!',)),
(ReplaceOne(), ('y', 'SPACE',)),
(SkipReplace(), ('n', 'DELETE',)),
(CancelReplace(), ('q', 'RETURN', 'C-]', 'C-n', 'C-p', 'C-a', 'C-e',
'C-f', 'C-b')),
)
# add the replace actions
for pair in default_actions:
(action, sequences) = pair
@ -31,51 +32,55 @@ class Replace(mode2.Fundamental):
return "Replace"
class ReplaceOne(method.Method):
def execute(self, window, **vargs):
m = window.buffer.method
def execute(self, w, **vargs):
m = w.buffer.method
old_window = m.old_window
_replace(m, old_window)
_find_next(window, True)
_finish(m, window, old_window)
_find_next(w, True)
_finish(m, w, old_window)
class SkipReplace(method.Method):
def execute(self, window, **vargs):
m = window.buffer.method
def execute(self, w, **vargs):
m = w.buffer.method
old_window = m.old_window
_find_next(window, True)
_finish(m, window, old_window)
_find_next(w, True)
_finish(m, w, old_window)
class ReplaceAll(method.Method):
def execute(self, window, **vargs):
m = window.buffer.method
def execute(self, w, **vargs):
m = w.buffer.method
old_window = m.old_window
while m.p1 is not None:
_replace(m, old_window)
_find_next(window, True)
_end(window)
window.application.set_error("Replace ended")
_find_next(w, True)
_end(w)
w.application.set_error("Replace ended")
class CancelReplace(method.Method):
def execute(self, window, **vargs):
_end(window)
window.application.set_error("Replace cancelled")
def execute(self, w, **vargs):
_end(w)
w.application.set_error("Replace cancelled")
def _set_prompt(m, window):
i = m.old_window.buffer.get_point_offset(m.p1)
s = m.old_window.buffer.make_string()
count = s[i:].count(m.before)
def _set_prompt(m, w):
(x, y) = m.p1.xy()
count = 0
while y < len(w.buffer.lines):
count += w.buffer.lines[y][x:].count(m.before)
y += 1
x = 0
if count > 1:
window.application.mini_prompt = 'Replace %r with %r [ynaq] (%d occurances)?' % (m.before, m.after, count)
p = 'Replace %r with %r [ynaq] (%d occurances)?' % (m.before, m.after, count)
else:
window.application.mini_prompt = 'Replace %r with %r [ynaq] (1 occurance)?' % (m.before, m.after)
p = 'Replace %r with %r [ynaq] (1 occurance)?' % (m.before, m.after)
w.application.mini_prompt = p
def _replace(m, old_window):
old_window.buffer.delete_string(m.p1, m.p2)
old_window.buffer.delete(m.p1, m.p2)
if m.after:
old_window.buffer.insert_string(m.p1, m.after)
def _find_next(window, move=False):
m = window.buffer.method
def _find_next(w, move=False):
m = w.buffer.method
old_window = m.old_window
b = old_window.buffer
s = m.before
@ -111,16 +116,15 @@ def _find_next(window, move=False):
m.p1 = None
m.p2 = None
def _finish(m, window, old_window):
def _finish(m, w, old_window):
if m.p1 is None:
_end(window)
window.application.set_error("Replace ended")
_end(w)
w.application.set_error("Replace ended")
else:
_set_prompt(m, old_window)
def _end(window):
window.application.close_mini_buffer()
#window.application.highlighted_range = []
window.application.clear_highlighted_ranges()
window.buffer.method.old_cursor = None
window.buffer.method.old_window = None
def _end(w):
w.application.close_mini_buffer()
w.application.clear_highlighted_ranges()
w.buffer.method.old_cursor = None
w.buffer.method.old_window = None

View File

@ -4,12 +4,11 @@ from point2 import Point
WORD_LETTERS = list(string.letters + string.digits)
# note about the cursor: the cursor position will insert in front of
# the character it highlights. to this end, it needs to be able to
# highlight behind the last character on a line. thus, the x
# coordinate of the (logical) cursor can equal the length of lines[y],
# even though lines[y][x] throws an index error. both buffer and
# window need to be aware of this possibility for points.
# note about the cursor: the cursor position will insert in front of the
# character it highlights. to this end, it needs to be able to highlight behind
# the last character on a line. thus, the x coordinate of the (logical) cursor
# can equal the length of lines[y], even though lines[y][x] throws an index
# error. both buffer and window need to be aware of this possibility for points.
class Window(object):
def __init__(self, b, a, height=24, width=80, mode_name=None):
@ -85,9 +84,31 @@ class Window(object):
if not self.point_is_visible(p):
self.application.set_error(msg % {'x': p.x, 'y': p.y})
# point left
def point_left(self, p):
if p.y == 0 and p.x == 0:
return None
elif p.x == 0:
return Point(len(self.buffer.lines[p.y - 1]), p.y - 1)
else:
return Point(p.x - 1, p.y)
# point right
def point_right(self, p):
if p.y == len(self.buffer.lines)-1 and p.x == len(self.buffer.lines[-1]):
return None
elif p.x == len(self.buffer.lines[p.y]):
return Point(0, p.y + 1)
else:
return Point(p.x + 1, p.y)
# cursors
def logical_cursor(self):
x = min(self.cursor.x, len(self.buffer.lines[self.cursor.y]))
if len(self.buffer.lines) > self.cursor.y:
l = len(self.buffer.lines[self.cursor.y])
else:
l = 0
x = min(self.cursor.x, l)
return Point(x, self.cursor.y)
# last visible point
@ -454,17 +475,20 @@ class Window(object):
return self.application.pop_kill()
# querying
def highlighted_char(self):
def cursor_char(self):
self.point_char(self.logical_cursor())
def point_char(self, p):
return self.xy_char(p.x, p.y)
def xy_char(self, x, y):
#assert 0 <= y and y < len(self.buffer.lines)
#assert 0 <= x and x <= len(self.buffer.lines[y])
if x == len(self.buffer.lines[y]):
return "\n"
else:
return self.buffer.lines[y][x]
# undo/redo
# XYZ
def undo(self):
# TODO: put something here to move the cursor to the area of the undo
self.buffer.undo()