From f274cdd973adf0f1b95036b00cf1522e785495d2 Mon Sep 17 00:00:00 2001 From: Erik Osheim Date: Sat, 11 Jul 2009 22:07:06 -0400 Subject: [PATCH 1/9] fix latin-1 bug --HG-- branch : pmacs2 --- buffer/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/buffer/__init__.py b/buffer/__init__.py index 9743cbc..8cdd57f 100644 --- a/buffer/__init__.py +++ b/buffer/__init__.py @@ -685,14 +685,14 @@ class FileBuffer(Buffer): try: data = self.make_string() if self.windows[0].mode.savetabs: - data = data.replace(" ", "\t").encode(self.codec) - - data = self.write_filter(data) + data = data.replace(" ", "\t") + data = self.write_filter(data.encode(self.codec)) f2 = self._open_file_w(self.path, preserve=False) f2.write(self.bytemark + data) f2.close() - except Exception, e: + #except Exception, e: + except NameError, e: if exists: shutil.copyfile(temp_path, self.path) raise e else: From a098646d4299756c2c294eeb0924e392d39d2a88 Mon Sep 17 00:00:00 2001 From: Erik Osheim Date: Sat, 11 Jul 2009 22:44:12 -0400 Subject: [PATCH 2/9] expand mode-detection beyond #! to --HG-- branch : pmacs2 --- IDEAS | 5 +++++ mode/xml.py | 42 ++++++++++++++++++++++++++++-------------- window.py | 2 +- 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/IDEAS b/IDEAS index 5f38283..3131e0e 100644 --- a/IDEAS +++ b/IDEAS @@ -1,3 +1,8 @@ +2009/07/11: + +Redo mode detection so that it uses regexes not words. Then fix all the modes +that want #! detection. + 2009/05/05: Either give buffers direct access to the application object, or make the diff --git a/mode/xml.py b/mode/xml.py index b0e3738..7b69903 100644 --- a/mode/xml.py +++ b/mode/xml.py @@ -18,11 +18,15 @@ class CommentGrammar(Grammar): rules = [PatternRule(r'data', r'(?:[^-]|-(?!-)|--(?!>))+')] class MetadataGrammar(Grammar): rules = [PatternRule(r'data', r'(?:[^?]|\?(?!>))+')] +class DoctypeGrammar(Grammar): + rules = [PatternRule(r'data', r'[^>]+')] class TagGrammar(Grammar): rules = [ PatternRule(r'attrname', r'[a-zA-Z_][a-zA-Z0-9_]+(?==)'), PatternRule(r'namespace', r'[a-zA-Z_]+(?=:)'), + PatternRule(r'meta', r'\?xml'), + PatternRule(r'doctype', r'!DOCTYPE'), PatternRule(r'name', r'[a-zA-Z_][a-zA-Z0-9_]*'), PatternRule(r'delimiter', r'[:/=]'), RegionRule(r'string', r'"', StringGrammar1, r'"'), @@ -41,9 +45,11 @@ class XMLGrammar(Grammar): PatternMatchRule('x', r'(<)(/)([a-zA-Z_][a-zA-Z0-9_]*)(>)', 'xml.tag.start', 'xml.tag.delimiter', 'xml.tag.name', 'xml.tag.end'), - RegionRule(r'xml.tag', r'<(?![\?!])', TagGrammar, r'/?>'), + #RegionRule(r'xml.tag', r'<(?![\?!])', TagGrammar, r'/?>'), + RegionRule(r'xml.tag', r'<', TagGrammar, r'/?>'), RegionRule(r'comment', r''), - RegionRule(r'xml.metadata', r'<\?', MetadataGrammar, r'\?>'), + #RegionRule(r'xml.metadata', r'<\?', MetadataGrammar, r'\?>'), + #RegionRule(r'xml.doctype', ''), RegionRule(r'xml.cdata', r''), ] @@ -84,20 +90,28 @@ class XmlCreateCdata(method.Method): class XML(mode.Fundamental): name = 'XML' extensions = ['.xml', '.xml.in', '.xsl', '.xsd'] + detection = ['?xml'] grammar = XMLGrammar colors = { - 'xml.metadata.start': ('magenta', 'default', 'bold'), - 'xml.metadata.data': ('magenta', 'default', 'bold'), - 'xml.metadata.end': ('magenta', 'default', 'bold'), - 'xml.tag.start': ('default', 'default', 'bold'), - 'xml.tag.namespace': ('magenta', 'default', 'bold'), - 'xml.tag.name': ('blue', 'default', 'bold'), - 'xml.tag.attrname': ('cyan', 'default', 'bold'), - 'xml.tag.end': ('default', 'default', 'bold'), - 'xml.entity': ('magenta', 'default', 'bold'), - 'xml.cdata.start': ('magenta', 'default', 'bold'), - 'xml.cdata.data': ('green', 'default', 'bold'), - 'xml.cdata.end': ('magenta', 'default', 'bold'), + #'xml.metadata.start': ('magenta', 'default', 'bold'), + #'xml.metadata.data': ('magenta', 'default', 'bold'), + #'xml.metadata.end': ('magenta', 'default', 'bold'), + #'xml.doctype.start': ('magenta', 'default', 'bold'), + #'xml.doctype.data': ('magenta', 'default', 'bold'), + #'xml.doctype.end': ('magenta', 'default', 'bold'), + + 'xml.tag.meta': ('magenta', 'default', 'bold'), + 'xml.tag.doctype': ('magenta', 'default', 'bold'), + + 'xml.tag.start': ('default', 'default', 'bold'), + 'xml.tag.namespace': ('magenta', 'default', 'bold'), + 'xml.tag.name': ('blue', 'default', 'bold'), + 'xml.tag.attrname': ('cyan', 'default', 'bold'), + 'xml.tag.end': ('default', 'default', 'bold'), + 'xml.entity': ('magenta', 'default', 'bold'), + 'xml.cdata.start': ('magenta', 'default', 'bold'), + 'xml.cdata.data': ('green', 'default', 'bold'), + 'xml.cdata.end': ('magenta', 'default', 'bold'), } actions = [XmlValidate, XmlCreateTag, XmlCreateComment, XmlCreateCdata] _bindings = { diff --git a/window.py b/window.py index b48f381..8c6515b 100644 --- a/window.py +++ b/window.py @@ -64,7 +64,7 @@ class Window(object): mode_name = regex.auto_mode_emacs.search(firstline).group(1) elif regex.auto_mode_vi.search(firstline): mode_name = regex.auto_mode_vi.search(firstline).group(1) - elif firstline.startswith('#!'): + else: line = b.lines[0] for word in a.mode_detection: if word in line: From d4ebbaf5c97183220254a4cb3d9355dff6d4614c Mon Sep 17 00:00:00 2001 From: Erik Osheim Date: Sun, 12 Jul 2009 01:23:13 -0400 Subject: [PATCH 3/9] mode detection now uses regexes; modes updated --HG-- branch : pmacs2 --- mode/perl.py | 3 +- mode/python.py | 3 +- mode/sh.py | 5 ++- mode/xml.py | 95 +++++++++++++++++++++++--------------------------- window.py | 8 ++--- 5 files changed, 55 insertions(+), 59 deletions(-) diff --git a/mode/perl.py b/mode/perl.py index 2923bb0..a22f253 100644 --- a/mode/perl.py +++ b/mode/perl.py @@ -698,7 +698,8 @@ class PerlContext(context.Context): class Perl(Fundamental): name = 'Perl' extensions = ['.pl', '.pm', '.pod'] - detection = ['perl'] + #detection = ['perl'] + detection = [re.compile('^#!(?:.+/)?perl')] tabbercls = PerlTabber2 grammar = PerlGrammar commentc = '#' diff --git a/mode/python.py b/mode/python.py index f053119..47ee471 100644 --- a/mode/python.py +++ b/mode/python.py @@ -560,7 +560,8 @@ class Python(mode.Fundamental): ''' name = 'Python' extensions = ['.py'] - detection = ['python'] + #detection = ['python'] + detection = [re.compile('^#!(?:.+/)python')] tabbercls = PythonTabber grammar = PythonGrammar opentokens = ('delimiter',) diff --git a/mode/sh.py b/mode/sh.py index fcc0f4e..18e0a6f 100644 --- a/mode/sh.py +++ b/mode/sh.py @@ -1,3 +1,5 @@ +import re + import commands from tab import StackTabber from mode import Fundamental @@ -190,7 +192,8 @@ class Sh(Fundamental): paths = ['/etc/profile'] basenames = ['.bashrc', '.bash_profile', '.profile'] extensions = ['.bash', '.sh'] - detection = ['sh', 'bash'] + #detection = ['sh', 'bash'] + detection = [re.compile('^#!(?:.+/)sh'), re.compile('^#!(?:.+/)bash')] grammar = ShGrammar tabbercls = ShTabber opentokens = ('delimiter', 'sh_reserved', 'case.start') diff --git a/mode/xml.py b/mode/xml.py index 7b69903..d4b7a48 100644 --- a/mode/xml.py +++ b/mode/xml.py @@ -1,56 +1,55 @@ +import re + import color, method, mode from lex import Grammar, Rule, PatternRule, RegionRule, PatternMatchRule class StringGrammar1(Grammar): rules = [ - PatternRule(r'data', r'[^"&]+'), - PatternRule(r'escaped', r'&[a-z]+;'), + PatternRule('data', '[^"&]+'), + PatternRule('escaped', '&[a-z]+;'), ] class StringGrammar2(Grammar): rules = [ - PatternRule(r'data', r"[^'&]+"), - PatternRule(r'escaped', r'&[a-z]+;'), + PatternRule('data', r"[^'&]+"), + PatternRule('escaped', '&[a-z]+;'), ] class CDataGrammar(Grammar): - rules = [PatternRule(r'data', r'(?:[^\]]|\](?!\])|\]\](?!>))+')] + rules = [PatternRule('data', r'(?:[^\]]|\](?!\])|\]\](?!>))+')] class CommentGrammar(Grammar): - rules = [PatternRule(r'data', r'(?:[^-]|-(?!-)|--(?!>))+')] -class MetadataGrammar(Grammar): - rules = [PatternRule(r'data', r'(?:[^?]|\?(?!>))+')] -class DoctypeGrammar(Grammar): - rules = [PatternRule(r'data', r'[^>]+')] - + rules = [PatternRule('data', '(?:[^-]|-(?!-)|--(?!>))+')] class TagGrammar(Grammar): rules = [ - PatternRule(r'attrname', r'[a-zA-Z_][a-zA-Z0-9_]+(?==)'), - PatternRule(r'namespace', r'[a-zA-Z_]+(?=:)'), - PatternRule(r'meta', r'\?xml'), - PatternRule(r'doctype', r'!DOCTYPE'), - PatternRule(r'name', r'[a-zA-Z_][a-zA-Z0-9_]*'), - PatternRule(r'delimiter', r'[:/=]'), - RegionRule(r'string', r'"', StringGrammar1, r'"'), - RegionRule(r'string', r"'", StringGrammar2, r"'"), - PatternRule(r'spaces', r' +'), - PatternRule(r'eol', r'\n'), + PatternRule('attrname', '[a-zA-Z_][a-zA-Z0-9_]+(?==)'), + PatternRule('namespace', '[a-zA-Z_]+(?=:)'), + PatternRule('name', '[a-zA-Z_][a-zA-Z0-9_]*'), + PatternRule('delimiter', '[:/=]'), + RegionRule('string', '"', StringGrammar1, '"'), + RegionRule('string', "'", StringGrammar2, "'"), + PatternRule('spaces', ' +'), + PatternRule('eol', r'\n'), ] +class MetadataGrammar(Grammar): + rules = [PatternRule('meta', r'\?(?:xml)?')] + TagGrammar.rules +class DoctypeGrammar(Grammar): + rules = [PatternRule('doctype', '!DOCTYPE')] + TagGrammar.rules class XMLGrammar(Grammar): rules = [ # TODO: how does cdata work again? - PatternRule(r'data', r'[^<& \n]+'), - PatternRule(r'spaces', r' +'), - PatternRule(r'xml.entity', r'&[a-z]+;'), - PatternRule(r'eol', r'\n'), - PatternMatchRule('x', r'(<)(/)([a-zA-Z_][a-zA-Z0-9_]*)(>)', + PatternRule('data', r'[^<& \n]+'), + PatternRule('spaces', ' +'), + PatternRule('xml.entity', '&[a-z]+;'), + PatternRule('eol', r'\n'), + PatternMatchRule('x', '(<)(/)([a-zA-Z_][a-zA-Z0-9_]*)(>)', 'xml.tag.start', 'xml.tag.delimiter', 'xml.tag.name', 'xml.tag.end'), - #RegionRule(r'xml.tag', r'<(?![\?!])', TagGrammar, r'/?>'), - RegionRule(r'xml.tag', r'<', TagGrammar, r'/?>'), - RegionRule(r'comment', r''), - #RegionRule(r'xml.metadata', r'<\?', MetadataGrammar, r'\?>'), - #RegionRule(r'xml.doctype', ''), - RegionRule(r'xml.cdata', r''), + RegionRule('xml.tag', r'<(?![\?!])', TagGrammar, '/?>'), + RegionRule('xml.tag', r'<(?![\?!])', TagGrammar, '/?>'), + RegionRule('comment', ''), + RegionRule('xml.tag', r'<(?=\?)', MetadataGrammar, r'\?>'), + RegionRule('xml.tag', '<(?!!)', DoctypeGrammar, '>'), + RegionRule('xml.cdata', r''), ] class XmlValidate(method.shell.Exec): @@ -90,28 +89,20 @@ class XmlCreateCdata(method.Method): class XML(mode.Fundamental): name = 'XML' extensions = ['.xml', '.xml.in', '.xsl', '.xsd'] - detection = ['?xml'] + detection = [re.compile(r'^<\?xml')] grammar = XMLGrammar colors = { - #'xml.metadata.start': ('magenta', 'default', 'bold'), - #'xml.metadata.data': ('magenta', 'default', 'bold'), - #'xml.metadata.end': ('magenta', 'default', 'bold'), - #'xml.doctype.start': ('magenta', 'default', 'bold'), - #'xml.doctype.data': ('magenta', 'default', 'bold'), - #'xml.doctype.end': ('magenta', 'default', 'bold'), - - 'xml.tag.meta': ('magenta', 'default', 'bold'), - 'xml.tag.doctype': ('magenta', 'default', 'bold'), - - 'xml.tag.start': ('default', 'default', 'bold'), - 'xml.tag.namespace': ('magenta', 'default', 'bold'), - 'xml.tag.name': ('blue', 'default', 'bold'), - 'xml.tag.attrname': ('cyan', 'default', 'bold'), - 'xml.tag.end': ('default', 'default', 'bold'), - 'xml.entity': ('magenta', 'default', 'bold'), - 'xml.cdata.start': ('magenta', 'default', 'bold'), - 'xml.cdata.data': ('green', 'default', 'bold'), - 'xml.cdata.end': ('magenta', 'default', 'bold'), + 'xml.tag.meta': ('magenta', 'default', 'bold'), + 'xml.tag.doctype': ('magenta', 'default', 'bold'), + 'xml.tag.start': ('default', 'default', 'bold'), + 'xml.tag.namespace': ('magenta', 'default', 'bold'), + 'xml.tag.name': ('blue', 'default', 'bold'), + 'xml.tag.attrname': ('cyan', 'default', 'bold'), + 'xml.tag.end': ('default', 'default', 'bold'), + 'xml.entity': ('magenta', 'default', 'bold'), + 'xml.cdata.start': ('magenta', 'default', 'bold'), + 'xml.cdata.data': ('green', 'default', 'bold'), + 'xml.cdata.end': ('magenta', 'default', 'bold'), } actions = [XmlValidate, XmlCreateTag, XmlCreateComment, XmlCreateCdata] _bindings = { diff --git a/window.py b/window.py index 8c6515b..afed9f5 100644 --- a/window.py +++ b/window.py @@ -65,10 +65,10 @@ class Window(object): elif regex.auto_mode_vi.search(firstline): mode_name = regex.auto_mode_vi.search(firstline).group(1) else: - line = b.lines[0] - for word in a.mode_detection: - if word in line: - mode_name = a.mode_detection[word] + for (r, name) in a.mode_detection.items(): + if r.match(b.lines[0]): + mode_name = name + break cls = a.modes.get(mode_name, a.modes['fundamental']) self.set_mode(cls(self)) From 3512296eb8763ec4e151e64e1cb8a90c48021cfe Mon Sep 17 00:00:00 2001 From: Erik Osheim Date: Sun, 12 Jul 2009 14:55:01 -0400 Subject: [PATCH 4/9] added parent-window to minibuffer --HG-- branch : pmacs2 --- application.py | 4 +++- minibuffer.py | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/application.py b/application.py index d1b5cb1..4f81c56 100755 --- a/application.py +++ b/application.py @@ -405,10 +405,12 @@ class Application(object): return self.mini_buffer is not None def open_mini_buffer(self, prompt, cb, method=None, tabber=None, modename=None, startvalue=None, queue='default'): + parentw = self.bufferlist.slots[self.active_slot].window if self.mini_buffer_is_open(): self.close_mini_buffer() self.mini_prompt = prompt - self.mini_buffer = MiniBuffer(cb, self, method, tabber, modename, queue) + self.mini_buffer = MiniBuffer(cb, self, method, tabber, modename, queue, + parentw) try: w = self.x - 1 - len(self.mini_prompt) - 1 window.Window(self.mini_buffer, self, height=1, width=w) diff --git a/minibuffer.py b/minibuffer.py index ebee996..da73812 100644 --- a/minibuffer.py +++ b/minibuffer.py @@ -14,7 +14,7 @@ class MiniBuffer(buffer.Buffer): return mini # the callback function should take one argument (window) def __init__(self, func, app, method=None, tabber=None, modename=None, - queue=None): + queue=None, parentw=None): buffer.Buffer.__init__(self) self.app = app self.callback = func @@ -22,6 +22,7 @@ class MiniBuffer(buffer.Buffer): self.tabber = tabber self.modename = modename self.queue = queue + self.parentw = parentw def name(self): return "*Minibuffer*" From e8bb97f4ea7812f22ca09a71aa86981d2ebc4273 Mon Sep 17 00:00:00 2001 From: Erik Osheim Date: Sun, 12 Jul 2009 14:55:22 -0400 Subject: [PATCH 5/9] updatd console-clear to use parentw --HG-- branch : pmacs2 --- mode/consolemini.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/mode/consolemini.py b/mode/consolemini.py index 1e65217..0733ef5 100644 --- a/mode/consolemini.py +++ b/mode/consolemini.py @@ -93,11 +93,12 @@ class ConsoleCancel(Method): w.application.close_completion_buffer() class ConsoleClear(Method): def execute(self, w, **vargs): - a = w.application - if not a.has_buffer_name('*Console*'): - raise Exception, "No console found!" - b = a.bufferlist.get_buffer_by_name('*Console*') - b.clear() + #a = w.application + #if not a.has_buffer_name('*Console*'): + # raise Exception, "No console found!" + #b = a.bufferlist.get_buffer_by_name('*Console*') + #b.clear() + w.buffer.parentw.buffer.clear() class ConsoleHistoryPrev(Method): def execute(self, w, **vargs): From f9ba992a1bbab103e14b04a44b0b6fd536fec060 Mon Sep 17 00:00:00 2001 From: Erik Osheim Date: Sun, 12 Jul 2009 14:55:37 -0400 Subject: [PATCH 6/9] fixed term emulation error --HG-- branch : pmacs2 --- buffer/emul.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/buffer/emul.py b/buffer/emul.py index 5e714de..06bb699 100644 --- a/buffer/emul.py +++ b/buffer/emul.py @@ -159,7 +159,9 @@ class XTermBuffer(Buffer, XTerm): self._towrite = self._towrite[n:] self._lock.release() if efd: - raise Exception, "exception is ready: %s" % repr(efd) + self.term_receive(repr(efd)) + #raise Exception, "exception is ready: %s" % repr(efd) + pass except OSError: pass except TypeError: From e3e88477f51826456f82c9f579efa1da38c7fe65 Mon Sep 17 00:00:00 2001 From: Erik Osheim Date: Sun, 12 Jul 2009 14:55:53 -0400 Subject: [PATCH 7/9] small ipython bug --HG-- branch : pmacs2 --- mode/python.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mode/python.py b/mode/python.py index 47ee471..6d2f932 100644 --- a/mode/python.py +++ b/mode/python.py @@ -335,7 +335,8 @@ class PythonSemanticComplete(method.introspect.TokenComplete): a = w.application a.methods['ipython-path-start'].execute(w, switch=False) - name = buffer.IperlBuffer.create_name(w.buffer) + #name = buffer.IperlBuffer.create_name(w.buffer) + name = buffer.IpythonBuffer.create_name(w.buffer) b = a.get_buffer_by_name(name) line = w.buffer.lines[t.y] From c034605a698f16bf910286444297861b9371d609 Mon Sep 17 00:00:00 2001 From: Erik Osheim Date: Sun, 12 Jul 2009 18:30:31 -0400 Subject: [PATCH 8/9] bug parsing python decorators --HG-- branch : pmacs2 --- mode/python.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mode/python.py b/mode/python.py index 6d2f932..b11a4f6 100644 --- a/mode/python.py +++ b/mode/python.py @@ -61,7 +61,7 @@ class PythonGrammar(Grammar): RegionRule('string', 'u?"', StringGrammar2, '"'), RegionRule('string', "u?'", StringGrammar1, "'"), - PatternRule('delimiter', r'\(|\)|\[|\]|{|}|@|,|:|\.|`|=|;|\+=|-=|\*=|/=|//=|%=|&=|\|=|\^=|>>=|<<=|\*\*='), + PatternRule('delimiter', r'\(|\)|\[|\]|{|}|,|:|\.|`|=|;|\+=|-=|\*=|/=|//=|%=|&=|\|=|\^=|>>=|<<=|\*\*='), PatternRule(r"python.integer", r"(?[.a-zA-Z0-9_]+):(?P[.a-zA-Z0-9_]+) *$'), PatternRule('comment', '#.*$'), PatternRule('continuation', r'\\\n$'), - PatternRule('decorator', '@[a-zA-Z_][a-zA-Z0-9_]*'), + PatternRule('python.decorator', '@[a-zA-Z_][a-zA-Z0-9_]*'), PatternRule('spaces', ' +'), PatternRule('eol', r'\n$'), ] From b321269b2e3479e083502d2f3ebe106bc4a0badc Mon Sep 17 00:00:00 2001 From: Erik Osheim Date: Mon, 13 Jul 2009 15:35:55 -0400 Subject: [PATCH 9/9] fix mutt header bug --HG-- branch : pmacs2 --- mode/mutt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mode/mutt.py b/mode/mutt.py index 45a1f97..49e17fa 100644 --- a/mode/mutt.py +++ b/mode/mutt.py @@ -17,7 +17,7 @@ rules = [ ] class HeaderGrammar(Grammar): - rules = [PatternRule('header', '^[^ ].*:')] + rules + rules = [PatternRule('header', '^[^ ][^:]*:')] + rules class BodyGrammar(Grammar): rules = rules class MuttGrammar(Grammar): rules = [RegionRule('mutt', '^', HeaderGrammar, '^\n$', BodyGrammar, '')]