home · contact · privacy
Improve paste code.
authorChristian Heller <c.heller@plomlompom.de>
Sun, 5 Oct 2025 00:45:25 +0000 (02:45 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Sun, 5 Oct 2025 00:45:25 +0000 (02:45 +0200)
src/ircplom/tui_base.py

index d910ccbd5bbaf583dc3ba3c1d8046e5e7d49da88..b3b016de9d175a1bcdbef1688867189a27865d49 100644 (file)
@@ -766,23 +766,30 @@ class Terminal(QueueMixin, TerminalInterface):
                     chars += new_chars
                 len_prefix = len(_OSC52_PREFIX)
                 if chars[:len_prefix] == _OSC52_PREFIX:
-                    to_yield = _B64_PREFIX[:]
-                    # 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:
+                    # previous .inkey may have got some, all, or even more than
+                    # the paste code: if we find _PASTE_DELIMITER in what's
+                    # collected already, we use what precedes it, and ungetch()
+                    # what's beyond; otherwise, we getch() until we get to it
+                    to_yield = chars[len_prefix:].decode('utf-8')
+                    if _PASTE_DELIMITER in to_yield:
+                        idx = to_yield.index(_PASTE_DELIMITER)
+                        to_yield, remains = to_yield[:idx], to_yield[idx+1:]
+                        if remains:
+                            self._blessed.ungetch(remains)
+                    else:
                         while (c := self._blessed.getch()) != _PASTE_DELIMITER:
                             to_yield += c
+                    # input hiccups may prefix actual paste code with ESC-char
+                    # prefixed OSC52_PREFIX or "OP" sequences -> delete those
+                    while True:
+                        garbage_found = False
+                        for garbage in (_OSC52_PREFIX.decode('utf-8'), 'OP'):
+                            while to_yield.startswith('\x1b' + garbage):
+                                garbage_found = True
+                                to_yield = to_yield[len(garbage)+1:]
+                        if not garbage_found:
+                            break
+                    to_yield = _B64_PREFIX + to_yield
                 else:
                     to_yield = 'esc:' + ':'.join([str(int(b)) for b in chars])
             yield (TuiEvent.affector('handle_keyboard_event'