Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions aider/copypaste.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@ def __init__(self, io, verbose=False):
def start(self):
"""Start watching clipboard for changes"""
self.stop_event = threading.Event()
self.last_clipboard = pyperclip.paste()
# guard against non-UTF8 bytes in the clipboard
try:
self.last_clipboard = pyperclip.paste()
except UnicodeDecodeError:
self.last_clipboard = ""

def watch_clipboard():
while not self.stop_event.is_set():
try:
current = pyperclip.paste()
current = self._safe_paste()
if current != self.last_clipboard:
self.last_clipboard = current
self.io.interrupt_input()
Expand Down Expand Up @@ -51,6 +55,23 @@ def stop(self):
self.watcher_thread = None
self.stop_event = None

def _safe_paste(self) -> str:
"""
Attempt a normal pyperclip.paste(); if it raises a UnicodeDecodeError
fall back to a raw xclip call and replace invalid bytes.
"""
try:
return pyperclip.paste()
except UnicodeDecodeError:
# linux fallback via xclip
import subprocess, shlex
try:
raw = subprocess.check_output(shlex.split("xclip -selection clipboard -o"))
# replace any invalid bytes with �
return raw.decode("utf-8", errors="replace")
except Exception:
return ""


def main():
"""Example usage of the clipboard watcher"""
Expand Down