parent
3ff927fdb7
commit
5a2f9b094f
|
@ -857,26 +857,28 @@ class Application(object):
|
||||||
def draw_nothing(self):
|
def draw_nothing(self):
|
||||||
self.win.addstr(self.y-1, 0, util.pad('', self.x - 1))
|
self.win.addstr(self.y-1, 0, util.pad('', self.x - 1))
|
||||||
|
|
||||||
def open_aes_file(path, nl, name=None, binary=False):
|
def open_aes_file(path, name=None, binary=False):
|
||||||
if os.path.isfile(path) or not os.path.exists(path):
|
if os.path.isfile(path) or not os.path.exists(path):
|
||||||
p = getpass.getpass("Please enter the AES password: ")
|
p = getpass.getpass("Please enter the AES password: ")
|
||||||
return buffer.AesBuffer(path, p, nl, name)
|
return buffer.AesBuffer(path, p, name)
|
||||||
else:
|
else:
|
||||||
raise Exception, "can't open %r; unsupported file type" % path
|
raise Exception, "can't open %r; unsupported file type" % path
|
||||||
def open_plain_file(path, nl, name=None, binary=False):
|
def open_plain_file(path, name=None, binary=False):
|
||||||
if os.path.isfile(path) or not os.path.exists(path):
|
if os.path.isfile(path) or not os.path.exists(path):
|
||||||
if binary:
|
if binary:
|
||||||
return buffer.Binary32Buffer(path, nl, name)
|
return buffer.Binary32Buffer(path, name)
|
||||||
else:
|
else:
|
||||||
return buffer.FileBuffer(path, nl, name)
|
return buffer.FileBuffer(path, name)
|
||||||
elif os.path.isdir(path):
|
elif os.path.isdir(path):
|
||||||
return buffer.DirBuffer(path, nl, name)
|
return buffer.DirBuffer(path, name)
|
||||||
else:
|
else:
|
||||||
raise Exception, "can't open %r; unsupported file type" % path
|
raise Exception, "can't open %r; unsupported file type" % path
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
ciphers = { 'none': open_plain_file, 'aes': open_aes_file }
|
ciphers = {
|
||||||
linetypes = { 'win': '\r\n', 'mac': '\r', 'unix': '\n' }
|
'none': open_plain_file,
|
||||||
|
'aes': open_aes_file,
|
||||||
|
}
|
||||||
|
|
||||||
# preprocess args
|
# preprocess args
|
||||||
argv = list(sys.argv[1:])
|
argv = list(sys.argv[1:])
|
||||||
|
@ -908,8 +910,6 @@ if __name__ == "__main__":
|
||||||
help='decrypt and encrypt with CIPHER (default: none)')
|
help='decrypt and encrypt with CIPHER (default: none)')
|
||||||
parser.add_option('-g', '--goto', dest='goto', metavar='NUM', type='int',
|
parser.add_option('-g', '--goto', dest='goto', metavar='NUM', type='int',
|
||||||
help='jump to line NUM of the first argument')
|
help='jump to line NUM of the first argument')
|
||||||
parser.add_option('-l', '--line-end', dest='linetype', metavar='TYPE',
|
|
||||||
help='use TYPE (win,mac,unix) line endings (default: unix)')
|
|
||||||
parser.add_option('-m', '--mode', dest='mode', metavar='MODE',
|
parser.add_option('-m', '--mode', dest='mode', metavar='MODE',
|
||||||
help='open arguments in MODE')
|
help='open arguments in MODE')
|
||||||
|
|
||||||
|
@ -928,12 +928,6 @@ if __name__ == "__main__":
|
||||||
if goto_line:
|
if goto_line:
|
||||||
opts.goto = goto_line
|
opts.goto = goto_line
|
||||||
|
|
||||||
# figure out which kind of line types we're using
|
|
||||||
if opts.linetype not in linetypes:
|
|
||||||
sys.stderr.write('invalid linetype: %r' % opts.linetype)
|
|
||||||
sys.exit(1)
|
|
||||||
nl = linetypes[opts.linetype]
|
|
||||||
|
|
||||||
# figure out what kind of file open function to use
|
# figure out what kind of file open function to use
|
||||||
if opts.cipher not in ciphers:
|
if opts.cipher not in ciphers:
|
||||||
sys.stderr.write('invalid cipher: %r' % opts.cipher)
|
sys.stderr.write('invalid cipher: %r' % opts.cipher)
|
||||||
|
@ -959,12 +953,12 @@ if __name__ == "__main__":
|
||||||
name = auxname
|
name = auxname
|
||||||
|
|
||||||
try:
|
try:
|
||||||
b = f(path, nl, name, opts.binary)
|
b = f(path, name, opts.binary)
|
||||||
b.open()
|
b.open()
|
||||||
except buffer.BinaryDataException, e:
|
except buffer.BinaryDataException, e:
|
||||||
if not opts.mode:
|
if not opts.mode:
|
||||||
opts.mode = 'hex'
|
opts.mode = 'hex'
|
||||||
b = f(path, nl, name, True)
|
b = f(path, name, True)
|
||||||
b.open()
|
b.open()
|
||||||
|
|
||||||
buffers.append(b)
|
buffers.append(b)
|
||||||
|
|
68
buffer.py
68
buffer.py
|
@ -50,19 +50,38 @@ class DelMove(object):
|
||||||
|
|
||||||
# abstract class
|
# abstract class
|
||||||
class Buffer(object):
|
class Buffer(object):
|
||||||
btype = 'generic'
|
btype = 'generic'
|
||||||
def __init__(self, nl='\n', stack_limit=STACK_LIMIT):
|
mac_re = re.compile('\r(?!\n)')
|
||||||
assert nl in ('\n', '\r', '\r\n'), "Invalid line ending"
|
unix_re = re.compile('(?<!\r)\n')
|
||||||
|
win_re = re.compile('\r\n')
|
||||||
|
def __init__(self, stack_limit=STACK_LIMIT):
|
||||||
self.lines = [""]
|
self.lines = [""]
|
||||||
self.windows = []
|
self.windows = []
|
||||||
self.undo_stack = []
|
self.undo_stack = []
|
||||||
self.redo_stack = []
|
self.redo_stack = []
|
||||||
self.stack_limit = stack_limit
|
self.stack_limit = stack_limit
|
||||||
self.nl = nl
|
self.nl = '\n'
|
||||||
self.modified = False
|
self.modified = False
|
||||||
self.highlights = {}
|
self.highlights = {}
|
||||||
self.indentlvl = 4
|
self.indentlvl = 4
|
||||||
|
|
||||||
|
def _detect_nl_type(self, data):
|
||||||
|
mac_c = len(self.mac_re.findall(data))
|
||||||
|
unix_c = len(self.unix_re.findall(data))
|
||||||
|
win_c = len(self.win_re.findall(data))
|
||||||
|
if (unix_c and mac_c) or (unix_c and win_c) or (mac_c and win_c):
|
||||||
|
# warn the user?
|
||||||
|
#raise Exception, 'inconsistent line endings %r' % \
|
||||||
|
# (data, [unix_c, mac_c, win_c])
|
||||||
|
pass
|
||||||
|
|
||||||
|
if unix_c >= win_c and unix_c >= mac_c:
|
||||||
|
return '\n'
|
||||||
|
elif mac_c >= win_c:
|
||||||
|
return '\r'
|
||||||
|
else:
|
||||||
|
return '\r\n'
|
||||||
|
|
||||||
# basic file operation stuff
|
# basic file operation stuff
|
||||||
def _open_file_r(self, path):
|
def _open_file_r(self, path):
|
||||||
path = os.path.realpath(path)
|
path = os.path.realpath(path)
|
||||||
|
@ -175,8 +194,8 @@ class Buffer(object):
|
||||||
return n
|
return n
|
||||||
def num_lines(self):
|
def num_lines(self):
|
||||||
return len(self.lines)
|
return len(self.lines)
|
||||||
def make_string(self, nl='\n'):
|
def make_string(self):
|
||||||
return nl.join(self.lines)
|
return self.nl.join(self.lines)
|
||||||
|
|
||||||
# methods to be overridden by subclasses
|
# methods to be overridden by subclasses
|
||||||
def name(self):
|
def name(self):
|
||||||
|
@ -200,7 +219,7 @@ class Buffer(object):
|
||||||
raise Exception, "oh no! %r already exists" % path
|
raise Exception, "oh no! %r already exists" % path
|
||||||
|
|
||||||
# create the string that we're going to write into the file
|
# create the string that we're going to write into the file
|
||||||
data = self.write_filter(self.make_string(nl=self.nl))
|
data = self.write_filter(self.make_string())
|
||||||
|
|
||||||
# create a safe temporary path to write to, and write out data to it
|
# create a safe temporary path to write to, and write out data to it
|
||||||
temp_path = self._temp_path()
|
temp_path = self._temp_path()
|
||||||
|
@ -339,8 +358,8 @@ class ScratchBuffer(Buffer):
|
||||||
|
|
||||||
class DataBuffer(Buffer):
|
class DataBuffer(Buffer):
|
||||||
btype = 'data'
|
btype = 'data'
|
||||||
def __init__(self, name, data, nl='\n'):
|
def __init__(self, name, data):
|
||||||
Buffer.__init__(self, nl)
|
Buffer.__init__(self)
|
||||||
self._name = name
|
self._name = name
|
||||||
self.lines = data.split("\n")
|
self.lines = data.split("\n")
|
||||||
def name(self):
|
def name(self):
|
||||||
|
@ -361,8 +380,8 @@ class ConsoleBuffer(Buffer):
|
||||||
b = object.__new__(ConsoleBuffer, *args, **kwargs)
|
b = object.__new__(ConsoleBuffer, *args, **kwargs)
|
||||||
console = b
|
console = b
|
||||||
return console
|
return console
|
||||||
def __init__(self, nl='\n'):
|
def __init__(self):
|
||||||
Buffer.__init__(self, nl)
|
Buffer.__init__(self)
|
||||||
self.clear()
|
self.clear()
|
||||||
def clear(self):
|
def clear(self):
|
||||||
lines = ['Python Console\n',
|
lines = ['Python Console\n',
|
||||||
|
@ -385,9 +404,9 @@ class BinaryDataException(Exception):
|
||||||
|
|
||||||
class FileBuffer(Buffer):
|
class FileBuffer(Buffer):
|
||||||
btype = 'file'
|
btype = 'file'
|
||||||
def __init__(self, path, nl='\n', name=None):
|
def __init__(self, path, name=None):
|
||||||
'''fb = FileBuffer(path)'''
|
'''fb = FileBuffer(path)'''
|
||||||
Buffer.__init__(self, nl)
|
Buffer.__init__(self)
|
||||||
self.path = os.path.realpath(path)
|
self.path = os.path.realpath(path)
|
||||||
self.checksum = None
|
self.checksum = None
|
||||||
if name is None:
|
if name is None:
|
||||||
|
@ -445,6 +464,7 @@ class FileBuffer(Buffer):
|
||||||
self.store_checksum(data)
|
self.store_checksum(data)
|
||||||
else:
|
else:
|
||||||
data = ''
|
data = ''
|
||||||
|
self.nl = self._detect_nl_type(data)
|
||||||
data = self.read_filter(data)
|
data = self.read_filter(data)
|
||||||
data = data.replace("\t", " ")
|
data = data.replace("\t", " ")
|
||||||
for i in range(0, min(len(data), 8)):
|
for i in range(0, min(len(data), 8)):
|
||||||
|
@ -478,7 +498,7 @@ class FileBuffer(Buffer):
|
||||||
raise Exception, "oh no! %r has changed on-disk!" % self.path
|
raise Exception, "oh no! %r has changed on-disk!" % self.path
|
||||||
|
|
||||||
temp_path = self._temp_path()
|
temp_path = self._temp_path()
|
||||||
data = self.make_string(nl=self.nl)
|
data = self.make_string()
|
||||||
if self.windows[0].mode.savetabs:
|
if self.windows[0].mode.savetabs:
|
||||||
data = data.replace(" ", "\t")
|
data = data.replace(" ", "\t")
|
||||||
|
|
||||||
|
@ -501,9 +521,9 @@ class FileBuffer(Buffer):
|
||||||
|
|
||||||
class AesBuffer(FileBuffer):
|
class AesBuffer(FileBuffer):
|
||||||
btype = 'aesfile'
|
btype = 'aesfile'
|
||||||
def __init__(self, path, password, nl='\n', name=None):
|
def __init__(self, path, password, name=None):
|
||||||
'''fb = FileBuffer(path)'''
|
'''fb = FileBuffer(path)'''
|
||||||
FileBuffer.__init__(self, path, nl, name)
|
FileBuffer.__init__(self, path, name)
|
||||||
self.password = password
|
self.password = password
|
||||||
def read_filter(self, data):
|
def read_filter(self, data):
|
||||||
return aes.decrypt_data(data, self.password)
|
return aes.decrypt_data(data, self.password)
|
||||||
|
@ -518,9 +538,9 @@ class Binary32Buffer(FileBuffer):
|
||||||
bytepad = 1
|
bytepad = 1
|
||||||
data = None
|
data = None
|
||||||
wordsize = 4
|
wordsize = 4
|
||||||
def __init__(self, path, nl='\n', name=None):
|
def __init__(self, path, name=None):
|
||||||
'''fb = FileBuffer(path)'''
|
'''fb = FileBuffer(path)'''
|
||||||
FileBuffer.__init__(self, path, nl, name)
|
FileBuffer.__init__(self, path, name)
|
||||||
def cursorx_to_datax(self, cy, cx):
|
def cursorx_to_datax(self, cy, cx):
|
||||||
bytespace = 2 + self.bytepad
|
bytespace = 2 + self.bytepad
|
||||||
groupspace = bytespace * self.groupsize - self.bytepad + self.grouppad
|
groupspace = bytespace * self.groupsize - self.bytepad + self.grouppad
|
||||||
|
@ -593,8 +613,8 @@ class Binary32Buffer(FileBuffer):
|
||||||
|
|
||||||
class DirBuffer(Buffer):
|
class DirBuffer(Buffer):
|
||||||
btype = 'dir'
|
btype = 'dir'
|
||||||
def __init__(self, path, nl='\n', name=None):
|
def __init__(self, path, name=None):
|
||||||
Buffer.__init__(self, nl)
|
Buffer.__init__(self)
|
||||||
self.path = os.path.realpath(path)
|
self.path = os.path.realpath(path)
|
||||||
def changed(self):
|
def changed(self):
|
||||||
return False
|
return False
|
||||||
|
@ -650,8 +670,8 @@ class DirBuffer(Buffer):
|
||||||
|
|
||||||
class PathListBuffer(DirBuffer):
|
class PathListBuffer(DirBuffer):
|
||||||
btype = 'pathlist'
|
btype = 'pathlist'
|
||||||
def __init__(self, name, paths, nl='\n'):
|
def __init__(self, name, paths):
|
||||||
Buffer.__init__(self, nl)
|
Buffer.__init__(self)
|
||||||
self.paths = list(paths)
|
self.paths = list(paths)
|
||||||
self.path = os.getcwd()
|
self.path = os.getcwd()
|
||||||
self._name = name
|
self._name = name
|
||||||
|
@ -721,12 +741,12 @@ class ColorDataBuffer(DataBuffer):
|
||||||
btype = 'colordata'
|
btype = 'colordata'
|
||||||
modename = 'colortext'
|
modename = 'colortext'
|
||||||
color_re = re.compile(r'\[([a-z:]+)\]')
|
color_re = re.compile(r'\[([a-z:]+)\]')
|
||||||
def __init__(self, name, data, nl='\n'):
|
def __init__(self, name, data):
|
||||||
data2 = ColorHighlighter.color_re.sub('', data)
|
data2 = ColorHighlighter.color_re.sub('', data)
|
||||||
data2 = data2.replace('\\[', '[')
|
data2 = data2.replace('\\[', '[')
|
||||||
data2 = data2.replace('\\]', ']')
|
data2 = data2.replace('\\]', ']')
|
||||||
data2 = data2.replace('\\\\', '\\')
|
data2 = data2.replace('\\\\', '\\')
|
||||||
DataBuffer.__init__(self, name, data2, nl)
|
DataBuffer.__init__(self, name, data2)
|
||||||
lines = data.split(self.nl)
|
lines = data.split(self.nl)
|
||||||
self.highlights = {
|
self.highlights = {
|
||||||
'Colortext': ColorHighlighter(),
|
'Colortext': ColorHighlighter(),
|
||||||
|
|
Loading…
Reference in New Issue