• R/O
  • SSH

SublimeFCFPlugin: コミット

Plugin for sublime text editor that automatically creates templates, packages, and modules


コミットメタ情報

リビジョンe090a13165e2bc9314f7556428af125317111825 (tree)
日時2021-04-21 02:15:52
作者Vladimir Markin <v.o.markin221@gmai...>
コミッターVladimir Markin

ログメッセージ

initialize

変更サマリ

差分

diff -r 000000000000 -r e090a13165e2 Side Bar.sublime-menu
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Side Bar.sublime-menu Tue Apr 20 20:15:52 2021 +0300
@@ -0,0 +1,26 @@
1+[
2+ {
3+ "caption": "FCF",
4+ "id": "fcf",
5+ "children":
6+ [
7+ { "command": "fcf_new_template", "caption": "New template", "args":{ "template": "template", "files": [], "dirs": []} },
8+ { "command": "fcf_new_template", "caption": "New template file", "args":{ "template": "template-file", "files": [], "dirs": []} },
9+ { "command": "fcf_new_template", "caption": "New wrapper file", "args":{ "template": "wrapper", "files": [], "dirs": []} },
10+ { "command": "fcf_new_template", "caption": "New hooks file", "args":{ "template": "hooks", "files": [], "dirs": []} },
11+ { "command": "fcf_new_template", "caption": "New module file", "args":{ "template": "module", "files": [], "dirs": []} },
12+ { "command": "fcf_new_template", "caption": "New receive file", "args":{ "template": "receive", "files": [], "dirs": []} },
13+ { "command": "fcf_new_template", "caption": "New projection file", "args":{ "template": "projection", "files": [], "dirs": []} },
14+ { "command": "fcf_new_template", "caption": "New package", "args":{ "template": "package", "files": [], "dirs": []} },
15+
16+
17+ ]
18+ },
19+ {
20+ "caption": "FCF: Copy file path",
21+ "id": "fcfgetpath",
22+ "caption": "Copy file path",
23+ "command": "fcf_get_path",
24+ "args": { "files": [], "dirs": []}
25+ }
26+]
\ No newline at end of file
diff -r 000000000000 -r e090a13165e2 SideBar.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SideBar.py Tue Apr 20 20:15:52 2021 +0300
@@ -0,0 +1,67 @@
1+import sublime
2+import sublime_plugin
3+import os
4+import sys
5+import subprocess
6+__dir__ = os.path.dirname(os.path.realpath(__file__));
7+sys.path.insert(1, __dir__)
8+import pyperclip
9+
10+
11+class FcfGetPathCommand(sublime_plugin.TextCommand):
12+ def run(self, edit, **args):
13+ path = None
14+
15+ try:
16+ if len(args["dirs"]) != 0:
17+ path = args["dirs"][0]
18+ elif len(args["files"]) != 0:
19+ path = args["files"][0]
20+ except:
21+ return
22+
23+ if path == None:
24+ return
25+ pyperclip.copy(path)
26+
27+
28+
29+
30+class FcfNewTemplateCommand(sublime_plugin.TextCommand):
31+ directory = None
32+ args = None
33+ template = None
34+
35+ def run(self, edit, **args):
36+ try:
37+ self.directory = ""
38+ self.args = {"file": ""}
39+ self.template = args["template"]
40+ if len(args["dirs"]) != 0:
41+ self.directory = args["dirs"][0]
42+ elif len(args["files"]) != 0:
43+ self.directory = os.path.dirname(args["files"][0])
44+ except:
45+ return;
46+
47+ if self.directory == None:
48+ return
49+
50+
51+ self.view.window().show_input_panel("Enter file name:", "",
52+ self.onDoneInput, None, None)
53+
54+ def onDoneInput(self, inputString):
55+ self.args["file"] = inputString.strip();
56+ self.action();
57+
58+
59+ def action(self):
60+ try:
61+ if len(self.directory) == 0:
62+ return
63+ if len(self.args["file"]) == 0:
64+ return
65+ subprocess.Popen(["fcfmngr", "c", self.template, self.args["file"]], cwd=self.directory)
66+ except e:
67+ print(e)
diff -r 000000000000 -r e090a13165e2 pyperclip-1.8.0-py3.8.egg-info/PKG-INFO
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pyperclip-1.8.0-py3.8.egg-info/PKG-INFO Tue Apr 20 20:15:52 2021 +0300
@@ -0,0 +1,54 @@
1+Metadata-Version: 1.1
2+Name: pyperclip
3+Version: 1.8.0
4+Summary: A cross-platform clipboard module for Python. (Only handles plain text for now.)
5+Home-page: https://github.com/asweigart/pyperclip
6+Author: Al Sweigart
7+Author-email: al@inventwithpython.com
8+License: BSD
9+Description: Pyperclip is a cross-platform Python module for copy and paste clipboard functions. It works with Python 2 and 3.
10+
11+ `pip install pyperclip`
12+
13+ Al Sweigart al@inventwithpython.com
14+ BSD License
15+
16+ Example Usage
17+ =============
18+
19+ >>> import pyperclip
20+ >>> pyperclip.copy('The text to be copied to the clipboard.')
21+ >>> pyperclip.paste()
22+ 'The text to be copied to the clipboard.'
23+
24+
25+ Currently only handles plaintext.
26+
27+ On Windows, no additional modules are needed.
28+
29+ On Mac, this module makes use of the pbcopy and pbpaste commands, which should come with the os.
30+
31+ On Linux, this module makes use of the xclip or xsel commands, which should come with the os. Otherwise run "sudo apt-get install xclip" or "sudo apt-get install xsel" (Note: xsel does not always seem to work.)
32+
33+ Otherwise on Linux, you will need the gtk or PyQt4 modules installed.
34+
35+Keywords: clipboard copy paste clip xsel xclip
36+Platform: UNKNOWN
37+Classifier: Development Status :: 5 - Production/Stable
38+Classifier: Environment :: Win32 (MS Windows)
39+Classifier: Environment :: X11 Applications
40+Classifier: Environment :: MacOS X
41+Classifier: Intended Audience :: Developers
42+Classifier: License :: OSI Approved :: BSD License
43+Classifier: Operating System :: OS Independent
44+Classifier: Programming Language :: Python
45+Classifier: Programming Language :: Python :: 2
46+Classifier: Programming Language :: Python :: 2.6
47+Classifier: Programming Language :: Python :: 2.7
48+Classifier: Programming Language :: Python :: 3
49+Classifier: Programming Language :: Python :: 3.1
50+Classifier: Programming Language :: Python :: 3.2
51+Classifier: Programming Language :: Python :: 3.3
52+Classifier: Programming Language :: Python :: 3.4
53+Classifier: Programming Language :: Python :: 3.5
54+Classifier: Programming Language :: Python :: 3.6
diff -r 000000000000 -r e090a13165e2 pyperclip-1.8.0-py3.8.egg-info/SOURCES.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pyperclip-1.8.0-py3.8.egg-info/SOURCES.txt Tue Apr 20 20:15:52 2021 +0300
@@ -0,0 +1,15 @@
1+MANIFEST.in
2+README.md
3+setup.cfg
4+setup.py
5+docs/Makefile
6+docs/conf.py
7+docs/index.rst
8+docs/make.bat
9+src/pyperclip/__init__.py
10+src/pyperclip/__main__.py
11+src/pyperclip.egg-info/PKG-INFO
12+src/pyperclip.egg-info/SOURCES.txt
13+src/pyperclip.egg-info/dependency_links.txt
14+src/pyperclip.egg-info/top_level.txt
15+tests/test_pyperclip.py
\ No newline at end of file
diff -r 000000000000 -r e090a13165e2 pyperclip-1.8.0-py3.8.egg-info/dependency_links.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pyperclip-1.8.0-py3.8.egg-info/dependency_links.txt Tue Apr 20 20:15:52 2021 +0300
@@ -0,0 +1,1 @@
1+
diff -r 000000000000 -r e090a13165e2 pyperclip-1.8.0-py3.8.egg-info/installed-files.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pyperclip-1.8.0-py3.8.egg-info/installed-files.txt Tue Apr 20 20:15:52 2021 +0300
@@ -0,0 +1,8 @@
1+../pyperclip/__init__.py
2+../pyperclip/__main__.py
3+../pyperclip/__pycache__/__init__.cpython-38.pyc
4+../pyperclip/__pycache__/__main__.cpython-38.pyc
5+PKG-INFO
6+SOURCES.txt
7+dependency_links.txt
8+top_level.txt
diff -r 000000000000 -r e090a13165e2 pyperclip-1.8.0-py3.8.egg-info/top_level.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pyperclip-1.8.0-py3.8.egg-info/top_level.txt Tue Apr 20 20:15:52 2021 +0300
@@ -0,0 +1,1 @@
1+pyperclip
diff -r 000000000000 -r e090a13165e2 pyperclip/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pyperclip/__init__.py Tue Apr 20 20:15:52 2021 +0300
@@ -0,0 +1,694 @@
1+"""
2+Pyperclip
3+
4+A cross-platform clipboard module for Python, with copy & paste functions for plain text.
5+By Al Sweigart al@inventwithpython.com
6+BSD License
7+
8+Usage:
9+ import pyperclip
10+ pyperclip.copy('The text to be copied to the clipboard.')
11+ spam = pyperclip.paste()
12+
13+ if not pyperclip.is_available():
14+ print("Copy functionality unavailable!")
15+
16+On Windows, no additional modules are needed.
17+On Mac, the pyobjc module is used, falling back to the pbcopy and pbpaste cli
18+ commands. (These commands should come with OS X.).
19+On Linux, install xclip or xsel via package manager. For example, in Debian:
20+ sudo apt-get install xclip
21+ sudo apt-get install xsel
22+
23+Otherwise on Linux, you will need the gtk or PyQt5/PyQt4 modules installed.
24+
25+gtk and PyQt4 modules are not available for Python 3,
26+and this module does not work with PyGObject yet.
27+
28+Note: There seems to be a way to get gtk on Python 3, according to:
29+ https://askubuntu.com/questions/697397/python3-is-not-supporting-gtk-module
30+
31+Cygwin is currently not supported.
32+
33+Security Note: This module runs programs with these names:
34+ - which
35+ - where
36+ - pbcopy
37+ - pbpaste
38+ - xclip
39+ - xsel
40+ - klipper
41+ - qdbus
42+A malicious user could rename or add programs with these names, tricking
43+Pyperclip into running them with whatever permissions the Python process has.
44+
45+"""
46+__version__ = '1.8.0'
47+
48+import contextlib
49+import ctypes
50+import os
51+import platform
52+import subprocess
53+import sys
54+import time
55+import warnings
56+
57+from ctypes import c_size_t, sizeof, c_wchar_p, get_errno, c_wchar
58+
59+
60+# `import PyQt4` sys.exit()s if DISPLAY is not in the environment.
61+# Thus, we need to detect the presence of $DISPLAY manually
62+# and not load PyQt4 if it is absent.
63+HAS_DISPLAY = os.getenv("DISPLAY", False)
64+
65+EXCEPT_MSG = """
66+ Pyperclip could not find a copy/paste mechanism for your system.
67+ For more information, please visit https://pyperclip.readthedocs.io/en/latest/index.html#not-implemented-error """
68+
69+PY2 = sys.version_info[0] == 2
70+
71+STR_OR_UNICODE = unicode if PY2 else str # For paste(): Python 3 uses str, Python 2 uses unicode.
72+
73+ENCODING = 'utf-8'
74+
75+# The "which" unix command finds where a command is.
76+if platform.system() == 'Windows':
77+ WHICH_CMD = 'where'
78+else:
79+ WHICH_CMD = 'which'
80+
81+def _executable_exists(name):
82+ return subprocess.call([WHICH_CMD, name],
83+ stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0
84+
85+
86+
87+# Exceptions
88+class PyperclipException(RuntimeError):
89+ pass
90+
91+class PyperclipWindowsException(PyperclipException):
92+ def __init__(self, message):
93+ message += " (%s)" % ctypes.WinError()
94+ super(PyperclipWindowsException, self).__init__(message)
95+
96+class PyperclipTimeoutException(PyperclipException):
97+ pass
98+
99+def _stringifyText(text):
100+ if PY2:
101+ acceptedTypes = (unicode, str, int, float, bool)
102+ else:
103+ acceptedTypes = (str, int, float, bool)
104+ if not isinstance(text, acceptedTypes):
105+ raise PyperclipException('only str, int, float, and bool values can be copied to the clipboard, not %s' % (text.__class__.__name__))
106+ return STR_OR_UNICODE(text)
107+
108+
109+def init_osx_pbcopy_clipboard():
110+
111+ def copy_osx_pbcopy(text):
112+ text = _stringifyText(text) # Converts non-str values to str.
113+ p = subprocess.Popen(['pbcopy', 'w'],
114+ stdin=subprocess.PIPE, close_fds=True)
115+ p.communicate(input=text.encode(ENCODING))
116+
117+ def paste_osx_pbcopy():
118+ p = subprocess.Popen(['pbpaste', 'r'],
119+ stdout=subprocess.PIPE, close_fds=True)
120+ stdout, stderr = p.communicate()
121+ return stdout.decode(ENCODING)
122+
123+ return copy_osx_pbcopy, paste_osx_pbcopy
124+
125+
126+def init_osx_pyobjc_clipboard():
127+ def copy_osx_pyobjc(text):
128+ '''Copy string argument to clipboard'''
129+ text = _stringifyText(text) # Converts non-str values to str.
130+ newStr = Foundation.NSString.stringWithString_(text).nsstring()
131+ newData = newStr.dataUsingEncoding_(Foundation.NSUTF8StringEncoding)
132+ board = AppKit.NSPasteboard.generalPasteboard()
133+ board.declareTypes_owner_([AppKit.NSStringPboardType], None)
134+ board.setData_forType_(newData, AppKit.NSStringPboardType)
135+
136+ def paste_osx_pyobjc():
137+ "Returns contents of clipboard"
138+ board = AppKit.NSPasteboard.generalPasteboard()
139+ content = board.stringForType_(AppKit.NSStringPboardType)
140+ return content
141+
142+ return copy_osx_pyobjc, paste_osx_pyobjc
143+
144+
145+def init_gtk_clipboard():
146+ global gtk
147+ import gtk
148+
149+ def copy_gtk(text):
150+ global cb
151+ text = _stringifyText(text) # Converts non-str values to str.
152+ cb = gtk.Clipboard()
153+ cb.set_text(text)
154+ cb.store()
155+
156+ def paste_gtk():
157+ clipboardContents = gtk.Clipboard().wait_for_text()
158+ # for python 2, returns None if the clipboard is blank.
159+ if clipboardContents is None:
160+ return ''
161+ else:
162+ return clipboardContents
163+
164+ return copy_gtk, paste_gtk
165+
166+
167+def init_qt_clipboard():
168+ global QApplication
169+ # $DISPLAY should exist
170+
171+ # Try to import from qtpy, but if that fails try PyQt5 then PyQt4
172+ try:
173+ from qtpy.QtWidgets import QApplication
174+ except:
175+ try:
176+ from PyQt5.QtWidgets import QApplication
177+ except:
178+ from PyQt4.QtGui import QApplication
179+
180+ app = QApplication.instance()
181+ if app is None:
182+ app = QApplication([])
183+
184+ def copy_qt(text):
185+ text = _stringifyText(text) # Converts non-str values to str.
186+ cb = app.clipboard()
187+ cb.setText(text)
188+
189+ def paste_qt():
190+ cb = app.clipboard()
191+ return STR_OR_UNICODE(cb.text())
192+
193+ return copy_qt, paste_qt
194+
195+
196+def init_xclip_clipboard():
197+ DEFAULT_SELECTION='c'
198+ PRIMARY_SELECTION='p'
199+
200+ def copy_xclip(text, primary=False):
201+ text = _stringifyText(text) # Converts non-str values to str.
202+ selection=DEFAULT_SELECTION
203+ if primary:
204+ selection=PRIMARY_SELECTION
205+ p = subprocess.Popen(['xclip', '-selection', selection],
206+ stdin=subprocess.PIPE, close_fds=True)
207+ p.communicate(input=text.encode(ENCODING))
208+
209+ def paste_xclip(primary=False):
210+ selection=DEFAULT_SELECTION
211+ if primary:
212+ selection=PRIMARY_SELECTION
213+ p = subprocess.Popen(['xclip', '-selection', selection, '-o'],
214+ stdout=subprocess.PIPE,
215+ stderr=subprocess.PIPE,
216+ close_fds=True)
217+ stdout, stderr = p.communicate()
218+ # Intentionally ignore extraneous output on stderr when clipboard is empty
219+ return stdout.decode(ENCODING)
220+
221+ return copy_xclip, paste_xclip
222+
223+
224+def init_xsel_clipboard():
225+ DEFAULT_SELECTION='-b'
226+ PRIMARY_SELECTION='-p'
227+
228+ def copy_xsel(text, primary=False):
229+ text = _stringifyText(text) # Converts non-str values to str.
230+ selection_flag = DEFAULT_SELECTION
231+ if primary:
232+ selection_flag = PRIMARY_SELECTION
233+ p = subprocess.Popen(['xsel', selection_flag, '-i'],
234+ stdin=subprocess.PIPE, close_fds=True)
235+ p.communicate(input=text.encode(ENCODING))
236+
237+ def paste_xsel(primary=False):
238+ selection_flag = DEFAULT_SELECTION
239+ if primary:
240+ selection_flag = PRIMARY_SELECTION
241+ p = subprocess.Popen(['xsel', selection_flag, '-o'],
242+ stdout=subprocess.PIPE, close_fds=True)
243+ stdout, stderr = p.communicate()
244+ return stdout.decode(ENCODING)
245+
246+ return copy_xsel, paste_xsel
247+
248+
249+def init_klipper_clipboard():
250+ def copy_klipper(text):
251+ text = _stringifyText(text) # Converts non-str values to str.
252+ p = subprocess.Popen(
253+ ['qdbus', 'org.kde.klipper', '/klipper', 'setClipboardContents',
254+ text.encode(ENCODING)],
255+ stdin=subprocess.PIPE, close_fds=True)
256+ p.communicate(input=None)
257+
258+ def paste_klipper():
259+ p = subprocess.Popen(
260+ ['qdbus', 'org.kde.klipper', '/klipper', 'getClipboardContents'],
261+ stdout=subprocess.PIPE, close_fds=True)
262+ stdout, stderr = p.communicate()
263+
264+ # Workaround for https://bugs.kde.org/show_bug.cgi?id=342874
265+ # TODO: https://github.com/asweigart/pyperclip/issues/43
266+ clipboardContents = stdout.decode(ENCODING)
267+ # even if blank, Klipper will append a newline at the end
268+ assert len(clipboardContents) > 0
269+ # make sure that newline is there
270+ assert clipboardContents.endswith('\n')
271+ if clipboardContents.endswith('\n'):
272+ clipboardContents = clipboardContents[:-1]
273+ return clipboardContents
274+
275+ return copy_klipper, paste_klipper
276+
277+
278+def init_dev_clipboard_clipboard():
279+ def copy_dev_clipboard(text):
280+ text = _stringifyText(text) # Converts non-str values to str.
281+ if text == '':
282+ warnings.warn('Pyperclip cannot copy a blank string to the clipboard on Cygwin. This is effectively a no-op.')
283+ if '\r' in text:
284+ warnings.warn('Pyperclip cannot handle \\r characters on Cygwin.')
285+
286+ fo = open('/dev/clipboard', 'wt')
287+ fo.write(text)
288+ fo.close()
289+
290+ def paste_dev_clipboard():
291+ fo = open('/dev/clipboard', 'rt')
292+ content = fo.read()
293+ fo.close()
294+ return content
295+
296+ return copy_dev_clipboard, paste_dev_clipboard
297+
298+
299+def init_no_clipboard():
300+ class ClipboardUnavailable(object):
301+
302+ def __call__(self, *args, **kwargs):
303+ raise PyperclipException(EXCEPT_MSG)
304+
305+ if PY2:
306+ def __nonzero__(self):
307+ return False
308+ else:
309+ def __bool__(self):
310+ return False
311+
312+ return ClipboardUnavailable(), ClipboardUnavailable()
313+
314+
315+
316+
317+# Windows-related clipboard functions:
318+class CheckedCall(object):
319+ def __init__(self, f):
320+ super(CheckedCall, self).__setattr__("f", f)
321+
322+ def __call__(self, *args):
323+ ret = self.f(*args)
324+ if not ret and get_errno():
325+ raise PyperclipWindowsException("Error calling " + self.f.__name__)
326+ return ret
327+
328+ def __setattr__(self, key, value):
329+ setattr(self.f, key, value)
330+
331+
332+def init_windows_clipboard():
333+ global HGLOBAL, LPVOID, DWORD, LPCSTR, INT, HWND, HINSTANCE, HMENU, BOOL, UINT, HANDLE
334+ from ctypes.wintypes import (HGLOBAL, LPVOID, DWORD, LPCSTR, INT, HWND,
335+ HINSTANCE, HMENU, BOOL, UINT, HANDLE)
336+
337+ windll = ctypes.windll
338+ msvcrt = ctypes.CDLL('msvcrt')
339+
340+ safeCreateWindowExA = CheckedCall(windll.user32.CreateWindowExA)
341+ safeCreateWindowExA.argtypes = [DWORD, LPCSTR, LPCSTR, DWORD, INT, INT,
342+ INT, INT, HWND, HMENU, HINSTANCE, LPVOID]
343+ safeCreateWindowExA.restype = HWND
344+
345+ safeDestroyWindow = CheckedCall(windll.user32.DestroyWindow)
346+ safeDestroyWindow.argtypes = [HWND]
347+ safeDestroyWindow.restype = BOOL
348+
349+ OpenClipboard = windll.user32.OpenClipboard
350+ OpenClipboard.argtypes = [HWND]
351+ OpenClipboard.restype = BOOL
352+
353+ safeCloseClipboard = CheckedCall(windll.user32.CloseClipboard)
354+ safeCloseClipboard.argtypes = []
355+ safeCloseClipboard.restype = BOOL
356+
357+ safeEmptyClipboard = CheckedCall(windll.user32.EmptyClipboard)
358+ safeEmptyClipboard.argtypes = []
359+ safeEmptyClipboard.restype = BOOL
360+
361+ safeGetClipboardData = CheckedCall(windll.user32.GetClipboardData)
362+ safeGetClipboardData.argtypes = [UINT]
363+ safeGetClipboardData.restype = HANDLE
364+
365+ safeSetClipboardData = CheckedCall(windll.user32.SetClipboardData)
366+ safeSetClipboardData.argtypes = [UINT, HANDLE]
367+ safeSetClipboardData.restype = HANDLE
368+
369+ safeGlobalAlloc = CheckedCall(windll.kernel32.GlobalAlloc)
370+ safeGlobalAlloc.argtypes = [UINT, c_size_t]
371+ safeGlobalAlloc.restype = HGLOBAL
372+
373+ safeGlobalLock = CheckedCall(windll.kernel32.GlobalLock)
374+ safeGlobalLock.argtypes = [HGLOBAL]
375+ safeGlobalLock.restype = LPVOID
376+
377+ safeGlobalUnlock = CheckedCall(windll.kernel32.GlobalUnlock)
378+ safeGlobalUnlock.argtypes = [HGLOBAL]
379+ safeGlobalUnlock.restype = BOOL
380+
381+ wcslen = CheckedCall(msvcrt.wcslen)
382+ wcslen.argtypes = [c_wchar_p]
383+ wcslen.restype = UINT
384+
385+ GMEM_MOVEABLE = 0x0002
386+ CF_UNICODETEXT = 13
387+
388+ @contextlib.contextmanager
389+ def window():
390+ """
391+ Context that provides a valid Windows hwnd.
392+ """
393+ # we really just need the hwnd, so setting "STATIC"
394+ # as predefined lpClass is just fine.
395+ hwnd = safeCreateWindowExA(0, b"STATIC", None, 0, 0, 0, 0, 0,
396+ None, None, None, None)
397+ try:
398+ yield hwnd
399+ finally:
400+ safeDestroyWindow(hwnd)
401+
402+ @contextlib.contextmanager
403+ def clipboard(hwnd):
404+ """
405+ Context manager that opens the clipboard and prevents
406+ other applications from modifying the clipboard content.
407+ """
408+ # We may not get the clipboard handle immediately because
409+ # some other application is accessing it (?)
410+ # We try for at least 500ms to get the clipboard.
411+ t = time.time() + 0.5
412+ success = False
413+ while time.time() < t:
414+ success = OpenClipboard(hwnd)
415+ if success:
416+ break
417+ time.sleep(0.01)
418+ if not success:
419+ raise PyperclipWindowsException("Error calling OpenClipboard")
420+
421+ try:
422+ yield
423+ finally:
424+ safeCloseClipboard()
425+
426+ def copy_windows(text):
427+ # This function is heavily based on
428+ # http://msdn.com/ms649016#_win32_Copying_Information_to_the_Clipboard
429+
430+ text = _stringifyText(text) # Converts non-str values to str.
431+
432+ with window() as hwnd:
433+ # http://msdn.com/ms649048
434+ # If an application calls OpenClipboard with hwnd set to NULL,
435+ # EmptyClipboard sets the clipboard owner to NULL;
436+ # this causes SetClipboardData to fail.
437+ # => We need a valid hwnd to copy something.
438+ with clipboard(hwnd):
439+ safeEmptyClipboard()
440+
441+ if text:
442+ # http://msdn.com/ms649051
443+ # If the hMem parameter identifies a memory object,
444+ # the object must have been allocated using the
445+ # function with the GMEM_MOVEABLE flag.
446+ count = wcslen(text) + 1
447+ handle = safeGlobalAlloc(GMEM_MOVEABLE,
448+ count * sizeof(c_wchar))
449+ locked_handle = safeGlobalLock(handle)
450+
451+ ctypes.memmove(c_wchar_p(locked_handle), c_wchar_p(text), count * sizeof(c_wchar))
452+
453+ safeGlobalUnlock(handle)
454+ safeSetClipboardData(CF_UNICODETEXT, handle)
455+
456+ def paste_windows():
457+ with clipboard(None):
458+ handle = safeGetClipboardData(CF_UNICODETEXT)
459+ if not handle:
460+ # GetClipboardData may return NULL with errno == NO_ERROR
461+ # if the clipboard is empty.
462+ # (Also, it may return a handle to an empty buffer,
463+ # but technically that's not empty)
464+ return ""
465+ return c_wchar_p(handle).value
466+
467+ return copy_windows, paste_windows
468+
469+
470+def init_wsl_clipboard():
471+ def copy_wsl(text):
472+ text = _stringifyText(text) # Converts non-str values to str.
473+ p = subprocess.Popen(['clip.exe'],
474+ stdin=subprocess.PIPE, close_fds=True)
475+ p.communicate(input=text.encode(ENCODING))
476+
477+ def paste_wsl():
478+ p = subprocess.Popen(['powershell.exe', '-command', 'Get-Clipboard'],
479+ stdout=subprocess.PIPE,
480+ stderr=subprocess.PIPE,
481+ close_fds=True)
482+ stdout, stderr = p.communicate()
483+ # WSL appends "\r\n" to the contents.
484+ return stdout[:-2].decode(ENCODING)
485+
486+ return copy_wsl, paste_wsl
487+
488+
489+# Automatic detection of clipboard mechanisms and importing is done in deteremine_clipboard():
490+def determine_clipboard():
491+ '''
492+ Determine the OS/platform and set the copy() and paste() functions
493+ accordingly.
494+ '''
495+
496+ global Foundation, AppKit, gtk, qtpy, PyQt4, PyQt5
497+
498+ # Setup for the CYGWIN platform:
499+ if 'cygwin' in platform.system().lower(): # Cygwin has a variety of values returned by platform.system(), such as 'CYGWIN_NT-6.1'
500+ # FIXME: pyperclip currently does not support Cygwin,
501+ # see https://github.com/asweigart/pyperclip/issues/55
502+ if os.path.exists('/dev/clipboard'):
503+ warnings.warn('Pyperclip\'s support for Cygwin is not perfect, see https://github.com/asweigart/pyperclip/issues/55')
504+ return init_dev_clipboard_clipboard()
505+
506+ # Setup for the WINDOWS platform:
507+ elif os.name == 'nt' or platform.system() == 'Windows':
508+ return init_windows_clipboard()
509+
510+ if platform.system() == 'Linux':
511+ with open('/proc/version', 'r') as f:
512+ if "Microsoft" in f.read():
513+ return init_wsl_clipboard()
514+
515+ # Setup for the MAC OS X platform:
516+ if os.name == 'mac' or platform.system() == 'Darwin':
517+ try:
518+ import Foundation # check if pyobjc is installed
519+ import AppKit
520+ except ImportError:
521+ return init_osx_pbcopy_clipboard()
522+ else:
523+ return init_osx_pyobjc_clipboard()
524+
525+ # Setup for the LINUX platform:
526+ if HAS_DISPLAY:
527+ try:
528+ import gtk # check if gtk is installed
529+ except ImportError:
530+ pass # We want to fail fast for all non-ImportError exceptions.
531+ else:
532+ return init_gtk_clipboard()
533+
534+ if _executable_exists("xsel"):
535+ return init_xsel_clipboard()
536+ if _executable_exists("xclip"):
537+ return init_xclip_clipboard()
538+ if _executable_exists("klipper") and _executable_exists("qdbus"):
539+ return init_klipper_clipboard()
540+
541+ try:
542+ # qtpy is a small abstraction layer that lets you write applications using a single api call to either PyQt or PySide.
543+ # https://pypi.python.org/pypi/QtPy
544+ import qtpy # check if qtpy is installed
545+ except ImportError:
546+ # If qtpy isn't installed, fall back on importing PyQt4.
547+ try:
548+ import PyQt5 # check if PyQt5 is installed
549+ except ImportError:
550+ try:
551+ import PyQt4 # check if PyQt4 is installed
552+ except ImportError:
553+ pass # We want to fail fast for all non-ImportError exceptions.
554+ else:
555+ return init_qt_clipboard()
556+ else:
557+ return init_qt_clipboard()
558+ else:
559+ return init_qt_clipboard()
560+
561+
562+ return init_no_clipboard()
563+
564+
565+def set_clipboard(clipboard):
566+ '''
567+ Explicitly sets the clipboard mechanism. The "clipboard mechanism" is how
568+ the copy() and paste() functions interact with the operating system to
569+ implement the copy/paste feature. The clipboard parameter must be one of:
570+ - pbcopy
571+ - pbobjc (default on Mac OS X)
572+ - gtk
573+ - qt
574+ - xclip
575+ - xsel
576+ - klipper
577+ - windows (default on Windows)
578+ - no (this is what is set when no clipboard mechanism can be found)
579+ '''
580+ global copy, paste
581+
582+ clipboard_types = {'pbcopy': init_osx_pbcopy_clipboard,
583+ 'pyobjc': init_osx_pyobjc_clipboard,
584+ 'gtk': init_gtk_clipboard,
585+ 'qt': init_qt_clipboard, # TODO - split this into 'qtpy', 'pyqt4', and 'pyqt5'
586+ 'xclip': init_xclip_clipboard,
587+ 'xsel': init_xsel_clipboard,
588+ 'klipper': init_klipper_clipboard,
589+ 'windows': init_windows_clipboard,
590+ 'no': init_no_clipboard}
591+
592+ if clipboard not in clipboard_types:
593+ raise ValueError('Argument must be one of %s' % (', '.join([repr(_) for _ in clipboard_types.keys()])))
594+
595+ # Sets pyperclip's copy() and paste() functions:
596+ copy, paste = clipboard_types[clipboard]()
597+
598+
599+def lazy_load_stub_copy(text):
600+ '''
601+ A stub function for copy(), which will load the real copy() function when
602+ called so that the real copy() function is used for later calls.
603+
604+ This allows users to import pyperclip without having determine_clipboard()
605+ automatically run, which will automatically select a clipboard mechanism.
606+ This could be a problem if it selects, say, the memory-heavy PyQt4 module
607+ but the user was just going to immediately call set_clipboard() to use a
608+ different clipboard mechanism.
609+
610+ The lazy loading this stub function implements gives the user a chance to
611+ call set_clipboard() to pick another clipboard mechanism. Or, if the user
612+ simply calls copy() or paste() without calling set_clipboard() first,
613+ will fall back on whatever clipboard mechanism that determine_clipboard()
614+ automatically chooses.
615+ '''
616+ global copy, paste
617+ copy, paste = determine_clipboard()
618+ return copy(text)
619+
620+
621+def lazy_load_stub_paste():
622+ '''
623+ A stub function for paste(), which will load the real paste() function when
624+ called so that the real paste() function is used for later calls.
625+
626+ This allows users to import pyperclip without having determine_clipboard()
627+ automatically run, which will automatically select a clipboard mechanism.
628+ This could be a problem if it selects, say, the memory-heavy PyQt4 module
629+ but the user was just going to immediately call set_clipboard() to use a
630+ different clipboard mechanism.
631+
632+ The lazy loading this stub function implements gives the user a chance to
633+ call set_clipboard() to pick another clipboard mechanism. Or, if the user
634+ simply calls copy() or paste() without calling set_clipboard() first,
635+ will fall back on whatever clipboard mechanism that determine_clipboard()
636+ automatically chooses.
637+ '''
638+ global copy, paste
639+ copy, paste = determine_clipboard()
640+ return paste()
641+
642+
643+def is_available():
644+ return copy != lazy_load_stub_copy and paste != lazy_load_stub_paste
645+
646+
647+# Initially, copy() and paste() are set to lazy loading wrappers which will
648+# set `copy` and `paste` to real functions the first time they're used, unless
649+# set_clipboard() or determine_clipboard() is called first.
650+copy, paste = lazy_load_stub_copy, lazy_load_stub_paste
651+
652+
653+
654+def waitForPaste(timeout=None):
655+ """This function call blocks until a non-empty text string exists on the
656+ clipboard. It returns this text.
657+
658+ This function raises PyperclipTimeoutException if timeout was set to
659+ a number of seconds that has elapsed without non-empty text being put on
660+ the clipboard."""
661+ startTime = time.time()
662+ while True:
663+ clipboardText = paste()
664+ if clipboardText != '':
665+ return clipboardText
666+ time.sleep(0.01)
667+
668+ if timeout is not None and time.time() > startTime + timeout:
669+ raise PyperclipTimeoutException('waitForPaste() timed out after ' + str(timeout) + ' seconds.')
670+
671+
672+def waitForNewPaste(timeout=None):
673+ """This function call blocks until a new text string exists on the
674+ clipboard that is different from the text that was there when the function
675+ was first called. It returns this text.
676+
677+ This function raises PyperclipTimeoutException if timeout was set to
678+ a number of seconds that has elapsed without non-empty text being put on
679+ the clipboard."""
680+ startTime = time.time()
681+ originalText = paste()
682+ while True:
683+ currentText = paste()
684+ if currentText != originalText:
685+ return currentText
686+ time.sleep(0.01)
687+
688+ if timeout is not None and time.time() > startTime + timeout:
689+ raise PyperclipTimeoutException('waitForNewPaste() timed out after ' + str(timeout) + ' seconds.')
690+
691+
692+__all__ = ['copy', 'paste', 'waitForPaste', 'waitForNewPaste' 'set_clipboard', 'determine_clipboard']
693+
694+
diff -r 000000000000 -r e090a13165e2 pyperclip/__main__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pyperclip/__main__.py Tue Apr 20 20:15:52 2021 +0300
@@ -0,0 +1,12 @@
1+import pyperclip
2+import sys
3+
4+if len(sys.argv) > 1 and sys.argv[1] in ('-c', '--copy'):
5+ pyperclip.copy(sys.stdin.read())
6+elif len(sys.argv) > 1 and sys.argv[1] in ('-p', '--paste'):
7+ sys.stdout.write(pyperclip.paste())
8+else:
9+ print('Usage: python -m pyperclip [-c | --copy] | [-p | --paste]')
10+ print()
11+ print('When copying, stdin will be placed on the clipboard.')
12+ print('When pasting, the clipboard will be written to stdout.')
\ No newline at end of file
旧リポジトリブラウザで表示