fill3: Separate keypresses in input

- Stdin can contain more than one keypress when inputted quickly.
This commit is contained in:
Andrew Hamilton 2022-02-13 09:09:10 +10:00
parent a016a36f61
commit 2e3004cd13
2 changed files with 36 additions and 8 deletions

View file

@ -494,14 +494,29 @@ async def update_screen(screen_widget):
APPEARANCE_CHANGED_EVENT.clear()
def digest_terminal_input(input_str):
cursor = 0
result = []
for index, char in enumerate(input_str):
if cursor != index:
if char == terminal.ESC:
result.append(input_str[cursor:index])
cursor = index
elif ord(char) < 32:
result.extend([input_str[cursor:index], char])
cursor = index + 1
if cursor != index + 1:
result.append(input_str[cursor:index+1])
return result
@handle_exception
def on_terminal_input(screen_widget):
term_code = sys.stdin.read()
if term_code.startswith(terminal.MOUSE):
for part in term_code.split(terminal.MOUSE)[1:]:
screen_widget.on_mouse_input(part)
else:
return screen_widget.on_keyboard_input(term_code)
for part in digest_terminal_input(sys.stdin.read()):
if part.startswith(terminal.MOUSE):
screen_widget.on_mouse_input(part[3:])
else:
screen_widget.on_keyboard_input(part)
@contextlib.contextmanager
@ -513,7 +528,7 @@ def signal_handler(loop, signal_, func):
loop.remove_signal_handler(signal_)
async def tui(title, screen_widget):
async def tui(title, screen_widget, input_handler=on_terminal_input):
global APPEARANCE_CHANGED_EVENT
global SHUTDOWN_EVENT
APPEARANCE_CHANGED_EVENT = asyncio.Event()
@ -525,7 +540,7 @@ async def tui(title, screen_widget):
terminal.alternate_buffer(), terminal.raw(), terminal.mouse_tracking()):
update_task = asyncio.create_task(update_screen(screen_widget))
try:
loop.add_reader(sys.stdin, on_terminal_input, screen_widget)
loop.add_reader(sys.stdin, input_handler, screen_widget)
try:
await SHUTDOWN_EVENT.wait()
finally: