mirror of
https://github.com/python/cpython.git
synced 2025-09-24 17:33:29 +00:00
GH-130328: Speedup pasting in legacy console on Windows (gh-133728)
This commit is contained in:
parent
2fd09b0110
commit
91b48868a8
5 changed files with 26 additions and 12 deletions
|
@ -370,6 +370,13 @@ class self_insert(EditCommand):
|
||||||
r = self.reader
|
r = self.reader
|
||||||
text = self.event * r.get_arg()
|
text = self.event * r.get_arg()
|
||||||
r.insert(text)
|
r.insert(text)
|
||||||
|
if r.paste_mode:
|
||||||
|
data = ""
|
||||||
|
ev = r.console.getpending()
|
||||||
|
data += ev.data
|
||||||
|
if data:
|
||||||
|
r.insert(data)
|
||||||
|
r.last_refresh_cache.invalidated = True
|
||||||
|
|
||||||
|
|
||||||
class insert_nl(EditCommand):
|
class insert_nl(EditCommand):
|
||||||
|
@ -484,7 +491,6 @@ class perform_bracketed_paste(Command):
|
||||||
data = ""
|
data = ""
|
||||||
start = time.time()
|
start = time.time()
|
||||||
while done not in data:
|
while done not in data:
|
||||||
self.reader.console.wait(100)
|
|
||||||
ev = self.reader.console.getpending()
|
ev = self.reader.console.getpending()
|
||||||
data += ev.data
|
data += ev.data
|
||||||
trace(
|
trace(
|
||||||
|
|
|
@ -419,10 +419,7 @@ class WindowsConsole(Console):
|
||||||
|
|
||||||
return info.srWindow.Bottom # type: ignore[no-any-return]
|
return info.srWindow.Bottom # type: ignore[no-any-return]
|
||||||
|
|
||||||
def _read_input(self, block: bool = True) -> INPUT_RECORD | None:
|
def _read_input(self) -> INPUT_RECORD | None:
|
||||||
if not block and not self.wait(timeout=0):
|
|
||||||
return None
|
|
||||||
|
|
||||||
rec = INPUT_RECORD()
|
rec = INPUT_RECORD()
|
||||||
read = DWORD()
|
read = DWORD()
|
||||||
if not ReadConsoleInput(InHandle, rec, 1, read):
|
if not ReadConsoleInput(InHandle, rec, 1, read):
|
||||||
|
@ -431,14 +428,10 @@ class WindowsConsole(Console):
|
||||||
return rec
|
return rec
|
||||||
|
|
||||||
def _read_input_bulk(
|
def _read_input_bulk(
|
||||||
self, block: bool, n: int
|
self, n: int
|
||||||
) -> tuple[ctypes.Array[INPUT_RECORD], int]:
|
) -> tuple[ctypes.Array[INPUT_RECORD], int]:
|
||||||
rec = (n * INPUT_RECORD)()
|
rec = (n * INPUT_RECORD)()
|
||||||
read = DWORD()
|
read = DWORD()
|
||||||
|
|
||||||
if not block and not self.wait(timeout=0):
|
|
||||||
return rec, 0
|
|
||||||
|
|
||||||
if not ReadConsoleInput(InHandle, rec, n, read):
|
if not ReadConsoleInput(InHandle, rec, n, read):
|
||||||
raise WinError(GetLastError())
|
raise WinError(GetLastError())
|
||||||
|
|
||||||
|
@ -449,8 +442,11 @@ class WindowsConsole(Console):
|
||||||
and there is no event pending, otherwise waits for the
|
and there is no event pending, otherwise waits for the
|
||||||
completion of an event."""
|
completion of an event."""
|
||||||
|
|
||||||
|
if not block and not self.wait(timeout=0):
|
||||||
|
return None
|
||||||
|
|
||||||
while self.event_queue.empty():
|
while self.event_queue.empty():
|
||||||
rec = self._read_input(block)
|
rec = self._read_input()
|
||||||
if rec is None:
|
if rec is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -551,12 +547,20 @@ class WindowsConsole(Console):
|
||||||
if e2:
|
if e2:
|
||||||
e.data += e2.data
|
e.data += e2.data
|
||||||
|
|
||||||
recs, rec_count = self._read_input_bulk(False, 1024)
|
recs, rec_count = self._read_input_bulk(1024)
|
||||||
for i in range(rec_count):
|
for i in range(rec_count):
|
||||||
rec = recs[i]
|
rec = recs[i]
|
||||||
|
# In case of a legacy console, we do not only receive a keydown
|
||||||
|
# event, but also a keyup event - and for uppercase letters
|
||||||
|
# an additional SHIFT_PRESSED event.
|
||||||
if rec and rec.EventType == KEY_EVENT:
|
if rec and rec.EventType == KEY_EVENT:
|
||||||
key_event = rec.Event.KeyEvent
|
key_event = rec.Event.KeyEvent
|
||||||
|
if not key_event.bKeyDown:
|
||||||
|
continue
|
||||||
ch = key_event.uChar.UnicodeChar
|
ch = key_event.uChar.UnicodeChar
|
||||||
|
if ch == "\x00":
|
||||||
|
# ignore SHIFT_PRESSED and special keys
|
||||||
|
continue
|
||||||
if ch == "\r":
|
if ch == "\r":
|
||||||
ch += "\n"
|
ch += "\n"
|
||||||
e.data += ch
|
e.data += ch
|
||||||
|
|
|
@ -20,6 +20,7 @@ except ImportError:
|
||||||
def unix_console(events, **kwargs):
|
def unix_console(events, **kwargs):
|
||||||
console = UnixConsole()
|
console = UnixConsole()
|
||||||
console.get_event = MagicMock(side_effect=events)
|
console.get_event = MagicMock(side_effect=events)
|
||||||
|
console.getpending = MagicMock(return_value=Event("key", ""))
|
||||||
|
|
||||||
height = kwargs.get("height", 25)
|
height = kwargs.get("height", 25)
|
||||||
width = kwargs.get("width", 80)
|
width = kwargs.get("width", 80)
|
||||||
|
|
|
@ -35,6 +35,7 @@ class WindowsConsoleTests(TestCase):
|
||||||
def console(self, events, **kwargs) -> Console:
|
def console(self, events, **kwargs) -> Console:
|
||||||
console = WindowsConsole()
|
console = WindowsConsole()
|
||||||
console.get_event = MagicMock(side_effect=events)
|
console.get_event = MagicMock(side_effect=events)
|
||||||
|
console.getpending = MagicMock(return_value=Event("key", ""))
|
||||||
console.wait = MagicMock()
|
console.wait = MagicMock()
|
||||||
console._scroll = MagicMock()
|
console._scroll = MagicMock()
|
||||||
console._hide_cursor = MagicMock()
|
console._hide_cursor = MagicMock()
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Speedup pasting in ``PyREPL`` on Windows in a legacy console. Patch by Chris
|
||||||
|
Eibl.
|
Loading…
Add table
Add a link
Reference in a new issue