undo id--awesome

--HG--
branch : pmacs2
This commit is contained in:
moculus 2008-08-20 01:10:47 +00:00
parent f3a9df9c23
commit 2e5eb32fd2
4 changed files with 21 additions and 27 deletions

7
BUGS
View File

@ -2,7 +2,6 @@
2008/06/25: 2008/06/25:
* when the "first" point is on a wrapping line bad things happen. * when the "first" point is on a wrapping line bad things happen.
* try implementing an "undo ID" in the application.
* the "last visible" calculation doesn't handle long lines correctly. * the "last visible" calculation doesn't handle long lines correctly.
this affects page-up/page-down/etc. this affects page-up/page-down/etc.
@ -21,7 +20,5 @@
first-visible/cursor syncing with drawn window may be buggy. first-visible/cursor syncing with drawn window may be buggy.
2007/09/14: 2007/09/14:
known deficiencies: known deficiencies:
1. a single action (global search and replace) may produce N actions that 3. opening files larger than 5-10k lines can be very slow
need to be individually "undone". This is annoying.
3. opening files larger than 5-10k lines can be very slow

View File

@ -28,7 +28,6 @@ def run_app(stdscr, buffers, jump_to_line=None, init_mode=None):
a.run() a.run()
MAX_ERROR_DISPLAY = 128 MAX_ERROR_DISPLAY = 128
KILL_RING_LIMIT = 128 KILL_RING_LIMIT = 128
WORD_LETTERS = list(string.letters + string.digits) WORD_LETTERS = list(string.letters + string.digits)
ERROR_TIMEOUT = -1 ERROR_TIMEOUT = -1
@ -42,7 +41,7 @@ class Application(object):
# initialize some basic stuff # initialize some basic stuff
# a highlighted_range contains three things: (window, start_p, end_p) # a highlighted_range contains three things: (window, start_p, end_p)
#self.state = defaultdict(lambda: {}) #self.state = defaultdict(lambda: {})
self.state = {} self.state = {}
self.config = {} self.config = {}
self.highlighted_ranges = [] self.highlighted_ranges = []

View File

@ -12,25 +12,13 @@ STACK_LIMIT = 1024
class ReadOnlyError(Exception): class ReadOnlyError(Exception):
pass pass
# used for multiple text additions/deletions
class GroupMove(object):
def __init__(self, buffer, p, moves):
self.buffer = buffer
self.lines = lines
self.moves = moves
def restore(self, act=ACT_UNDO):
assert act == ACT_UNDO or act == ACT_REDO
for move in self.moves:
move.restore(act)
def getpos(self):
return self.moves[-1].getpos()
# used for undo/redo stacks when text will need to be added back # used for undo/redo stacks when text will need to be added back
class AddMove(object): class AddMove(object):
def __init__(self, buffer, p, lines): def __init__(self, buffer, p, lines):
self.buffer = buffer self.buffer = buffer
self.p = p self.p = p
self.lines = lines self.lines = lines
self.undo_id = buffer.undo_id
def restore(self, act=ACT_UNDO): def restore(self, act=ACT_UNDO):
assert act == ACT_UNDO or act == ACT_REDO assert act == ACT_UNDO or act == ACT_REDO
self.buffer.insert_lines(self.p, self.lines, act) self.buffer.insert_lines(self.p, self.lines, act)
@ -43,6 +31,7 @@ class DelMove(object):
self.buffer = buffer self.buffer = buffer
self.p1 = p1 self.p1 = p1
self.p2 = p2 self.p2 = p2
self.undo_id = buffer.undo_id
def restore(self, act): def restore(self, act):
assert act == ACT_UNDO or act == ACT_REDO assert act == ACT_UNDO or act == ACT_REDO
self.buffer.delete(self.p1, self.p2, act) self.buffer.delete(self.p1, self.p2, act)
@ -58,6 +47,7 @@ class Buffer(object):
def __init__(self, stack_limit=STACK_LIMIT): def __init__(self, stack_limit=STACK_LIMIT):
self.lines = [""] self.lines = [""]
self.windows = [] self.windows = []
self.undo_id = 1
self.undo_stack = [] self.undo_stack = []
self.redo_stack = [] self.redo_stack = []
self.stack_limit = stack_limit self.stack_limit = stack_limit
@ -126,16 +116,24 @@ class Buffer(object):
raise Exception, "Invalid act: %d" % (act) raise Exception, "Invalid act: %d" % (act)
def undo(self): def undo(self):
if len(self.undo_stack): if len(self.undo_stack):
move = self.undo_stack.pop(-1) undo_id = self.undo_stack[-1].undo_id
move.restore(ACT_UNDO) pos = None
return move.getpos() while self.undo_stack and self.undo_stack[-1].undo_id == undo_id:
move = self.undo_stack.pop(-1)
move.restore(ACT_UNDO)
pos = move.getpos()
return pos
else: else:
raise Exception, "Nothing to Undo!" raise Exception, "Nothing to Undo!"
def redo(self): def redo(self):
if len(self.redo_stack): if len(self.redo_stack):
move = self.redo_stack.pop(-1) undo_id = self.redo_stack[-1].undo_id
move.restore(ACT_REDO) pos = None
return move.getpos() while self.redo_stack and self.redo_stack[-1].undo_id == undo_id:
move = self.redo_stack.pop(-1)
move.restore(ACT_REDO)
pos = move.getpos()
return pos
else: else:
raise Exception, "Nothing to Redo!" raise Exception, "Nothing to Redo!"

View File

@ -108,7 +108,7 @@ class Method(object):
arg.ask_for_value(self, w, **vargs) arg.ask_for_value(self, w, **vargs)
return return
self._execute(w, **vargs) self._execute(w, **vargs)
w.buffer.undo_id += 1
def _execute(self, w, **vargs): def _execute(self, w, **vargs):
raise Exception, "Unimplemented Method: %s %r" % (self.name, vargs) raise Exception, "Unimplemented Method: %s %r" % (self.name, vargs)