diff --git a/IDEAS b/IDEAS index d835bcf..1ad79a9 100644 --- a/IDEAS +++ b/IDEAS @@ -1,3 +1,9 @@ +2007/07/17: + +It would be nice to be able to toggle various lexing rules on/off, so that for +instance text mode could make spell checking optional, or optionally highlight +URLs/emails/etc. + 2007/07/15: Vertical split would be awesome. Also, need more fine-grained controls for diff --git a/application.py b/application.py index e148554..5a19a78 100755 --- a/application.py +++ b/application.py @@ -10,9 +10,9 @@ from point2 import Point import mode2 import mode_mini, mode_search, mode_replace, mode_which import mode_console, mode_consolemini -import mode_c, mode_python, mode_perl, mode_nasm, mode_sh +import mode_c, mode_python, mode_perl, mode_nasm, mode_sh, mode_sql import mode_blame, mode_diff -import mode_javascript, mode_sql, mode_xml, mode_tt, mode_css +import mode_xml, mode_tt, mode_css, mode_javascript, mode_html import mode_text, mode_mutt import mode_bds, mode_life @@ -95,6 +95,7 @@ class Application(object): 'text': mode_text.Text, 'which': mode_which.Which, 'xml': mode_xml.XML, + 'html': mode_html.HTML, 'css': mode_css.CSS, 'life': mode_life.Life, 'mutt': mode_mutt.Mutt, @@ -127,8 +128,8 @@ class Application(object): '.bash': 'sh', '.xml': 'xml', '.xml.in': 'xml', - '.html': 'xml', - '.htm': 'xml', + '.html': 'html', + '.htm': 'html', '.js': 'javascript', '.sql': 'sql', '.tt': 'template', @@ -399,14 +400,8 @@ class Application(object): # the might run-loop! def run(self): self.done = False - #keycodes = [] while not self.done: i = self.win.getch() - #if i > 0: - # if len(keycodes) >= 6: - # keycodes.pop(0) - # keycodes.append(str(i)) - #self.set_error('keycodes: %s' % repr(keycodes)) if i == curses.KEY_RESIZE: while i == curses.KEY_RESIZE: i = self.win.getch() @@ -422,8 +417,7 @@ class Application(object): self.draw() if err: self.set_error(err) - if self.error_timestamp is not None and \ - ERROR_TIMEOUT > 0 and \ + if self.error_timestamp is not None and ERROR_TIMEOUT > 0 and \ time.time() - self.error_timestamp > ERROR_TIMEOUT: self.clear_error() return @@ -451,7 +445,6 @@ class Application(object): if p.y >= len(b.lines): return (vy, vx) = (self.y - 1, min(p.x + len(self.mini_prompt), self.x - 2)) - #self.win.move(self.y-1, cx + len(self.mini_prompt)) else: slot = self.bufferlist.slots[self.active_slot] w = slot.window @@ -472,7 +465,6 @@ class Application(object): else: x += slot.width count += 1 - #self.win.move(slot.offset + count, p.x - x) if vy is None or vx is None: return try: @@ -528,13 +520,9 @@ class Application(object): while count < slot.height: if p1.y == y and px >= x and px - x < slot.width: if slot.width > p2.x - x: - #assert p2.x-x < self.x, \ - # "%d-%d < %d" % (p2.x, x, self.x) self.highlight_chars(slot.offset + count, px-x, p2.x-x, fg, bg) break else: - #assert px - x < self.x, \ - # "%d+%d-%d-1 < %d" % (px, slot.width, x, self.x) self.highlight_chars(slot.offset + count, px-x, slot.width, fg, bg) px += slot.width - px + x if x + slot.width >= len(w.buffer.lines[y]): @@ -608,7 +596,8 @@ class Application(object): s = tstring[s_offset:] token_done = x_offset + len(s) <= slot.width token_wrap = x_offset + len(s) > slot.width - self.win.addstr(slot.offset + count, x_offset, s[:slot.width - x_offset], token.color) + attr = color.build(*token.color) + self.win.addstr(slot.offset + count, x_offset, s[:slot.width - x_offset], attr) if token_wrap: self.win.addch(slot.offset + count, slot.width, '\\', redattr) @@ -620,8 +609,7 @@ class Application(object): break # we have finished this logical line of tokens - j = 0 - x = 0 + j = x = 0 y += 1 count += 1 else: @@ -633,11 +621,11 @@ class Application(object): if slot.window is None: return - w = slot.window - b = w.buffer + w = slot.window + b = w.buffer cursor = w.logical_cursor() - first = w.first - last = w.last + first = w.first + last = w.last if b.readonly(): if b.changed(): @@ -765,8 +753,8 @@ if __name__ == "__main__": # open each path using our callback to get a buffer, open that buffer, etc. buffers = [] - names = sets.Set() - paths = sets.Set() + names = sets.Set() + paths = sets.Set() for path in args: path = os.path.abspath(os.path.realpath(util.expand_tilde(path))) if path in paths: diff --git a/code_examples/PowerAttacker.html b/code_examples/PowerAttacker.html new file mode 100644 index 0000000..0c0f29e --- /dev/null +++ b/code_examples/PowerAttacker.html @@ -0,0 +1,89 @@ + + + + + + + + Power Attacker! + + + + + + + + +
+ + + + + + + + + + + + + + +
Attack Modifier
666.00 hp/rnd
Damage Modifier
Enemy AC
+ + +
+
+ + + + + + + + + + + + + + + + +
Base AttackTotal Attack
Total DamageHas Power Attack
Threat Range + +
+ +
+
Crit Multiplier +
+ + +
+
+
+
+ + diff --git a/code_examples/body.tt b/code_examples/body.tt index 407b627..343d6a1 100644 --- a/code_examples/body.tt +++ b/code_examples/body.tt @@ -1,5 +1,6 @@ +
diff --git a/color.py b/color.py index 860e969..378c71e 100644 --- a/color.py +++ b/color.py @@ -9,14 +9,16 @@ def init(): if not inited: index = 1 - colors = { 'cyan': curses.COLOR_CYAN, - 'green': curses.COLOR_GREEN, - 'red': curses.COLOR_RED, - 'yellow': curses.COLOR_YELLOW, - 'blue': curses.COLOR_BLUE, - 'magenta': curses.COLOR_MAGENTA, - 'black': curses.COLOR_BLACK, - 'white': curses.COLOR_WHITE } + colors = { + 'cyan': curses.COLOR_CYAN, + 'green': curses.COLOR_GREEN, + 'red': curses.COLOR_RED, + 'yellow': curses.COLOR_YELLOW, + 'blue': curses.COLOR_BLUE, + 'magenta': curses.COLOR_MAGENTA, + 'black': curses.COLOR_BLACK, + 'white': curses.COLOR_WHITE + } if default_color: colors["default"] = -1 @@ -31,12 +33,14 @@ def init(): _colors.append(key) index = len(_colors) + 1 - attributes = { 'bold': curses.A_BOLD, - 'reverse': curses.A_REVERSE, - 'normal': curses.A_NORMAL, - 'underline': curses.A_UNDERLINE, - 'dim': curses.A_DIM, - 'standout': curses.A_STANDOUT } + attributes = { + 'bold': curses.A_BOLD, + 'reverse': curses.A_REVERSE, + 'normal': curses.A_NORMAL, + 'underline': curses.A_UNDERLINE, + 'dim': curses.A_DIM, + 'standout': curses.A_STANDOUT, + } inited = True @@ -79,4 +83,3 @@ def build_attr(*attr): x = attributes[x] v = v | x return v - diff --git a/lex3.py b/lex3.py index 09364df..ac63c26 100755 --- a/lex3.py +++ b/lex3.py @@ -430,13 +430,14 @@ class Lexer: mode = self.mstack[-1] else: mode = self.mode - c = mode.default_color + v = list(mode.default_color) for j in range(0, len(fqlist)): name = '.'.join(fqlist[j:]) if name in mode.colors: - c = mode.colors[name] + assert type(mode.colors[name]) == type(()), repr(mode) + v = list(mode.colors[name]) break #if DARK_BACKGROUND: if True: - c |= curses.A_BOLD - return c + v.append('bold') + return v diff --git a/method.py b/method.py index d025bbb..b9093e6 100644 --- a/method.py +++ b/method.py @@ -1374,7 +1374,7 @@ class GetToken(Method): class RegisterSave(Method): MAX_TXT = 30 MAX_REG = 20 - '''help here''' + '''Save the top item of the kill stack into the named register''' args = [Argument('name', datatype="str", prompt="Register name: ")] def _pre_execute(self, w, **vargs): if not w.has_kill(): @@ -1392,7 +1392,7 @@ class RegisterSave(Method): class RegisterRestore(Method): MAX_TXT = 30 MAX_REG = 18 - '''help here''' + '''Push the value saved in the named register onto the kill stack''' args = [Argument('name', datatype="str", prompt="Register name: ")] def _execute(self, w, **vargs): name = vargs['name'] @@ -1408,7 +1408,7 @@ class RegisterRestore(Method): w.set_error('Restored %r from register %r' % (text2, name2)) class Pipe(Method): - '''help here''' + '''Pipe the buffer's contents through the given command, and display the output in a new buffer''' args = [Argument('cmd', datatype="str", prompt="Command: ")] def _parse(self, w, **vargs): m = regex.shell_command.match(vargs['cmd']) @@ -1438,8 +1438,56 @@ class Pipe(Method): w.set_error("%s exited with status %d" % (prog, status)) class Grep(Pipe): - '''help here''' + '''Grep the buffer's contents for instances of a pattern, and display them in a new buffer''' args = [Argument('pattern', datatype="str", prompt="Pattern: ")] def _parse(self, w, **vargs): return ('grep', ('/usr/bin/grep', '-E', '-n', vargs['pattern'])) - \ No newline at end of file + +class TokenComplete(Method): + '''Complete token names based on other tokens in the buffer''' + name_overrides = {} + def _min_completion(self, w, t): + h = w.get_highlighter() + minlen = None + if t.name in self.name_overrides: + ok = name_overrides[t.name] + else: + ok = (t.name,) + + strings = {} + for line in h.tokens: + for t2 in line: + if t2 is t: + continue + elif t2.name not in ok: + continue + elif t2.string.startswith(t.string): + strings[t2.string] = 1 + if minlen is None: + minlen = len(t2.string) + else: + minlen = min(minlen, len(t2.string)) + + strings = strings.keys() + if not strings: + return (0, t.string) + + i = len(t.string) + while i < minlen: + c = strings[0][i] + for s in strings: + if s[i] != c: + return (len(strings), strings[0][:i]) + i += 1 + return (len(strings), strings[0][:minlen]) + + def _execute(self, w, **vargs): + t = w.get_token2() + if regex.reserved_token_names.match(t.name): + return + + (n, s) = self._min_completion(w, t) + if not n: + return + + w.set_error("%r (%r) completing to %r (%d)" % (t.string, t.fqname(), s, n)) diff --git a/mode2.py b/mode2.py index 03f3f15..f4739c4 100644 --- a/mode2.py +++ b/mode2.py @@ -76,13 +76,13 @@ class Fundamental(Handler): grammar = None lexer = None tabber = None + default_color = ('default', 'default',) + colors = {} def __init__(self, w): self.window = w # we need to defer this due to curses startup - self.default_color = color.pairs('default', 'default') - self.colors = {} - + #self.default_color = color.pairs('default', 'default') Handler.__init__(self) # first let's add all the "default" actions diff --git a/mode_bds.py b/mode_bds.py index f1f35e9..a164c5f 100644 --- a/mode_bds.py +++ b/mode_bds.py @@ -1,14 +1,13 @@ import color, mode2 from lex3 import Grammar, PatternRule, RegionRule, Grammar from mode_perl import PerlGrammar -from mode_xml import OpenTagGrammar +from mode_xml import TagGrammar from mode_perl import StringGrammar class BDSGrammar(Grammar): rules = [ RegionRule(r'comment', r''), - RegionRule(r'opentag', r'<', OpenTagGrammar, r'/?>'), - PatternRule(r'closetag', r'< */ *[ =>\n]+ *>'), + RegionRule(r'tag', r'< */?', TagGrammar, r'/?>'), PatternRule(r'delimiter', r'[\[\]\{\}\(\),\?:]'), PatternRule(r'derived', r'(?:FM|CD|FS|FM|TA)[0-9]{3}-[0-9]{3}-[0-9]{3}'), PatternRule(r'question', r'GQ[0-9]{3}-[0-9]{3}-[0-9]{3}:MQ[0-9]{3}-[0-9]{3}-[0-9]{3}'), @@ -27,34 +26,37 @@ class BDS(mode2.Fundamental): opentags = {'(': ')', '[': ']', '{': '}'} closetokens = ('delimiter',) closetags = {')': '(', ']': '[', '}': '{'} + colors = { + 'comment.start': ('red', 'default'), + 'comment.null': ('red', 'default'), + 'comment.end': ('red', 'default'), + + 'tag.start': ('default', 'default'), + 'tag.namespace': ('magenta', 'default'), + 'tag.name': ('blue', 'default'), + 'tag.attrname': ('blue', 'default'), + 'tag.string.start': ('cyan', 'default'), + 'tag.string.null': ('cyan', 'default'), + 'tag.string.end': ('cyan', 'default'), + 'tag.end': ('default', 'default'), + + 'string.start': ('green', 'default'), + 'string.octal': ('magenta', 'default'), + 'string.escaped': ('magenta', 'default'), + 'string.null': ('green', 'default'), + 'string.end': ('green', 'default'), + + 'derived': ('yellow', 'default'), + 'question': ('yellow', 'default'), + 'misquoted': ('yellow', 'red'), + 'bdsfunc': ('magenta', 'default'), + 'perlfunc': ('magenta', 'default'), + 'operator': ('magenta', 'default'), + } def __init__(self, w): mode2.Fundamental.__init__(self, w) self.add_bindings('close-paren', (')',)) self.add_bindings('close-brace', ('}',)) self.add_bindings('close-bracket', (']',)) - self.colors = { - 'comment.start': color.build('red', 'default'), - 'comment.null': color.build('red', 'default'), - 'comment.end': color.build('red', 'default'), - 'opentag.start': color.build('default', 'default'), - 'opentag.namespace': color.build('magenta', 'default'), - 'opentag.name': color.build('blue', 'default'), - 'opentag.attrname': color.build('blue', 'default'), - 'opentag.string.start': color.build('cyan', 'default'), - 'opentag.string.null': color.build('cyan', 'default'), - 'opentag.string.end': color.build('cyan', 'default'), - 'opentag.end': color.build('default', 'default'), - 'string.start': color.build('green', 'default'), - 'string.octal': color.build('magenta', 'default'), - 'string.escaped': color.build('magenta', 'default'), - 'string.null': color.build('green', 'default'), - 'string.end': color.build('green', 'default'), - 'derived': color.build('yellow', 'default'), - 'question': color.build('yellow', 'default'), - 'misquoted': color.build('yellow', 'red'), - 'bdsfunc': color.build('magenta', 'default'), - 'perlfunc': color.build('magenta', 'default'), - 'operator': color.build('magenta', 'default'), - } def name(self): return "BDS" diff --git a/mode_blame.py b/mode_blame.py index 3d0aa9f..1ef5cd6 100644 --- a/mode_blame.py +++ b/mode_blame.py @@ -16,12 +16,10 @@ class BlameGrammar(Grammar): class Blame(mode2.Fundamental): grammar = BlameGrammar - def __init__(self, w): - mode2.Fundamental.__init__(self, w) - self.colors = { - 'metadata.start': color.build('blue', 'default', 'bold'), - 'metadata.username': color.build('cyan', 'default', 'bold'), - 'metadata.end': color.build('green', 'default', 'bold'), - } + colors = { + 'metadata.start': ('blue', 'default', 'bold'), + 'metadata.username': ('cyan', 'default', 'bold'), + 'metadata.end': ('green', 'default', 'bold'), + } def name(self): return "Blame" diff --git a/mode_c.py b/mode_c.py index b7856a2..260518e 100644 --- a/mode_c.py +++ b/mode_c.py @@ -169,60 +169,60 @@ class C(mode2.Fundamental): opentags = {'(': ')', '[': ']', '{': '}'} closetokens = ('delimiter',) closetags = {')': '(', ']': '[', '}': '{'} + colors = { + 'macrocomment.start': ('red', 'default'), + 'macrocomment.null': ('red', 'default'), + 'macrocomment.end': ('red', 'default'), + 'comment': ('red', 'default'), + 'comment.start': ('red', 'default'), + 'comment.end': ('red', 'default'), + 'comment.null': ('red', 'default'), + + 'include': ('blue', 'default'), + 'header': ('green', 'default'), + + 'macro': ('blue', 'default'), + 'macro.start': ('blue', 'default'), + 'macro.name': ('yellow', 'default'), + 'macro.null': ('magenta', 'default'), + #'macro.null': ('default', 'default'), + 'macro.continued': ('red', 'default'), + 'macro.delimiter': ('default', 'default'), + 'macro.integer': ('green', 'default'), + 'macro.float': ('green', 'default'), + 'macro.char': ('green', 'default'), + 'macro.string.start': ('green', 'default'), + 'macro.string.escaped': ('magenta', 'default'), + 'macro.string.octal': ('magenta', 'default'), + #'macro.string.escaped': ('default', 'default'), + #'macro.string.octal': ('default', 'default'), + 'macro.string.null': ('green', 'default'), + 'macro.string.end': ('green', 'default'), + 'macro.end': ('magenta', 'default'), + #'macro.end': ('default', 'default'), + + 'label': ('magenta', 'default'), + 'keyword': ('cyan', 'default'), + 'function': ('blue', 'default'), + 'builtin': ('magenta', 'default'), + 'structname': ('yellow', 'default'), + 'enumname': ('yellow', 'default'), + + 'char': ('green', 'default'), + 'string.start': ('green', 'default'), + 'string.octal': ('green', 'default'), + 'string.escaped': ('green', 'default'), + 'string.null': ('green', 'default'), + 'string.end': ('green', 'default'), + 'integer': ('green', 'default'), + 'float': ('green', 'default'), + + 'bizzaro': ('magenta', 'green'), + } def __init__(self, w): mode2.Fundamental.__init__(self, w) self.add_bindings('close-paren', (')',)) self.add_bindings('close-brace', ('}',)) self.add_bindings('close-bracket', (']',)) - self.colors = { - 'macrocomment.start': color.build('red', 'default'), - 'macrocomment.null': color.build('red', 'default'), - 'macrocomment.end': color.build('red', 'default'), - 'comment': color.build('red', 'default'), - 'comment.start': color.build('red', 'default'), - 'comment.end': color.build('red', 'default'), - 'comment.null': color.build('red', 'default'), - - 'include': color.build('blue', 'default'), - 'header': color.build('green', 'default'), - - 'macro': color.build('blue', 'default'), - 'macro.start': color.build('blue', 'default'), - 'macro.name': color.build('yellow', 'default'), - 'macro.null': color.build('magenta', 'default'), - #'macro.null': color.build('default', 'default'), - 'macro.continued': color.build('red', 'default'), - 'macro.delimiter': color.build('default', 'default'), - 'macro.integer': color.build('green', 'default'), - 'macro.float': color.build('green', 'default'), - 'macro.char': color.build('green', 'default'), - 'macro.string.start': color.build('green', 'default'), - 'macro.string.escaped': color.build('magenta', 'default'), - 'macro.string.octal': color.build('magenta', 'default'), - #'macro.string.escaped': color.build('default', 'default'), - #'macro.string.octal': color.build('default', 'default'), - 'macro.string.null': color.build('green', 'default'), - 'macro.string.end': color.build('green', 'default'), - 'macro.end': color.build('magenta', 'default'), - #'macro.end': color.build('default', 'default'), - - 'label': color.build('magenta', 'default'), - 'keyword': color.build('cyan', 'default'), - 'function': color.build('blue', 'default'), - 'builtin': color.build('magenta', 'default'), - 'structname': color.build('yellow', 'default'), - 'enumname': color.build('yellow', 'default'), - - 'char': color.build('green', 'default'), - 'string.start': color.build('green', 'default'), - 'string.octal': color.build('green', 'default'), - 'string.escaped': color.build('green', 'default'), - 'string.null': color.build('green', 'default'), - 'string.end': color.build('green', 'default'), - 'integer': color.build('green', 'default'), - 'float': color.build('green', 'default'), - - 'bizzaro': color.build('magenta', 'green'), - } def name(self): return "C" diff --git a/mode_console.py b/mode_console.py index 4116f76..56305e4 100644 --- a/mode_console.py +++ b/mode_console.py @@ -15,18 +15,16 @@ class ConsoleGrammar(Grammar): ] class Console(mode2.Fundamental): grammar = ConsoleGrammar() - def __init__(self, w): - mode2.Fundamental.__init__(self, w) - self.colors = { - 'mesg': color.build('blue', 'default'), - 'input': color.build('cyan', 'default'), - 'output': color.build('default', 'default'), + colors = { + 'mesg': ('blue', 'default'), + 'input': ('cyan', 'default'), + 'output': ('default', 'default'), - 'string.start': color.build('green', 'default'), - 'string.octal': color.build('magenta', 'default'), - 'string.escaped': color.build('magenta', 'default'), - 'string.null': color.build('green', 'default'), - 'string.end': color.build('green', 'default'), - } + 'string.start': ('green', 'default'), + 'string.octal': ('magenta', 'default'), + 'string.escaped': ('magenta', 'default'), + 'string.null': ('green', 'default'), + 'string.end': ('green', 'default'), + } def name(self): return "Console" diff --git a/mode_css.py b/mode_css.py index 3f75c0e..88ac356 100644 --- a/mode_css.py +++ b/mode_css.py @@ -43,51 +43,51 @@ class CSSGrammar(Grammar): class CSS(mode2.Fundamental): grammar = CSSGrammar + colors = { + 'comment': ('red', 'default'), + 'comment.start': ('red', 'default'), + 'comment.null': ('red', 'default'), + 'comment.end': ('red', 'default'), + + 'htmlcomment': ('red', 'default'), + 'htmlcomment.start': ('red', 'default'), + 'htmlcomment.null': ('red', 'default'), + 'htmlcomment.end': ('red', 'default'), + + 'dimension': ('magenta', 'default'), + 'percentage': ('magenta', 'default'), + 'length': ('magenta', 'default'), + 'real': ('magenta', 'default'), + 'int': ('magenta', 'default'), + 'color': ('magenta', 'default'), + + 'hash': ('cyan', 'default'), + 'label': ('cyan', 'default'), + 'rule': ('cyan', 'default'), + 'keyword': ('cyan', 'default'), + + 'ident': ('default', 'default'), + 'name': ('default', 'default'), + + 'delimiter': ('default', 'default'), + + 'keyword': ('cyan', 'default'), + 'keyword.start': ('default', 'default'), + 'keyword.null': ('cyan', 'default'), + 'keyword.octal': ('magenta', 'default'), + 'keyword.escaped': ('magenta', 'default'), + 'keyword.end': ('default', 'default'), + + 'string.start': ('green', 'default'), + 'string.null': ('green', 'default'), + 'string.octal': ('magenta', 'default'), + 'string.escaped': ('magenta', 'default'), + 'string.end': ('green', 'default'), + } def __init__(self, w): mode2.Fundamental.__init__(self, w) self.add_bindings('close-paren', (')',)) self.add_bindings('close-brace', ('}',)) self.add_bindings('close-bracket', (']',)) - self.colors = { - 'comment': color.build('red', 'default'), - 'comment.start': color.build('red', 'default'), - 'comment.null': color.build('red', 'default'), - 'comment.end': color.build('red', 'default'), - - 'htmlcomment': color.build('red', 'default'), - 'htmlcomment.start': color.build('red', 'default'), - 'htmlcomment.null': color.build('red', 'default'), - 'htmlcomment.end': color.build('red', 'default'), - - 'dimension': color.build('magenta', 'default'), - 'percentage': color.build('magenta', 'default'), - 'length': color.build('magenta', 'default'), - 'real': color.build('magenta', 'default'), - 'int': color.build('magenta', 'default'), - 'color': color.build('magenta', 'default'), - - 'hash': color.build('cyan', 'default'), - 'label': color.build('cyan', 'default'), - 'rule': color.build('cyan', 'default'), - 'keyword': color.build('cyan', 'default'), - - 'ident': color.build('default', 'default'), - 'name': color.build('default', 'default'), - - 'delimiter': color.build('default', 'default'), - - 'keyword': color.build('cyan', 'default'), - 'keyword.start': color.build('default', 'default'), - 'keyword.null': color.build('cyan', 'default'), - 'keyword.octal': color.build('magenta', 'default'), - 'keyword.escaped': color.build('magenta', 'default'), - 'keyword.end': color.build('default', 'default'), - - 'string.start': color.build('green', 'default'), - 'string.null': color.build('green', 'default'), - 'string.octal': color.build('magenta', 'default'), - 'string.escaped': color.build('magenta', 'default'), - 'string.end': color.build('green', 'default'), - } def name(self): return "Javascript" diff --git a/mode_diff.py b/mode_diff.py index ceea689..6b801b4 100644 --- a/mode_diff.py +++ b/mode_diff.py @@ -13,17 +13,17 @@ class DiffGrammar(Grammar): class Diff(mode2.Fundamental): grammar = DiffGrammar() + colors = { + 'left': ('red', 'default', 'bold'), + 'right': ('blue', 'default', 'bold'), + 'seperator': ('magenta', 'default', 'bold'), + 'metadata': ('magenta', 'default', 'bold'), + 'location': ('magenta', 'default', 'bold'), + } def __init__(self, w): mode2.Fundamental.__init__(self, w) #self.add_action_and_bindings(DiffNextSection(), ('M-n', 'M-D_ARROW',)) #self.add_action_and_bindings(DiffPreviousSection(), ('M-p', 'M-U_ARROW',)) - self.colors = { - 'left': color.build('red', 'default', 'bold'), - 'right': color.build('blue', 'default', 'bold'), - 'seperator': color.build('magenta', 'default', 'bold'), - 'metadata': color.build('magenta', 'default', 'bold'), - 'location': color.build('magenta', 'default', 'bold'), - } def name(self): return "Diff" diff --git a/mode_html.py b/mode_html.py index a163928..7248cc3 100644 --- a/mode_html.py +++ b/mode_html.py @@ -1,42 +1,52 @@ import color, mode2 from lex3 import Grammar, PatternRule, RegionRule +from mode_xml import TagGrammar +from mode_javascript import JavascriptGrammar, Javascript -class TagGrammar(Grammar): - rules = [ - RegionRule(r'string', r'(?P["\'])', Grammar, r'%(tag)s'), - PatternRule(r'namespace', pattern=r'[a-zA-Z_]+:'), - PatternRule(r'attrname', pattern=r'[^ =>\n]+(?==)'), - PatternRule(r'name', pattern=r'[^ =>\n]+'), - ] - -class TemplateGrammar(Grammar): +class HTMLGrammar(Grammar): rules = [ + # TODO: how does cdata work again? RegionRule(r'comment', r''), - RegionRule(r'template', r'\[\%', Grammar, r'%%\]'), - RegionRule(r'opentag', r'<', TagGrammar, r'/?>'), - PatternRule(r'closetag', pattern=r'< */ *[ =>\n]+ *>'), + # BUG: not all scripts are javascript... but, dynamically choosing a + # grammar based on the 'type' attribute (which may be on a different + # line) could be pretty hairy. + RegionRule(r'script', r'<(?=script[^a-zA-Z0-9_])', TagGrammar, r'>', JavascriptGrammar, r')', TagGrammar, r'>'), + RegionRule(r'tag', r''), ] -class Template(mode2.Fundamental): - grammar = TemplateGrammar +class HTML(mode2.Fundamental): + grammar = HTMLGrammar + colors = { + 'comment.start': ('red', 'default'), + 'comment.null': ('red', 'default'), + 'comment.end': ('red', 'default'), + + 'script.start': ('default', 'default'), + 'script.namespace': ('magenta', 'default'), + 'script.name': ('blue', 'default'), + 'script.attrname': ('cyan', 'default'), + 'script.string.start': ('green', 'default'), + 'script.string.null': ('green', 'default'), + 'script.string.end': ('green', 'default'), + 'script.end': ('default', 'default'), + + 'tag.start': ('default', 'default'), + 'tag.namespace': ('magenta', 'default'), + 'tag.name': ('blue', 'default'), + 'tag.attrname': ('cyan', 'default'), + 'tag.string.start': ('green', 'default'), + 'tag.string.null': ('green', 'default'), + 'tag.string.end': ('green', 'default'), + 'tag.end': ('default', 'default'), + } + js = Javascript(None) + for name in js.colors: + colors['script.%s' % name] = js.colors[name] + del js def __init__(self, w): mode2.Fundamental.__init__(self, w) self.add_bindings('close-paren', (')',)) self.add_bindings('close-brace', ('}',)) self.add_bindings('close-bracket', (']',)) - self.colors = { - 'comment': color.build('red', 'default'), - 'template.start': color.build('magenta', 'default'), - 'template.null': color.build('magenta', 'default'), - 'template.end': color.build('magenta', 'default'), - 'opentag.start': color.build('default', 'default'), - 'opentag.namespace': color.build('magenta', 'default'), - 'opentag.name': color.build('blue', 'default'), - 'opentag.attrname': color.build('cyan', 'default'), - 'opentag.string.start': color.build('green', 'default'), - 'opentag.string.null': color.build('green', 'default'), - 'opentag.string.end': color.build('green', 'default'), - 'opentag.end': color.build('default', 'default'), - } def name(self): - return "Template" + return "HTML" diff --git a/mode_javascript.py b/mode_javascript.py index a7699ad..7d8b8a1 100644 --- a/mode_javascript.py +++ b/mode_javascript.py @@ -59,39 +59,39 @@ class Javascript(mode2.Fundamental): opentags = {'(': ')', '[': ']', '{': '}'} closetokens = ('delimiter',) closetags = {')': '(', ']': '[', '}': '{'} + colors = { + 'comment': ('red', 'default'), + 'comment.start': ('red', 'default'), + 'comment.null': ('red', 'default'), + 'comment.end': ('red', 'default'), + 'continuation': ('red', 'default'), + 'function': ('blue', 'default'), + 'class': ('green', 'default'), + + 'reserved': ('cyan', 'default'), + 'nonreserved': ('cyan', 'default'), + + 'delimiter': ('default', 'default'), + 'operator': ('default', 'default'), + 'integer': ('default', 'default'), + 'float': ('default', 'default'), + + 'string.start': ('green', 'default'), + 'string.null': ('green', 'default'), + 'string.octal': ('magenta', 'default'), + 'string.escaped': ('magenta', 'default'), + 'string.end': ('green', 'default'), + + 'regex.start': ('cyan', 'default'), + 'regex.null': ('cyan', 'default'), + 'regex.octal': ('magenta', 'default'), + 'regex.escaped': ('magenta', 'default'), + 'regex.end': ('cyan', 'default'), + } def __init__(self, w): mode2.Fundamental.__init__(self, w) self.add_bindings('close-paren', (')',)) self.add_bindings('close-brace', ('}',)) self.add_bindings('close-bracket', (']',)) - self.colors = { - 'comment': color.build('red', 'default'), - 'comment.start': color.build('red', 'default'), - 'comment.null': color.build('red', 'default'), - 'comment.end': color.build('red', 'default'), - 'continuation': color.build('red', 'default'), - 'function': color.build('blue', 'default'), - 'class': color.build('green', 'default'), - - 'reserved': color.build('cyan', 'default'), - 'nonreserved': color.build('cyan', 'default'), - - 'delimiter': color.build('default', 'default'), - 'operator': color.build('default', 'default'), - 'integer': color.build('default', 'default'), - 'float': color.build('default', 'default'), - - 'string.start': color.build('green', 'default'), - 'string.null': color.build('green', 'default'), - 'string.octal': color.build('magenta', 'default'), - 'string.escaped': color.build('magenta', 'default'), - 'string.end': color.build('green', 'default'), - - 'regex.start': color.build('cyan', 'default'), - 'regex.null': color.build('cyan', 'default'), - 'regex.octal': color.build('magenta', 'default'), - 'regex.escaped': color.build('magenta', 'default'), - 'regex.end': color.build('cyan', 'default'), - } def name(self): return "Javascript" diff --git a/mode_mutt.py b/mode_mutt.py index fe39909..42f6f19 100644 --- a/mode_mutt.py +++ b/mode_mutt.py @@ -17,25 +17,25 @@ class MuttGrammar(Grammar): class Mutt(mode2.Fundamental): grammar = MuttGrammar() + colors = { + 'header': ('green', 'default', 'bold'), + 'email': ('cyan', 'default', 'bold'), + 'url': ('cyan', 'default', 'bold'), + 'quotea': ('yellow', 'default', 'bold'), + 'quoteb': ('cyan', 'default', 'bold'), + 'quotec': ('magenta', 'default', 'bold'), + 'misspelled': ('red', 'default'), + 'cont.start': ('default', 'default'), + 'cont.end': ('default', 'default'), + 'word': ('default', 'default'), + 'punct': ('default', 'default'), + 'stuff': ('default', 'default'), + } def __init__(self, w): mode2.Fundamental.__init__(self, w) self.add_action_and_bindings(mode_text.LearnWord(), ('C-c l',)) self.add_action_and_bindings(MuttWrapParagraph(), ('M-q',)) self.add_action_and_bindings(MuttInsertSpace(), ('SPACE',)) - self.colors = { - 'header': color.build('green', 'default', 'bold'), - 'email': color.build('cyan', 'default', 'bold'), - 'url': color.build('cyan', 'default', 'bold'), - 'quotea': color.build('yellow', 'default', 'bold'), - 'quoteb': color.build('cyan', 'default', 'bold'), - 'quotec': color.build('magenta', 'default', 'bold'), - 'misspelled': color.build('red', 'default'), - 'cont.start': color.build('default', 'default'), - 'cont.end': color.build('default', 'default'), - 'word': color.build('default', 'default'), - 'punct': color.build('default', 'default'), - 'stuff': color.build('default', 'default'), - } def name(self): return "Mutt" diff --git a/mode_nasm.py b/mode_nasm.py index 7568b14..8021321 100644 --- a/mode_nasm.py +++ b/mode_nasm.py @@ -28,18 +28,18 @@ class NasmGrammar(Grammar): class Nasm(mode2.Fundamental): grammar = NasmGrammar + colors = { + 'keyword': ('cyan', 'default', 'bold'), + 'macros': ('blue', 'default', 'bold'), + 'string.start': ('green', 'default'), + 'string.null': ('green', 'default'), + 'string.end': ('green', 'default'), + 'comment': ('red', 'default'), + 'registers': ('yellow', 'default'), + 'instructions': ('magenta', 'default'), + 'label': ('blue', 'default'), + } def __init__(self, w): mode2.Fundamental.__init__(self, w) - self.colors = { - 'keyword': color.build('cyan', 'default', 'bold'), - 'macros': color.build('blue', 'default', 'bold'), - 'string.start': color.build('green', 'default'), - 'string.null': color.build('green', 'default'), - 'string.end': color.build('green', 'default'), - 'comment': color.build('red', 'default'), - 'registers': color.build('yellow', 'default'), - 'instructions': color.build('magenta', 'default'), - 'label': color.build('blue', 'default'), - } def name(self): return "Nasm" diff --git a/mode_perl.py b/mode_perl.py index 89210eb..3ca481b 100644 --- a/mode_perl.py +++ b/mode_perl.py @@ -165,6 +165,94 @@ class Perl(mode2.Fundamental): opentags = {'(': ')', '[': ']', '{': '}'} closetokens = ('delimiter',) closetags = {')': '(', ']': '[', '}': '{'} + colors = { + # basic stuff + 'escaped': ('magenta', 'default'), + 'null': ('default', 'default'), + 'delimiter': ('default', 'default'), + 'sub': ('cyan', 'default'), + 'number': ('default', 'default'), + 'operator': ('default', 'default'), + 'noperator': ('magenta', 'default'), + 'endblock': ('red', 'default'), + 'keyword': ('magenta', 'default'), + 'cast': ('yellow', 'default'), + 'scalar': ('yellow', 'default'), + 'array': ('yellow', 'default'), + 'deref': ('yellow', 'default'), + 'hash': ('yellow', 'default'), + 'hash_key': ('green', 'default'), + 'comment': ('red', 'default'), + 'function': ('cyan', 'default'), + 'builtin': ('magenta', 'default'), + 'method': ('cyan', 'default'), + 'bareword': ('default', 'default'), + 'label': ('cyan', 'default'), + 'package': ('cyan', 'default'), + 'class': ('cyan', 'default'), + 'use': ('cyan', 'default'), + 'require': ('cyan', 'default'), + 'method': ('cyan', 'default'), + + # heredoc/evaldoc + 'heredoc.start': ('green', 'default'), + 'heredoc.null': ('green', 'default'), + 'heredoc.end': ('green', 'default'), + 'evaldoc.start': ('cyan', 'default'), + 'evaldoc.null': ('cyan', 'default'), + 'evaldoc.end': ('cyan', 'default'), + + # pod + 'pod.start': ('red', 'default'), + 'pod.null': ('red', 'default'), + 'pod.entry.start': ('magenta', 'default'), + 'pod.entry.null': ('magenta', 'default'), + 'pod.entry.end': ('magenta', 'default'), + 'pod.end': ('red', 'default'), + + # strings + 'string.start': ('green', 'default'), + 'string.null': ('green', 'default'), + 'string.escaped': ('magenta', 'default'), + 'string.deref': ('yellow', 'default'), + 'string.end': ('green', 'default'), + + # `` strings + 'evalstring.start': ('cyan', 'default'), + 'evalstring.null': ('cyan', 'default'), + 'evalstring.escaped': ('magenta', 'default'), + 'evalstring.deref': ('yellow', 'default'), + 'evalstring.end': ('cyan', 'default'), + + # quoted region + 'quoted': ('cyan', 'default'), + 'quoted.start': ('cyan', 'default'), + 'quoted.null': ('cyan', 'default'), + 'quoted.end': ('cyan', 'default'), + + # match regex + 'match.start': ('cyan', 'default'), + 'match.end': ('cyan', 'default'), + 'match.null': ('cyan', 'default'), + + # replace regex + 'replace.start': ('cyan', 'default'), + 'replace.middle0': ('cyan', 'default'), + 'replace.end': ('cyan', 'default'), + 'replace.null': ('cyan', 'default'), + 'replace.escaped': ('magenta', 'default'), + 'replace.deref': ('yellow', 'default'), + 'replace.length': ('yellow', 'default'), + 'replace.scalar': ('yellow', 'default'), + 'replace.hash': ('yellow', 'default'), + 'replace.cast': ('yellow', 'default'), + + # translate regex + 'translate.start': ('magenta', 'default'), + 'translate.middle0': ('magenta', 'default'), + 'translate.end': ('magenta', 'default'), + 'translate.null': ('magenta', 'default'), + } def __init__(self, w): mode2.Fundamental.__init__(self, w) @@ -185,95 +273,6 @@ class Perl(mode2.Fundamental): self.add_bindings('close-bracket', (']')) self.add_bindings('close-brace', ('}')) - self.colors = { - # 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'), - 'noperator': color.build('magenta', 'default'), - 'endblock': color.build('red', 'default'), - 'keyword': color.build('magenta', 'default'), - 'cast': color.build('yellow', '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'), - 'require': color.build('cyan', 'default'), - 'method': color.build('cyan', 'default'), - - # heredoc/evaldoc - 'heredoc.start': color.build('green', 'default'), - 'heredoc.null': color.build('green', 'default'), - 'heredoc.end': color.build('green', 'default'), - 'evaldoc.start': color.build('cyan', 'default'), - 'evaldoc.null': color.build('cyan', 'default'), - 'evaldoc.end': color.build('cyan', 'default'), - - # pod - 'pod.start': color.build('red', 'default'), - 'pod.null': color.build('red', 'default'), - 'pod.entry.start': color.build('magenta', 'default'), - 'pod.entry.null': color.build('magenta', 'default'), - 'pod.entry.end': color.build('magenta', 'default'), - 'pod.end': color.build('red', 'default'), - - # strings - 'string.start': color.build('green', 'default'), - 'string.null': color.build('green', 'default'), - 'string.escaped': color.build('magenta', 'default'), - 'string.deref': color.build('yellow', 'default'), - 'string.end': color.build('green', 'default'), - - # `` strings - 'evalstring.start': color.build('cyan', 'default'), - 'evalstring.null': color.build('cyan', 'default'), - 'evalstring.escaped': color.build('magenta', 'default'), - 'evalstring.deref': color.build('yellow', 'default'), - 'evalstring.end': 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.middle0': color.build('cyan', 'default'), - 'replace.end': color.build('cyan', 'default'), - 'replace.null': color.build('cyan', 'default'), - 'replace.escaped': color.build('magenta', 'default'), - 'replace.deref': color.build('yellow', 'default'), - 'replace.length': color.build('yellow', 'default'), - 'replace.scalar': color.build('yellow', 'default'), - 'replace.hash': color.build('yellow', 'default'), - 'replace.cast': color.build('yellow', 'default'), - - # translate regex - 'translate.start': color.build('magenta', 'default'), - 'translate.middle0': color.build('magenta', 'default'), - 'translate.end': color.build('magenta', 'default'), - 'translate.null': color.build('magenta', 'default'), - } - # perl-specific self.functions = None self.perllib = 'lib' diff --git a/mode_python.py b/mode_python.py index 759809d..76f385e 100644 --- a/mode_python.py +++ b/mode_python.py @@ -1,8 +1,7 @@ import commands, os.path, sets, string import color, completer, default, mode2, method, regex, tab2 -import ctag_python from point2 import Point -from lex3 import Grammar, PatternRule, RegionRule +from lex3 import Grammar, PatternRule, RegionRule, OverridePatternRule class StringGrammar(Grammar): rules = [ @@ -32,6 +31,7 @@ class PythonGrammar(Grammar): RegionRule(r'string', r"'''", StringGrammar, r"'''"), RegionRule(r'string', r'"', StringGrammar, r'"'), RegionRule(r'string', r"'", StringGrammar, r"'"), + OverridePatternRule(r'comment', r'#@@:(?P[.a-zA-Z0-9_]+):(?P[.a-zA-Z0-9_]+) *$'), PatternRule(r'comment', r'#.*$'), PatternRule(r'continuation', r'\\\n$'), PatternRule(r'eol', r'\n$'), @@ -172,6 +172,25 @@ class Python(mode2.Fundamental): opentags = {'(': ')', '[': ']', '{': '}'} closetokens = ('delimiter',) closetags = {')': '(', ']': '[', '}': '{'} + colors = { + 'keyword': ('cyan', 'default'), + 'reserved': ('magenta', 'default'), + 'builtin': ('cyan', 'default'), + 'functionname': ('blue', 'default'), + 'classname': ('green', 'default'), + 'string.start': ('green', 'default'), + 'string.null': ('green', 'default'), + 'string.octal': ('magenta', 'default'), + 'string.escaped': ('magenta', 'default'), + 'string.format': ('yellow', 'default'), + 'string.end': ('green', 'default'), + 'integer': ('default', 'default'), + 'float': ('default', 'default'), + 'imaginary': ('default', 'default'), + 'comment': ('red', 'default'), + 'continuation': ('red', 'default'), + 'system_identifier': ('cyan', 'default'), + } def __init__(self, w): mode2.Fundamental.__init__(self, w) # tag matching @@ -181,28 +200,7 @@ class Python(mode2.Fundamental): # add python-specific methods self.add_action_and_bindings(PythonCheckSyntax(), ('C-c s',)) self.add_action_and_bindings(PythonDictCleanup(), ('C-c h',)) - #self.add_action_and_bindings(PythonUpdateTags(), ('C-c t',)) - #self.add_action_and_bindings(PythonTagComplete(), ('C-c k',)) # highlighting - self.colors = { - 'keyword': color.build('cyan', 'default'), - 'reserved': color.build('magenta', 'default'), - 'builtin': color.build('cyan', 'default'), - 'functionname': color.build('blue', 'default'), - 'classname': color.build('green', 'default'), - 'string.start': color.build('green', 'default'), - 'string.null': color.build('green', 'default'), - 'string.octal': color.build('magenta', 'default'), - 'string.escaped': color.build('magenta', 'default'), - 'string.format': color.build('yellow', 'default'), - 'string.end': color.build('green', 'default'), - 'integer': color.build('default', 'default'), - 'float': color.build('default', 'default'), - 'imaginary': color.build('default', 'default'), - 'comment': color.build('red', 'default'), - 'continuation': color.build('red', 'default'), - 'system_identifier': color.build('cyan', 'default'), - } self.pythonlib = "." def name(self): return "Python" @@ -227,78 +225,6 @@ class PythonCheckSyntax(method.Method): output = output + "\ncommand exit status: %d" % (status) w.application.data_buffer("python-syntax", output, switch_to=True) -#class PythonUpdateTags(method.Method): -# '''Update the CTag data associated with a python buffer''' -# args = [method.Argument("lib", prompt="Module Base: ", datatype='path', -# default=default.build_constant("."))] -# def _execute(self, w, **vargs): -# w.mode.ctagger = ctag_python.PythonCTagger() -# w.mode.ctagger.process_paths([vargs['lib']]) -# w.application.set_error('Tag data updated') -# -#class PythonTagComplete(method.Method): -# '''Complete a symbol using tag data''' -# def _execute(self, w, **vargs): -# if not w.mode.ctagger.packages: -# w.application.methods['python-update-tags'].execute(w) -# return -# -# cursor = w.logical_cursor() -# b = w.buffer -# line = b.lines[cursor.y] -# end = cursor.x -# start = cursor.x -# -# word_chars = string.letters + string.digits + '_' -# if start == 0: -# w.application.set_error('walrus 1') -# return -# -# c = line[start - 1] -# if c == '(': -# w.application.set_error('goldfinch 1') -# return -# elif c not in word_chars: -# w.application.set_error('walrus 2') -# return -# -# while start > 0 and line[start - 1] in word_chars: -# start -= 1 -# if start == end: -# w.application.set_error('walrus 3') -# return -# word = line[start:end] -# -# candidates = [] -# seen = sets.Set() -# for p in w.mode.ctagger.packages.iterkeys(): -# if p.startswith(word): -# if p in seen: -# continue -# candidates.append(p) -# seen.add(p) -# for e in w.mode.ctagger.entries.itervalues(): -# if e.symbol.startswith(word): -# if e.symbol in seen: -# continue -# candidates.append(e.symbol) -# seen.add(e.symbol) -# if len(candidates) == 0: -# w.application.set_error('No match: %r' % word) -# return -# elif len(candidates) == 1: -# newword = candidates[0] -# if word == newword: -# w.application.set_error('Already completed!') -# return -# else: -# w.application.set_error('Unique match!') -# else: -# newword = completer.find_common_string(candidates) -# w.application.set_error('Ambiguous match: %r' % (candidates)) -# 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''' def _execute(self, w, **vargs): diff --git a/mode_sh.py b/mode_sh.py index ecf9698..0b84169 100644 --- a/mode_sh.py +++ b/mode_sh.py @@ -64,36 +64,34 @@ class Sh(mode2.Fundamental): closetokens = ('delimiter', 'reserved',) closetags = {')': '(', ']': '[', '}': '{', 'done': 'do', 'fi': 'then', 'esac': 'case'} - def __init__(self, w): - mode2.Fundamental.__init__(self, w) - self.colors = { - 'builtin': color.build('cyan', 'default', 'bold'), - 'function': color.build('magenta', 'default', 'bold'), - 'reserved': color.build('magenta', 'default', 'bold'), - 'variable': color.build('yellow', 'default', 'bold'), + colors = { + 'builtin': ('cyan', 'default', 'bold'), + 'function': ('magenta', 'default', 'bold'), + 'reserved': ('magenta', 'default', 'bold'), + 'variable': ('yellow', 'default', 'bold'), - 'delimiter': color.build('default', 'default', 'bold'), - 'operator': color.build('magenta', 'default', 'bold'), + 'delimiter': ('default', 'default', 'bold'), + 'operator': ('magenta', 'default', 'bold'), - 'string.start': color.build('green', 'default'), - 'string.variable': color.build('yellow', 'default'), - 'string.null': color.build('green', 'default'), - 'string.end': color.build('green', 'default'), + 'string.start': ('green', 'default'), + 'string.variable': ('yellow', 'default'), + 'string.null': ('green', 'default'), + 'string.end': ('green', 'default'), - 'eval.start': color.build('cyan', 'default'), - 'eval.variable': color.build('yellow', 'default'), - 'eval.null': color.build('cyan', 'default'), - 'eval.end': color.build('cyan', 'default'), + 'eval.start': ('cyan', 'default'), + 'eval.variable': ('yellow', 'default'), + 'eval.null': ('cyan', 'default'), + 'eval.end': ('cyan', 'default'), - #'neval.start': color.build('cyan', 'default'), - #'neval.end': color.build('cyan', 'default'), - 'neval.start': color.build('yellow', 'default'), - 'neval.variable': color.build('yellow', 'default'), - 'neval.null': color.build('cyan', 'default'), - 'neval.end': color.build('yellow', 'default'), + #'neval.start': ('cyan', 'default'), + #'neval.end': ('cyan', 'default'), + 'neval.start': ('yellow', 'default'), + 'neval.variable': ('yellow', 'default'), + 'neval.null': ('cyan', 'default'), + 'neval.end': ('yellow', 'default'), - 'comment': color.build('red', 'default'), - 'continuation': color.build('red', 'default'), - } + 'comment': ('red', 'default'), + 'continuation': ('red', 'default'), + } def name(self): return "Sh" diff --git a/mode_sql.py b/mode_sql.py index 541a6d2..d4d53b6 100644 --- a/mode_sql.py +++ b/mode_sql.py @@ -1,4 +1,4 @@ -import color, mode2, tab2 +import mode2, tab2 from lex3 import Grammar, PatternRule, NocasePatternRule, RegionRule, NocaseRegionRule from mode_python import StringGrammar @@ -99,37 +99,38 @@ class Sql(mode2.Fundamental): opentags = {'(': ')', '[': ']', '{': '}'} closetokens = ('delimiter',) closetags = {')': '(', ']': '[', '}': '{'} + colors = { + 'comment': ('red', 'default'), + 'operator': ('yellow', 'default'), + 'attribute': ('magenta', 'default'), + 'keyword': ('cyan', 'default'), + 'pseudokeyword': ('cyan', 'default'), + 'type': ('green', 'default'), + 'builtin': ('yellow', 'default'), + 'quoted': ('yellow', 'default'), + 'string.start': ('green', 'default'), + 'string.null': ('green', 'default'), + 'string.escaped': ('magenta', 'default'), + 'string.octal': ('magenta', 'default'), + 'string.end': ('green', 'default'), + 'bareword': ('default', 'default'), + + 'function.start': ('cyan', 'default'), + 'function.null': ('default', 'default'), + 'function.name': ('magenta', 'default'), + 'function.language': ('magenta', 'default'), + 'function.end': ('default', 'default'), + + 'function.definition.start': ('magenta', 'default'), + 'function.definition.bareword': ('magenta', 'default'), + 'function.definition.null': ('magenta', 'default'), + 'function.definition.end': ('magenta', 'default'), + } + def __init__(self, w): mode2.Fundamental.__init__(self, w) self.add_bindings('close-paren', (')',)) self.add_bindings('close-brace', ('}',)) self.add_bindings('close-bracket', (']',)) - self.colors = { - 'comment': color.build('red', 'default'), - 'operator': color.build('yellow', 'default'), - 'attribute': color.build('magenta', 'default'), - 'keyword': color.build('cyan', 'default'), - 'pseudokeyword': color.build('cyan', 'default'), - 'type': color.build('green', 'default'), - 'builtin': color.build('yellow', 'default'), - 'quoted': color.build('yellow', '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.end': color.build('green', 'default'), - 'bareword': color.build('default', 'default'), - - 'function.start': color.build('cyan', 'default'), - 'function.null': color.build('default', 'default'), - 'function.name': color.build('magenta', 'default'), - 'function.language': color.build('magenta', 'default'), - 'function.end': color.build('default', 'default'), - - 'function.definition.start': color.build('magenta', 'default'), - 'function.definition.bareword': color.build('magenta', 'default'), - 'function.definition.null': color.build('magenta', 'default'), - 'function.definition.end': color.build('magenta', 'default'), - } def name(self): return "Sql" diff --git a/mode_text.py b/mode_text.py index 8b1e022..e08d427 100644 --- a/mode_text.py +++ b/mode_text.py @@ -10,14 +10,17 @@ class WordRule(PatternRule): return speller.check(word, caps=False, title=False) else: return True - def _match(self, lexer, parent, m): - s = m.group(0) - if self._spelled_ok(s): - token = Token('word', self, lexer.y, lexer.x, s, parent, {}) - else: - token = Token('misspelled', self, lexer.y, lexer.x, s, parent, {}) - lexer.add_token(token) - lexer.x += len(s) + def lex(self, lexer, parent, m): + if m: + s = m.group(0) + if self._spelled_ok(s): + token = Token('word', self, lexer.y, lexer.x, s, None, parent, {}) + else: + token = Token('misspelled', self, lexer.y, lexer.x, s, None, parent, {}) + token.color = lexer.get_color(token) + lexer.x += len(s) + yield token + raise StopIteration class ContinuedRule(RegionRule): def __init__(self): @@ -32,20 +35,20 @@ class TextGrammar(Grammar): ] class Text(mode2.Fundamental): - grammar = TextGrammar() + grammar = TextGrammar + colors = { + 'misspelled': ('red', 'default'), + 'cont.start': ('default', 'default'), + 'cont.end': ('default', 'default'), + 'word': ('default', 'default'), + 'punct': ('default', 'default'), + 'stuff': ('default', 'default'), + } def __init__(self, w): mode2.Fundamental.__init__(self, w) self.add_action_and_bindings(LearnWord(), ('C-c l',)) self.add_action_and_bindings(TextInsertSpace(), ('SPACE',)) self.add_action_and_bindings(method.WrapParagraph(), ('M-q',)) - self.colors = { - 'misspelled': color.build('red', 'default'), - 'cont.start': color.build('default', 'default'), - 'cont.end': color.build('default', 'default'), - 'word': color.build('default', 'default'), - 'punct': color.build('default', 'default'), - 'stuff': color.build('default', 'default'), - } def name(self): return "Text" diff --git a/mode_tt.py b/mode_tt.py index 84d5a32..7c9a9d7 100644 --- a/mode_tt.py +++ b/mode_tt.py @@ -1,51 +1,64 @@ import color, mode2 from lex3 import Grammar, PatternRule, RegionRule -from mode_xml import OpenTagGrammar +#from mode_xml import TagGrammar from mode_perl import StringGrammar class DirectiveGrammar(Grammar): rules = [ - PatternRule(r'keyword', r'BLOCK|CALL|CASE|CATCH|CLEAR|DEBUG|DEFAULT|FINAL|FILTER|FOREACH|ELSIF|ELSE|END|GET|IF|INCLUDE|INSERT|LAST|MACRO|META|NEXT|PERL|PROCESS|RAWPERL|RETURN|SET|STOP|SWITCH|TAGS|THROW|TRY|UNLESS|USE|WHILE|WRAPPER'), + PatternRule(r'comment', r'#(?:[^%]|%(?!\]))*'), + PatternRule(r'keyword', r'BLOCK|CALL|CASE|CATCH|CLEAR|DEBUG|DEFAULT|FINAL|FILTER|FOREACH|ELSIF|ELSE|END|GET|IF|INCLUDE|INSERT|IN|LAST|MACRO|META|NEXT|PERL|PROCESS|RAWPERL|RETURN|SET|STOP|SWITCH|TAGS|THROW|TRY|UNLESS|USE|WHILE|WRAPPER'), RegionRule(r'string', r'"', StringGrammar, r'"'), RegionRule(r'string', r"'", StringGrammar, r"'"), ] +class TagGrammar(Grammar): + rules = [ + RegionRule(r'directive', r'\[\%', DirectiveGrammar, r'%%\]'), + RegionRule(r'string', r'"', Grammar, r'"'), + RegionRule(r'string', r"'", Grammar, r"'"), + PatternRule(r'namespace', r'[a-zA-Z_]+:'), + PatternRule(r'attrname', r'[^ =>\n]+(?==)'), + PatternRule(r'name', r'[^\[\] =>\n]+'), + ] + class TemplateGrammar(Grammar): rules = [ RegionRule(r'comment', r''), RegionRule(r'directive', r'\[\%', DirectiveGrammar, r'%%\]'), - RegionRule(r'opentag', r'<', OpenTagGrammar, r'/?>'), - PatternRule(r'closetag', pattern=r'< */ *[ =>\n]+ *>'), + RegionRule(r'tag', r''), ] class Template(mode2.Fundamental): grammar = TemplateGrammar + colors = { + 'comment.start': ('red', 'default'), + 'comment.null': ('red', 'default'), + 'comment.end': ('red', 'default'), + + 'directive.start': ('magenta', 'default'), + 'directive.comment': ('red', 'default'), + 'directive.keyword': ('cyan', 'default'), + 'directive.string.start': ('green', 'default'), + 'directive.string.escaped': ('magenta', 'default'), + 'directive.string.octal': ('magenta', 'default'), + 'directive.string.null': ('green', 'default'), + 'directive.string.end': ('green', 'default'), + 'directive.null': ('magenta', 'default'), + 'directive.end': ('magenta', 'default'), + + 'tag.start': ('default', 'default'), + 'tag.namespace': ('magenta', 'default'), + 'tag.name': ('blue', 'default'), + 'tag.attrname': ('cyan', 'default'), + 'tag.string.start': ('green', 'default'), + 'tag.string.null': ('green', 'default'), + 'tag.string.end': ('green', 'default'), + 'tag.end': ('default', 'default'), + } def __init__(self, w): mode2.Fundamental.__init__(self, w) self.add_bindings('close-paren', (')',)) self.add_bindings('close-brace', ('}',)) self.add_bindings('close-bracket', (']',)) - self.colors = { - 'comment': color.build('red', 'default'), - - 'directive.start': color.build('magenta', 'default'), - 'directive.keyword': color.build('cyan', 'default'), - 'directive.string.start': color.build('green', 'default'), - 'directive.string.escaped': color.build('magenta', 'default'), - 'directive.string.octal': color.build('magenta', 'default'), - 'directive.string.null': color.build('green', 'default'), - 'directive.string.end': color.build('green', 'default'), - 'directive.null': color.build('magenta', 'default'), - 'directive.end': color.build('magenta', 'default'), - - 'opentag.start': color.build('default', 'default'), - 'opentag.namespace': color.build('magenta', 'default'), - 'opentag.name': color.build('blue', 'default'), - 'opentag.attrname': color.build('cyan', 'default'), - 'opentag.string.start': color.build('green', 'default'), - 'opentag.string.null': color.build('green', 'default'), - 'opentag.string.end': color.build('green', 'default'), - 'opentag.end': color.build('default', 'default'), - } def name(self): return "Template" diff --git a/mode_xml.py b/mode_xml.py index 156c464..18d5f1e 100644 --- a/mode_xml.py +++ b/mode_xml.py @@ -1,38 +1,36 @@ import color, mode2 from lex3 import Grammar, PatternRule, RegionRule -class OpenTagGrammar(Grammar): +class TagGrammar(Grammar): rules = [ RegionRule(r'string', r'"', Grammar, r'"'), RegionRule(r'string', r"'", Grammar, r"'"), PatternRule(r'namespace', r'[a-zA-Z_]+:'), PatternRule(r'attrname', r'[^ =>\n]+(?==)'), - PatternRule(r'name', r'[^ =>\n]+'), + PatternRule(r'name', r'[^\[\] =>\n]+'), ] class XMLGrammar(Grammar): rules = [ + # TODO: how does cdata work again? RegionRule(r'comment', r''), - RegionRule(r'opentag', r'<', OpenTagGrammar, r'/?>'), - PatternRule(r'closetag', r'< */ *[ =>\n]+ *>'), + RegionRule(r'tag', r'<', TagGrammar, r'/?>'), ] class XML(mode2.Fundamental): grammar = XMLGrammar - def __init__(self, w): - mode2.Fundamental.__init__(self, w) - self.colors = { - 'comment.start': color.build('red', 'default'), - 'comment.null': color.build('red', 'default'), - 'comment.end': color.build('red', 'default'), - 'opentag.start': color.build('default', 'default'), - 'opentag.namespace': color.build('magenta', 'default'), - 'opentag.name': color.build('blue', 'default'), - 'opentag.attrname': color.build('cyan', 'default'), - 'opentag.string.start': color.build('green', 'default'), - 'opentag.string.null': color.build('green', 'default'), - 'opentag.string.end': color.build('green', 'default'), - 'opentag.end': color.build('default', 'default'), - } + colors = { + 'comment.start': ('red', 'default'), + 'comment.null': ('red', 'default'), + 'comment.end': ('red', 'default'), + 'tag.start': ('default', 'default'), + 'tag.namespace': ('magenta', 'default'), + 'tag.name': ('blue', 'default'), + 'tag.attrname': ('cyan', 'default'), + 'tag.string.start': ('green', 'default'), + 'tag.string.null': ('green', 'default'), + 'tag.string.end': ('green', 'default'), + 'tag.end': ('default', 'default'), + } def name(self): return "XML" diff --git a/window2.py b/window2.py index c72cd46..e92d672 100644 --- a/window2.py +++ b/window2.py @@ -1,5 +1,5 @@ import os.path, string -import regex +import highlight2, regex from point2 import Point WORD_LETTERS = list(string.letters + string.digits) @@ -79,6 +79,11 @@ class Window(object): # mode stuff def set_mode(self, m): self.mode = m + modename = m.name() + if modename not in self.buffer.highlights and m.lexer is not None: + self.buffer.highlights[modename] = highlight2.Highlighter(m.lexer) + self.buffer.highlights[modename].highlight(self.buffer.lines) + #self.redraw() def get_highlighter(self): if self.mode.lexer is None: @@ -558,6 +563,9 @@ class Window(object): # highlighting tokens def get_token(self): return self.get_token_at_point(self.logical_cursor()) + def get_token2(self): + c = self.logical_cursor() + return self.get_token_at_point(Point(min(0, c.x - 1), c.y)) def get_token_at_point(self, p): for token in self.get_highlighter().tokens[p.y]: if token.end_x() <= p.x: