summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd2/ansi.py51
-rw-r--r--cmd2/cmd2.py7
-rwxr-xr-xexamples/pirate.py2
-rw-r--r--tests/test_cmd2.py4
-rw-r--r--tests/test_utils.py6
5 files changed, 48 insertions, 22 deletions
diff --git a/cmd2/ansi.py b/cmd2/ansi.py
index 5b3dff2c..f10c29ea 100644
--- a/cmd2/ansi.py
+++ b/cmd2/ansi.py
@@ -1,7 +1,7 @@
# coding=utf-8
"""Support for ANSI escape codes which are used for things like applying style to text"""
import re
-from typing import Any
+from typing import Any, Optional
import colorama
from colorama import Fore, Back, Style
@@ -95,17 +95,32 @@ class TextStyle:
# Default styles. These can be altered to suit an application's needs.
-SuccessStyle = TextStyle(fg='green')
+SuccessStyle = TextStyle(fg='green', bold=True)
WarningStyle = TextStyle(fg='lightyellow')
ErrorStyle = TextStyle(fg='lightred')
-def style(text: Any, text_style: TextStyle) -> str:
+def style(text: Any, text_style: Optional[TextStyle] = None, *,
+ fg: Optional[str] = None, bg: Optional[str] = None,
+ bold: Optional[bool] = None, underline: Optional[bool] = None) -> str:
"""
Applies a style to text
:param text: Any object compatible with str.format()
- :param text_style: the style to be applied
+ :param text_style: a TextStyle object. Defaults to None.
+
+ The following are keyword-only parameters which allow calling style without creating a TextStyle object
+ style(text, fg='blue')
+
+ They can also be used to override a setting in a provided TextStyle
+ style(text, ErrorStyle, underline=True)
+
+ :param fg: foreground color. Expects color names in FG_COLORS (e.g. 'lightred'). Defaults to None.
+ :param bg: background color. Expects color names in BG_COLORS (e.g. 'black'). Defaults to None.
+ :param bold: apply the bold style if True. Defaults to None.
+ :param underline: apply the underline style if True. Defaults to None.
+
+ :return: the stylized string
"""
# List of strings that add style
additions = []
@@ -116,26 +131,38 @@ def style(text: Any, text_style: TextStyle) -> str:
# Convert the text object into a string if it isn't already one
text = "{}".format(text)
- if text_style.fg:
+ # Figure out what parameters to use
+ if fg is None and text_style is not None:
+ fg = text_style.fg
+ if bg is None and text_style is not None:
+ bg = text_style.bg
+ if bold is None and text_style is not None:
+ bold = text_style.bold
+ if underline is None and text_style is not None:
+ underline = text_style.underline
+
+ # Process the style settings
+ if fg:
try:
- additions.append(FG_COLORS[text_style.fg.lower()])
+ additions.append(FG_COLORS[fg.lower()])
removals.append(FG_COLORS['reset'])
except KeyError:
- raise ValueError('Color {} does not exist.'.format(text_style.fg))
+ raise ValueError('Color {} does not exist.'.format(fg))
- if text_style.bg:
+ if bg:
try:
- additions.append(BG_COLORS[text_style.bg.lower()])
+ additions.append(BG_COLORS[bg.lower()])
removals.append(BG_COLORS['reset'])
except KeyError:
- raise ValueError('Color {} does not exist.'.format(text_style.bg))
+ raise ValueError('Color {} does not exist.'.format(bg))
- if text_style.bold:
+ if bold:
additions.append(Style.BRIGHT)
removals.append(Style.NORMAL)
- if text_style.underline:
+ if underline:
additions.append(UNDERLINE_ENABLE)
removals.append(UNDERLINE_DISABLE)
+ # Combine the ANSI escape strings with the text
return "".join(additions) + text + "".join(removals)
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index 0ea958b0..dbc540cd 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -3738,13 +3738,12 @@ class Cmd(cmd.Cmd):
verinfo = ".".join(map(str, sys.version_info[:3]))
num_transcripts = len(transcripts_expanded)
plural = '' if len(transcripts_expanded) == 1 else 's'
- self.poutput(ansi.style(utils.center_text('cmd2 transcript test', pad='='), ansi.TextStyle(bold=True)))
+ self.poutput(ansi.style(utils.center_text('cmd2 transcript test', pad='='), bold=True))
self.poutput('platform {} -- Python {}, cmd2-{}, readline-{}'.format(sys.platform, verinfo, cmd2.__version__,
rl_type))
self.poutput('cwd: {}'.format(os.getcwd()))
self.poutput('cmd2 app: {}'.format(sys.argv[0]))
- self.poutput(ansi.style('collected {} transcript{}'.format(num_transcripts, plural),
- ansi.TextStyle(bold=True)))
+ self.poutput(ansi.style('collected {} transcript{}'.format(num_transcripts, plural), bold=True))
self.__class__.testfiles = transcripts_expanded
sys.argv = [sys.argv[0]] # the --test argument upsets unittest.main()
@@ -3757,7 +3756,7 @@ class Cmd(cmd.Cmd):
if test_results.wasSuccessful():
self._decolorized_write(sys.stderr, stream.read())
finish_msg = '{0} transcript{1} passed in {2:.3f} seconds'.format(num_transcripts, plural, execution_time)
- finish_msg = ansi.style(utils.center_text(finish_msg, pad='='), ansi.TextStyle(fg="green", bold=True))
+ finish_msg = ansi.style(utils.center_text(finish_msg, pad='='), ansi.SuccessStyle)
self.poutput(finish_msg)
else:
# Strip off the initial traceback which isn't particularly useful for end users
diff --git a/examples/pirate.py b/examples/pirate.py
index fad6e2c9..eda3994e 100755
--- a/examples/pirate.py
+++ b/examples/pirate.py
@@ -70,7 +70,7 @@ class Pirate(cmd2.Cmd):
def do_sing(self, arg):
"""Sing a colorful song."""
- self.poutput(cmd2.ansi.style(arg, cmd2.ansi.TextStyle(fg=self.songcolor)))
+ self.poutput(cmd2.ansi.style(arg, fg=self.songcolor))
yo_parser = argparse.ArgumentParser()
yo_parser.add_argument('--ho', type=int, default=2, help="How often to chant 'ho'")
diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py
index 80077a68..3b6089f4 100644
--- a/tests/test_cmd2.py
+++ b/tests/test_cmd2.py
@@ -1460,7 +1460,7 @@ def test_poutput_none(outsim_app):
def test_poutput_color_always(outsim_app):
msg = 'Hello World'
outsim_app.colors = 'Always'
- outsim_app.poutput(ansi.style(msg, ansi.TextStyle(fg='cyan')))
+ outsim_app.poutput(ansi.style(msg, fg='cyan'))
out = outsim_app.stdout.getvalue()
expected = Fore.CYAN + msg + Fore.RESET + '\n'
assert out == expected
@@ -1468,7 +1468,7 @@ def test_poutput_color_always(outsim_app):
def test_poutput_color_never(outsim_app):
msg = 'Hello World'
outsim_app.colors = 'Never'
- outsim_app.poutput(ansi.style(msg, ansi.TextStyle(fg='cyan')))
+ outsim_app.poutput(ansi.style(msg, fg='cyan'))
out = outsim_app.stdout.getvalue()
expected = msg + '\n'
assert out == expected
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 6e3600db..a4db3132 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -29,18 +29,18 @@ def test_ansi_safe_wcswidth():
def test_style():
base_str = HELLO_WORLD
ansi_str = Fore.BLUE + Back.GREEN + base_str + Fore.RESET + Back.RESET
- assert ansi.style(base_str, ansi.TextStyle(fg='blue', bg='green')) == ansi_str
+ assert ansi.style(base_str, fg='blue', bg='green') == ansi_str
def test_style_color_not_exist():
base_str = HELLO_WORLD
try:
- ansi.style(base_str, ansi.TextStyle(fg='fake', bg='green'))
+ ansi.style(base_str, fg='fake', bg='green')
assert False
except ValueError:
assert True
try:
- ansi.style(base_str, ansi.TextStyle(fg='blue', bg='fake'))
+ ansi.style(base_str, fg='blue', bg='fake')
assert False
except ValueError:
assert True