GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-128388: pyrepl on Windows: add meta and ctrl+arrow keybindings by paulie4 · Pull Request #128389 · python/cpython

gh-128388: pyrepl on Windows: add meta and ctrl+arrow keybindings #128389

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Sign up for GitHub

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
encukou merged 10 commits into python:main from paulie4:fix-issue-128388
Jan 10, 2025

Uh oh!

There was an error while loading. Please reload this page.

Merged

gh-128388: pyrepl on Windows: add meta and ctrl+arrow keybindings #128389

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
10 commits
Select commit Hold shift + click to select a range
283e7c3
pyrepl on Windows: add meta and ctrl+arrow keybindings
paulie4 Jan 1, 2025
d3df8a2
📜🤖 Added by blurb_it.
blurb-it[bot] Jan 1, 2025
459b379
`2025-01-01-19-24-43.gh-issue-128388.8UdMz_.rst`: fix typo
paulie4 Jan 1, 2025
abe1f62
lint fix `Misc/NEWS.d/next/Library/2025-01-01-19-24-43.gh-issue-12838…
paulie4 Jan 2, 2025
3d07c34
`Lib/_pyrepl/windows_console.py`: temp var `ctrlstate` is not needed
paulie4 Jan 4, 2025
16f2a13
`Lib/_pyrepl/windows_console.py`: clearer comment
paulie4 Jan 4, 2025
e3f6438
PR suggestions
paulie4 Jan 4, 2025
46b22d1
`Lib\_pyrepl\windows_console.py`: fix `Alt`+`←` handling
paulie4 Jan 4, 2025
55e4fbf
`Lib/_pyrepl/windows_console.py`: standardize `Ctrl`+special key
paulie4 Jan 5, 2025
d117d52
Merge branch 'main' into fix-issue-128388
paulie4 Jan 9, 2025
File filter
Filter by extension

Clear filters
Conversations
Failed to load comments.
Loading

Uh oh!

There was an error while loading. Please reload this page.

Jump to
Jump to file
Failed to load files.
Loading

Uh oh!

There was an error while loading. Please reload this page.

Diff view
Diff view

There are no files selected for viewing

42 changes: 26 additions & 16 deletions 42 Lib/_pyrepl/windows_console.py
Show comments
View file
Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ def __init__(self, err: int | None, descr: str | None = None) -> None:
MOVE_DOWN = "\x1b[{}B"
CLEAR = "\x1b[H\x1b[J"

# State of control keys: https://learn.microsoft.com/en-us/windows/console/key-event-record-str
ALT_ACTIVE = 0x01 | 0x02
Comment thread

@vstinner vstinner Jan 7, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

I'm not sure about including the right ALT in ALT_ACTIVE. On Linux, ALT+Backspace removes a whole word, whereas AltGr+Backspace removes a single character.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@paulie4 paulie4 Jan 8, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Lib/_pyrepl/keymap.py doesn't distinguish between right and left (it just has C- and M-), so I'm not sure that was a conscious decision that was made for the Linux code. Maybe that's actually a bug in the _pyrepl/unix_* code?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@vstinner vstinner Jan 8, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Lib/_pyrepl/keymap.py doesn't distinguish between right and left

Python 3.14 on Linux behaves differently for left Alt and right AltGr:

  • Left Alt + backspace: remove a word
  • Right AltGr + backspace: remove a single character

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@encukou encukou Jan 8, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

On my Linux, the English keyboard layout has Right Alt which generally works like Left Alt (in a terminal).
The French or Czech layout has AltGr instead, which is apparently not Meta enough, so AltGr+Backspace works like Backspace (in both pyrepl and bash).

I tried on some Windows consoles:

LAlt+Backspace RAlt+Backspace AltGr+Backspace
cmd Delete single character Nothing Nothing
powershell Nothing Nothing Nothing

Doesn't look useful, so it's probably best to have Linux-like behaviour here.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@paulie4 paulie4 Jan 8, 2025

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

I don't understand what you are saying. Are you saying because the existing functionality isn't useful, we should continue to make the right Alt key not be useful in _pyrepl?

Either way, if this is about AltGr, I think we have to really understand how it works in Windows... I don't have an AltGr key, so I can't test it, but https://en.wikipedia.org/wiki/AltGr_key says, "Windows interprets Ctrl+Alt as AltGr," and since the _KEY_EVENT_RECORD doc doesn't show a dwControlKeyState value for AltGr, doesn't that mean that RIGHT_ALT_PRESSED is not the same thing as AltGr and that the Lib/_pyrepl/windows_console.py code would actually have to look for a combination of Ctrl (left/right) and Alt (left/right) (or maybe just lefts?) being pressed to know if AltGr is being pressed, or am I misunderstanding how the _KEY_EVENT_RECORD works?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@vstinner vstinner Jan 8, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

I didn't know that other keyboards have a right ALT key different than AltGr. In this case, I'm fine with ALT_ACTIVE = 0x01 | 0x02.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@encukou encukou Jan 9, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

I don't understand what you are saying.

Sorry for being unclear!
I meant that the behaviour of Windows terminals I tried (cmd & powershell) is not useful, so Python should not emulate that.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@encukou encukou Jan 9, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

I don't have an AltGr key, so I can't test it

It's a feature of the keyboard layout, not the physical keyboard. To test it you can add, for example, French "AZERTY" in system settings.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
CTRL_ACTIVE = 0x04 | 0x08


class _error(Exception):
pass
Expand Down Expand Up @@ -407,31 +411,37 @@ def get_event(self, block: bool = True) -> Event | None:
continue
return None

key = rec.Event.KeyEvent.uChar.UnicodeChar
key_event = rec.Event.KeyEvent
raw_key = key = key_event.uChar.UnicodeChar
Comment thread
eendebakpt marked this conversation as resolved.
Resolved

Uh oh!

There was an error while loading. Please reload this page.


if rec.Event.KeyEvent.uChar.UnicodeChar == "\r":
# Make enter make unix-like
if key == "\r":
# Make enter unix-like
return Event(evt="key", data="\n", raw=b"\n")
elif rec.Event.KeyEvent.wVirtualKeyCode == 8:
elif key_event.wVirtualKeyCode == 8:
# Turn backspace directly into the command
return Event(
evt="key",
data="backspace",
raw=rec.Event.KeyEvent.uChar.UnicodeChar,
)
elif rec.Event.KeyEvent.uChar.UnicodeChar == "\x00":
key = "backspace"
elif key == "\x00":
# Handle special keys like arrow keys and translate them into the appropriate command
code = VK_MAP.get(rec.Event.KeyEvent.wVirtualKeyCode)
if code:
return Event(
evt="key", data=code, raw=rec.Event.KeyEvent.uChar.UnicodeChar
)
key = VK_MAP.get(key_event.wVirtualKeyCode)
if key:
if key_event.dwControlKeyState & CTRL_ACTIVE:
key = f"ctrl {key}"
elif key_event.dwControlKeyState & ALT_ACTIVE:
# queue the key, return the meta command
self.event_queue.insert(0, Event(evt="key", data=key, raw=key))
return Event(evt="key", data="\033") # keymap.py uses this for meta
Comment thread
Comment on lines +431 to +432

@eendebakpt eendebakpt Jan 4, 2025

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

I don't know the answer. But why pass the ctrl modifier as a key f'ctrl {key}`, and the alt modifier using a special event?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@paulie4 paulie4 Jan 5, 2025

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Yeah, it took me a while to figure out what was going on in Lib\_pyrepl\keymap.py, cause the code is not very readable, but that's what it expects. If we wanted Ctrl and Alt to be treated in a similar way, we'd probably have to make some major edits to Lib\_pyrepl\keymap.py and Lib\_pyrepl\unix_eventqueue.py.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
return Event(evt="key", data=key, raw=key)
if block:
continue

