Skip to content

Commit b911f7a

Browse files
committed
Migrated emoji, markup, and highlight from rich_print_kwargs to
dedicated print_to() parameters to simplify the API and improve discoverability of core functionality.
1 parent f911b9f commit b911f7a

File tree

4 files changed

+76
-35
lines changed

4 files changed

+76
-35
lines changed

cmd2/cmd2.py

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,22 +1198,39 @@ def print_to(
11981198
end: str = "\n",
11991199
style: StyleType | None = None,
12001200
soft_wrap: bool = True,
1201+
emoji: bool = False,
1202+
markup: bool = False,
1203+
highlight: bool = False,
12011204
rich_print_kwargs: RichPrintKwargs | None = None,
12021205
**kwargs: Any, # noqa: ARG002
12031206
) -> None:
12041207
"""Print objects to a given file stream.
12051208
1209+
This method is configured for general-purpose printing. By default, it enables
1210+
soft wrap and disables Rich's automatic detection for markup, emoji, and highlighting.
1211+
These defaults can be overridden by passing explicit keyword arguments.
1212+
12061213
:param file: file stream being written to
12071214
:param objects: objects to print
12081215
:param sep: string to write between printed text. Defaults to " ".
12091216
:param end: string to write at end of printed text. Defaults to a newline.
12101217
:param style: optional style to apply to output
1211-
:param soft_wrap: Enable soft wrap mode. If True, lines of text will not be word-wrapped or cropped to
1212-
fit the terminal width. Defaults to True.
1218+
:param soft_wrap: Enable soft wrap mode. If True, lines of text will not be
1219+
word-wrapped or cropped to fit the terminal width. Defaults to True.
1220+
:param emoji: If True, Rich will replace emoji codes (e.g., :smiley:) with their
1221+
corresponding Unicode characters. Defaults to False.
1222+
:param markup: If True, Rich will interpret strings with tags (e.g., [bold]hello[/bold])
1223+
as styled output. Defaults to False.
1224+
:param highlight: If True, Rich will automatically apply highlighting to elements within
1225+
strings, such as common Python data types like numbers, booleans, or None.
1226+
This is particularly useful when pretty printing objects like lists and
1227+
dictionaries to display them in color. Defaults to False.
12131228
:param rich_print_kwargs: optional additional keyword arguments to pass to Rich's Console.print().
12141229
:param kwargs: Arbitrary keyword arguments. This allows subclasses to extend the signature of this
12151230
method and still call `super()` without encountering unexpected keyword argument errors.
12161231
These arguments are not passed to Rich's Console.print().
1232+
1233+
See the Rich documentation for more details on emoji codes, markup tags, and highlighting.
12171234
"""
12181235
prepared_objects = ru.prepare_objects_for_rendering(*objects)
12191236

@@ -1224,6 +1241,9 @@ def print_to(
12241241
end=end,
12251242
style=style,
12261243
soft_wrap=soft_wrap,
1244+
emoji=emoji,
1245+
markup=markup,
1246+
highlight=highlight,
12271247
**(rich_print_kwargs if rich_print_kwargs is not None else {}),
12281248
)
12291249
except BrokenPipeError:
@@ -1242,6 +1262,9 @@ def poutput(
12421262
end: str = "\n",
12431263
style: StyleType | None = None,
12441264
soft_wrap: bool = True,
1265+
emoji: bool = False,
1266+
markup: bool = False,
1267+
highlight: bool = False,
12451268
rich_print_kwargs: RichPrintKwargs | None = None,
12461269
**kwargs: Any, # noqa: ARG002
12471270
) -> None:
@@ -1256,6 +1279,9 @@ def poutput(
12561279
end=end,
12571280
style=style,
12581281
soft_wrap=soft_wrap,
1282+
emoji=emoji,
1283+
markup=markup,
1284+
highlight=highlight,
12591285
rich_print_kwargs=rich_print_kwargs,
12601286
)
12611287

@@ -1266,6 +1292,9 @@ def perror(
12661292
end: str = "\n",
12671293
style: StyleType | None = Cmd2Style.ERROR,
12681294
soft_wrap: bool = True,
1295+
emoji: bool = False,
1296+
markup: bool = False,
1297+
highlight: bool = False,
12691298
rich_print_kwargs: RichPrintKwargs | None = None,
12701299
**kwargs: Any, # noqa: ARG002
12711300
) -> None:
@@ -1282,6 +1311,9 @@ def perror(
12821311
end=end,
12831312
style=style,
12841313
soft_wrap=soft_wrap,
1314+
emoji=emoji,
1315+
markup=markup,
1316+
highlight=highlight,
12851317
rich_print_kwargs=rich_print_kwargs,
12861318
)
12871319

@@ -1291,6 +1323,9 @@ def psuccess(
12911323
sep: str = " ",
12921324
end: str = "\n",
12931325
soft_wrap: bool = True,
1326+
emoji: bool = False,
1327+
markup: bool = False,
1328+
highlight: bool = False,
12941329
rich_print_kwargs: RichPrintKwargs | None = None,
12951330
**kwargs: Any, # noqa: ARG002
12961331
) -> None:
@@ -1304,6 +1339,9 @@ def psuccess(
13041339
end=end,
13051340
style=Cmd2Style.SUCCESS,
13061341
soft_wrap=soft_wrap,
1342+
emoji=emoji,
1343+
markup=markup,
1344+
highlight=highlight,
13071345
rich_print_kwargs=rich_print_kwargs,
13081346
)
13091347

@@ -1313,6 +1351,9 @@ def pwarning(
13131351
sep: str = " ",
13141352
end: str = "\n",
13151353
soft_wrap: bool = True,
1354+
emoji: bool = False,
1355+
markup: bool = False,
1356+
highlight: bool = False,
13161357
rich_print_kwargs: RichPrintKwargs | None = None,
13171358
**kwargs: Any, # noqa: ARG002
13181359
) -> None:
@@ -1326,6 +1367,9 @@ def pwarning(
13261367
end=end,
13271368
style=Cmd2Style.WARNING,
13281369
soft_wrap=soft_wrap,
1370+
emoji=emoji,
1371+
markup=markup,
1372+
highlight=highlight,
13291373
rich_print_kwargs=rich_print_kwargs,
13301374
)
13311375

@@ -1390,6 +1434,9 @@ def pfeedback(
13901434
end: str = "\n",
13911435
style: StyleType | None = None,
13921436
soft_wrap: bool = True,
1437+
emoji: bool = False,
1438+
markup: bool = False,
1439+
highlight: bool = False,
13931440
rich_print_kwargs: RichPrintKwargs | None = None,
13941441
**kwargs: Any, # noqa: ARG002
13951442
) -> None:
@@ -1408,6 +1455,9 @@ def pfeedback(
14081455
end=end,
14091456
style=style,
14101457
soft_wrap=soft_wrap,
1458+
emoji=emoji,
1459+
markup=markup,
1460+
highlight=highlight,
14111461
rich_print_kwargs=rich_print_kwargs,
14121462
)
14131463
else:
@@ -1417,6 +1467,9 @@ def pfeedback(
14171467
end=end,
14181468
style=style,
14191469
soft_wrap=soft_wrap,
1470+
emoji=emoji,
1471+
markup=markup,
1472+
highlight=highlight,
14201473
rich_print_kwargs=rich_print_kwargs,
14211474
)
14221475

@@ -1428,6 +1481,9 @@ def ppaged(
14281481
style: StyleType | None = None,
14291482
chop: bool = False,
14301483
soft_wrap: bool = True,
1484+
emoji: bool = False,
1485+
markup: bool = False,
1486+
highlight: bool = False,
14311487
rich_print_kwargs: RichPrintKwargs | None = None,
14321488
**kwargs: Any, # noqa: ARG002
14331489
) -> None:
@@ -1479,6 +1535,9 @@ def ppaged(
14791535
end=end,
14801536
style=style,
14811537
soft_wrap=soft_wrap,
1538+
emoji=emoji,
1539+
markup=markup,
1540+
highlight=highlight,
14821541
**(rich_print_kwargs if rich_print_kwargs is not None else {}),
14831542
)
14841543
output_bytes = capture.get().encode('utf-8', 'replace')
@@ -1503,6 +1562,9 @@ def ppaged(
15031562
end=end,
15041563
style=style,
15051564
soft_wrap=soft_wrap,
1565+
emoji=emoji,
1566+
markup=markup,
1567+
highlight=highlight,
15061568
rich_print_kwargs=rich_print_kwargs,
15071569
)
15081570

