diff --git a/Lib/_colorize.py b/Lib/_colorize.py index 478f81894911e7..bafe8a221c027f 100644 --- a/Lib/_colorize.py +++ b/Lib/_colorize.py @@ -350,6 +350,7 @@ class LiveProfiler(ThemeSection): @dataclass(frozen=True, kw_only=True) class Syntax(ThemeSection): prompt: str = ANSIColors.BOLD_MAGENTA + error: str = ANSIColors.BOLD_RED keyword: str = ANSIColors.BOLD_BLUE keyword_constant: str = ANSIColors.BOLD_BLUE builtin: str = ANSIColors.CYAN diff --git a/Lib/_pyrepl/commands.py b/Lib/_pyrepl/commands.py index e79fbfa6bb0b38..bbe884a83f8370 100644 --- a/Lib/_pyrepl/commands.py +++ b/Lib/_pyrepl/commands.py @@ -296,8 +296,10 @@ def do(self) -> None: r.select_item(r.historyi + 1) r.pos = r.eol(0) return - r.pos = len(b) - r.error("end of buffer") + if r.pos == len(b): + r.error("end of buffer") + else: + r.pos = len(b) return if ( diff --git a/Lib/_pyrepl/reader.py b/Lib/_pyrepl/reader.py index b8e1e425b0bb35..4f8c787312d772 100644 --- a/Lib/_pyrepl/reader.py +++ b/Lib/_pyrepl/reader.py @@ -288,6 +288,7 @@ class Reader: ps3: str = "|.. " ps4: str = R"\__ " kill_ring: list[list[str]] = field(default_factory=list) + error_prefix: str = "! " msg: str = "" arg: int | None = None finished: bool = False @@ -875,9 +876,13 @@ def finish(self) -> None: pass def error(self, msg: str = "none") -> None: - self.msg = "! " + msg + " " - self.invalidate_message() + error_prefix = self.error_prefix + if self.can_colorize: + t = THEME() + error_prefix = f"{t.error}{error_prefix}{t.reset}" self.console.beep() + self.msg = error_prefix + msg + self.invalidate_message() def update_screen(self) -> None: if self.invalidation.is_cursor_only: diff --git a/Lib/_pyrepl/readline.py b/Lib/_pyrepl/readline.py index f8f1727d2a1d1f..6d8bab6b7718e9 100644 --- a/Lib/_pyrepl/readline.py +++ b/Lib/_pyrepl/readline.py @@ -124,9 +124,6 @@ def __post_init__(self) -> None: self.commands["backspace_dedent"] = backspace_dedent self.commands["backspace-dedent"] = backspace_dedent - def error(self, msg: str = "none") -> None: - pass # don't show error messages by default - def get_stem(self) -> str: b = self.buffer p = self.pos - 1 diff --git a/Lib/test/test_pyrepl/test_pyrepl.py b/Lib/test/test_pyrepl/test_pyrepl.py index 9d0a4ed5316a3f..6eb870eb83501f 100644 --- a/Lib/test/test_pyrepl/test_pyrepl.py +++ b/Lib/test/test_pyrepl/test_pyrepl.py @@ -213,13 +213,15 @@ def test_down_arrow_end_of_input(self): events = itertools.chain( code_to_events(code), [ + # Go left first to avoid end of buffer error. + Event(evt="key", data="left", raw=bytearray(b"\x1bOD")), Event(evt="key", data="down", raw=bytearray(b"\x1bOB")), ], ) reader, console = handle_all_events(events) self.assertEqual(reader.cxy, (0, 2)) - console.move_cursor.assert_called_once_with(0, 2) + console.move_cursor.assert_called_with(0, 2) def test_left_arrow_simple(self): events = itertools.chain( @@ -237,13 +239,15 @@ def test_right_arrow_end_of_line(self): events = itertools.chain( code_to_events("11+11"), [ + # Go left first to avoid end of buffer error. + Event(evt="key", data="left", raw=bytearray(b"\x1bOD")), Event(evt="key", data="right", raw=bytearray(b"\x1bOC")), ], ) reader, console = handle_all_events(events) self.assertEqual(reader.cxy, (5, 0)) - console.move_cursor.assert_called_once_with(5, 0) + console.move_cursor.assert_called_with(5, 0) def test_cursor_position_simple_character(self): events = itertools.chain(code_to_events("k"))