From a4f796fe6913497a7e212ce8d07837037adcc135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Davorin=20S=CC=8Cego?= Date: Sat, 11 Mar 2017 16:58:50 +0100 Subject: [PATCH] Revert "Follow terminal ANSI color styles" This reverts commit b0fde07cfd8676a75292188dd8bedab7de74e6f2. --- httpie/cli.py | 6 +- httpie/output/formatters/colors.py | 146 +++++++++++++++++++++++++++-- 2 files changed, 144 insertions(+), 8 deletions(-) diff --git a/httpie/cli.py b/httpie/cli.py index 1a8fa762..7d13972f 100644 --- a/httpie/cli.py +++ b/httpie/cli.py @@ -20,7 +20,7 @@ from httpie.input import ( PRETTY_STDOUT_TTY_ONLY, SessionNameValidator, readable_file_arg, SSL_VERSION_ARG_MAPPING ) -from httpie.output.formatters.colors import AVAILABLE_STYLES +from httpie.output.formatters.colors import AVAILABLE_STYLES, DEFAULT_STYLE from httpie.plugins import plugin_manager from httpie.plugins.builtin import BuiltinAuthPlugin from httpie.sessions import DEFAULT_SESSIONS_DIR @@ -204,9 +204,10 @@ output_processing.add_argument( '--style', '-s', dest='style', metavar='STYLE', + default=DEFAULT_STYLE, choices=AVAILABLE_STYLES, help=""" - Output coloring style. One of: + Output coloring style (default is "{default}"). One of: {available} @@ -215,6 +216,7 @@ output_processing.add_argument( (e.g., via `export TERM=xterm-256color' in your ~/.bashrc). """.format( + default=DEFAULT_STYLE, available='\n'.join( '{0}{1}'.format(8 * ' ', line.strip()) for line in wrap(', '.join(sorted(AVAILABLE_STYLES)), 60) diff --git a/httpie/output/formatters/colors.py b/httpie/output/formatters/colors.py index b251b5c4..b0177433 100644 --- a/httpie/output/formatters/colors.py +++ b/httpie/output/formatters/colors.py @@ -10,12 +10,20 @@ from pygments.formatters.terminal import TerminalFormatter from pygments.formatters.terminal256 import Terminal256Formatter from pygments.lexers.special import TextLexer from pygments.util import ClassNotFound -from pygments.lexers.text import HttpLexer +from httpie.compat import is_windows from httpie.plugins import FormatterPlugin AVAILABLE_STYLES = set(pygments.styles.STYLE_MAP.keys()) +AVAILABLE_STYLES.add('solarized') + +if is_windows: + # Colors on Windows via colorama don't look that + # great and fruity seems to give the best result there + DEFAULT_STYLE = 'fruity' +else: + DEFAULT_STYLE = 'solarized' class ColorFormatter(FormatterPlugin): @@ -29,7 +37,7 @@ class ColorFormatter(FormatterPlugin): group_name = 'colors' def __init__(self, env, explicit_json=False, - color_scheme=None, **kwargs): + color_scheme=DEFAULT_STYLE, **kwargs): super(ColorFormatter, self).__init__(**kwargs) if not env.colors: self.enabled = False @@ -38,13 +46,19 @@ class ColorFormatter(FormatterPlugin): # --json, -j self.explicit_json = explicit_json - if color_scheme and env.colors == 256: - self.formatter = Terminal256Formatter(style=color_scheme) + try: + style_class = pygments.styles.get_style_by_name(color_scheme) + except ClassNotFound: + style_class = Solarized256Style + + if env.colors == 256: + fmt_class = Terminal256Formatter else: - self.formatter = TerminalFormatter() + fmt_class = TerminalFormatter + self.formatter = fmt_class(style=style_class) def format_headers(self, headers): - return pygments.highlight(headers, HttpLexer(), self.formatter).strip() + return pygments.highlight(headers, HTTPLexer(), self.formatter).strip() def format_body(self, body, mime): lexer = self.get_lexer(mime, body) @@ -105,3 +119,123 @@ def get_lexer(mime, explicit_json=False, body=''): lexer = pygments.lexers.get_lexer_by_name('json') return lexer + + +class HTTPLexer(pygments.lexer.RegexLexer): + """Simplified HTTP lexer for Pygments. + + It only operates on headers and provides a stronger contrast between + their names and values than the original one bundled with Pygments + (:class:`pygments.lexers.text import HttpLexer`), especially when + Solarized color scheme is used. + + """ + name = 'HTTP' + aliases = ['http'] + filenames = ['*.http'] + tokens = { + 'root': [ + # Request-Line + (r'([A-Z]+)( +)([^ ]+)( +)(HTTP)(/)(\d+\.\d+)', + pygments.lexer.bygroups( + pygments.token.Name.Function, + pygments.token.Text, + pygments.token.Name.Namespace, + pygments.token.Text, + pygments.token.Keyword.Reserved, + pygments.token.Operator, + pygments.token.Number + )), + # Response Status-Line + (r'(HTTP)(/)(\d+\.\d+)( +)(\d{3})( +)(.+)', + pygments.lexer.bygroups( + pygments.token.Keyword.Reserved, # 'HTTP' + pygments.token.Operator, # '/' + pygments.token.Number, # Version + pygments.token.Text, + pygments.token.Number, # Status code + pygments.token.Text, + pygments.token.Name.Exception, # Reason + )), + # Header + (r'(.*?)( *)(:)( *)(.+)', pygments.lexer.bygroups( + pygments.token.Name.Attribute, # Name + pygments.token.Text, + pygments.token.Operator, # Colon + pygments.token.Text, + pygments.token.String # Value + )) + ] + } + + +class Solarized256Style(pygments.style.Style): + """ + solarized256 + ------------ + + A Pygments style inspired by Solarized's 256 color mode. + + :copyright: (c) 2011 by Hank Gay, (c) 2012 by John Mastro. + :license: BSD, see LICENSE for more details. + + """ + BASE03 = "#1c1c1c" + BASE02 = "#262626" + BASE01 = "#4e4e4e" + BASE00 = "#585858" + BASE0 = "#808080" + BASE1 = "#8a8a8a" + BASE2 = "#d7d7af" + BASE3 = "#ffffd7" + YELLOW = "#af8700" + ORANGE = "#d75f00" + RED = "#af0000" + MAGENTA = "#af005f" + VIOLET = "#5f5faf" + BLUE = "#0087ff" + CYAN = "#00afaf" + GREEN = "#5f8700" + + background_color = BASE03 + styles = { + pygments.token.Keyword: GREEN, + pygments.token.Keyword.Constant: ORANGE, + pygments.token.Keyword.Declaration: BLUE, + pygments.token.Keyword.Namespace: ORANGE, + pygments.token.Keyword.Reserved: BLUE, + pygments.token.Keyword.Type: RED, + pygments.token.Name.Attribute: BASE1, + pygments.token.Name.Builtin: BLUE, + pygments.token.Name.Builtin.Pseudo: BLUE, + pygments.token.Name.Class: BLUE, + pygments.token.Name.Constant: ORANGE, + pygments.token.Name.Decorator: BLUE, + pygments.token.Name.Entity: ORANGE, + pygments.token.Name.Exception: YELLOW, + pygments.token.Name.Function: BLUE, + pygments.token.Name.Tag: BLUE, + pygments.token.Name.Variable: BLUE, + pygments.token.String: CYAN, + pygments.token.String.Backtick: BASE01, + pygments.token.String.Char: CYAN, + pygments.token.String.Doc: CYAN, + pygments.token.String.Escape: RED, + pygments.token.String.Heredoc: CYAN, + pygments.token.String.Regex: RED, + pygments.token.Number: CYAN, + pygments.token.Operator: BASE1, + pygments.token.Operator.Word: GREEN, + pygments.token.Comment: BASE01, + pygments.token.Comment.Preproc: GREEN, + pygments.token.Comment.Special: GREEN, + pygments.token.Generic.Deleted: CYAN, + pygments.token.Generic.Emph: 'italic', + pygments.token.Generic.Error: RED, + pygments.token.Generic.Heading: ORANGE, + pygments.token.Generic.Inserted: GREEN, + pygments.token.Generic.Strong: 'bold', + pygments.token.Generic.Subheading: ORANGE, + pygments.token.Token: BASE1, + pygments.token.Token.Other: ORANGE, + }