general clean-up, refactoring, commenting

--HG--
branch : pmacs2
This commit is contained in:
Erik Osheim 2009-07-23 10:04:12 -04:00
parent 94ee3cd017
commit cdbc5c0c79
3 changed files with 57 additions and 46 deletions

View File

@ -1,16 +1,33 @@
#!/usr/bin/env python #!/usr/bin/env python
import curses, curses.ascii, getpass, os, re, string, sys, termios, time import curses
from getpass import getpass
import locale import locale
import math import os
import traceback import string
from subprocess import Popen, PIPE, STDOUT from subprocess import Popen, PIPE, STDOUT
import sys
import termios
import time
import traceback
import buffer, buffer.about, buffer.colors, buffer.console, buffer.data import buffer
import buffer.fs, buffer.aes import buffer.about
import bufferlist, color, completer, ispell, keyinput, method import buffer.colors
import buffer.console
import buffer.data
import buffer.fs
import buffer.aes
from bufferlist import BufferList
import color
import completer
import keyinput
import method
from minibuffer import MiniBuffer, MiniBufferError from minibuffer import MiniBuffer, MiniBufferError
import mode, util, window import mode
from point import Point from point import Point
import util
from window import Window
class Application(object): class Application(object):
def __init__(self, stdscr, buffers=[], **kwargs): def __init__(self, stdscr, buffers=[], **kwargs):
@ -142,7 +159,7 @@ class Application(object):
# buffer list stuff # buffer list stuff
height = self.y - 1 height = self.y - 1
width = self.x width = self.x
self.bufferlist = bufferlist.BufferList(height, width) self.bufferlist = BufferList(height, width)
self.active_slot = 0 self.active_slot = 0
self.complete_slot = None self.complete_slot = None
@ -160,9 +177,9 @@ class Application(object):
# build windows for our buffers # build windows for our buffers
for b in buffers: for b in buffers:
if b.modename: if b.modename:
window.Window(b, self) Window(b, self)
else: else:
window.Window(b, self, mode_name=kwargs.get('init_mode')) Window(b, self, mode_name=kwargs.get('init_mode'))
self.bufferlist.add_buffer(b) self.bufferlist.add_buffer(b)
self.bufferlist.set_slot(self.active_slot, buffers[0]) self.bufferlist.set_slot(self.active_slot, buffers[0])
@ -359,7 +376,7 @@ class Application(object):
return name return name
def open_path(self, path, binary=False, cipher=None, password=None): def open_path(self, path, binary=False, cipher=None, password=None):
path = os.path.abspath(os.path.realpath(util.expand_tilde(path))) path = util.literal_path(path)
b = self.get_buffer_by_path(path) b = self.get_buffer_by_path(path)
if b is None: if b is None:
name = self.make_name(os.path.basename(path)) name = self.make_name(os.path.basename(path))
@ -394,7 +411,7 @@ class Application(object):
b.open() b.open()
if mode_name is None: if mode_name is None:
mode_name = 'hex' mode_name = 'hex'
window.Window(b, self, height=0, width=0, mode_name=mode_name) Window(b, self, height=0, width=0, mode_name=mode_name)
self.add_buffer(b) self.add_buffer(b)
return b return b
@ -413,7 +430,7 @@ class Application(object):
parentw) parentw)
try: try:
w = self.x - 1 - len(self.mini_prompt) - 1 w = self.x - 1 - len(self.mini_prompt) - 1
window.Window(self.mini_buffer, self, height=1, width=w) Window(self.mini_buffer, self, height=1, width=w)
if startvalue: if startvalue:
self.mini_buffer.set_data(startvalue) self.mini_buffer.set_data(startvalue)
self.arg_history.setdefault(queue, []) self.arg_history.setdefault(queue, [])
@ -472,7 +489,7 @@ class Application(object):
b = buffer.Binary32Buffer(path) b = buffer.Binary32Buffer(path)
b.open() b.open()
b.modename = 'hex' b.modename = 'hex'
window.Window(b, self, height=0, width=0) Window(b, self, height=0, width=0)
self.add_buffer(b) self.add_buffer(b)
if switch_to: if switch_to:
self.switch_buffer(b) self.switch_buffer(b)
@ -484,7 +501,7 @@ class Application(object):
b = buffer.data.DataBuffer(name, data) b = buffer.data.DataBuffer(name, data)
if modename is not None: if modename is not None:
b.modename = modename b.modename = modename
window.Window(b, self, height=0, width=0) Window(b, self, height=0, width=0)
self.add_buffer(b) self.add_buffer(b)
if switch_to: if switch_to:
self.switch_buffer(b) self.switch_buffer(b)
@ -498,7 +515,7 @@ class Application(object):
b = buffer.colors.ColorDataBuffer(name, data) b = buffer.colors.ColorDataBuffer(name, data)
if modename is not None: if modename is not None:
b.modename = modename b.modename = modename
window.Window(b, self, height=0, width=0) Window(b, self, height=0, width=0)
self.add_buffer(b) self.add_buffer(b)
if switch_to: if switch_to:
self.switch_buffer(b) self.switch_buffer(b)
@ -529,7 +546,7 @@ class Application(object):
def add_window_to_buffer(self, b, slotname): def add_window_to_buffer(self, b, slotname):
if not b.has_window(slotname): if not b.has_window(slotname):
slot = self.bufferlist.slots[slotname] slot = self.bufferlist.slots[slotname]
window.Window(b, self, height=slot.height, width=slot.width) Window(b, self, height=slot.height, width=slot.width)
# error string handling # error string handling
def set_msg(self, s): def set_msg(self, s):
@ -1038,7 +1055,7 @@ class Application(object):
def open_aes_file(path, 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("Please enter the AES password: ")
return buffer.aes.AesBuffer(path, p, name) return buffer.aes.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
@ -1194,5 +1211,4 @@ if __name__ == "__main__":
# restore terminal state before exiting # restore terminal state before exiting
termios.tcsetattr(sys.stdin, termios.TCSANOW, attr) termios.tcsetattr(sys.stdin, termios.TCSANOW, attr)
ispell.free()
sys.exit(err) sys.exit(err)

View File

@ -16,6 +16,7 @@ def get_speller():
def free(): def free():
if _speller: if _speller:
_speller.stop() _speller.stop()
_speller = None
class Speller(object): class Speller(object):
def __init__(self, cmd='ispell'): def __init__(self, cmd='ispell'):

48
util.py
View File

@ -5,9 +5,11 @@ import regex
cbuf_re = re.compile(r'[\[\]\\]') cbuf_re = re.compile(r'[\[\]\\]')
def cbuf_escape(s): def cbuf_escape(s):
'''escape characters which have special meaning in color buffers'''
return cbuf_re.sub(lambda m: '\\' + m.group(0), s) return cbuf_re.sub(lambda m: '\\' + m.group(0), s)
def flatzip(a, b): def flatzip(a, b):
'''interleave two lists, e.g. ((a,b),(1,2)) -> (a,1,b,2)'''
l = [] l = []
for x, y in zip(a, b): for x, y in zip(a, b):
l.append(x) l.append(x)
@ -15,65 +17,57 @@ def flatzip(a, b):
return l return l
def should_ignore_path(path, suffixes): def should_ignore_path(path, suffixes):
'''whether file (or any parent) should be ignored based on suffixes '''
for name in path.split('/'): for name in path.split('/'):
for suffix in suffixes: for suffix in suffixes:
if name.endswith(suffix): if name.endswith(suffix):
return True return True
return False return False
def literal_path(path):
'''return the system path for the given user path'''
path = os.path.realpath(expand_tilde(path))
return os.path.abspath(path)
def normal_path(path): def normal_path(path):
#path = os.path.realpath(path) '''return the user path for the given system path '''
path = os.path.normpath(path) path = os.path.normpath(path)
home = os.getenv('HOME') home = os.getenv('HOME')
isdir = os.path.isdir(path) isdir = os.path.isdir(path)
if path.startswith(home): if path.startswith(home):
path = path.replace(home, '~', 1) path = path.replace(home, '~', 1)
if isdir and not path.endswith('/'): if isdir and not path.endswith('/'):
return path + '/' path += '/'
else: return path
return path
def expand_tilde(path): def expand_tilde(path):
isd = path.endswith('/') '''correctly expand the tilde in the provided path'''
isdir = path.endswith('/')
if not path.startswith('~'): if not path.startswith('~'):
return path return path
parts = path.split('/', 1) parts = path.split('/', 1)
if parts[0] == '~': if parts[0] == '~':
parts[0] = os.getenv('HOME') parts[0] = os.getenv('HOME')
elif parts[0].startswith('~'): elif parts[0].startswith('~'):
users = [x[0] for x in pwd.getpwall()] try:
if parts[0][1:] in users: parts[0] = pwd.getpwnam(parts[0][1:])[5]
home = pwd.getpwnam(parts[0][1:])[5] except KeyError:
parts[0] = home pass
if len(parts) > 1: if len(parts) > 1:
s = os.path.join(parts[0], parts[1]) s = os.path.join(parts[0], parts[1])
else: else:
s = parts[0] s = parts[0]
s = os.path.realpath(s) s = os.path.realpath(s)
if os.path.isdir(s) and isd: if os.path.isdir(s) and isdir:
s += '/' s += '/'
return s return s
def cleanse(s):
s2 = s.replace("\n", "")
return s2
def padtrunc(s, i, c=' '):
return s.ljust(i, c)[:i]
def pad(s, i, c=' '):
return s.ljust(i, c)
def count_leading_whitespace(s): def count_leading_whitespace(s):
'''return the amount of leading whitespace of the provided string'''
m = regex.leading_whitespace.match(s) m = regex.leading_whitespace.match(s)
assert m, "count leading whitespace failed somehow" assert m, "count leading whitespace failed somehow"
return m.end() - m.start() return m.end() - m.start()
def dump(x):
d = {}
for name in dir(x):
d[name] = getattr(x, name)
return '%s: %r' % (x, d)
def get_margin_limit(w, def_limit=80): def get_margin_limit(w, def_limit=80):
lname = '%s.margin' % w.mode.name.lower() lname = '%s.margin' % w.mode.name.lower()
if lname in w.application.config: if lname in w.application.config: