From 3c23b94187bd353fb3f0204cc3caf1ae1ae5db5b Mon Sep 17 00:00:00 2001 From: Erik Osheim Date: Fri, 24 Jul 2009 00:07:03 -0400 Subject: [PATCH] more clean-up, comments and docs --HG-- branch : pmacs2 --- application.py | 93 ++++++++++++++++++----------------------------- mode/colortest.py | 37 ------------------- mode/perl.py | 20 +++++----- util.py | 11 ++++++ 4 files changed, 56 insertions(+), 105 deletions(-) delete mode 100644 mode/colortest.py diff --git a/application.py b/application.py index b6d2a30..0b62d6c 100755 --- a/application.py +++ b/application.py @@ -96,14 +96,6 @@ class Application(object): color.default_color = True except: color.default_color = False - - ## this is how we can change color settings - #if curses.can_change_color(): - # #curses.init_color(28, 700, 0, 0) - # #curses.init_color(29, 0, 0, 700) - # pass - #else: - # self.set_error("Dynamic color not available") color.init() # initialize our modes @@ -144,7 +136,7 @@ class Application(object): 'latex', 'insertmini', 'conf', 'haskell', 'erlang', 'iperl', 'iperlmini', 'ipython', 'ipythonmini', 'awk', 'shell', 'shellmini', 'fstab', 'yacc', 'pipe', - 'mbox', 'error', 'lua', 'lily', 'forth', 'ebnf', 'colortest', + 'mbox', 'error', 'lua', 'lily', 'forth', 'ebnf', ) for name in names: exec("import mode.%s; mode.%s.install(self)" % (name, name)) @@ -366,14 +358,15 @@ class Application(object): self.close_buffer(self.get_buffer_by_name(name)) def make_name(self, name): - 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 - return name + return util.make_name(name, self.has_buffer_name) + #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 + #return name def open_path(self, path, binary=False, cipher=None, password=None): path = util.literal_path(path) @@ -476,7 +469,6 @@ class Application(object): # buffer handling def new_file_buffer(self, path, data, switch_to=True): assert not self.has_buffer_name(path), '%r is already open' % path - #assert not os.path.exists(path), '%r already exists' % path # touch the file f = open(path, 'w') f.write(data) @@ -506,6 +498,7 @@ class Application(object): if switch_to: self.switch_buffer(b) return b + # NOTE: make sure that data has escaped \, [, and ] properly, or else you # will get undesirable results def color_data_buffer(self, name, data, switch_to=True, modename='colortext'): @@ -540,7 +533,6 @@ class Application(object): def switch_buffer(self, b): assert self.has_buffer_name(b.name()), "buffer %s does not exist" % (b.name()) assert 0 <= self.active_slot and self.active_slot < len(self.bufferlist.slots) - #self.add_window_to_buffer(b, self.active_slot) self.bufferlist.set_slot(self.active_slot, b) def add_window_to_buffer(self, b, slotname): @@ -617,14 +609,15 @@ class Application(object): # load user configuration NOW def loadrc(self): path = os.path.join(os.getenv('HOME'), '.pmc', 'conf') - if os.path.exists(path): - try: - f = open(path, 'r') - exec(f) - f.close() - except Exception, e: - s = traceback.format_exc() - self.rcerror = 'There was an error during startup:\n\n%s' % s + if not os.path.exists(path): + return + try: + f = open(path, 'r') + exec(f) + f.close() + except Exception, e: + s = traceback.format_exc() + self.rcerror = 'There was an error during startup:\n\n' + s # after actions get handled, do some stuff def post_action_hook(self, act): @@ -635,6 +628,7 @@ class Application(object): else: self.highlight_mark = False + # UTF-8 aware way to write to the screen def addstr(self, y, x, s, attr=curses.A_NORMAL): self.win.addstr(y, x, s.encode('utf-8'), attr) @@ -676,7 +670,6 @@ class Application(object): # clear the error line; it might look confusing to the user try: - #self.win.addstr(self.y-1, 0, ' ' * self.x) self.addstr(self.y-1, 0, ' ' * self.x) except: pass @@ -918,10 +911,8 @@ class Application(object): for hr in self.highlighted_ranges: (high_w, p1, p2, fg, bg) = hr if w is high_w and p2 >= w.first and p1 <= w.last: - #raise Exception(repr((slot, p1, p2, fg, bg))) self.highlight_range(slot, p1, p2, fg, bg) - #self.highlight_range(slot, Point(13, 8), Point(29, 8), 'black', 'magenta') if (self.active_slot == i and not self.highlighted_ranges and self.highlight_mark): fg, bg = 'black', 'cyan' cursor = w.logical_cursor() @@ -936,9 +927,7 @@ class Application(object): if p1 < w.first: p1 = w.first if p2 > w.last: p2 = w.last - #raise Exception("blargh") self.highlight_range(slot, p1, p2, fg, bg) - #raise Exception("p1=%r p2=%r fg=%r bg=%r" % (p1, p2, fg, bg)) if w.margins_visible: shade = util.get_margin_color(w, 'blue') @@ -947,7 +936,6 @@ class Application(object): for j in range(0, slot.height): char = chr(self.win.inch(j + slot.y_offset, limit) & 255) attr = color.build('default', shade, 'bold') - #self.win.addstr(j + slot.y_offset, limit + w.mode.lmargin, char, attr) self.addstr(j + slot.y_offset, limit + w.mode.lmargin, char, attr) def _draw_slot(self, i): @@ -965,28 +953,27 @@ class Application(object): # figure out which "physical line" is the first to be shown. note that # the cursor shouldn't be in the last column unless it's the end of a # line. - k = x // swidth - #if x < len(lines[y]) and x == swidth - 1: #xyz - # k += 1 - while count < slot.height: if lit: rlines = w.render_line_lit(y, swidth) else: rlines = w.render_line_raw(y, swidth) for j in range(k, len(rlines)): + y2 = slot.y_offset + count if lm: lcont = j > 0 - for rstr in slot.window.mode.get_lmargin(w, y, x, ended, lcont): - rstr.draw(self.win, slot.y_offset + count, 0) + rstrs = slot.window.mode.get_lmargin(w, y, x, ended, lcont) + for rstr in rstrs: + rstr.draw(self.win, y2, 0) for rstr in rlines[j]: - rstr.draw(self.win, slot.y_offset + count, 0 + lm) + rstr.draw(self.win, y2, 0 + lm) if rm: rcont = j < len(rlines) - 1 - for rstr in slot.window.mode.get_rmargin(w, y, x, ended, rcont): - rstr.draw(self.win, slot.y_offset + count, slot.width - rm) + rstrs = slot.window.mode.get_rmargin(w, y, x, ended, rcont) + for rstr in rstrs: + rstr.draw(self.win, y2, slot.width - rm) count += 1 if count >= slot.height: break @@ -1000,7 +987,6 @@ class Application(object): return status = slot.window.mode.get_status_bar() status = status.ljust(slot.width)[:slot.width] - #self.win.addstr(slot.height + slot.y_offset, 0, status, curses.A_REVERSE) self.addstr(slot.height + slot.y_offset, 0, status, curses.A_REVERSE) # input bar drawing @@ -1012,7 +998,6 @@ class Application(object): for i in range(0, len(lines)): line = lines[i] try: - #self.win.addstr(self.y - len(lines) + i, 0, line, attr) self.addstr(self.y - len(lines) + i, 0, line, attr) except: raise @@ -1023,7 +1008,6 @@ class Application(object): for i in range(0, len(plines)): pline = plines[i] try: - #self.win.addstr(self.y - len(lines) + i, 0, pline, pattr) self.addstr(self.y - len(lines) + i, 0, pline, pattr) except: pass @@ -1059,6 +1043,7 @@ def open_aes_file(path, name=None, binary=False): return buffer.aes.AesBuffer(path, p, name) else: raise Exception, "can't open %r; unsupported file type" % path + def open_plain_file(path, name=None, binary=False): if os.path.isfile(path) or not os.path.exists(path): if binary: @@ -1080,10 +1065,8 @@ def run_app(stdscr, buffers, **kwargs): return 0 if __name__ == "__main__": - ciphers = { - 'none': open_plain_file, - 'aes': open_aes_file, - } + ciphers = {'none': open_plain_file, + 'aes': open_aes_file} locale.setlocale(locale.LC_ALL, '') @@ -1099,6 +1082,7 @@ if __name__ == "__main__": else: i += 1 + # set up the option parser, and set some defaults import optparse parser = optparse.OptionParser() parser.set_defaults(debug=False) @@ -1177,14 +1161,9 @@ if __name__ == "__main__": path = os.path.abspath(os.path.realpath(util.expand_tilde(path))) if path in paths: continue - name = os.path.basename(path) - if name in names: - i = 1 - auxname = '%s/%d' % (name, i) - while auxname in names: - i += 1 - auxname = '%s/%d' % (name, i) - name = auxname + + # find a free name that doesn't conflict with any others + name = util.make_name(os.path.basename(path), lambda x: x in names) try: b = f(path, name, opts.binary) diff --git a/mode/colortest.py b/mode/colortest.py deleted file mode 100644 index 6027d65..0000000 --- a/mode/colortest.py +++ /dev/null @@ -1,37 +0,0 @@ -import color -from mode import Fundamental -from lex import Grammar, PatternRule - -class ColortestGrammar(Grammar): - rules = [] - for i in range(0, 256): - c = '%02x' % i - rules.append(PatternRule('z' + c, c)) - -class Colortest(Fundamental): - name = 'Colortest' - grammar = ColortestGrammar - colors = {} - -def abc(name, r, g, b): - name2 = name + str(r) + str(g) + str(b) - ColortestGrammar.rules.append(PatternRule('z-' + name2, name2)) - Colortest.colors['z-' + name2] = (name2, 'default') - -for name, r, g, b in color.iter256(): - abc(name, r, g, b) - -#for i in range(1, 6): -# for j in range(0, i): -# for k in range(0, i): -# abc('red', i, j, k) -# abc('green', j, i, k) -# abc('blue', j, k, i) -# -#for i in range(1, 6): -# for j in range(0, i): -# abc('yellow', i, i, j) -# abc('cyan', j, i, i) -# abc('magenta', i, j, i) - -install = Colortest.install diff --git a/mode/perl.py b/mode/perl.py index 3bbe9f2..fb73c28 100644 --- a/mode/perl.py +++ b/mode/perl.py @@ -59,13 +59,13 @@ def _make_string_rules(forbidden): PatternRule('array', r"@\$*" + word2), ] if forbidden == ')': - rules.append(PatternRule('data', r"\([^\(\)]*\)")) + rules.append(PatternRule('data', r"\([^$%@\(\)]*\)")) elif forbidden == '}': - rules.append(PatternRule('data', r"{[^{}]*}")) + rules.append(PatternRule('data', r"{[^$%@{}]*}")) elif forbidden == ']': - rules.append(PatternRule('data', r"\[[^\[\]]*\]")) + rules.append(PatternRule('data', r"\[[^$%@\[\]]*\]")) elif forbidden == '>': - rules.append(PatternRule('data', r"<[^<>]*>")) + rules.append(PatternRule('data', r"<[^$%@<>]*>")) return rules class QuotedWords(Grammar): rules = [ @@ -85,9 +85,9 @@ class StrictStringGrammar(Grammar): rules = [ PatternRule('data', r"[^\\']+"), ] class StringGrammar(Grammar): - rules = _make_string_rules('"') + [PatternRule('data', r'[^\\"]+')] + rules = _make_string_rules('"') + [PatternRule('data', r'[^$%@\\"]+')] class EvalGrammar(Grammar): - rules = _make_string_rules('`') + [PatternRule('data', r'[^\\`]+')] + rules = _make_string_rules('`') + [PatternRule('data', r'[^$%@\\`]+')] class TranslateGrammar1(Grammar): rules = [PatternRule('data', r"(?:\\.|[^\\/])")] @@ -226,9 +226,8 @@ class PerlGrammar(Grammar): RegionRule('perl.quoted', 'q[rqx] *(?P<)', QuotedGrammar3, '>'), RegionRule('perl.quoted', r'q[rqx] *(?P\[)', QuotedGrammar4, r'\]'), RegionRule('perl.quoted', "q[rqx] *(?P')", Grammar, "'"), - RegionRule('perl.quoted', 'q[rqx] *(?P[^ a-zA-Z0-9#])', - MatchGrammar0, '%(delim)s'), RegionRule('perl.quoted', 'q[rqx](?P#)', MatchGrammar0, '#'), + RegionRule('perl.quoted', 'q[rqx] *(?P[^ a-zA-Z0-9#])', MatchGrammar0, '%(delim)s'), # quote operator: q() and qw() do not interpolate RegionRule('perl.quoted', r'qw? *\(', QuotedWords, r'\)'), @@ -236,8 +235,7 @@ class PerlGrammar(Grammar): RegionRule('perl.quoted', 'qw? *<', NoAngle, '>'), RegionRule('perl.quoted', r'qw? *\[', NoBracket, r'\]'), RegionRule('perl.quoted', 'qw?#', NoHash, '#'), - RegionRule('perl.quoted', 'qw? *(?P[^ a-zA-Z0-9#])', - Grammar, '%(delim)s'), + RegionRule('perl.quoted', 'qw? *(?P[^ a-zA-Z0-9#])', Grammar, '%(delim)s'), PatternRule('perl.function', word2 + r"(?= *\()"), PatternRule('perl.class', word2 + "(?=->)"), @@ -722,7 +720,7 @@ class PerlContext(context.Context): class Perl(Fundamental): name = 'Perl' - extensions = ['.pl', '.pm', '.pod'] + extensions = ['.pl', '.pm', '.pod', '.t'] detection = [re.compile('^#!(?:.+/)?perl')] tabbercls = PerlTabber grammar = PerlGrammar diff --git a/util.py b/util.py index 0131cea..008c58c 100644 --- a/util.py +++ b/util.py @@ -70,6 +70,17 @@ def count_leading_whitespace(s): assert m, "count leading whitespace failed somehow" return m.end() - m.start() +def make_name(name, testf): + '''generate a new name, using testf() to see which names are taken''' + if testf(name): + i = 1 + auxname = '%s/%d' % (name, i) + while testf(auxname): + i += 1 + auxname = '%s/%d' % (name, i) + name = auxname + return name + # TODO: move these somewhere more sensible. they aren't really utilities. def get_margin_limit(w, def_limit=80): lname = '%s.margin' % w.mode.name.lower()