From 99dfb30e3e4539f3c2623bd7177accdc0aa856af Mon Sep 17 00:00:00 2001 From: moculus Date: Tue, 5 Jun 2007 04:49:24 +0000 Subject: [PATCH] !!!!!!!! --HG-- branch : pmacs2 --- application.py | 103 +++++++++++++-------------- buffer2.py | 20 +++++- lex2_perl.py | 38 +++++----- method.py | 63 ++++++++-------- mode2.py | 32 --------- mode_mini.py | 13 +--- mode_mini2.py | 41 ----------- mode_perl.py | 190 +++++++++++++++++++++++++++++++++++-------------- mode_python.py | 96 +++++++++++++++++-------- point.py | 2 + window2.py | 9 ++- 11 files changed, 333 insertions(+), 274 deletions(-) delete mode 100644 mode_mini2.py diff --git a/application.py b/application.py index 248b1e3..24c91c5 100755 --- a/application.py +++ b/application.py @@ -10,7 +10,7 @@ from point2 import Point #import mode, mode_c, mode_mini, mode_python, mode_nasm, mode_perl, mode_search #import mode_replace, mode_xml, mode_console, mode_sh, mode_text, mode_which #import mode_mutt, mode_sql, mode_javascript, mode_diff, mode_blame, mode_tt -import mode2, mode_mini2 +import mode2, mode_mini, mode_python, mode_perl def run(buffers, jump_to_line=None, init_mode=None): # save terminal state so we can restore it when the program exits @@ -78,19 +78,15 @@ class Application: # initialize our modes self.modes = { - 'fundamental': mode2.Fundamental, - 'mini': mode_mini2.Mini, - } -# self.modes = { # 'blame': mode_blame.Blame, # 'c': mode_c.C, # 'console': mode_console.Console, # 'diff': mode_diff.Diff, -# 'fundamental': mode.Fundamental, -# 'mini': mode_mini.Mini, + 'fundamental': mode2.Fundamental, + 'mini': mode_mini.Mini, # 'nasm': mode_nasm.Nasm, -# 'perl': mode_perl.Perl, -# 'python': mode_python.Python, + 'perl': mode_perl.Perl, + 'python': mode_python.Python, # 'replace': mode_replace.Replace, # 'search': mode_search.Search, # 'sh': mode_sh.Sh, @@ -101,7 +97,7 @@ class Application: # 'sql': mode_sql.Sql, # 'javascript': mode_javascript.Javascript, # 'template': mode_tt.Template, -# } + } # these are used in this order to determine which mode to open certain # kinds of files @@ -114,10 +110,10 @@ class Application: #'.profile': 'sh', } self.mode_extensions = { -# '.py': 'python', -# '.pl': 'perl', -# '.pm': 'perl', -# '.t': 'perl', + '.py': 'python', + '.pl': 'perl', + '.pm': 'perl', + '.t': 'perl', # '.c': 'c', # '.txt': 'text', # '.s': 'nasm', @@ -132,8 +128,8 @@ class Application: # '.tt': 'template' } self.mode_detection = { -# 'python': 'python', -# 'perl': 'perl', + 'python': 'python', + 'perl': 'perl', # 'sh': 'sh', # 'bash': 'sh', } @@ -281,7 +277,7 @@ class Application: f.close() b = buffer2.FileBuffer(path) b.open() - self.add_window_to_buffer(b, self.active_slot) + #self.add_window_to_buffer(b, self.active_slot) self.add_buffer(b) if switch_to: self.switch_buffer(b) @@ -292,7 +288,7 @@ class Application: b = buffer2.DataBuffer(name, data) if modename is not None: b.modename = modename - self.add_window_to_buffer(b, self.active_slot) + #self.add_window_to_buffer(b, self.active_slot) self.add_buffer(b) if switch_to: self.switch_buffer(b) @@ -318,10 +314,11 @@ class Application: 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.add_window_to_buffer(b, self.active_slot) self.bufferlist.set_slot(self.active_slot, b) def add_window_to_buffer(self, b, slotname): + # XYZ if not b.has_window(slotname): slot = self.bufferlist.slots[slotname] window2.Window(b, self, height=slot.height, width=slot.width) @@ -445,34 +442,6 @@ class Application: self.hide_cursor() curses.doupdate() - # debugging - def dump(self): - w = self.window() - ll = len(w.buffer.lines) - pl = len(w.get_physical_lines()) - vl = len(w.visible_lines()) - - first = w.first - last = w.last - cursor = w.logical_cursor() - vcursor = w.visible_cursor() - s = "" - s += "width: %d\n" % (w.width) - s += "height: %d\n" % (w.height) - s += "len logical lines: %d\n" % (ll) - s += "logical first: %s\n" % (first) - s += "logical last: %s\n" % (last) - s += "logical cursor: %s\n" % (cursor) - s += "len physical lines: %d\n" % (pl) - s += "physical first: %s\n" % (w.physical_point(first)) - s += "physical last: %s\n" % (w.physical_point(last)) - s += "physical cursor: %s\n" % (w.physical_point(cursor)) - s += "len visible lines: %d\n" % (vl) - s += "visible first: %s\n" % ("n/a") - s += "visible last: %s\n" % ("n/a") - s += "visible cursor: %s\n" % (vcursor) - return s - # sub-drawing methods def draw_slots(self): self.win.erase() @@ -486,6 +455,7 @@ class Application: if slot.window is None: return w = slot.window + modename = w.mode.name() redattr = color.build_attr(color.pairs('red', 'default')) @@ -497,17 +467,44 @@ class Application: (px, py) = (None, None) while count < slot.height: if y >= len(lines): - self.win.addstr(slot.offset + count, 0, '~' + ' ' * (slot.width - 1), redattr) + self.win.addstr(slot.offset + count, 0, '~', redattr) else: + # let's find the cursor if cy == y and cx >= x and cx < x + slot.width: px = cx - x py = count - line = lines[y] - subline = line[x:x + slot.width] - if len(subline) < slot.width: - subline += ' ' * (slot.width - len(subline)) - self.win.addstr(slot.offset + count, 0, line[x:x + slot.width]) + line = lines[y] + if modename in w.buffer.highlights: + group = w.buffer.highlights[modename].tokens[y] + j = 0 + for token in group: + assert token.y == y + if token.x < x: + continue + elif token.x >= x + slot.width: + break + + c = w.mode.colors.get(token.name, w.mode.default_color) +# c = w.mode.default_color +# name_parts = token.name.split('.') +# for i in range(0, len(name_parts)): +# name = '.'.join(name_parts[i:]) +# if name in w.mode.colors: +# c = w.mode.colors[name] +# break + + if DARK_BACKGROUND: + c |= curses.A_BOLD + if token.x + len(token.string) >= x + slot.width: + n = len(token.string) - x - slot.width + token.x + s = token.string[:n] + self.win.addstr(slot.offset + count, token.x - x, s, c) + else: + self.win.addstr(slot.offset + count, token.x - x, token.string, c) + else: + self.win.addstr(slot.offset + count, 0, line[x:x + slot.width]) + if x + slot.width >= len(line): x = 0 y += 1 diff --git a/buffer2.py b/buffer2.py index cb2a764..5d31f90 100644 --- a/buffer2.py +++ b/buffer2.py @@ -1,5 +1,5 @@ import md5, os, sets, shutil -import aes, regex +import aes, regex, highlight2 from point2 import Point # undo/redo stack constants @@ -39,7 +39,7 @@ class Buffer(object): self.stack_limit = stack_limit self.nl = nl self.modified = False - self.modes = {} + self.highlights = {} # basic file operation stuff def _open_file_r(self, path): @@ -99,19 +99,35 @@ class Buffer(object): def add_window(self, w): if w not in self.windows: self.windows.append(w) + modename = w.mode.name() + if modename not in self.highlights and w.mode.lexer is not None: + self.highlights[modename] = highlight2.Highlighter(w.mode.lexer) + self.highlights[modename].highlight(self.lines) def remove_window(self, w): if w in self.windows: self.windows.remove(w) + modename = w.mode.name() + found = False + for w2 in self.windows: + if w2.mode.name() == modename: + found = True + break + if not found: + del self.highlights[modename] def _region_add(self, p1, p2, lines, act): move = DelMove(self, p1, p2) self.add_to_stack(move, act) for w in self.windows: w.region_added(p1, lines) + for name in self.highlights: + self.highlights[name].relex_add(self.lines, p1.y, p1.x, lines) def _region_del(self, p1, p2, lines, act): move = AddMove(self, p1, lines) self.add_to_stack(move, act) for w in self.windows: w.region_removed(p1, p2) + for name in self.highlights: + self.highlights[name].relex_del(self.lines, p1.y, p1.x, p2.y, p2.x) # internal validation def _validate_point(self, p): diff --git a/lex2_perl.py b/lex2_perl.py index c1052fc..c91aa67 100755 --- a/lex2_perl.py +++ b/lex2_perl.py @@ -303,25 +303,25 @@ class PerlGrammar(Grammar): pattern=r"(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*", ), - # nested regions - RegionRule( - name=r'paren', - start=r'\(', - grammar=None, - end=r'\)', - ), - RegionRule( - name=r'brace', - start=r'{', - grammar=None, - end=r'}', - ), - RegionRule( - name=r'bracket', - start=r'\[', - grammar=None, - end=r'\]', - ), +# # nested regions +# RegionRule( +# name=r'paren', +# start=r'\(', +# grammar=None, +# end=r'\)', +# ), +# RegionRule( +# name=r'brace', +# start=r'{', +# grammar=None, +# end=r'}', +# ), +# RegionRule( +# name=r'bracket', +# start=r'\[', +# grammar=None, +# end=r'\]', +# ), # some basic stuff PatternRule( diff --git a/method.py b/method.py index be10a0b..c3144e4 100644 --- a/method.py +++ b/method.py @@ -1,5 +1,6 @@ import os, commands, popen2, re -import buffer, default, point, regex, util, window +import buffer2, default, regex, util, window2 +from point2 import Point DATATYPES = { "path": None, @@ -204,10 +205,9 @@ class OpenFile(Method): i += 1 auxname = '%s/%d' % (name, i) name = auxname - b = buffer.FileBuffer(path, name=name) + b = buffer2.FileBuffer(path, name=name) b.open() - (height, width) = a.get_window_height_width(a.active_slot) - window.Window(b, a, height=height, width=width, slot=a.active_slot) + window2.Window(b, a, height=0, width=0) w.application.add_buffer(b) SwitchBuffer().execute(w, buffername=b.name()) class OpenAesFile(Method): @@ -221,10 +221,9 @@ class OpenAesFile(Method): path = os.path.abspath(os.path.realpath(util.expand_tilde(path))) a = w.application if not w.application.has_buffer_name(path): - b = buffer.AesBuffer(path, password) + b = buffer2.AesBuffer(path, password) b.open() - (height, width) = a.get_window_height_width(a.active_slot) - window.Window(b, a, height=height, width=width, slot=a.active_slot) + window.Window(b, a, height=0, width=0) w.application.add_buffer(b) SwitchBuffer().execute(w, buffername=path) class SwitchBuffer(Method): @@ -297,11 +296,12 @@ class SaveBuffer(Method): class RelexBuffer(Method): '''Relex the buffer; this resets syntax highlighting''' def _execute(self, w, **vargs): - if w.mode.lexer is not None: - w.mode.highlighter.invalidate_tokens() - w.application.set_error("Buffer relexed.") - else: + h = w.get_highlighter() + if h is None: w.application.set_error("No lexer for buffer.") + else: + h.highlight(w.buffer.lines) + w.application.set_error("Buffer relexed.") class ToggleWindow(Method): '''Move between visible windows''' def _execute(self, w, **vargs): @@ -395,8 +395,8 @@ class DeleteLeft(Method): cursor = w.logical_cursor() line = w.buffer.lines[cursor.y] if cursor.x >= 4 and line[0:cursor.x].isspace(): - w.kill(point.Point(cursor.x-4, cursor.y), - point.Point(cursor.x, cursor.y)) + w.kill(Point(cursor.x-4, cursor.y), + Point(cursor.x, cursor.y)) else: w.left_delete() class DeleteRight(Method): @@ -405,8 +405,8 @@ class DeleteRight(Method): cursor = w.logical_cursor() line = w.buffer.lines[cursor.y] if len(line[cursor.x:]) >= 4 and line[:cursor.x + 4].isspace(): - w.kill(point.Point(cursor.x, cursor.y), - point.Point(cursor.x + 4, cursor.y)) + w.kill(Point(cursor.x, cursor.y), + Point(cursor.x + 4, cursor.y)) else: w.right_delete() class DeleteLeftWord(Method): @@ -496,24 +496,25 @@ class InsertTab(Method): '''Insert tab into buffer, or tabbify line, depending on mode''' def _execute(self, window, **vargs): cursor = window.logical_cursor() - i = window.mode.get_indentation_level(cursor.y) + #i = window.mode.get_indentation_level(cursor.y) + i = None if i is None: window.insert_string_at_cursor(' ') else: j = window.buffer.count_leading_whitespace(cursor.y) if i != j: KillWhitespace().execute(window) - window.insert(point.Point(0, cursor.y), ' ' * i) + window.insert(Point(0, cursor.y), ' ' * i) else: - window.goto(point.Point(j, cursor.y)) + window.goto(Point(j, cursor.y)) class KillWhitespace(Method): '''Delete leading whitespace on current line''' def _execute(self, window, **vargs): cursor = window.logical_cursor() i = window.buffer.count_leading_whitespace(cursor.y) if i > 0: - window.kill(point.Point(0, cursor.y), - point.Point(i, cursor.y)) + window.kill(Point(0, cursor.y), + Point(i, cursor.y)) # tabification class TabBuffer(Method): @@ -541,7 +542,7 @@ class CommentRegion(Method): window.input_line = "Empty kill region" return for y in range(p1.y, p2.y): - window.buffer.insert_string_at_cursor(point.Point(0, y), "#") + window.buffer.insert_string_at_cursor(Point(0, y), "#") class UncommentRegion(Method): '''Remove a comment from every line in the current buffer''' def _execute(self, w, **vargs): @@ -557,7 +558,7 @@ class UncommentRegion(Method): return for y in range(p1.y, p2.y): if w.buffer.lines[y].startswith("#"): - w.buffer.delete_string(point.Point(0, y), point.Point(1, y)) + w.buffer.delete_string(Point(0, y), Point(1, y)) # wrapping/justifying/etc class WrapLine(Method): @@ -580,7 +581,7 @@ class WrapLine(Method): move_old_cursor = False old_cursor.x -= j + 1 old_cursor.y += 1 - window.goto(point.Point(j, i)) + window.goto(Point(j, i)) window.right_delete() window.insert_string_at_cursor('\n') i += 1 @@ -589,7 +590,7 @@ class WrapLine(Method): if l > old_cursor.x: window.goto(old_cursor) else: - window.goto(point.Point(l, old_cursor.y)) + window.goto(Point(l, old_cursor.y)) class WrapParagraph(Method): limit = 80 wrapper = WrapLine @@ -658,7 +659,7 @@ class JustifyLeft(Method): return if this_line[i] != ' ': return - window.buffer.delete_string(point.Point(i, cursor.y), cursor) + window.buffer.delete_string(Point(i, cursor.y), cursor) # undo/redo class Undo(Method): @@ -766,8 +767,8 @@ class UnindentBlock(Method): for i in range(0, len(lines)): if lines[i].startswith(' '): lines[i] = lines[i][4:] - w.buffer.delete_string(point.Point(0, p1.y), point.Point(0, p2.y)) - w.buffer.insert_string_at_cursor(point.Point(0, p1.y), '\n'.join(lines) + '\n') + w.buffer.delete_string(Point(0, p1.y), Point(0, p2.y)) + w.buffer.insert_string_at_cursor(Point(0, p1.y), '\n'.join(lines) + '\n') class IndentBlock(Method): '''Add 4 spaces to each line in region''' def _execute(self, w, **vargs): @@ -784,8 +785,8 @@ class IndentBlock(Method): lines = w.buffer.lines[p1.y:p2.y] for i in range(0, len(lines)): lines[i] = ' ' + lines[i] - w.buffer.delete_string(point.Point(0, p1.y), point.Point(0, p2.y)) - w.buffer.insert_string_at_cursor(point.Point(0, p1.y), '\n'.join(lines) + '\n') + w.buffer.delete_string(Point(0, p1.y), Point(0, p2.y)) + w.buffer.insert_string_at_cursor(Point(0, p1.y), '\n'.join(lines) + '\n') class CodeComplete(Method): '''Complete based on tokenized strings''' @@ -844,7 +845,7 @@ class OpenConsole(Method): def execute(self, w, **vargs): a = w.application if not a.has_buffer_name('*Console*'): - a.add_buffer(buffer.ConsoleBuffer()) + a.add_buffer(buffer2.ConsoleBuffer()) b = a.bufferlist.get_buffer_by_name('*Console*') if a.window().buffer is not b: a.switch_buffer(b) @@ -1343,7 +1344,7 @@ class CloseTag(Method): assert len(tag_stack) == 0, "no match for %r found" % (tag_stack[0]) - p = w.logical_point(point.Point(region[0], j)) + p = w.logical_point(Point(region[0], j)) w.set_active_point(p, msg='match found on line %(y)d, at character %(x)d') class CloseParen(CloseTag): diff --git a/mode2.py b/mode2.py index 78ad0ae..05163a6 100644 --- a/mode2.py +++ b/mode2.py @@ -155,7 +155,6 @@ class Fundamental(Handler): # initialize the default colors, highlighter, etc. self.default_color = color.pairs('default', 'default') self.colors = {} - self.highlighter = highlight.Highlighter(self) # get mode name def name(self): @@ -190,34 +189,3 @@ class Fundamental(Handler): else: err = "%s in mode '%s'" % (e, self.name()) self.window.application.set_error(err) - - def invalidate(self): - if self.lexer is not None: - self.highlighter.invalidate_regions() - - def get_regions(self): - if self.lexer is not None: - return self.highlighter.tokens - else: - raise Exception, "" - regions = [] - for i in range(0, len(self.window.buffer.lines)): - l = self.window.buffer.lines[i] - regions.append([lex2.Token('line', '', i, 0, l)]) - return regions - - def visible_regions(self): - i = self.window.visible_offset() - regions = self.get_regions() - return regions[i:i+self.window.height] - - def region_added(self, p, newlines): - if self.lexer is not None: - self.highlighter.relex_add(lines, p.y, p.x, newlines) - - def region_removed(self, p1, p2): - if self.lexer is not None: - self.highlighter.relex_del(lines, p1, p2) - - def get_indentation_level(self, y): - return None diff --git a/mode_mini.py b/mode_mini.py index 00b0b90..7bdb7ac 100644 --- a/mode_mini.py +++ b/mode_mini.py @@ -1,11 +1,9 @@ -import sets, string +import method, mode2 -import color, highlight, method, minibuffer, mode, point - -class Mini(mode.Fundamental): +class Mini(mode2.Fundamental): '''This is the default mode''' def __init__(self, w): - mode.Fundamental.__init__(self, w) + mode2.Fundamental.__init__(self, w) # delete actions relating to multiple lines self.del_action('center-view') @@ -41,8 +39,3 @@ class MiniTabComplete(method.Method): s1 = b.make_string() s2, exists, complete = b.tabber.tab_string(s1, window) b.set_data(s2) - -#class MiniCancel(method.Method): -# def execute(self, window, **vargs): -# window.application.close_mini_buffer() -# window.application.error_string = "Cancel" diff --git a/mode_mini2.py b/mode_mini2.py deleted file mode 100644 index 7bdb7ac..0000000 --- a/mode_mini2.py +++ /dev/null @@ -1,41 +0,0 @@ -import method, mode2 - -class Mini(mode2.Fundamental): - '''This is the default mode''' - def __init__(self, w): - mode2.Fundamental.__init__(self, w) - - # delete actions relating to multiple lines - self.del_action('center-view') - self.del_action('next-line') - self.del_action('previous-line') - self.del_action('page-down') - self.del_action('page-up') - self.del_action('goto-beginning') - self.del_action('goto-end') - self.del_action('switch-buffer') - - # add some new actions for the minibuffer - self.add_action_and_bindings(MiniCallback(), ('RETURN',)) - self.add_action_and_bindings(MiniTabComplete(), ('TAB',)) - #self.add_action_and_bindings(MiniCancel(), ('C-]',)) - - def name(self): - return "Mini" - -class MiniCallback(method.Method): - def execute(self, window, **vargs): - window.buffer.do_callback() - -class MiniTabComplete(method.Method): - def __init__(self): - self.name = "tab-complete" - self.args = [] - def execute(self, window, **vargs): - b = window.buffer - if b.tabber is None: - window.application.set_error("No tab completion") - return - s1 = b.make_string() - s2, exists, complete = b.tabber.tab_string(s1, window) - b.set_data(s2) diff --git a/mode_perl.py b/mode_perl.py index 7983a42..f6082ee 100644 --- a/mode_perl.py +++ b/mode_perl.py @@ -1,13 +1,14 @@ import re, sets, string, sys -import color, commands, default, lex, lex_perl, method, mode, point, regex, tab_perl +import color, commands, default, lex2, lex2_perl, method, mode2, regex, tab_perl +from point2 import Point -class Perl(mode.Fundamental): +class Perl(mode2.Fundamental): def __init__(self, w): - mode.Fundamental.__init__(self, w) + mode2.Fundamental.__init__(self, w) - self.tag_matching = True - self.grammar = lex_perl.PerlGrammar() - self.lexer = lex.Lexer(self.grammar) + #self.tag_matching = True + self.grammar = lex2_perl.PerlGrammar() + self.lexer = lex2.Lexer(self.name(), self.grammar) self.add_action_and_bindings(PerlCheckSyntax(), ('C-c s',)) self.add_action_and_bindings(PerlHashCleanup(), ('C-c h',)) @@ -24,51 +25,134 @@ class Perl(mode.Fundamental): self.add_bindings('close-bracket', (']',)) self.default_color = color.build('default', 'default') + self.colors = { - 'heredoc': color.build('green', 'default'), - 'endblock': color.build('red', 'default'), - 'pod': color.build('red', 'default'), - 'comment': color.build('red', 'default'), - 'string1': color.build('green', 'default'), - 'string2': color.build('green', 'default'), - 'evalstring': color.build('cyan', 'default'), - 'default string': color.build('green', 'default'), - 'keyword': color.build('magenta', 'default'), - 'length scalar': color.build('yellow', 'default'), - 'system scalar': color.build('yellow', 'default'), - 'system array': color.build('yellow', 'default'), - 'scalar': color.build('yellow', 'default'), - 'dereference': color.build('yellow', 'default'), - 'array': color.build('yellow', 'default'), - 'hash': color.build('yellow', 'default'), - 'hash bareword index': color.build('green', 'default'), - 'quoted region': color.build('cyan', 'default'), - 'match regex': color.build('cyan', 'default'), - 'replace regex': color.build('cyan', 'default'), - 'literal hash bareword index': color.build('green', 'default'), - 'interpolated scalar': color.build('yellow', 'default'), - 'interpolated system scalar': color.build('yellow', 'default'), - 'interpolated array': color.build('yellow', 'default'), - 'interpolated system array': color.build('yellow', 'default'), - 'interpolated hash': color.build('yellow', 'default'), - 'label': color.build('cyan', 'default'), - 'package': color.build('cyan', 'default'), - 'use': color.build('cyan', 'default'), - 'method': color.build('cyan', 'default'), - 'methodref': color.build('cyan', 'default'), - 'method declaration': color.build('cyan', 'default'), - 'instance method': color.build('cyan', 'default'), - 'static method': color.build('cyan', 'default'), - 'built-in method': color.build('magenta', 'default'), - 'bareword method': color.build('cyan', 'default'), - #'bareword': color.build('yellow', 'magenta'), - 'bizzaro': color.build('magenta', 'green') + # basic stuff + 'escaped': color.build('magenta', 'default'), + 'null': color.build('default', 'default'), + 'delimiter': color.build('default', 'default'), + 'sub': color.build('cyan', 'default'), + 'number': color.build('default', 'default'), + 'operator': color.build('default', 'default'), + 'endblock': color.build('red', 'default'), + 'keyword': color.build('magenta', 'default'), + 'scalar': color.build('yellow', 'default'), + 'array': color.build('yellow', 'default'), + 'deref': color.build('yellow', 'default'), + 'hash': color.build('yellow', 'default'), + 'hash_key': color.build('green', 'default'), + 'comment': color.build('red', 'default'), + 'function': color.build('cyan', 'default'), + 'builtin': color.build('magenta', 'default'), + 'method': color.build('cyan', 'default'), + 'bareword': color.build('default', 'default'), + 'label': color.build('cyan', 'default'), + 'package': color.build('cyan', 'default'), + 'class': color.build('cyan', 'default'), + 'use': color.build('cyan', 'default'), + 'method': color.build('cyan', 'default'), + + # heredoc + 'heredoc1.start': color.build('green', 'default'), + 'heredoc1.null': color.build('green', 'default'), + 'heredoc1.end': color.build('green', 'default'), + 'heredoc2.start': color.build('green', 'default'), + 'heredoc2.null': color.build('green', 'default'), + 'heredoc2.end': color.build('green', 'default'), + 'eval_heredoc.start': color.build('cyan', 'default'), + 'eval_heredoc.null': color.build('cyan', 'default'), + 'eval_heredoc.end': color.build('cyan', 'default'), + + # pod + 'pod.start': color.build('red', 'default'), + 'pod.null': color.build('red', 'default'), + 'pod.entry': color.build('magenta', 'default'), + 'pod.end': color.build('red', 'default'), + + # "" strings + 'string1.start': color.build('green', 'default'), + 'string1.null': color.build('green', 'default'), + 'string1.escaped': color.build('magenta', 'default'), + 'string1.deref': color.build('yellow', 'default'), + 'string1.end': color.build('green', 'default'), + + # '' strings + 'string2.start': color.build('green', 'default'), + 'string2.null': color.build('green', 'default'), + 'string2.end': color.build('green', 'default'), + + # `` strings + 'evalstring': color.build('cyan', 'default'), + + # quoted region + 'quoted': color.build('cyan', 'default'), + 'quoted.start': color.build('cyan', 'default'), + 'quoted.null': color.build('cyan', 'default'), + 'quoted.end': color.build('cyan', 'default'), + + # match regex + 'match.start': color.build('cyan', 'default'), + 'match.end': color.build('cyan', 'default'), + 'match.null': color.build('cyan', 'default'), + + # replace regex + 'replace.start': color.build('cyan', 'default'), + 'replace.middle': color.build('cyan', 'default'), + 'replace.end': color.build('cyan', 'default'), + 'replace.null': color.build('cyan', 'default'), + + # translate regex + 'translate.start': color.build('magenta', 'default'), + 'translate.middle': color.build('magenta', 'default'), + 'translate.end': color.build('magenta', 'default'), + 'translate.null': color.build('magenta', 'default'), } +# self.colors = { +# 'heredoc': color.build('green', 'default'), +# 'endblock': color.build('red', 'default'), +# 'pod': color.build('red', 'default'), +# 'comment': color.build('red', 'default'), +# 'string1': color.build('green', 'default'), +# 'string2': color.build('green', 'default'), +# 'evalstring': color.build('cyan', 'default'), +# 'default string': color.build('green', 'default'), +# 'keyword': color.build('magenta', 'default'), +# 'length scalar': color.build('yellow', 'default'), +# 'system scalar': color.build('yellow', 'default'), +# 'system array': color.build('yellow', 'default'), +# 'scalar': color.build('yellow', 'default'), +# 'dereference': color.build('yellow', 'default'), +# 'array': color.build('yellow', 'default'), +# 'hash': color.build('yellow', 'default'), +# 'hash bareword index': color.build('green', 'default'), +# 'quoted region': color.build('cyan', 'default'), +# 'match regex': color.build('cyan', 'default'), +# 'replace regex': color.build('cyan', 'default'), +# 'literal hash bareword index': color.build('green', 'default'), +# 'interpolated scalar': color.build('yellow', 'default'), +# 'interpolated system scalar': color.build('yellow', 'default'), +# 'interpolated array': color.build('yellow', 'default'), +# 'interpolated system array': color.build('yellow', 'default'), +# 'interpolated hash': color.build('yellow', 'default'), +# 'label': color.build('cyan', 'default'), +# 'package': color.build('cyan', 'default'), +# 'use': color.build('cyan', 'default'), +# 'method': color.build('cyan', 'default'), +# 'methodref': color.build('cyan', 'default'), +# 'method declaration': color.build('cyan', 'default'), +# 'instance method': color.build('cyan', 'default'), +# 'static method': color.build('cyan', 'default'), +# 'built-in method': color.build('magenta', 'default'), +# 'bareword method': color.build('cyan', 'default'), +# #'bareword': color.build('yellow', 'magenta'), +# 'bizzaro': color.build('magenta', 'green') +# } + #self.highlighter.lex_buffer() #self.get_regions() - self.tabber = tab_perl.PerlTabber(self) - self.functions = None + #self.tabber = tab_perl.PerlTabber(self) + #self.functions = None def name(self): return "Perl" @@ -143,8 +227,8 @@ class PerlWrapLine(method.Method): lines.append(pad + word) # remove the old text and add the new - start_p = point.Point(0, start) - end_p = point.Point(len(w.buffer.lines[end-1]), end-1) + start_p = Point(0, start) + end_p = Point(len(w.buffer.lines[end-1]), end-1) w.kill(start_p, end_p) w.insert(start_p, '\n'.join(lines)) @@ -242,7 +326,7 @@ class PerlGotoFunction(method.Method): functions = w.mode.get_functions() if name in functions: number = functions[name] - p = point.Point(0, number) + p = Point(0, number) w.goto(p) else: w.application.set_error("Function %r was not found" % name) @@ -342,8 +426,8 @@ class PerlHashCleanup(method.Method): data += indent_pad + key + key_pad + ' ' + sep + ' ' + value + '\n' # remove the old text and add the new - start_p = point.Point(0, start) - end_p = point.Point(0, end + 1) + start_p = Point(0, start) + end_p = Point(0, end + 1) window.kill(start_p, end_p) window.insert(start_p, data) @@ -443,7 +527,7 @@ class PerlHashCleanup2(method.Method): data += line + '\n' # remove the old text and add the new - start_p = point.Point(0, start) - end_p = point.Point(0, end + 1) + start_p = Point(0, start) + end_p = Point(0, end + 1) w.kill(start_p, end_p) w.insert(start_p, data) diff --git a/mode_python.py b/mode_python.py index 7ef03ce..00efbea 100644 --- a/mode_python.py +++ b/mode_python.py @@ -1,15 +1,17 @@ import commands, os.path, sets, string, sys -import color, default, mode, lex, lex_python, method, point, regex, tab_python +import color, default, mode2, lex2, lex2_python, method, regex, tab_python import ctag_python, completer -class Python(mode.Fundamental): +from point2 import Point + +class Python(mode2.Fundamental): def __init__(self, w): - mode.Fundamental.__init__(self, w) + mode2.Fundamental.__init__(self, w) self.tag_matching = True - self.grammar = lex_python.PythonGrammar() - self.lexer = lex.Lexer(self.grammar) + self.grammar = lex2_python.PythonGrammar() + self.lexer = lex2.Lexer(self.name(), self.grammar) self.add_action_and_bindings(PythonCheckSyntax(), ('C-c s',)) self.add_action_and_bindings(PythonDictCleanup(), ('C-c h',)) @@ -21,30 +23,64 @@ class Python(mode.Fundamental): self.add_bindings('close-bracket', (']',)) self.default_color = color.build('default', 'default') + self.colors = { - 'keyword' : color.build('cyan', 'default', 'bold'), - 'pseudo-keyword' : color.build('cyan', 'default', 'bold'), - 'built-in method' : color.build('cyan', 'default', 'bold'), - 'method declaration' : color.build('blue', 'default', 'bold'), - 'class declaration' : color.build('green', 'default'), - 'string4' : color.build('green', 'default'), - 'string3' : color.build('green', 'default'), - 'string2' : color.build('green', 'default'), - 'string1' : color.build('green', 'default'), - 'comment' : color.build('red', 'default'), - 'continuation' : color.build('red', 'default'), - #'operator' : color.build('yellow', 'default'), - #'delimiter' : color.build('magenta', 'default'), - 'system_identifier' : color.build('cyan', 'default', 'bold'), - #'bound method' : color.build('yellow', 'default'), - 'import statement' : color.build('magenta', 'green'), - 'bizzaro' : color.build('magenta', 'green'), + 'keyword': color.build('cyan', 'default'), + 'builtin_method': color.build('cyan', 'default'), + 'methodname': color.build('blue', 'default'), + 'classname': color.build('green', 'default'), + + 'string.start': color.build('green', 'default'), + 'string.null': color.build('green', 'default'), + 'string.escaped': color.build('magenta', 'default'), + 'string.octal': color.build('magenta', 'default'), + 'string.format': color.build('yellow', 'default'), + 'string.end': color.build('green', 'default'), + + 'integer': color.build('red', 'default'), + 'float': color.build('red', 'default'), + 'imaginary': color.build('red', 'default'), + + 'tq_string.start': color.build('green', 'default'), + 'tq_string.null': color.build('green', 'default'), + 'tq_string.end': color.build('green', 'default'), + + 'docstring.start': color.build('green', 'default'), + 'docstring.null': color.build('green', 'default'), + 'docstring.end': color.build('green', 'default'), + + 'comment': color.build('red', 'default'), + 'continuation': color.build('red', 'default'), + #'operator': color.build('yellow', 'default'), + #'delimiter': color.build('magenta', 'default'), + 'system_identifier': color.build('cyan', 'default'), + #'bound method': color.build(color.build('yellow', 'default'), 'default'), + 'import': color.build('magenta', 'default'), + #'bizzaro': color.build('magenta', 'default'), } - #self.highlighter.lex_buffer() - #self.get_regions() - self.tabber = tab_python.PythonTabber(self) - self.ctagger = ctag_python.PythonCTagger() +# self.colors = { +# 'keyword' : color.build('cyan', 'default', 'bold'), +# 'pseudo-keyword' : color.build('cyan', 'default', 'bold'), +# 'built-in method' : color.build('cyan', 'default', 'bold'), +# 'method declaration' : color.build('blue', 'default', 'bold'), +# 'class declaration' : color.build('green', 'default'), +# 'string4' : color.build('green', 'default'), +# 'string3' : color.build('green', 'default'), +# 'string2' : color.build('green', 'default'), +# 'string1' : color.build('green', 'default'), +# 'comment' : color.build('red', 'default'), +# 'continuation' : color.build('red', 'default'), +# #'operator' : color.build('yellow', 'default'), +# #'delimiter' : color.build('magenta', 'default'), +# 'system_identifier' : color.build('cyan', 'default', 'bold'), +# #'bound method' : color.build('yellow', 'default'), +# 'import statement' : color.build('magenta', 'green'), +# 'bizzaro' : color.build('magenta', 'green'), +# } + + #self.tabber = tab_python.PythonTabber(self) + #self.ctagger = ctag_python.PythonCTagger() def name(self): return "Python" @@ -138,8 +174,8 @@ class PythonTagComplete(method.Method): else: newword = completer.find_common_string(candidates) w.application.set_error('Ambiguous match: %r' % (candidates)) - b.delete_string(point.Point(start, cursor.y), point.Point(end, cursor.y)) - b.insert_string(point.Point(start, cursor.y), newword) + b.delete_string(Point(start, cursor.y), Point(end, cursor.y)) + b.insert_string(Point(start, cursor.y), newword) class PythonDictCleanup(method.Method): '''Align assignment blocks and literal dictionaries''' @@ -214,7 +250,7 @@ class PythonDictCleanup(method.Method): data += indent_pad + key + sep + ' ' + key_pad + value + '\n' # remove the old text and add the new - start_p = point.Point(0, start) - end_p = point.Point(0, end + 1) + start_p = Point(0, start) + end_p = Point(0, end + 1) w.kill(start_p, end_p) w.insert(start_p, data) diff --git a/point.py b/point.py index f3232a3..b1331f8 100644 --- a/point.py +++ b/point.py @@ -1,8 +1,10 @@ LOGICAL = "logical" PHYSICAL = "physical" + class Point: def __init__(self, x=0, y=0, t=None): + raise Exception, "argh!" assert t is None or \ t == LOGICAL or \ t == PHYSICAL diff --git a/window2.py b/window2.py index d95cecb..b6f9db6 100644 --- a/window2.py +++ b/window2.py @@ -15,7 +15,6 @@ class Window(object): def __init__(self, b, a, height=24, width=80, mode_name=None): self.buffer = b self.application = a - self.buffer.add_window(self) self.first = Point(0, 0) self.last = None @@ -59,6 +58,7 @@ class Window(object): m = self.application.modes[mode_name](self) self.set_mode(m) + self.buffer.add_window(self) # private method used in window constructor def _get_path_ext(self, path): @@ -73,6 +73,11 @@ class Window(object): def set_mode(self, m): self.mode = m #self.redraw() + def get_highlighter(self): + if self.mode.lexer is None: + return None + else: + return self.buffer.highlights[self.mode.name()] # this is used to temporarily draw the user's attention to another point def set_active_point(self, p, msg='marking on line %(y)d, character %(x)d'): @@ -127,7 +132,6 @@ class Window(object): elif y == p.y and x >= p.x: self.cursor = Point(x + len(newlines[0]), y) self.assure_visible_cursor() - #self.mode.region_added(p, newlines) # region removed def region_removed(self, p1, p2): @@ -142,7 +146,6 @@ class Window(object): else: self.cursor = Point(self.cursor.x, self.cursor.y - p2.y + p1.y) self.assure_visible_cursor() - #self.mode.region_removed(p1, p2) def point_is_visible(self, p): return self.first <= p and p <= self.last