From b0fde07cfd8676a75292188dd8bedab7de74e6f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Davorin=20S=CC=8Cego?= Date: Mon, 6 Mar 2017 01:05:50 +0100 Subject: [PATCH 1/4] Follow terminal ANSI color styles Removes the default solarized color scheme and custom http lexer class. --- httpie/cli.py | 6 +- httpie/output/formatters/colors.py | 146 ++--------------------------- 2 files changed, 8 insertions(+), 144 deletions(-) diff --git a/httpie/cli.py b/httpie/cli.py index 7d13972f..1a8fa762 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, DEFAULT_STYLE +from httpie.output.formatters.colors import AVAILABLE_STYLES from httpie.plugins import plugin_manager from httpie.plugins.builtin import BuiltinAuthPlugin from httpie.sessions import DEFAULT_SESSIONS_DIR @@ -204,10 +204,9 @@ output_processing.add_argument( '--style', '-s', dest='style', metavar='STYLE', - default=DEFAULT_STYLE, choices=AVAILABLE_STYLES, help=""" - Output coloring style (default is "{default}"). One of: + Output coloring style. One of: {available} @@ -216,7 +215,6 @@ 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 b0177433..b251b5c4 100644 --- a/httpie/output/formatters/colors.py +++ b/httpie/output/formatters/colors.py @@ -10,20 +10,12 @@ 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): @@ -37,7 +29,7 @@ class ColorFormatter(FormatterPlugin): group_name = 'colors' def __init__(self, env, explicit_json=False, - color_scheme=DEFAULT_STYLE, **kwargs): + color_scheme=None, **kwargs): super(ColorFormatter, self).__init__(**kwargs) if not env.colors: self.enabled = False @@ -46,19 +38,13 @@ class ColorFormatter(FormatterPlugin): # --json, -j self.explicit_json = explicit_json - try: - style_class = pygments.styles.get_style_by_name(color_scheme) - except ClassNotFound: - style_class = Solarized256Style - - if env.colors == 256: - fmt_class = Terminal256Formatter + if color_scheme and env.colors == 256: + self.formatter = Terminal256Formatter(style=color_scheme) else: - fmt_class = TerminalFormatter - self.formatter = fmt_class(style=style_class) + self.formatter = TerminalFormatter() 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) @@ -119,123 +105,3 @@ 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, - } 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 2/4] 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, + } From 9886f01f91b9007e9b21601264b9c42fecc0d9f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Davorin=20S=CC=8Cego?= Date: Sat, 11 Mar 2017 18:00:35 +0100 Subject: [PATCH 3/4] New style option that applies the terminal ANSI color scheme --- httpie/cli.py | 2 +- httpie/output/formatters/colors.py | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/httpie/cli.py b/httpie/cli.py index 7d13972f..a9ec1eff 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, DEFAULT_STYLE +from httpie.output.formatters.colors import AVAILABLE_STYLES, DEFAULT_STYLE, PRESET_STYLE from httpie.plugins import plugin_manager from httpie.plugins.builtin import BuiltinAuthPlugin from httpie.sessions import DEFAULT_SESSIONS_DIR diff --git a/httpie/output/formatters/colors.py b/httpie/output/formatters/colors.py index b0177433..b07c6b5a 100644 --- a/httpie/output/formatters/colors.py +++ b/httpie/output/formatters/colors.py @@ -9,6 +9,7 @@ import pygments.style from pygments.formatters.terminal import TerminalFormatter from pygments.formatters.terminal256 import Terminal256Formatter from pygments.lexers.special import TextLexer +from pygments.lexers.text import HttpLexer as PygmentsHttpLexer from pygments.util import ClassNotFound from httpie.compat import is_windows @@ -18,6 +19,10 @@ from httpie.plugins import FormatterPlugin AVAILABLE_STYLES = set(pygments.styles.STYLE_MAP.keys()) AVAILABLE_STYLES.add('solarized') +# This is the native style provided by the terminal emulator color scheme +PRESET_STYLE = 'preset'; +AVAILABLE_STYLES.add(PRESET_STYLE); + if is_windows: # Colors on Windows via colorama don't look that # great and fruity seems to give the best result there @@ -51,14 +56,19 @@ class ColorFormatter(FormatterPlugin): except ClassNotFound: style_class = Solarized256Style - if env.colors == 256: + if color_scheme != PRESET_STYLE and env.colors == 256: fmt_class = Terminal256Formatter else: fmt_class = TerminalFormatter self.formatter = fmt_class(style=style_class) + if color_scheme == PRESET_STYLE: + self.http_lexer = PygmentsHttpLexer(); + else: + self.http_lexer = HTTPLexer() + def format_headers(self, headers): - return pygments.highlight(headers, HTTPLexer(), self.formatter).strip() + return pygments.highlight(headers, self.http_lexer, self.formatter).strip() def format_body(self, body, mime): lexer = self.get_lexer(mime, body) From 02209c2db1b4399c17f50718cc19fb37461eba39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Davorin=20S=CC=8Cego?= Date: Sat, 11 Mar 2017 18:11:22 +0100 Subject: [PATCH 4/4] Oops, remove semicolons --- httpie/output/formatters/colors.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/httpie/output/formatters/colors.py b/httpie/output/formatters/colors.py index b07c6b5a..87174bf1 100644 --- a/httpie/output/formatters/colors.py +++ b/httpie/output/formatters/colors.py @@ -20,8 +20,8 @@ AVAILABLE_STYLES = set(pygments.styles.STYLE_MAP.keys()) AVAILABLE_STYLES.add('solarized') # This is the native style provided by the terminal emulator color scheme -PRESET_STYLE = 'preset'; -AVAILABLE_STYLES.add(PRESET_STYLE); +PRESET_STYLE = 'preset' +AVAILABLE_STYLES.add(PRESET_STYLE) if is_windows: # Colors on Windows via colorama don't look that @@ -63,7 +63,7 @@ class ColorFormatter(FormatterPlugin): self.formatter = fmt_class(style=style_class) if color_scheme == PRESET_STYLE: - self.http_lexer = PygmentsHttpLexer(); + self.http_lexer = PygmentsHttpLexer() else: self.http_lexer = HTTPLexer()