diff --git a/src/prompt_toolkit/formatted_text/ansi.py b/src/prompt_toolkit/formatted_text/ansi.py index 2f355c2b7..ad992abb6 100644 --- a/src/prompt_toolkit/formatted_text/ansi.py +++ b/src/prompt_toolkit/formatted_text/ansi.py @@ -119,7 +119,8 @@ def _parse_corot(self) -> Generator[None, str, None]: # Check and evaluate cursor forward elif char == "C": - for i in range(params[0]): + # A missing or zero count defaults to one column. + for i in range(params[0] or 1): # add using current style formatted_text.append((style, " ")) break diff --git a/tests/test_formatted_text.py b/tests/test_formatted_text.py index a111a7f20..9fe9ef24a 100644 --- a/tests/test_formatted_text.py +++ b/tests/test_formatted_text.py @@ -1,5 +1,7 @@ from __future__ import annotations +import pytest + from prompt_toolkit.formatted_text import ( ANSI, HTML, @@ -145,6 +147,19 @@ def test_ansi_true_color(): ] +@pytest.mark.parametrize("csi", ["\x1b[", "\x9b"]) +@pytest.mark.parametrize( + "parameter, count", [("", 1), ("0", 1), ("00", 1), ("1", 1), ("3", 3)] +) +@pytest.mark.parametrize("color, style", [("", ""), ("31", "ansired")]) +def test_ansi_cursor_forward_defaults(csi, parameter, count, color, style): + value = ANSI(f"{csi}{color}ma{csi}{parameter}Cb{csi}0mc") + + assert to_formatted_text(value) == ( + [(style, "a")] + [(style, " ")] * count + [(style, "b"), ("", "c")] + ) + + def test_ansi_interpolation(): # %-style interpolation. value = ANSI("\x1b[1m%s\x1b[0m") % "hello\x1b"