return None

return Event(evt="key", data=key, raw=rec.Event.KeyEvent.uChar.UnicodeChar)
if key_event.dwControlKeyState & ALT_ACTIVE:
# queue the key, return the meta command
self.event_queue.insert(0, Event(evt="key", data=key, raw=raw_key))
return Event(evt="key", data="\033") # keymap.py uses this for meta
Comment thread
paulie4 marked this conversation as resolved.
Resolved

Uh oh!

There was an error while loading. Please reload this page.


return Event(evt="key", data=key, raw=raw_key)

def push_char(self, char: int | bytes) -> None:
"""
Expand Down
1 change: 1 addition & 0 deletions 1 Misc/NEWS.d/next/Library/2025-01-01-19-24-43.gh-issue-128388.8UdMz_.rst
Show comments
View file
Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix ``PyREPL`` on Windows to support more keybindings, like the :kbd:`Control-←` and :kbd:`Control-→` word-skipping keybindings and those with meta (i.e. :kbd:`Alt`), e.g. :kbd:`Alt-d` to ``kill-word`` or :kbd:`Alt-Backspace` ``backward-kill-word``.
Add this suggestion to a batch that can be applied as a single commit. This suggestion is invalid because no changes were made to the code. Suggestions cannot be applied while the pull request is closed. Suggestions cannot be applied while viewing a subset of changes. Only one suggestion per line can be applied in a batch. Add this suggestion to a batch that can be applied as a single commit. Applying suggestions on deleted lines is not supported. You must change the existing code in this line in order to create a valid suggestion. Outdated suggestions cannot be applied. This suggestion has been applied or marked resolved. Suggestions cannot be applied from pending reviews. Suggestions cannot be applied on multi-line comments. Suggestions cannot be applied while the pull request is queued to merge. Suggestion cannot be applied right now. Please check back later.
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.