summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd2/ansi.py62
-rw-r--r--cmd2/argparse_completer.py4
-rw-r--r--cmd2/cmd2.py18
3 files changed, 24 insertions, 60 deletions
diff --git a/cmd2/ansi.py b/cmd2/ansi.py
index f10c29ea..97fb1e8a 100644
--- a/cmd2/ansi.py
+++ b/cmd2/ansi.py
@@ -1,7 +1,8 @@
# coding=utf-8
"""Support for ANSI escape codes which are used for things like applying style to text"""
+import functools
import re
-from typing import Any, Optional
+from typing import Any
import colorama
from colorama import Fore, Back, Style
@@ -77,48 +78,15 @@ UNDERLINE_ENABLE = colorama.ansi.code_to_chars(4)
UNDERLINE_DISABLE = colorama.ansi.code_to_chars(24)
-class TextStyle:
- """Style settings for text"""
-
- def __init__(self, *, fg: str = '', bg: str = '', bold: bool = False, underline: bool = False):
- """
- Initializer
- :param fg: foreground color. Expects color names in FG_COLORS (e.g. 'lightred'). Defaults to blank.
- :param bg: background color. Expects color names in BG_COLORS (e.g. 'black'). Defaults to blank.
- :param bold: apply the bold style if True. Defaults to False.
- :param underline: apply the underline style if True. Defaults to False.
- """
- self.fg = fg
- self.bg = bg
- self.bold = bold
- self.underline = underline
-
-
-# Default styles. These can be altered to suit an application's needs.
-SuccessStyle = TextStyle(fg='green', bold=True)
-WarningStyle = TextStyle(fg='lightyellow')
-ErrorStyle = TextStyle(fg='lightred')
-
-
-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:
+def style(text: Any, *, fg: str = '', bg: str = '', bold: bool = False, underline: bool = False) -> str:
"""
Applies a style to text
:param text: Any object compatible with str.format()
- :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.
+ :param fg: foreground color. Expects color names in FG_COLORS (e.g. 'lightred'). Defaults to no color.
+ :param bg: background color. Expects color names in BG_COLORS (e.g. 'black'). Defaults to no color.
+ :param bold: apply the bold style if True. Defaults to False.
+ :param underline: apply the underline style if True. Defaults to False.
:return: the stylized string
"""
@@ -131,16 +99,6 @@ def style(text: Any, text_style: Optional[TextStyle] = None, *,
# Convert the text object into a string if it isn't already one
text = "{}".format(text)
- # 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:
@@ -166,3 +124,9 @@ def style(text: Any, text_style: Optional[TextStyle] = None, *,
# Combine the ANSI escape strings with the text
return "".join(additions) + text + "".join(removals)
+
+
+# Default styles. These can be altered to suit an application's needs.
+style_success = functools.partial(style, fg='green', bold=True)
+style_warning = functools.partial(style, fg='lightyellow')
+style_error = functools.partial(style, fg='lightred')
diff --git a/cmd2/argparse_completer.py b/cmd2/argparse_completer.py
index fd0eb0ec..72973bec 100644
--- a/cmd2/argparse_completer.py
+++ b/cmd2/argparse_completer.py
@@ -66,7 +66,7 @@ import sys
from argparse import ZERO_OR_MORE, ONE_OR_MORE, ArgumentError, _, _get_action_name, SUPPRESS
from typing import List, Dict, Tuple, Callable, Union
-from .ansi import ansi_safe_wcswidth, style, ErrorStyle
+from .ansi import ansi_safe_wcswidth, style_error
from .rl_utils import rl_force_redisplay
# attribute that can optionally added to an argparse argument (called an Action) to
@@ -994,7 +994,7 @@ class ACArgumentParser(argparse.ArgumentParser):
linum += 1
self.print_usage(sys.stderr)
- formatted_message = style(formatted_message, ErrorStyle)
+ formatted_message = style_error(formatted_message)
self.exit(2, '{}\n\n'.format(formatted_message))
def format_help(self) -> str:
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index dbc540cd..c92a32ec 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -60,7 +60,7 @@ if rl_type == RlType.NONE: # pragma: no cover
rl_warning = "Readline features including tab completion have been disabled since no \n" \
"supported version of readline was found. To resolve this, install \n" \
"pyreadline on Windows or gnureadline on Mac.\n\n"
- sys.stderr.write(ansi.style(rl_warning, ansi.WarningStyle))
+ sys.stderr.write(ansi.style_warning(rl_warning))
else:
from .rl_utils import rl_force_redisplay, readline
@@ -616,7 +616,7 @@ class Cmd(cmd.Cmd):
where the message text already has the desired style. Defaults to True.
"""
if apply_style:
- final_msg = ansi.style(msg, ansi.ErrorStyle)
+ final_msg = ansi.style_error(msg)
else:
final_msg = "{}".format(msg)
self._decolorized_write(sys.stderr, final_msg + end)
@@ -639,11 +639,11 @@ class Cmd(cmd.Cmd):
final_msg = "{}".format(msg)
if apply_style:
- final_msg = ansi.style(final_msg, ansi.ErrorStyle)
+ final_msg = ansi.style_error(final_msg)
if not self.debug:
warning = "\nTo enable full traceback, run the following command: 'set debug true'"
- final_msg += ansi.style(warning, ansi.WarningStyle)
+ final_msg += ansi.style_warning(warning)
# Set apply_style to False since style has already been applied
self.perror(final_msg, end=end, apply_style=False)
@@ -3246,7 +3246,7 @@ class Cmd(cmd.Cmd):
if args.__statement__.command == "pyscript":
warning = ("pyscript has been renamed and will be removed in the next release, "
"please use run_pyscript instead\n")
- self.perror(ansi.style(warning, ansi.WarningStyle))
+ self.perror(ansi.style_warning(warning))
return py_return
@@ -3555,7 +3555,7 @@ class Cmd(cmd.Cmd):
# Check if all commands ran
if commands_run < len(history):
warning = "Command {} triggered a stop and ended transcript generation early".format(commands_run)
- self.perror(ansi.style(warning, ansi.WarningStyle))
+ self.perror(ansi.style_warning(warning))
# finally, we can write the transcript out to the file
try:
@@ -3675,7 +3675,7 @@ class Cmd(cmd.Cmd):
if args.__statement__.command == "load":
warning = ("load has been renamed and will be removed in the next release, "
"please use run_script instead\n")
- self.perror(ansi.style(warning, ansi.WarningStyle))
+ self.perror(ansi.style_warning(warning))
# load has been deprecated
do_load = do_run_script
@@ -3702,7 +3702,7 @@ class Cmd(cmd.Cmd):
if args.__statement__.command == "_relative_load":
warning = ("_relative_load has been renamed and will be removed in the next release, "
"please use _relative_run_script instead\n")
- self.perror(ansi.style(warning, ansi.WarningStyle))
+ self.perror(ansi.style_warning(warning))
file_path = args.file_path
# NOTE: Relative path is an absolute path, it is just relative to the current script directory
@@ -3756,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.SuccessStyle)
+ finish_msg = ansi.style_success(utils.center_text(finish_msg, pad='='))
self.poutput(finish_msg)
else:
# Strip off the initial traceback which isn't particularly useful for end users