summaryrefslogtreecommitdiffstats
path: root/Lib/_pyrepl/unix_eventqueue.py
diff options
context:
space:
mode:
authorY5 <124019959+y5c4l3@users.noreply.github.com>2025-02-23 19:30:33 (GMT)
committerGitHub <noreply@github.com>2025-02-23 19:30:33 (GMT)
commita65366ed879a3d9f27cbcc811ed2e05ad1a2af06 (patch)
tree24446b1acaf844ba65a606b449b7feed93a50424 /Lib/_pyrepl/unix_eventqueue.py
parent25a7ddf2efeaf77bcf94dbfca28ba3a6fe9ab57e (diff)
downloadcpython-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.py86
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)