mirror of
https://github.com/xonsh/xonsh.git
synced 2025-03-04 16:34:47 +01:00
commit
27a37758c7
5 changed files with 65 additions and 16 deletions
17
news/tracer.rst
Normal file
17
news/tracer.rst
Normal file
|
@ -0,0 +1,17 @@
|
|||
**Added:**
|
||||
|
||||
* The ``trace`` will automatically disable color printing when
|
||||
stdout is not a TTY or stdout is captured.
|
||||
|
||||
**Changed:** None
|
||||
|
||||
**Deprecated:** None
|
||||
|
||||
**Removed:** None
|
||||
|
||||
**Fixed:**
|
||||
|
||||
* The ``trace`` utility will now correctly color output and not
|
||||
print extraneous newlines when called in a script.
|
||||
|
||||
**Security:** None
|
|
@ -48,7 +48,7 @@ def sp(cmd):
|
|||
|
||||
|
||||
class DummyStyler():
|
||||
styles = defaultdict(None.__class__)
|
||||
styles = defaultdict(str)
|
||||
|
||||
|
||||
class DummyBaseShell(BaseShell):
|
||||
|
@ -92,6 +92,7 @@ class DummyEnv(MutableMapping):
|
|||
|
||||
DEFAULTS = {
|
||||
'XONSH_DEBUG': 1,
|
||||
'XONSH_COLOR_STYLE': 'default',
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
|
|
@ -353,11 +353,12 @@ def xonfig(args, stdin=None):
|
|||
|
||||
|
||||
@unthreadable
|
||||
def trace(args, stdin=None):
|
||||
def trace(args, stdin=None, stdout=None, stderr=None, spec=None):
|
||||
"""Runs the xonsh tracer utility."""
|
||||
from xonsh.tracer import tracermain # lazy import
|
||||
try:
|
||||
return tracermain(args)
|
||||
return tracermain(args, stdin=stdin, stdout=stdout,
|
||||
stderr=stderr, spec=spec)
|
||||
except SystemExit:
|
||||
pass
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@ from xonsh.completer import Completer
|
|||
from xonsh.prompt.base import multiline_prompt, PromptFormatter
|
||||
from xonsh.events import events
|
||||
from xonsh.shell import transform_command
|
||||
from xonsh.lazyimps import pygments, pyghooks
|
||||
from xonsh.ansi_colors import ansi_partial_color_format
|
||||
|
||||
if ON_WINDOWS:
|
||||
import ctypes
|
||||
|
@ -475,19 +477,32 @@ class BaseShell(object):
|
|||
self.settitle()
|
||||
return p
|
||||
|
||||
def format_color(self, string, **kwargs):
|
||||
"""Formats the colors in a string. This base implmentation does not
|
||||
actually do any coloring, but just returns the string directly.
|
||||
def format_color(self, string, hide=False, force_string=False, **kwargs):
|
||||
"""Formats the colors in a string. This base implmentation colors based
|
||||
on ANSI color codes
|
||||
"""
|
||||
return string
|
||||
style = builtins.__xonsh_env__.get('XONSH_COLOR_STYLE')
|
||||
return ansi_partial_color_format(string, hide=hide, style=style)
|
||||
|
||||
def print_color(self, string, **kwargs):
|
||||
"""Prints a string in color. This base implmentation does not actually
|
||||
do any coloring, but just prints the string directly.
|
||||
def print_color(self, string, hide=False, **kwargs):
|
||||
"""Prints a string in color. This base implmentation will color based
|
||||
ANSI color codes if a string was given as input. If a list of token
|
||||
pairs is given, it will color based on pygments, if available. If
|
||||
pygments is not available, it will print a colorless string.
|
||||
"""
|
||||
if not isinstance(string, str):
|
||||
string = ''.join([x for _, x in string])
|
||||
print(string, **kwargs)
|
||||
if isinstance(string, str):
|
||||
s = self.format_color(string, hide=hide)
|
||||
elif HAS_PYGMENTS:
|
||||
# assume this is a list of (Token, str) tuples and format it
|
||||
env = builtins.__xonsh_env__
|
||||
self.styler.style_name = env.get('XONSH_COLOR_STYLE')
|
||||
style_proxy = pyghooks.xonsh_style_proxy(self.styler)
|
||||
formatter = pyghooks.XonshTerminal256Formatter(style=style_proxy)
|
||||
s = pygments.format(string, formatter).rstrip()
|
||||
else:
|
||||
# assume this is a list of (Token, str) tuples and remove color
|
||||
s = ''.join([x for _, x in string])
|
||||
print(s, **kwargs)
|
||||
|
||||
def color_style_names(self):
|
||||
"""Returns an iterable of all available style names."""
|
||||
|
|
|
@ -13,9 +13,9 @@ from xonsh.platform import HAS_PYGMENTS
|
|||
from xonsh.tools import DefaultNotGiven, print_color, normabspath, to_bool
|
||||
from xonsh.inspectors import find_file, getouterframes
|
||||
from xonsh.lazyimps import pygments, pyghooks
|
||||
from xonsh.proc import STDOUT_CAPTURE_KINDS
|
||||
import xonsh.prompt.cwd as prompt
|
||||
|
||||
|
||||
terminal = LazyObject(lambda: importlib.import_module(
|
||||
'pygments.formatters.terminal'),
|
||||
globals(), 'terminal')
|
||||
|
@ -45,6 +45,14 @@ class TracerType(object):
|
|||
for f in set(self.files):
|
||||
self.stop(f)
|
||||
|
||||
def color_output(self, usecolor):
|
||||
"""Specify whether or not the tracer output should be colored."""
|
||||
# we have to use a function to set usecolor because of the way that
|
||||
# lazyasd works. Namely, it cannot dispatch setattr to the target
|
||||
# object without being unable to access its own __dict__. This makes
|
||||
# setting an atter look like getting a function.
|
||||
self.usecolor = usecolor
|
||||
|
||||
def start(self, filename):
|
||||
"""Starts tracing a file."""
|
||||
files = self.files
|
||||
|
@ -109,6 +117,10 @@ def tracer_format_line(fname, lineno, line, color=True, lexer=None, formatter=No
|
|||
tokens = pyghooks.partial_color_tokenize(cline)
|
||||
lexer = lexer or pyghooks.XonshLexer()
|
||||
tokens += pygments.lex(line, lexer=lexer)
|
||||
if tokens[-1][1] == '\n':
|
||||
del tokens[-1]
|
||||
elif tokens[-1][1].endswith('\n'):
|
||||
tokens[-1] = (tokens[-1][0], tokens[-1][1].rstrip())
|
||||
return tokens
|
||||
|
||||
|
||||
|
@ -157,7 +169,7 @@ def _off(ns, args):
|
|||
|
||||
def _color(ns, args):
|
||||
"""Manages color action for tracer CLI."""
|
||||
tracer.usecolor = ns.toggle
|
||||
tracer.color_output(ns.toggle)
|
||||
|
||||
|
||||
@functools.lru_cache(1)
|
||||
|
@ -194,8 +206,11 @@ _TRACER_MAIN_ACTIONS = {
|
|||
}
|
||||
|
||||
|
||||
def tracermain(args=None):
|
||||
def tracermain(args=None, stdin=None, stdout=None, stderr=None, spec=None):
|
||||
"""Main function for tracer command-line interface."""
|
||||
parser = _tracer_create_parser()
|
||||
ns = parser.parse_args(args)
|
||||
usecolor = ((spec.captured not in STDOUT_CAPTURE_KINDS) and
|
||||
sys.stdout.isatty())
|
||||
tracer.color_output(usecolor)
|
||||
return _TRACER_MAIN_ACTIONS[ns.action](ns, args)
|
||||
|
|
Loading…
Add table
Reference in a new issue