clipboard.py
101 lines
| 3.0 KiB
| text/x-python
|
PythonLexer
Robert Kern
|
r1841 | """ Utilities for accessing the platform's clipboard. | ||
""" | ||||
Artur Svistunov
|
r27660 | import os | ||
Robert Kern
|
r1841 | import subprocess | ||
Brian Granger
|
r2205 | from IPython.core.error import TryNext | ||
Jörgen Stenarson
|
r8308 | import IPython.utils.py3compat as py3compat | ||
Robert Kern
|
r1841 | |||
Artur Svistunov
|
r27660 | |||
Thomas Kluyver
|
r13426 | class ClipboardEmpty(ValueError): | ||
pass | ||||
Artur Svistunov
|
r27660 | |||
Robert Kern
|
r1841 | def win32_clipboard_get(): | ||
""" Get the current clipboard's text on Windows. | ||||
Requires Mark Hammond's pywin32 extensions. | ||||
""" | ||||
try: | ||||
import win32clipboard | ||||
Ram Rachum
|
r25833 | except ImportError as e: | ||
Bradley M. Froehle
|
r7334 | raise TryNext("Getting text from the clipboard requires the pywin32 " | ||
Ram Rachum
|
r25833 | "extensions: http://sourceforge.net/projects/pywin32/") from e | ||
Bernardo B. Marques
|
r4872 | win32clipboard.OpenClipboard() | ||
Thomas Kluyver
|
r13426 | try: | ||
text = win32clipboard.GetClipboardData(win32clipboard.CF_UNICODETEXT) | ||||
Thomas Kluyver
|
r16764 | except (TypeError, win32clipboard.error): | ||
Thomas Kluyver
|
r13426 | try: | ||
text = win32clipboard.GetClipboardData(win32clipboard.CF_TEXT) | ||||
text = py3compat.cast_unicode(text, py3compat.DEFAULT_ENCODING) | ||||
Ram Rachum
|
r25833 | except (TypeError, win32clipboard.error) as e: | ||
raise ClipboardEmpty from e | ||||
Thomas Kluyver
|
r13426 | finally: | ||
win32clipboard.CloseClipboard() | ||||
Robert Kern
|
r1841 | return text | ||
Artur Svistunov
|
r27660 | |||
Matthias Bussonnier
|
r25288 | def osx_clipboard_get() -> str: | ||
Robert Kern
|
r1841 | """ Get the clipboard's text on OS X. | ||
""" | ||||
p = subprocess.Popen(['pbpaste', '-Prefer', 'ascii'], | ||||
stdout=subprocess.PIPE) | ||||
Matthias Bussonnier
|
r25288 | bytes_, stderr = p.communicate() | ||
Robert Kern
|
r1841 | # Text comes in with old Mac \r line endings. Change them to \n. | ||
Matthias Bussonnier
|
r25288 | bytes_ = bytes_.replace(b'\r', b'\n') | ||
text = py3compat.decode(bytes_) | ||||
Robert Kern
|
r1841 | return text | ||
Artur Svistunov
|
r27660 | |||
Robert Kern
|
r1841 | def tkinter_clipboard_get(): | ||
""" Get the clipboard's text using Tkinter. | ||||
This is the default on systems that are not Windows or OS X. It may | ||||
interfere with other UI toolkits and should be replaced with an | ||||
implementation that uses that toolkit. | ||||
""" | ||||
try: | ||||
Srinivas Reddy Thatiparthy
|
r23056 | from tkinter import Tk, TclError | ||
Ram Rachum
|
r25833 | except ImportError as e: | ||
raise TryNext("Getting text from the clipboard on this platform requires tkinter.") from e | ||||
Srinivas Reddy Thatiparthy
|
r23056 | |||
Thomas Kluyver
|
r13354 | root = Tk() | ||
Robert Kern
|
r1841 | root.withdraw() | ||
Thomas Kluyver
|
r13426 | try: | ||
text = root.clipboard_get() | ||||
Ram Rachum
|
r25833 | except TclError as e: | ||
raise ClipboardEmpty from e | ||||
Thomas Kluyver
|
r13426 | finally: | ||
root.destroy() | ||||
Jörgen Stenarson
|
r8305 | text = py3compat.cast_unicode(text, py3compat.DEFAULT_ENCODING) | ||
Robert Kern
|
r1841 | return text | ||
Artur Svistunov
|
r27519 | def wayland_clipboard_get(): | ||
"""Get the clipboard's text under Wayland using wl-paste command. | ||||
This requires Wayland and wl-clipboard installed and running. | ||||
""" | ||||
if os.environ.get("XDG_SESSION_TYPE") != "wayland": | ||||
raise TryNext("wayland is not detected") | ||||
try: | ||||
with subprocess.Popen(["wl-paste"], stdout=subprocess.PIPE) as p: | ||||
Artur Svistunov
|
r27660 | raw, err = p.communicate() | ||
if p.wait(): | ||||
raise TryNext(err) | ||||
Artur Svistunov
|
r27519 | except FileNotFoundError as e: | ||
Artur Svistunov
|
r27660 | raise TryNext( | ||
Artur Svistunov
|
r27519 | "Getting text from the clipboard under Wayland requires the wl-clipboard " | ||
"extension: https://github.com/bugaevc/wl-clipboard" | ||||
) from e | ||||
Artur Svistunov
|
r27660 | if not raw: | ||
raise ClipboardEmpty | ||||
Artur Svistunov
|
r27519 | try: | ||
text = py3compat.decode(raw) | ||||
except UnicodeDecodeError as e: | ||||
raise ClipboardEmpty from e | ||||
return text | ||||