Skip to content

Commit e36cb0e

Browse files
committed
Add pending() and flush() to BaseEventQueue
1 parent 46acb79 commit e36cb0e

1 file changed

Lines changed: 33 additions & 0 deletions

File tree

Lib/_pyrepl/base_eventqueue.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,39 @@ def empty(self) -> bool:
5454
"""
5555
return not self.events
5656

57+
def pending(self) -> bool:
58+
"""
59+
True when we have received the start of an escape/key sequence but
60+
are still waiting for further bytes to disambiguate it.
61+
62+
This is the case right after a byte (such as ESC) that our keymap
63+
knows only as a prefix of a longer sequence has been pushed, but
64+
before the rest of that sequence arrives. Consoles use this to
65+
decide whether the next read should block indefinitely or only for
66+
the escape timeout.
67+
"""
68+
return self.keymap is not self.compiled_keymap
69+
70+
def flush(self) -> None:
71+
"""
72+
Finalize any pending, incomplete input as discrete events.
73+
"""
74+
if self.keymap is self.compiled_keymap:
75+
# Nothing pending: either idle, or a complete key was already
76+
# emitted by ``push``.
77+
return
78+
buf = self.buf.take_bytes()
79+
self.keymap = self.compiled_keymap
80+
if buf and buf[0] == 27: # escape
81+
self.insert(Event('key', '\033', b'\033'))
82+
for _c in buf[1:]:
83+
self.push(_c)
84+
else:
85+
# Defensive: a pending prefix that does not start with ESC
86+
# (e.g. a partial multi-byte sequence). Emit it as text.
87+
data = bytes(buf).decode(self.encoding, 'replace')
88+
self.insert(Event('key', data, buf))
89+
5790
def insert(self, event: Event) -> None:
5891
"""
5992
Inserts an event into the queue.

0 commit comments

Comments
 (0)