From ae691b7cd858bebd4609ad78c5ceaecb2275516f Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 13 Apr 2013 14:47:39 +0400 Subject: [PATCH] Improve shown errors --- powerline/lint/__init__.py | 12 +++-- powerline/lint/markedjson/error.py | 3 ++ powerline/lint/markedjson/markedvalue.py | 58 +++++++++++++++++++++++- 3 files changed, 66 insertions(+), 7 deletions(-) diff --git a/powerline/lint/__init__.py b/powerline/lint/__init__.py index d8609ba1..726f255d 100644 --- a/powerline/lint/__init__.py +++ b/powerline/lint/__init__.py @@ -894,10 +894,12 @@ def check_args(get_segment_variants, args, data, context, echoerr): if not count: hadproblem = True - new_echoerr.echo_all() - echoerr(context='Error while checking segment arguments (key {key})'.format(key=context_key(context)), - context_mark=context[-2][1].mark, - problem='no suitable segments found') + if new_echoerr: + new_echoerr.echo_all() + else: + echoerr(context='Error while checking segment arguments (key {key})'.format(key=context_key(context)), + context_mark=context[-2][1].mark, + problem='no suitable segments found') return True, False, hadproblem @@ -912,7 +914,7 @@ def get_one_segment_variant(data, context, echoerr): def get_all_possible_segments(data, context, echoerr): name = context[-2][0] - module, name = (gen_marked_value(value, name.mark) for value in name.rpartition('.')[::2]) + module, name = name.rpartition('.')[::2] if module: func = import_segment(name, data, context, echoerr, module=module) if func: diff --git a/powerline/lint/markedjson/error.py b/powerline/lint/markedjson/error.py index 66fcacef..d1466675 100644 --- a/powerline/lint/markedjson/error.py +++ b/powerline/lint/markedjson/error.py @@ -29,6 +29,9 @@ class Mark: self.buffer = buffer self.pointer = pointer + def copy(self): + return Mark(self.name, self.line, self.column, self.buffer, self.pointer) + def get_snippet(self, indent=4, max_length=75): if self.buffer is None: return None diff --git a/powerline/lint/markedjson/markedvalue.py b/powerline/lint/markedjson/markedvalue.py index db45fd13..6a304b9f 100644 --- a/powerline/lint/markedjson/markedvalue.py +++ b/powerline/lint/markedjson/markedvalue.py @@ -1,17 +1,71 @@ __all__ = ['gen_marked_value', 'MarkedValue'] +try: + from __builtin__ import unicode +except ImportError: + unicode = str + + +def gen_new(cls): + def __new__(arg_cls, value, mark): + r = super(arg_cls, arg_cls).__new__(arg_cls, value) + r.mark = mark + r.value = value + return r + return __new__ + + +class MarkedUnicode(unicode): + __new__ = gen_new(unicode) + + def _proc_partition(self, part_result): + pointdiff = 1 + r = [] + for s in part_result: + mark = self.mark.copy() + # XXX Does not work properly with escaped strings, but this requires + # saving much more information in mark. + mark.column += pointdiff + mark.pointer += pointdiff + r.append(MarkedUnicode(s, mark)) + pointdiff += len(s) + return tuple(r) + + def rpartition(self, sep): + return self._proc_partition(super(MarkedUnicode, self).rpartition(sep)) + + def partition(self, sep): + return self._proc_partition(super(MarkedUnicode, self).partition(sep)) + + +class MarkedInt(int): + __new__ = gen_new(int) + + +class MarkedFloat(float): + __new__ = gen_new(float) + + class MarkedValue: def __init__(self, value, mark): self.mark = mark self.value = value +specialclasses = { + unicode: MarkedUnicode, + int: MarkedInt, + float: MarkedFloat, +} + classcache = {} -def gen_marked_value(value, mark): - if value.__class__ in classcache: +def gen_marked_value(value, mark, use_special_classes=True): + if use_special_classes and value.__class__ in specialclasses: + Marked = specialclasses[value.__class__] + elif value.__class__ in classcache: Marked = classcache[value.__class__] else: class Marked(MarkedValue):