Skip to content

Commit

Permalink
Make colored output configurable
Browse files Browse the repository at this point in the history
Colored exception output is now disabled by default and configurable through
`hy.errors._hy_colored_errors` and the environment variable
`HY_COLORED_ERRORS`.

Likewise, Hy model/AST color printing is now configurable and disabled by
default.  The corresponding variables are `hy.models._hy_colored_ast_objects`
and `HY_COLORED_AST_OBJECTS`.

Closes hylang#1429, closes hylang#1510.
  • Loading branch information
brandonwillard authored and Kodiologist committed Jan 20, 2019
1 parent 4bee362 commit ed9b1c0
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 23 deletions.
49 changes: 30 additions & 19 deletions hy/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

_hy_filter_internal_errors = _initialize_env_var('HY_FILTER_INTERNAL_ERRORS',
True)
_hy_colored_errors = _initialize_env_var('HY_COLORED_ERRORS', False)


class HyError(Exception):
Expand Down Expand Up @@ -73,9 +74,16 @@ def __init__(self, message, filename=None, expression=None, source=None):
source)

def __str__(self):
global _hy_colored_errors

result = ""

if _hy_colored_errors:
from clint.textui import colored
red, green, yellow = colored.red, colored.green, colored.yellow
else:
red = green = yellow = lambda x: x

if all(getattr(self.expression, x, None) is not None
for x in ("start_line", "start_column", "end_column")):

Expand All @@ -97,28 +105,28 @@ def __str__(self):
start)

if len(source) == 1:
result += ' %s\n' % colored.red(source[0])
result += ' %s\n' % red(source[0])
result += ' %s%s\n' % (' '*(start-1),
colored.green('^' + '-'*(length-1) + '^'))
green('^' + '-'*(length-1) + '^'))
if len(source) > 1:
result += ' %s\n' % colored.red(source[0])
result += ' %s\n' % red(source[0])
result += ' %s%s\n' % (' '*(start-1),
colored.green('^' + '-'*length))
green('^' + '-'*length))
if len(source) > 2: # write the middle lines
for line in source[1:-1]:
result += ' %s\n' % colored.red("".join(line))
result += ' %s\n' % colored.green("-"*len(line))
result += ' %s\n' % red("".join(line))
result += ' %s\n' % green("-"*len(line))

# write the last line
result += ' %s\n' % colored.red("".join(source[-1]))
result += ' %s\n' % colored.green('-'*(end-1) + '^')
result += ' %s\n' % red("".join(source[-1]))
result += ' %s\n' % green('-'*(end-1) + '^')

else:
result += ' File "%s", unknown location\n' % self.filename

result += colored.yellow("%s: %s\n\n" %
(self.__class__.__name__,
self.message))
result += yellow("%s: %s\n\n" %
(self.__class__.__name__,
self.message))

return result

Expand Down Expand Up @@ -199,18 +207,21 @@ def from_expression(message, expression, filename=None, source=None):
return HySyntaxError(message, filename, lineno, colno, source)

def __str__(self):
global _hy_colored_errors

output = traceback.format_exception_only(SyntaxError,
SyntaxError(*self.args))

output[-1] = colored.yellow(output[-1])
if len(self.source) > 0:
output[-2] = colored.green(output[-2])
for line in output[::-2]:
if line.strip().startswith(
'File "{}", line'.format(self.filename)):
break
output[-3] = colored.red(output[-3])
if _hy_colored_errors:
from hy.errors import colored
output[-1] = colored.yellow(output[-1])
if len(self.source) > 0:
output[-2] = colored.green(output[-2])
for line in output[::-2]:
if line.strip().startswith(
'File "{}", line'.format(self.filename)):
break
output[-3] = colored.red(output[-3])

# Avoid "...expected str instance, ColoredString found"
return reduce(lambda x, y: x + y, output)
Expand Down
12 changes: 8 additions & 4 deletions hy/models.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
# Copyright 2018 the authors.
# This file is part of Hy, which is free software licensed under the Expat
# license. See the LICENSE.

from __future__ import unicode_literals

from contextlib import contextmanager
from math import isnan, isinf
from hy import _initialize_env_var
from hy._compat import PY3, str_type, bytes_type, long_type, string_types
from fractions import Fraction
from clint.textui import colored


PRETTY = True
_hy_colored_ast_objects = _initialize_env_var('HY_COLORED_AST_OBJECTS', False)


@contextmanager
Expand Down Expand Up @@ -271,8 +272,9 @@ def __repr__(self):
return str(self) if PRETTY else super(HySequence, self).__repr__()

def __str__(self):
global _hy_colored_ast_objects
with pretty():
c = self.color
c = self.color if _hy_colored_ast_objects else str
if self:
return ("{}{}\n {}{}").format(
c(self.__class__.__name__),
Expand All @@ -298,10 +300,12 @@ class HyDict(HySequence):
"""
HyDict (just a representation of a dict)
"""
color = staticmethod(colored.green)

def __str__(self):
global _hy_colored_ast_objects
with pretty():
g = colored.green
g = self.color if _hy_colored_ast_objects else str
if self:
pairs = []
for k, v in zip(self[::2],self[1::2]):
Expand Down

0 comments on commit ed9b1c0

Please sign in to comment.