Skip to content
7 changes: 7 additions & 0 deletions Lib/_pyrepl/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,13 @@ def do(self) -> None:
r.dirty = True


class clear_display(Command):
def do(self) -> None:
r = self.reader
r.console.clear_all()
r.dirty = True


class refresh(Command):
def do(self) -> None:
self.reader.dirty = True
Expand Down
4 changes: 4 additions & 0 deletions Lib/_pyrepl/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ def clear(self) -> None:
"""Wipe the screen"""
...

def clear_all(self) -> None:
"""Clear screen and scrollback buffer."""
...

@abstractmethod
def finish(self) -> None:
"""Move the cursor to the end of the display and otherwise get
Expand Down
1 change: 1 addition & 0 deletions Lib/_pyrepl/reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ def make_default_commands() -> dict[CommandName, type[Command]]:
(r"\<return>", "accept"),
(r"\C-k", "kill-line"),
(r"\C-l", "clear-screen"),
(r"\C-\M-l", "clear-display"),
(r"\C-m", "accept"),
(r"\C-t", "transpose-characters"),
(r"\C-u", "unix-line-discard"),
Expand Down
5 changes: 5 additions & 0 deletions Lib/_pyrepl/unix_console.py
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,11 @@ def clear(self):
self.posxy = 0, 0
self.screen = []

def clear_all(self) -> None:
"""Clear screen and scrollback buffer."""
self.__write("\x1b[3J\x1b[2J\x1b[H")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.__write("\x1b[3J\x1b[2J\x1b[H")
self.__write("\x1b[H\x1b[3J\x1b[2J")

Altough both worked for me on Ubuntu 24.0.4.3 LTS, maybe starting with \x1b[H is better?
Since it is used like so for clear

"clear": b"\x1b[H\x1b[2J", # Clear screen and home cursor

"clear": b"\x1b[H\x1b[J", # Clear screen and home cursor (different from ansi!)

And for symmetry with Windows (see below)?

self.clear()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This writes another "clear" sequence to the terminal, which did not play nicely on Ubuntu 24.0.4.3 LTS for me.
Replacing this with

        self.__gone_tall = 1
        self.__move = self.__move_tall
        self.posxy = 0, 0
        self.screen = []

did work for me, though. But I suggest to extract that in a new method (maybe called _clear?) to avoid repetition. Can be used in

self.posxy = 0, 0
self.__gone_tall = 0
self.__move = self.__move_short
self.__offset = 0

and the self.screen = [] a few lines above, too.


@property
def input_hook(self):
# avoid inline imports here so the repl doesn't get flooded
Expand Down
7 changes: 7 additions & 0 deletions Lib/_pyrepl/windows_console.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ def __init__(self, err: int | None, descr: str | None = None) -> None:
MOVE_UP = "\x1b[{}A"
MOVE_DOWN = "\x1b[{}B"
CLEAR = "\x1b[H\x1b[J"
CLEAR_ALL= "\x1b[3J\x1b[2J\x1b[H"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
CLEAR_ALL= "\x1b[3J\x1b[2J\x1b[H"
CLEAR_ALL= "\x1b[H\x1b[3J\x1b[J"

Using this works for me in the new virtual console on Windows. Also more symmetric to the CLEAR above.


# State of control keys: https://learn.microsoft.com/en-us/windows/console/key-event-record-str
ALT_ACTIVE = 0x01 | 0x02
Expand Down Expand Up @@ -516,6 +517,12 @@ def clear(self) -> None:
self.posxy = 0, 0
self.screen = [""]


def clear_all(self) -> None:
"""Clear screen and scrollback buffer."""
self.__write(CLEAR_ALL)
self.clear()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comments wrt to Unix above. Although on Windows this does no harm for me, I'd suggest to extract that, too. Please note that #138732 should be merged first, though, since this is the reason for self.screen = [""] here vs self.screen = [] in prepare (see #138732 (comment)).


def finish(self) -> None:
"""Move the cursor to the end of the display and otherwise get
ready for end. XXX could be merged with restore? Hmm."""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Added a new ``clear_display`` command in the REPL. ``Ctrl+Alt+L`` now clears
the screen and, if possible, the terminal’s scrollback buffer, then redraws
the current line at the top of the screen.

Manually tested on Unix; Windows behavior not yet verified.
Loading