From 0d300a637de6f6505df21a83f60998c205c8b3b8 Mon Sep 17 00:00:00 2001 From: moculus Date: Wed, 3 Dec 2008 05:15:22 +0000 Subject: [PATCH] error buffer handling --HG-- branch : pmacs2 --- application.py | 7 ++++--- mode/error.py | 47 +++++++++++++++++++++++++++++++++++++++++++++++ mode/perl.py | 3 ++- mode/python.py | 3 ++- 4 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 mode/error.py diff --git a/application.py b/application.py index 03dcae5..c9acbd2 100755 --- a/application.py +++ b/application.py @@ -111,7 +111,7 @@ class Application(object): 'latex', 'insertmini', 'conf', 'haskell', 'erlang', 'iperl', 'iperlmini', 'ipython', 'ipythonmini', 'awk', 'shell', 'shellmini', 'fstab', 'yacc', 'pipe', - 'mbox', + 'mbox', 'error', ) for name in names: exec("import mode.%s; mode.%s.install(self)" % (name, name)) @@ -443,6 +443,7 @@ class Application(object): self.add_buffer(b) if switch_to: self.switch_buffer(b) + return b def data_buffer(self, name, data, switch_to=True, modename=None): if self.has_buffer_name(name): b = self.bufferlist.buffer_names[name] @@ -627,7 +628,7 @@ class Application(object): i += 1 # running external programs - def run_pipe(self, args, b, name='*Output*', switch='yes'): + def run_pipe(self, args, b, name='*Output*', switch='yes', modename=None): pipe = Popen(args=args, stdin=PIPE, stdout=PIPE, stderr=STDOUT) pipe.stdin.write(b.make_string()) pipe.stdin.close() @@ -637,7 +638,7 @@ class Application(object): switch_to = switch(status) else: switch_to = bool(switch) - self.data_buffer(name, output, switch_to=switch_to) + self.data_buffer(name, output, switch_to=switch_to, modename=None) return status def run_external(self, *args): curses.reset_shell_mode() diff --git a/mode/error.py b/mode/error.py new file mode 100644 index 0000000..a9255bf --- /dev/null +++ b/mode/error.py @@ -0,0 +1,47 @@ +import re +from method import Method +import mode + +_error_regexes = [ + r'at (?P\S+) line (?P\d+)$', #perl + r'File "(?P.+?)", line (?P\d+)(?:, in \S+)?$', #python + r'^(?P\S+?):(?P\d+): ', #javac/gcc + r'at \S+\((?P.+?):(?P\d+)\)$', #java +] +error_regexes = [re.compile(s) for s in _error_regexes] + +def find_next_error(w): + b = w.buffer + x, y = w.logical_cursor().xy() + while y < len(b.lines): + for regex in error_regexes: + m = regex.search(b.lines[y], x) + if m: + return (m, y) + x = 0 + y += 1 + return (None, None) + +class ErrorGotoLine(Method): + '''Goto the line of the file indicated''' + def _execute(self, w, **vargs): + a = w.application + (m, y) = find_next_error(w) + if m is None: + w.set_error("nothing found") + return + errline = w.buffer.lines[y] + path, line = m.group('file'), int(m.group('line')) + b2 = a.open_path(path) + a.switch_buffer(b2) + a.methods['goto-line'].execute(b2.windows[0], lineno=line) + w.set_error(errline) + +class Error(mode.Fundamental): + modename = 'Error' + actions = [ErrorGotoLine] + def __init__(self, w): + mode.Fundamental.__init__(self, w) + self.add_bindings('error-goto-line', ('C-c M-g',)) + +install = Error.install diff --git a/mode/perl.py b/mode/perl.py index c8104f4..969d4d7 100644 --- a/mode/perl.py +++ b/mode/perl.py @@ -212,7 +212,8 @@ class PerlCheckSyntax(Method): args.extend(('-c', '-')) else: args = ('perl', '-I', a.config.get('perl.lib', '.'), '-c', '-') - retval = a.run_pipe(args, w.buffer, '*Perl-Syntax*', lambda x: x != 0) + retval = a.run_pipe(args, w.buffer, '*Perl-Syntax*', lambda x: x != 0, + modename='error') if retval == 0: a.set_error("Syntax OK") class PerlViewModulePerldoc(Method): diff --git a/mode/python.py b/mode/python.py index bf86b3e..a1bb916 100644 --- a/mode/python.py +++ b/mode/python.py @@ -216,7 +216,8 @@ class PythonCheckSyntax(method.Method): w.set_error("Syntax OK") except Exception, e: output = traceback.format_exc() - w.application.data_buffer("*PythonSyntax*", output, switch_to=True) + w.application.data_buffer("*PythonSyntax*", output, switch_to=True, + modename='error') del sys.path[0] class PythonDictCleanup(method.Method):