diff --git a/hy/models.py b/hy/models.py index 4866734..a9fe201 100644 --- a/hy/models.py +++ b/hy/models.py @@ -3,9 +3,28 @@ # license. See the LICENSE. from __future__ import unicode_literals +from contextlib import contextmanager from math import isnan, isinf from hy._compat import PY3, str_type, bytes_type, long_type, string_types from fractions import Fraction +from clint.textui import colored + + +PRETTY = True + + +@contextmanager +def pretty(pretty=True): + """ + Context manager to temporarily enable + or disable pretty-printing of Hy model reprs. + """ + global PRETTY + old, PRETTY = PRETTY, pretty + try: + yield + finally: + PRETTY = old class HyObject(object): @@ -114,7 +133,7 @@ class HyKeyword(HyObject, str_type): return obj def __repr__(self): - return "HyKeyword(%s)" % (repr(self[1:])) + return "%s(%s)" % (self.__class__.__name__, repr(self[1:])) def strip_digit_separators(number): @@ -222,13 +241,22 @@ class HyList(HyObject, list): return ret + color = staticmethod(colored.cyan) + def __repr__(self): - if self: - return "%s([\n %s])" % ( - self.__class__.__name__, - ",\n ".join([repr_indent(e) for e in self])) - else: - return self.__class__.__name__ + "()" + return str(self) if PRETTY else super(HyList, self).__repr__() + + def __str__(self): + with pretty(): + c = self.color + if self: + return ("{}{}\n {}{}").format( + c(self.__class__.__name__), + c("(["), + (c(",") + "\n ").join([repr_indent(e) for e in self]), + c("])")) + else: + return '' + c(self.__class__.__name__ + "()") _wrappers[list] = lambda l: HyList(wrap_value(x) for x in l) _wrappers[tuple] = lambda t: HyList(wrap_value(x) for x in t) @@ -239,17 +267,24 @@ class HyDict(HyList): HyDict (just a representation of a dict) """ - def __repr__(self): - if self: - pairs = [] - for k, v in zip(self[::2],self[1::2]): - k, v = repr_indent(k), repr_indent(v) - pairs.append("%s, %s," % (k, v)) - if len(self) % 2 == 1: - pairs.append("%s # odd\n" % repr_indent(self[-1])) - return "HyDict([\n %s])" % ("\n ".join(pairs),) - else: - return "HyDict()" + def __str__(self): + with pretty(): + g = colored.green + if self: + pairs = [] + for k, v in zip(self[::2],self[1::2]): + k, v = repr_indent(k), repr_indent(v) + pairs.append( + ("{0}{c}\n {1}\n {c}" + if '\n' in k+v + else "{0}{c} {1}{c}").format(k, v, c=g(','))) + if len(self) % 2 == 1: + pairs.append("{} {}\n".format( + repr_indent(self[-1]), g("# odd"))) + return "{}\n {}{}".format( + g("HyDict(["), ("\n ".join(pairs)), g("])")) + else: + return '' + g("HyDict()") def keys(self): return self[0::2] @@ -267,6 +302,7 @@ class HyExpression(HyList): """ Hy S-Expression. Basically just a list. """ + color = staticmethod(colored.yellow) _wrappers[HyExpression] = lambda e: HyExpression(wrap_value(x) for x in e) _wrappers[Fraction] = lambda e: HyExpression( @@ -277,6 +313,7 @@ class HySet(HyList): """ Hy set (just a representation of a set) """ + color = staticmethod(colored.red) _wrappers[set] = lambda s: HySet(wrap_value(x) for x in s) @@ -352,14 +389,24 @@ class HyCons(HyObject): HyObject.replace(self, other) def __repr__(self): - lines = ["" % (repr_indent(self.cdr),)) - return '\n'.join(lines) + if PRETTY: + return str(self) + else: + return "HyCons({}, {})".format( + repr(self.car), repr(self.cdr)) + + def __str__(self): + with pretty(): + c = colored.yellow + lines = ['' + c(""))) + return '\n'.join(lines) def __eq__(self, other): return (