nl type autodetection

--HG--
branch : pmacs2
This commit is contained in:
moculus 2008-04-16 04:44:32 +00:00
parent 3ff927fdb7
commit 5a2f9b094f
2 changed files with 56 additions and 42 deletions

View File

@ -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)

View File

@ -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(),