cmd2/rich_utils.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,6 @@ class RichPrintKwargs(TypedDict, total=False):
110110
justify: JustifyMethod | None
111111
overflow: OverflowMethod | None
112112
no_wrap: bool | None
113-
markup: bool | None
114-
emoji: bool | None
115-
highlight: bool | None
116113
width: int | None
117114
height: int | None
118115
crop: bool
@@ -216,9 +213,11 @@ def __init__(self, file: IO[str] | None = None) -> None:
216213
:param file: optional file object where the console should write to.
217214
Defaults to sys.stdout.
218215
"""
219-
# Disable Rich's automatic detection for markup, emoji, and highlighting.
220-
# rich-argparse does markup and highlighting without involving the console
221-
# so these won't affect its internal functionality.
216+
# Since this console is used to print error messages which may not have
217+
# been pre-formatted by rich-argparse, disable Rich's automatic detection
218+
# for markup, emoji, and highlighting. rich-argparse does markup and
219+
# highlighting without involving the console so these won't affect its
220+
# internal functionality.
222221
super().__init__(
223222
file=file,
224223
markup=False,
@@ -236,7 +235,7 @@ class Cmd2ExceptionConsole(Cmd2BaseConsole):
236235

237236
def console_width() -> int:
238237
"""Return the width of the console."""
239-
return Cmd2BaseConsole().width
238+
return Console().width
240239

241240

242241
def rich_text_to_string(text: Text) -> str:

tests/test_cmd2.py

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2136,33 +2136,21 @@ def test_poutput_ansi_terminal(outsim_app) -> None:
21362136

21372137
@with_ansi_style(ru.AllowStyle.ALWAYS)
21382138
def test_poutput_highlight(outsim_app):
2139-
rich_print_kwargs = RichPrintKwargs(highlight=True)
2140-
outsim_app.poutput(
2141-
"My IP Address is 192.168.1.100.",
2142-
rich_print_kwargs=rich_print_kwargs,
2143-
)
2139+
outsim_app.poutput("My IP Address is 192.168.1.100.", highlight=True)
21442140
out = outsim_app.stdout.getvalue()
21452141
assert out == "My IP Address is \x1b[1;92m192.168.1.100\x1b[0m.\n"
21462142

21472143

21482144
@with_ansi_style(ru.AllowStyle.ALWAYS)
21492145
def test_poutput_markup(outsim_app):
2150-
rich_print_kwargs = RichPrintKwargs(markup=True)
2151-
outsim_app.poutput(
2152-
"The leaves are [green]green[/green].",
2153-
rich_print_kwargs=rich_print_kwargs,
2154-
)
2146+
outsim_app.poutput("The leaves are [green]green[/green].", markup=True)
21552147
out = outsim_app.stdout.getvalue()
21562148
assert out == "The leaves are \x1b[32mgreen\x1b[0m.\n"
21572149

21582150

21592151
@with_ansi_style(ru.AllowStyle.ALWAYS)
21602152
def test_poutput_emoji(outsim_app):
2161-
rich_print_kwargs = RichPrintKwargs(emoji=True)
2162-
outsim_app.poutput(
2163-
"Look at the emoji :1234:.",
2164-
rich_print_kwargs=rich_print_kwargs,
2165-
)
2153+
outsim_app.poutput("Look at the emoji :1234:.", emoji=True)
21662154
out = outsim_app.stdout.getvalue()
21672155
assert out == "Look at the emoji 🔢.\n"
21682156

@@ -2196,13 +2184,9 @@ def test_poutput_no_wrap_and_overflow(outsim_app):
21962184
@with_ansi_style(ru.AllowStyle.ALWAYS)
21972185
def test_poutput_pretty_print(outsim_app):
21982186
"""Test that cmd2 passes objects through so they can be pretty-printed when highlighting is enabled."""
2199-
rich_print_kwargs = RichPrintKwargs(highlight=True)
22002187
dictionary = {1: 'hello', 2: 'person', 3: 'who', 4: 'codes'}
22012188

2202-
outsim_app.poutput(
2203-
dictionary,
2204-
rich_print_kwargs=rich_print_kwargs,
2205-
)
2189+
outsim_app.poutput(dictionary, highlight=True)
22062190
out = outsim_app.stdout.getvalue()
22072191
assert out.startswith("\x1b[1m{\x1b[0m\x1b[1;36m1\x1b[0m: \x1b[32m'hello'\x1b[0m")
22082192

@@ -2214,9 +2198,6 @@ def test_poutput_all_keyword_args(outsim_app):
22142198
justify="center",
22152199
overflow="ellipsis",
22162200
no_wrap=True,
2217-
markup=True,
2218-
emoji=True,
2219-
highlight=True,
22202201
width=40,
22212202
height=50,
22222203
crop=False,

tests/test_rich_utils.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,9 @@ def test_cmd2_base_console() -> None:
3131

3232

3333
def test_indented_text() -> None:
34-
console = ru.Cmd2GeneralConsole()
34+
console = Console(width=20)
3535

3636
# With an indention of 10, text will be evenly split across two lines.
37-
console.width = 20
3837
text = "A" * 20
3938
level = 10
4039
indented_text = ru.indent(text, level)
@@ -50,7 +49,7 @@ def test_indented_text() -> None:
5049

5150

5251
def test_indented_table() -> None:
53-
console = ru.Cmd2GeneralConsole()
52+
console = Console()
5453

5554
level = 2
5655
table = Table("Column", box=rich.box.ASCII)

0 commit comments

Comments
 (0)