Skip to content

Commit 617ef9e

Browse files
Prevent several arrow keys in a paste event from causing problems
Two parts: * last character of things like "KEY_LEFT" was being added when rendering got slow enough that holding down the key resulted in two keypress events getting queued up so that they ended up in a paste event. Stopped code from sanitizing control sequences by taking the last character, just throw out events instead. * To prevent cursor from being stuck in the above case, if all events in a paste event are the same, and they're all control characters, process just one of them.
1 parent aa2d90c commit 617ef9e

File tree

1 file changed

+21
-1
lines changed

1 file changed

+21
-1
lines changed

bpython/curtsiesfrontend/repl.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,9 @@ def process_event(self, e):
277277
self.update_completion()
278278
return
279279
elif isinstance(e, events.PasteEvent):
280+
ctrl_char = compress_paste_event(e)
281+
if ctrl_char is not None:
282+
return self.process_event(ctrl_char)
280283
with self.in_paste_mode():
281284
for ee in e.events:
282285
self.process_simple_event(ee)
@@ -416,7 +419,8 @@ def process_simple_event(self, e):
416419
elif isinstance(e, events.Event):
417420
pass # ignore events
418421
else:
419-
self.add_normal_character(e if len(e) == 1 else e[-1]) #strip control seq
422+
if len(e) == 1:
423+
self.add_normal_character(e if len(e) == 1 else e[-1]) #strip control seq
420424

421425
def send_current_block_to_external_editor(self, filename=None):
422426
text = self.send_to_external_editor(self.get_current_block())
@@ -919,6 +923,22 @@ def getstdout(self):
919923
s = '\n'.join([x.s if isinstance(x, FmtStr) else x for x in lines]
920924
) if lines else ''
921925
return s
926+
927+
def compress_paste_event(paste_event):
928+
"""If all events in a paste event are identical and not simple characters, returns one of them
929+
930+
Useful for when the UI is running so slowly that repeated keypresses end up in a paste event.
931+
If we value not getting delayed and assume the user is holding down a key to produce such frequent
932+
key events, it makes sense to drop some of the events.
933+
"""
934+
if not all(paste_event.events[0] == e for e in paste_event.events):
935+
return None
936+
event = paste_event.events[0]
937+
if len(event) > 1:# basically "is there a special curses names for this key?"
938+
return event
939+
else:
940+
return None
941+
922942
def simple_repl():
923943
refreshes = []
924944
def request_refresh():

0 commit comments

Comments
 (0)