diff options
author | Y5 <124019959+y5c4l3@users.noreply.github.com> | 2025-02-23 19:30:33 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-23 19:30:33 (GMT) |
commit | a65366ed879a3d9f27cbcc811ed2e05ad1a2af06 (patch) | |
tree | 24446b1acaf844ba65a606b449b7feed93a50424 /Lib/_pyrepl/unix_eventqueue.py | |
parent | 25a7ddf2efeaf77bcf94dbfca28ba3a6fe9ab57e (diff) | |
download | cpython-a65366ed879a3d9f27cbcc811ed2e05ad1a2af06.zip cpython-a65366ed879a3d9f27cbcc811ed2e05ad1a2af06.tar.gz cpython-a65366ed879a3d9f27cbcc811ed2e05ad1a2af06.tar.bz2 |
gh-124096: Enable REPL virtual terminal support on Windows (#124119)
To support virtual terminal mode in Windows PYREPL, we need a scanner
to read over the supported escaped VT sequences.
Windows REPL input was using virtual key mode, which does not support
terminal escape sequences. This patch calls `SetConsoleMode` properly
when initializing and send sequences to enable bracketed-paste modes
to support verbatim copy-and-paste.
Signed-off-by: y5c4l3 <y5c4l3@proton.me>
Co-authored-by: Petr Viktorin <encukou@gmail.com>
Co-authored-by: Pablo Galindo Salgado <Pablogsal@gmail.com>
Co-authored-by: Dustin L. Howett <dustin@howett.net>
Co-authored-by: wheeheee <104880306+wheeheee@users.noreply.github.com>
Diffstat (limited to 'Lib/_pyrepl/unix_eventqueue.py')
-rw-r--r-- | Lib/_pyrepl/unix_eventqueue.py | 86 |
1 files changed, 5 insertions, 81 deletions
diff --git a/Lib/_pyrepl/unix_eventqueue.py b/Lib/_pyrepl/unix_eventqueue.py index 70cfade..29b3e9d 100644 --- a/Lib/_pyrepl/unix_eventqueue.py +++ b/Lib/_pyrepl/unix_eventqueue.py @@ -18,12 +18,9 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -from collections import deque - -from . import keymap -from .console import Event from . import curses from .trace import trace +from .base_eventqueue import BaseEventQueue from termios import tcgetattr, VERASE import os @@ -70,83 +67,10 @@ def get_terminal_keycodes() -> dict[bytes, str]: keycodes.update(CTRL_ARROW_KEYCODES) return keycodes -class EventQueue: +class EventQueue(BaseEventQueue): def __init__(self, fd: int, encoding: str) -> None: - self.keycodes = get_terminal_keycodes() + keycodes = get_terminal_keycodes() if os.isatty(fd): backspace = tcgetattr(fd)[6][VERASE] - self.keycodes[backspace] = "backspace" - self.compiled_keymap = keymap.compile_keymap(self.keycodes) - self.keymap = self.compiled_keymap - trace("keymap {k!r}", k=self.keymap) - self.encoding = encoding - self.events: deque[Event] = deque() - self.buf = bytearray() - - def get(self) -> Event | None: - """ - Retrieves the next event from the queue. - """ - if self.events: - return self.events.popleft() - else: - return None - - def empty(self) -> bool: - """ - Checks if the queue is empty. - """ - return not self.events - - def flush_buf(self) -> bytearray: - """ - Flushes the buffer and returns its contents. - """ - old = self.buf - self.buf = bytearray() - return old - - def insert(self, event: Event) -> None: - """ - Inserts an event into the queue. - """ - trace('added event {event}', event=event) - self.events.append(event) - - def push(self, char: int | bytes) -> None: - """ - Processes a character by updating the buffer and handling special key mappings. - """ - ord_char = char if isinstance(char, int) else ord(char) - char = bytes(bytearray((ord_char,))) - self.buf.append(ord_char) - if char in self.keymap: - if self.keymap is self.compiled_keymap: - #sanity check, buffer is empty when a special key comes - assert len(self.buf) == 1 - k = self.keymap[char] - trace('found map {k!r}', k=k) - if isinstance(k, dict): - self.keymap = k - else: - self.insert(Event('key', k, self.flush_buf())) - self.keymap = self.compiled_keymap - - elif self.buf and self.buf[0] == 27: # escape - # escape sequence not recognized by our keymap: propagate it - # outside so that i can be recognized as an M-... key (see also - # the docstring in keymap.py - trace('unrecognized escape sequence, propagating...') - self.keymap = self.compiled_keymap - self.insert(Event('key', '\033', bytearray(b'\033'))) - for _c in self.flush_buf()[1:]: - self.push(_c) - - else: - try: - decoded = bytes(self.buf).decode(self.encoding) - except UnicodeError: - return - else: - self.insert(Event('key', decoded, self.flush_buf())) - self.keymap = self.compiled_keymap + keycodes[backspace] = "backspace" + BaseEventQueue.__init__(self, encoding, keycodes) |