home · contact · privacy
Handle even more edge cases for pasting. master
authorChristian Heller <c.heller@plomlompom.de>
Fri, 25 Jul 2025 07:24:56 +0000 (09:24 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Fri, 25 Jul 2025 07:24:56 +0000 (09:24 +0200)
ircplom/tui.py

index 49c6acb106ff99f529506acae690e283e221a787..0e3df99d0ba16020af2e94d07631357e174cb137 100644 (file)
@@ -615,12 +615,25 @@ class Terminal(QueueMixin):
                 while (new_chars := self._blessed.inkey(timeout=0, esc_delay=0
                                                         ).encode('utf-8')):
                     chars += new_chars
-                if chars[:len(_OSC52_PREFIX)] == _OSC52_PREFIX:
+                len_prefix = len(_OSC52_PREFIX)
+                if chars[:len_prefix] == _OSC52_PREFIX:
                     to_yield = _B64_PREFIX[:]
-                    # mostly adds nothing, but sometimes swallowed first char
-                    to_yield += chars[len(_OSC52_PREFIX):].decode('utf-8')
-                    while (gotch := self._blessed.getch()) != _PASTE_DELIMITER:
-                        to_yield += gotch
+                    # sometimes, prev .inkey got some or all (including paste
+                    # delimiter) of the paste code (maybe even more), so first
+                    # harvest potential remains of chars post prefix …
+                    caught_delimiter = False
+                    post_prefix_str = chars[len_prefix:].decode('utf-8')
+                    for idx, c in enumerate(post_prefix_str):
+                        if c == _PASTE_DELIMITER:
+                            caught_delimiter = True
+                            if (remains := post_prefix_str[idx + 1:]):
+                                self._blessed.ungetch(remains)
+                            break
+                        to_yield += c
+                    # … before .getch() further until expected delimiter found
+                    if not caught_delimiter:
+                        while (c := self._blessed.getch()) != _PASTE_DELIMITER:
+                            to_yield += c
                 else:
                     to_yield = 'esc:' + ':'.join([str(int(b)) for b in chars])
             yield _KeyboardEvent(to_yield) if to_yield else None