undo/redo fix, some other features, open file improvements
--HG-- branch : pmacs2
This commit is contained in:
parent
6afec24fe0
commit
5a59f28525
9
IDEAS
9
IDEAS
|
@ -1,3 +1,12 @@
|
||||||
|
2007/07/19:
|
||||||
|
|
||||||
|
Convert all classes to subclass object.
|
||||||
|
|
||||||
|
2007/07/19:
|
||||||
|
|
||||||
|
The minibuffer should be able to expand to become multi-line if the
|
||||||
|
prompt/input string becomes too long.
|
||||||
|
|
||||||
2007/07/17:
|
2007/07/17:
|
||||||
|
|
||||||
It would be nice to be able to toggle various lexing rules on/off, so that for
|
It would be nice to be able to toggle various lexing rules on/off, so that for
|
||||||
|
|
|
@ -233,6 +233,41 @@ class Application(object):
|
||||||
slot = self.bufferlist.slots[i]
|
slot = self.bufferlist.slots[i]
|
||||||
return (slot.height, slot.width)
|
return (slot.height, slot.width)
|
||||||
|
|
||||||
|
# files and stuff
|
||||||
|
def open_path(self, path, cipher=None, password=None):
|
||||||
|
path = os.path.abspath(os.path.realpath(util.expand_tilde(path)))
|
||||||
|
b = self.get_buffer_by_path(path)
|
||||||
|
if b is None:
|
||||||
|
name = os.path.basename(path)
|
||||||
|
if self.has_buffer_name(name):
|
||||||
|
i = 1
|
||||||
|
auxname = '%s/%d' % (name, i)
|
||||||
|
while self.has_buffer_name(auxname):
|
||||||
|
i += 1
|
||||||
|
auxname = '%s/%d' % (name, i)
|
||||||
|
name = auxname
|
||||||
|
|
||||||
|
mode_name = None
|
||||||
|
if cipher is None:
|
||||||
|
if not os.path.exists(path) or os.path.isfile(path):
|
||||||
|
b = buffer2.FileBuffer(path, name=name)
|
||||||
|
elif os.path.isdir(path):
|
||||||
|
b = buffer2.DirBuffer(path, name=name)
|
||||||
|
mode_name = 'fundamental'
|
||||||
|
else:
|
||||||
|
raise Exception, "not a file or dir: %r" % path
|
||||||
|
elif cipher == 'aes':
|
||||||
|
if not password:
|
||||||
|
raise Exception, "password is required"
|
||||||
|
if not os.path.exists(path) or os.path.isfile(path):
|
||||||
|
b = buffer2.AesBuffer(path, password, name=name)
|
||||||
|
else:
|
||||||
|
raise Exception, "not a file or dir: %r" % path
|
||||||
|
b.open()
|
||||||
|
window2.Window(b, self, height=0, width=0, mode_name=mode_name)
|
||||||
|
self.add_buffer(b)
|
||||||
|
return b
|
||||||
|
|
||||||
# mini buffer handling
|
# mini buffer handling
|
||||||
def get_mini_buffer(self):
|
def get_mini_buffer(self):
|
||||||
return self.mini_buffer
|
return self.mini_buffer
|
||||||
|
@ -702,7 +737,6 @@ def open_aes_file(path, nl, name=None):
|
||||||
p = getpass.getpass("Please enter the AES password: ")
|
p = getpass.getpass("Please enter the AES password: ")
|
||||||
b = buffer2.AesBuffer(path, p, nl, name)
|
b = buffer2.AesBuffer(path, p, nl, name)
|
||||||
return b
|
return b
|
||||||
|
|
||||||
def open_plain_file(path, nl, name=None):
|
def open_plain_file(path, nl, name=None):
|
||||||
b = buffer2.FileBuffer(path, nl, name)
|
b = buffer2.FileBuffer(path, nl, name)
|
||||||
return b
|
return b
|
||||||
|
|
42
buffer2.py
42
buffer2.py
|
@ -17,6 +17,8 @@ class AddMove:
|
||||||
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)
|
||||||
|
def getpos(self):
|
||||||
|
return self.p
|
||||||
|
|
||||||
# used for undo/redo stacks when text will need to be removed
|
# used for undo/redo stacks when text will need to be removed
|
||||||
class DelMove:
|
class DelMove:
|
||||||
|
@ -27,9 +29,12 @@ class DelMove:
|
||||||
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)
|
||||||
|
def getpos(self):
|
||||||
|
return self.p1
|
||||||
|
|
||||||
# abstract class
|
# abstract class
|
||||||
class Buffer(object):
|
class Buffer(object):
|
||||||
|
btype = 'generic'
|
||||||
def __init__(self, nl='\n', stack_limit=STACK_LIMIT):
|
def __init__(self, nl='\n', stack_limit=STACK_LIMIT):
|
||||||
assert nl in ('\n', '\r', '\r\n'), "Invalid line ending"
|
assert nl in ('\n', '\r', '\r\n'), "Invalid line ending"
|
||||||
self.lines = [""]
|
self.lines = [""]
|
||||||
|
@ -86,12 +91,14 @@ class Buffer(object):
|
||||||
if len(self.undo_stack):
|
if len(self.undo_stack):
|
||||||
move = self.undo_stack.pop(-1)
|
move = self.undo_stack.pop(-1)
|
||||||
move.restore(ACT_UNDO)
|
move.restore(ACT_UNDO)
|
||||||
|
return move.getpos()
|
||||||
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)
|
move = self.redo_stack.pop(-1)
|
||||||
move.restore(ACT_REDO)
|
move.restore(ACT_REDO)
|
||||||
|
return move.getpos()
|
||||||
else:
|
else:
|
||||||
raise Exception, "Nothing to Redo!"
|
raise Exception, "Nothing to Redo!"
|
||||||
|
|
||||||
|
@ -293,6 +300,7 @@ class Buffer(object):
|
||||||
# scratch is a singleton
|
# scratch is a singleton
|
||||||
scratch = None
|
scratch = None
|
||||||
class ScratchBuffer(Buffer):
|
class ScratchBuffer(Buffer):
|
||||||
|
btype = 'scratch'
|
||||||
def __new__(cls, *args, **kwargs):
|
def __new__(cls, *args, **kwargs):
|
||||||
global scratch
|
global scratch
|
||||||
if scratch is None:
|
if scratch is None:
|
||||||
|
@ -305,6 +313,7 @@ class ScratchBuffer(Buffer):
|
||||||
scratch = None
|
scratch = None
|
||||||
|
|
||||||
class DataBuffer(Buffer):
|
class DataBuffer(Buffer):
|
||||||
|
btype = 'data'
|
||||||
def __init__(self, name, data, nl='\n'):
|
def __init__(self, name, data, nl='\n'):
|
||||||
Buffer.__init__(self, nl)
|
Buffer.__init__(self, nl)
|
||||||
self._name = name
|
self._name = name
|
||||||
|
@ -319,6 +328,7 @@ class DataBuffer(Buffer):
|
||||||
# console is another singleton
|
# console is another singleton
|
||||||
console = None
|
console = None
|
||||||
class ConsoleBuffer(Buffer):
|
class ConsoleBuffer(Buffer):
|
||||||
|
btype = 'console'
|
||||||
def __new__(cls, *args, **kwargs):
|
def __new__(cls, *args, **kwargs):
|
||||||
global console
|
global console
|
||||||
if console is None:
|
if console is None:
|
||||||
|
@ -345,6 +355,7 @@ class ConsoleBuffer(Buffer):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
class FileBuffer(Buffer):
|
class FileBuffer(Buffer):
|
||||||
|
btype = 'file'
|
||||||
def __init__(self, path, nl='\n', name=None):
|
def __init__(self, path, nl='\n', name=None):
|
||||||
'''fb = FileBuffer(path)'''
|
'''fb = FileBuffer(path)'''
|
||||||
Buffer.__init__(self, nl)
|
Buffer.__init__(self, nl)
|
||||||
|
@ -454,6 +465,7 @@ class FileBuffer(Buffer):
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
class AesBuffer(FileBuffer):
|
class AesBuffer(FileBuffer):
|
||||||
|
btype = 'aesfile'
|
||||||
def __init__(self, path, password, nl='\n', name=None):
|
def __init__(self, path, password, nl='\n', name=None):
|
||||||
'''fb = FileBuffer(path)'''
|
'''fb = FileBuffer(path)'''
|
||||||
FileBuffer.__init__(self, path, nl, name)
|
FileBuffer.__init__(self, path, nl, name)
|
||||||
|
@ -462,3 +474,33 @@ class AesBuffer(FileBuffer):
|
||||||
return aes.decrypt_data(data, self.password)
|
return aes.decrypt_data(data, self.password)
|
||||||
def write_filter(self, data):
|
def write_filter(self, data):
|
||||||
return aes.encrypt_data(data, self.password)
|
return aes.encrypt_data(data, self.password)
|
||||||
|
|
||||||
|
class DirBuffer(Buffer):
|
||||||
|
btype = 'dir'
|
||||||
|
def __init__(self, path, nl='\n', name=None):
|
||||||
|
Buffer.__init__(self, nl)
|
||||||
|
self.path = os.path.realpath(path)
|
||||||
|
if name is None:
|
||||||
|
self._name = os.path.basename(self.path)
|
||||||
|
else:
|
||||||
|
self._name = name
|
||||||
|
def readonly(self):
|
||||||
|
return True
|
||||||
|
def name(self):
|
||||||
|
return self._name
|
||||||
|
def path_exists(self):
|
||||||
|
return os.path.exists(self.path)
|
||||||
|
def open(self):
|
||||||
|
if not self.path_exists():
|
||||||
|
raise Exception, "directory %r does not exists" % self.path
|
||||||
|
self.lines = []
|
||||||
|
if self.path != '/':
|
||||||
|
self.lines.append('..')
|
||||||
|
for name in os.listdir(self.path):
|
||||||
|
self.lines.append(name)
|
||||||
|
def reload(self):
|
||||||
|
self.open()
|
||||||
|
def save(self, force=False):
|
||||||
|
raise Exception, "can't save a directory buffer"
|
||||||
|
def save_as(self, path):
|
||||||
|
raise Exception, "can't save a directory buffer"
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
line one
another line
this is the last
|
|
@ -0,0 +1,4 @@
|
||||||
|
line one
|
||||||
|
another line
|
||||||
|
this is the last
|
||||||
|
(uh oh i added a fourth line!)
|
|
@ -0,0 +1,3 @@
|
||||||
|
line one
|
||||||
|
another line
|
||||||
|
this is the last
|
35
method.py
35
method.py
|
@ -173,39 +173,16 @@ class OpenFile(Method):
|
||||||
'''Open file in a new buffer, or go to file's open buffer'''
|
'''Open file in a new buffer, or go to file's open buffer'''
|
||||||
args = [Argument('filename', datatype="path", prompt="Open File: ")]
|
args = [Argument('filename', datatype="path", prompt="Open File: ")]
|
||||||
def _execute(self, w, **vargs):
|
def _execute(self, w, **vargs):
|
||||||
path = vargs['filename']
|
b = w.application.open_path(vargs['filename'])
|
||||||
path = os.path.abspath(os.path.realpath(util.expand_tilde(path)))
|
|
||||||
a = w.application
|
|
||||||
b = w.application.get_buffer_by_path(path)
|
|
||||||
if b is None:
|
|
||||||
name = os.path.basename(path)
|
|
||||||
if w.application.has_buffer_name(name):
|
|
||||||
i = 1
|
|
||||||
auxname = '%s/%d' % (name, i)
|
|
||||||
while w.application.has_buffer_name(auxname):
|
|
||||||
i += 1
|
|
||||||
auxname = '%s/%d' % (name, i)
|
|
||||||
name = auxname
|
|
||||||
b = buffer2.FileBuffer(path, name=name)
|
|
||||||
b.open()
|
|
||||||
window2.Window(b, a, height=0, width=0)
|
|
||||||
w.application.add_buffer(b)
|
|
||||||
SwitchBuffer().execute(w, buffername=b.name())
|
SwitchBuffer().execute(w, buffername=b.name())
|
||||||
class OpenAesFile(Method):
|
class OpenAesFile(Method):
|
||||||
'''Open AES encrypted file in a new buffer, or go to file's open buffer'''
|
'''Open AES encrypted file in a new buffer, or go to file's open buffer'''
|
||||||
args = [Argument('filename', datatype="path", prompt="Open AES File: "),
|
args = [Argument('filename', datatype="path", prompt="Open AES File: "),
|
||||||
Argument('password', prompt="Use AES Password: ")]
|
Argument('password', prompt="Use AES Password: ")]
|
||||||
def _execute(self, w, **vargs):
|
def _execute(self, w, **vargs):
|
||||||
path = vargs['filename']
|
b = w.application.open_path(vargs['filename'], 'aes', vargs['password'])
|
||||||
password = vargs['password']
|
SwitchBuffer().execute(w, buffername=b.name())
|
||||||
path = os.path.abspath(os.path.realpath(util.expand_tilde(path)))
|
return
|
||||||
a = w.application
|
|
||||||
if not w.application.has_buffer_name(path):
|
|
||||||
b = buffer2.AesBuffer(path, password)
|
|
||||||
b.open()
|
|
||||||
window2.Window(b, a, height=0, width=0)
|
|
||||||
w.application.add_buffer(b)
|
|
||||||
SwitchBuffer().execute(w, buffername=path)
|
|
||||||
class SwitchBuffer(Method):
|
class SwitchBuffer(Method):
|
||||||
'''Switch to a different'''
|
'''Switch to a different'''
|
||||||
args = [Argument('buffername', datatype="buffer", prompt="Switch To Buffer: ",
|
args = [Argument('buffername', datatype="buffer", prompt="Switch To Buffer: ",
|
||||||
|
@ -736,14 +713,14 @@ class Undo(Method):
|
||||||
'''Undo last action'''
|
'''Undo last action'''
|
||||||
def _execute(self, w, **vargs):
|
def _execute(self, w, **vargs):
|
||||||
try:
|
try:
|
||||||
w.buffer.undo()
|
w.undo()
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
w.application.set_error("%s" % (e))
|
w.application.set_error("%s" % (e))
|
||||||
class Redo(Method):
|
class Redo(Method):
|
||||||
'''Redo last undone action'''
|
'''Redo last undone action'''
|
||||||
def _execute(self, w, **vargs):
|
def _execute(self, w, **vargs):
|
||||||
try:
|
try:
|
||||||
w.buffer.redo()
|
w.redo()
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
w.application.set_error("%s" % (e))
|
w.application.set_error("%s" % (e))
|
||||||
|
|
||||||
|
|
11
window2.py
11
window2.py
|
@ -552,13 +552,14 @@ class Window(object):
|
||||||
return self.buffer.lines[y][x]
|
return self.buffer.lines[y][x]
|
||||||
|
|
||||||
# undo/redo
|
# undo/redo
|
||||||
# XYZ
|
|
||||||
def undo(self):
|
def undo(self):
|
||||||
# TODO: put something here to move the cursor to the area of the undo
|
p = self.buffer.undo()
|
||||||
self.buffer.undo()
|
if not self.point_is_visible(p):
|
||||||
|
self.goto(p)
|
||||||
def redo(self):
|
def redo(self):
|
||||||
# TODO: put something here to move the cursor to the area of the redo
|
p = self.buffer.redo()
|
||||||
self.buffer.redo()
|
if not self.point_is_visible(p):
|
||||||
|
self.goto(p)
|
||||||
|
|
||||||
# highlighting tokens
|
# highlighting tokens
|
||||||
def get_token(self):
|
def get_token(self):
|
||||||
|
|
Loading…
Reference in New Issue