Skip to content

gh-134746: implement Ctrl+Alt+L clear display keymap in pyREPL - #138521

Open
sharmaigne wants to merge 9 commits into
python:mainfrom
sharmaigne:fix-issue-134746
Open

gh-134746: implement Ctrl+Alt+L clear display keymap in pyREPL#138521
sharmaigne wants to merge 9 commits into
python:mainfrom
sharmaigne:fix-issue-134746

Conversation

@sharmaigne

@sharmaignesharmaigne commented Sep 5, 2025

Copy link
Copy Markdown

Changes:

  • added a clear_all() method to console files that does what clear() does + clears scrollback
  • added the Ctrl+Alt+L keymap

Note:

  • description of clear_display behavior: Clear the screen and, if possible, the terminal's scrollback buffer, then redraw the current line, leaving the current line at the top of the screen.

  • Manually tested for unix but not yet tested for windows

@python-cla-bot

python-cla-botBot commented Sep 5, 2025

Copy link
Copy Markdown

All commit authors signed the Contributor License Agreement.

CLA signed

@bedevere-app

Copy link
Copy Markdown

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@StanFromIrelandStanFromIreland left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please undo all of the unrelated changes.

@bedevere-app

Copy link
Copy Markdown

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@bedevere-app

Copy link
Copy Markdown

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@bedevere-app

Copy link
Copy Markdown

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@sharmaigne

Copy link
Copy Markdown
Author

Please undo all of the unrelated changes.

Done! Sorry, forgot to turn off the formatter.

@bedevere-app

Copy link
Copy Markdown

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@sharmaigne

Copy link
Copy Markdown
Author

cc @corona10

@corona10

Copy link
Copy Markdown
Member

@ambv@pablogsal

  • She asked me onsite whether she needs to add a test case for this.
  • If there isn’t already such a test, would it be okay for her to open a new issue for it?

Comment threadLib/_pyrepl/console.py
Co-authored-by: Donghee Na <donghee.na92@gmail.com>
@corona10

Copy link
Copy Markdown
Member

ERROR: test_multiline_edit (test.test_pyrepl.test_pyrepl.TestPyReplOutput.test_multiline_edit)


Traceback (most recent call last):
File "/Users/admin/actions-runner/_work/cpython/cpython/Lib/test/test_pyrepl/test_pyrepl.py", line 686, in test_multiline_edit
reader = self.prepare_reader(events)
File "/Users/admin/actions-runner/_work/cpython/cpython/Lib/test/test_pyrepl/test_pyrepl.py", line 624, in prepare_reader
console = FakeConsole(events)
TypeError: Can't instantiate abstract class FakeConsole without an implementation for abstract method 'clear_all'

@sharmaigne

Copy link
Copy Markdown
Author

@corona10 reran the test suite, should be good now

MOVE_UP = "\x1b[{}A"
MOVE_DOWN = "\x1b[{}B"
CLEAR = "\x1b[H\x1b[J"
CLEAR_ALL= "\x1b[3J\x1b[2J\x1b[H"

Copy link
Copy Markdown
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.


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

Copy link
Copy Markdown
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)?

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

Copy link
Copy Markdown
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=1self.__move=self.__move_tallself.posxy=0, 0self.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.

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

Copy link
Copy Markdown
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)).

@chris-eibl

Copy link
Copy Markdown
Member

In the legacy console on Windows this command is not executed, because in

elifkey=="\x00":
# Handle special keys like arrow keys and translate them into the appropriate command
key=VK_MAP.get(key_event.wVirtualKeyCode)
ifkey:
ifkey_event.dwControlKeyState&CTRL_ACTIVE:
key=f"ctrl {key}"
elifkey_event.dwControlKeyState&ALT_ACTIVE:
# queue the key, return the meta command
self.event_queue.insert(Event(evt="key", data=key))
returnEvent(evt="key", data="\033") # keymap.py uses this for meta
returnEvent(evt="key", data=key)

  • VK_MAP is missing all regular keys (at least L 0x4C needs to be added, see here for all possible codes)
  • the if - elif does not handle a key_event like this that has both CTRL_ACTIVE and ALT_ACTIVE set.

@ambvambv added the topic-repl Related to the interactive shell label Sep 15, 2025
@chris-eibl

Copy link
Copy Markdown
Member

To smoothly work on Windows in the virtual console (AKA Windows Terminal), #139263 is needed, too.

@github-actions

Copy link
Copy Markdown

This PR is stale because it has been open for 30 days with no activity.

@github-actionsgithub-actionsBot added the stale Stale PR or inactive for long period of time. label Apr 29, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting reviewstaleStale PR or inactive for long period of time.topic-replRelated to the interactive shell

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@sharmaigne@corona10@chris-eibl@StanFromIreland@ambv@nazeerali4325-commits