Skip to content

Commit 20dae38

Browse files
committed
Fix raw ANSI codes displaying for CompletionError in prompt_toolkit
When raising a CompletionError with apply_style=True during tab completion in prompt_toolkit mode, the error message was printed directly to stdout using ANSI codes. prompt_toolkit's patch_stdout would capture this but fail to interpret the ANSI codes, resulting in raw escape sequences being displayed. This commit fixes the issue by: 1. Modifying cmd2.complete to capture the styled error message into self.completion_header instead of printing directly to stdout. 2. Updating Cmd2Completer.get_completions (in pt_utils.py) to print completion_header using print_formatted_text wrapped in ANSI, which correctly renders the styled text above the prompt. 3. Updating tests/conftest.py complete_tester to print completion_header so existing tests (like test_completion_error) continue to pass by capturing the error output.
1 parent f1803b3 commit 20dae38

3 files changed

Lines changed: 17 additions & 5 deletions

File tree

cmd2/cmd2.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,6 +1624,7 @@ def _reset_completion_defaults(self) -> None:
16241624
self.formatted_completions = ''
16251625
self.completion_matches = []
16261626
self.display_matches = []
1627+
self.completion_header = ''
16271628
self.matches_delimited = False
16281629
self.matches_sorted = False
16291630

@@ -2468,11 +2469,12 @@ def complete(
24682469
# If apply_style is True, then this is an error message that should be printed
24692470
# above the prompt so it remains in the scrollback.
24702471
if ex.apply_style:
2471-
self.print_to(
2472-
sys.stdout,
2473-
"\n" + err_str,
2474-
style=Cmd2Style.ERROR,
2475-
)
2472+
# Render the error with style to a string using Rich
2473+
console = ru.Cmd2GeneralConsole()
2474+
with console.capture() as capture:
2475+
console.print("\n" + err_str, style=Cmd2Style.ERROR)
2476+
self.completion_header = capture.get()
2477+
24762478
# Otherwise, this is a hint that should be displayed below the prompt.
24772479
else:
24782480
self.completion_hint = err_str

cmd2/pt_utils.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ def get_completions(self, document: Document, _complete_event: object) -> Iterab
7676
print_formatted_text(ANSI("\n" + self.cmd_app.formatted_completions))
7777
self.cmd_app.formatted_completions = ""
7878

79+
# Print completion header (e.g. CompletionError) if present
80+
if self.cmd_app.completion_header:
81+
print_formatted_text(ANSI(self.cmd_app.completion_header))
82+
self.cmd_app.completion_header = ""
83+
7984
# Print hint if present
8085
if self.cmd_app.completion_hint:
8186
print_formatted_text(ANSI(self.cmd_app.completion_hint))

tests/conftest.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,11 @@ def get_endidx() -> int:
151151
if app.completion_hint:
152152
print(app.completion_hint)
153153

154+
# If the completion resulted in a header being set (e.g. CompletionError), then print it now
155+
# so that it can be captured by tests using capsys.
156+
if app.completion_header:
157+
print(app.completion_header)
158+
154159
return res
155160

156161

0 commit comments

Comments
 (0)