diff --git a/application.py b/application.py index d749e13..2ba1ff3 100755 --- a/application.py +++ b/application.py @@ -113,7 +113,7 @@ class Application(object): 'dir', 'elisp', 'hex', 'html', 'java', 'javascript', 'lisp', 'make', 'mini', 'mutt', 'nasm', 'ocaml', 'perl', 'python', 'replace', 'rst', 'scheme', 'search', 'sh', 'sql', 'tt', - 'text', 'text2', 'which', 'xml', 'cheetah') + 'text', 'text2', 'which', 'xml', 'cheetah', 'colortext') for name in names: exec("import mode.%s; mode.%s.install(self)" % (name, name)) diff --git a/buffer.py b/buffer.py index 28e930f..3c8cea7 100644 --- a/buffer.py +++ b/buffer.py @@ -1,5 +1,5 @@ import datetime, grp, md5, os, pwd, re, sets, shutil, stat, string -import aes, dirutil, regex, highlight +import aes, dirutil, regex, highlight, lex from point import Point # undo/redo stack constants @@ -8,6 +8,19 @@ ACT_UNDO = 1 ACT_REDO = 2 STACK_LIMIT = 1024 +# used for multiple text additions/deletions +class GroupMove(object): + def __init__(self, buffer, p, moves): + self.buffer = buffer + self.lines = lines + self.moves = moves + def restore(self, act=ACT_UNDO): + assert act == ACT_UNDO or act == ACT_REDO + for move in self.moves: + move.restore(act) + def getpos(self): + return self.moves[-1].getpos() + # used for undo/redo stacks when text will need to be added back class AddMove(object): def __init__(self, buffer, p, lines): @@ -110,8 +123,7 @@ class Buffer(object): if modename not in self.highlights and w.mode.lexer is not None: self.highlights[modename] = highlight.Highlighter(w.mode.lexer) self.highlights[modename].highlight(self.lines) - #if modename not in self.tabbing and w.mode.tabber is not None: - # self.tabbing[modename] = + def remove_window(self, w): if w in self.windows: self.windows.remove(w) @@ -339,7 +351,7 @@ class DataBuffer(Buffer): # console is another singleton console = None class ConsoleBuffer(Buffer): - btype = 'console' + btype = 'console' modename = 'console' def __new__(cls, *args, **kwargs): global console @@ -615,27 +627,89 @@ class PathListBuffer(DirBuffer): def name(self): return self._name -ABOUT_DATA = ''' -================================================================================ - -************ ********** ****** ****** **** ******** ********* -************** ****************** ************* ********** *********** -******* ***** ****** ***** **** **** ****** **** **** ***** **** - *** *** *** *** *** **** **** **** ******* - *** *** *** *** *** **** **** **** ******* - ***** ***** ***** ***** **** **** ****** **** **** **** ***** - ************ ***** ***** **** ************* ********** *********** - ********** ***** ***** **** ****** **** ******** ********* - *** - *** pmacs is a python-based text editor by Erik Osheim, (c) 2005-2008 -***** pmacs is available to you under the GNU General Public License v2 -***** -***** to see all available commands use: C-c M-h (show-bindings-buffer) - -================================================================================ -''' -class AboutBuffer(DataBuffer): - btype = 'about' - modename = 'about' +# NOTE: this highlighter will not reprocess the data given. it is intended to +# be used with read-only buffers like DataBuffer and ColorBuffer +class ColorHighlighter(highlight.Highlighter): + color_re = re.compile(r'\[([a-zA-Z0-9\*:]+)\]') + color_map = { + 'B': 'black', + 'r': 'red', + 'g': 'green', + 'y': 'yellow', + 'b': 'blue', + 'm': 'magenta', + 'c': 'cyan', + 'w': 'white', + 'd': 'default', + '*': 'bold', + } def __init__(self): - DataBuffer.__init__(self, '*About*', ABOUT_DATA) + self.tokens = [] + def append_token(self, y, x, s, color): + s = s.replace('\\[', '[') + s = s.replace('\\]', ']') + s = s.replace('\\\\', '\\') + t = lex.Token('color_data', None, y, x, s, color) + self.tokens[y].append(t) + def highlight(self, lines): + if self.tokens: + return + self.tokens = [None] * len(lines) + for y in range(0, len(lines)): + self.tokens[y] = [] + line = lines[y] + c = ['default', 'default'] + i = 0 + offset = 0 + while i < len(line): + m = self.color_re.search(line, i) + if m: + (j, k) = (m.start(), m.end()) + if j > i: + self.append_token(y, i - offset, line[i:j], c) + fields = m.group(1).split(':') + c = [self.color_map.get(x, x) for x in fields] + offset += k - j + i = k + else: + self.append_token(y, i - offset, line[i:], c) + break + +class ColorDataBuffer(DataBuffer): + btype = 'colordata' + modename = 'colortext' + color_re = re.compile(r'\[([a-z:]+)\]') + def __init__(self, name, data, nl='\n'): + data2 = ColorHighlighter.color_re.sub('', data) + data2 = data2.replace('\\[', '[') + data2 = data2.replace('\\]', ']') + data2 = data2.replace('\\\\', '\\') + DataBuffer.__init__(self, name, data2, nl) + lines = data.split(self.nl) + self.highlights = { + 'Colortext': ColorHighlighter(), + } + self.highlights['Colortext'].highlight(lines) + +ABOUT_DATA = ''' +[r:d:*]================================================================================ + +[y:d:*]************ ********** ****** ****** **** ******** ********* +[y:d:*]************** ****************** ************* ********** *********** +[y:d:*]******* ***** ****** ***** **** **** ****** **** **** ***** **** +[y:d:*] *** *** *** *** *** **** **** **** ******* +[y:d:*] *** *** *** *** *** **** **** **** ******* +[y:d:*] ***** ***** ***** ***** **** **** ****** **** **** **** ***** +[y:d:*] ************ ***** ***** **** ************* ********** *********** +[y:d:*] ********** ***** ***** **** ****** **** ******** ********* +[y:d:*] *** +[y:d:*] *** [c:d:*]pmacs[d:d:*] is a python-based text editor by [c:d:*]Erik Osheim[d:d:*], [b:d:*](c) 2005-2008 +[y:d:*]***** [c:d:*]pmacs[d:d:*] is available to you under the [c:d:*]GNU General Public License v2 +[y:d:*]***** +[y:d:*]***** [d:d:*]to see all available commands use: [c:d:*]C-c M-h [b:d:*](show-bindings-buffer) + +[r:d:*]================================================================================ +''' +class AboutBuffer(ColorDataBuffer): + def __init__(self): + ColorDataBuffer.__init__(self, '*About*', ABOUT_DATA) diff --git a/highlight.py b/highlight.py index a76a5ea..82f5937 100644 --- a/highlight.py +++ b/highlight.py @@ -33,8 +33,8 @@ def token_vmatch2(self, token, *pairs): class Highlighter(object): def __init__(self, lexer): - self.lexer = lexer - self.tokens = [] + self.lexer = lexer + self.tokens = [] def dump(self, fmt='(%3s, %2s) | %s'): print fmt % ('y', 'x', 'string') diff --git a/mode/__init__.py b/mode/__init__.py index b6a3989..9fc880f 100644 --- a/mode/__init__.py +++ b/mode/__init__.py @@ -197,9 +197,11 @@ class Fundamental(Handler): # lexing for highlighting, etc. if self.grammar: - self.lexer = Lexer(self, self.grammar) - self.gstack = {} - self.ghist = {} + self.lexer = Lexer(self, self.grammar) + else: + self.lexer = None + self.gstack = {} + self.ghist = {} # tab handling if self.tabbercls: diff --git a/mode/colortext.py b/mode/colortext.py new file mode 100644 index 0000000..72f6854 --- /dev/null +++ b/mode/colortext.py @@ -0,0 +1,6 @@ +import mode + +class Colortext(mode.Fundamental): + modename = 'Colortext' + +install = Colortext.install