comparison cmd2.py @ 27:a76798cde34c

hooray, pasting working in windows
author catherine@cordelia
date Sun, 18 May 2008 07:24:51 -0400
parents 82dde2f60e46
children 28b3fb301d3d
comparison
equal deleted inserted replaced
26:82dde2f60e46 27:a76798cde34c
18 As of 0.3.0, options should be specified as `optparse` options. See README.txt. 18 As of 0.3.0, options should be specified as `optparse` options. See README.txt.
19 flagReader.py options are still supported for backward compatibility 19 flagReader.py options are still supported for backward compatibility
20 """ 20 """
21 import cmd, re, os, sys, optparse, subprocess, tempfile 21 import cmd, re, os, sys, optparse, subprocess, tempfile
22 from optparse import make_option 22 from optparse import make_option
23 try:
24 import win32clipboard
25 except:
26 pass
23 27
24 class OptionParser(optparse.OptionParser): 28 class OptionParser(optparse.OptionParser):
25 def exit(self, status=0, msg=None): 29 def exit(self, status=0, msg=None):
26 if msg: 30 if msg:
27 print msg 31 print msg
56 return result 60 return result
57 newFunc.__doc__ = '%s\n%s' % (func.__doc__, optionParser.format_help()) 61 newFunc.__doc__ = '%s\n%s' % (func.__doc__, optionParser.format_help())
58 return newFunc 62 return newFunc
59 return option_setup 63 return option_setup
60 64
65 class PasteBufferError(EnvironmentError):
66 if sys.platform[:3] == 'win':
67 errmsg = """Redirecting to or from paste buffer requires pywin32
68 to be installed on operating system.
69 Download from http://sourceforge.net/projects/pywin32/"""
70 else:
71 errmsg = """Redirecting to or from paste buffer requires xclip
72 to be installed on operating system.
73 On Debian/Ubuntu, 'sudo apt-get install xclip' will install it."""
74 def __init__(self, msg):
75 Exception.__init__(self, self.errmsg)
76
77 if sys.platform[:3] == 'win':
78 def getPasteBuffer():
79 if not win32clipboard:
80 raise PasteBufferError
81 win32clipboard.OpenClipboard(0)
82 try:
83 result = win32clipboard.GetClipboardData()
84 except TypeError:
85 result = '' #non-text
86 win32clipboard.CloseClipboard()
87 return result
88 def writeToPasteBuffer(txt):
89 if not win32clipboard:
90 raise PasteBufferError
91 win32clipboard.OpenClipboard(0)
92 win32clipboard.EmptyClipboard()
93 win32clipboard.SetClipboardText(txt)
94 win32clipboard.CloseClipboard()
95 else:
96 def getPasteBuffer():
97 try:
98 xclipproc = subprocess.check_call('xc1ip -o -sel clip', shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
99 except subprocess.CalledProcessError:
100 raise PasteBufferError
101 return xclipproc.stdout.read()
102 def writeToPasteBuffer(txt):
103 try:
104 xclipproc = subprocess.check_call('xclip -sel clip', shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
105 except subprocess.CalledProcessError:
106 raise PasteBufferError
107 xclipporc.stdin.write(txt)
108
61 class Cmd(cmd.Cmd): 109 class Cmd(cmd.Cmd):
62 caseInsensitive = True 110 caseInsensitive = True
63 multilineCommands = [] 111 multilineCommands = []
64 continuationPrompt = '> ' 112 continuationPrompt = '> '
65 shortcuts = {'?': 'help', '!': 'shell', '@': 'load'} 113 shortcuts = {'?': 'help', '!': 'shell', '@': 'load'}
141 return newStatement, redirect, 'w' 189 return newStatement, redirect, 'w'
142 newStatement, redirect = self.parseRedirector(statement, '<', mustBeTerminated) 190 newStatement, redirect = self.parseRedirector(statement, '<', mustBeTerminated)
143 if redirect: 191 if redirect:
144 return newStatement, redirect, 'r' 192 return newStatement, redirect, 'r'
145 return statement, '', '' 193 return statement, '', ''
146 194
147 def pasteBufferProcess(self, mode='read'):
148 if mode == 'read':
149 command = 'xc1ip -o -sel clip'
150 else:
151 command = 'xclip -sel clip'
152 result = subprocess.check_call(command, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
153 return result
154
155 def onecmd(self, line): 195 def onecmd(self, line):
156 """Interpret the argument as though it had been typed in response 196 """Interpret the argument as though it had been typed in response
157 to the prompt. 197 to the prompt.
158 198
159 This may be overridden, but should not normally need to be; 199 This may be overridden, but should not normally need to be;
169 statekeeper = None 209 statekeeper = None
170 stop = 0 210 stop = 0
171 statement, redirect, mode = self.parseRedirectors(statement) 211 statement, redirect, mode = self.parseRedirectors(statement)
172 if redirect == self._TO_PASTE_BUFFER: 212 if redirect == self._TO_PASTE_BUFFER:
173 try: 213 try:
174 if mode in ('a', 'r'): 214 clipcontents = getPasteBuffer()
175 clipcontents = self.pasteBufferProcess('read').stdout.read()
176 if mode in ('w', 'a'): 215 if mode in ('w', 'a'):
177 statekeeper = Statekeeper(self, ('stdout',)) 216 statekeeper = Statekeeper(self, ('stdout',))
178 self.stdout = self.pasteBufferProcess('write').stdin 217 self.stdout = tempfile.TemporaryFile()
179 if mode == 'a': 218 if mode == 'a':
180 self.stdout.write(clipcontents) 219 self.stdout.write(clipcontents)
181 else: 220 else:
182 statement = '%s %s' % (statement, clipcontents) 221 statement = '%s %s' % (statement, clipcontents)
183 except subprocess.CalledProcessError: 222 except PasteBufferError:
184 print """Redirecting to or from paste buffer requires xclip
185 to be installed on operating system.
186 On Debian/Ubuntu, 'sudo apt-get install xclip' will install it."""
187 return 0 223 return 0
188 elif redirect: 224 elif redirect:
189 if mode in ('w','a'): 225 if mode in ('w','a'):
190 statekeeper = Statekeeper(self, ('stdout',)) 226 statekeeper = Statekeeper(self, ('stdout',))
191 self.stdout = open(redirect, mode) 227 self.stdout = open(redirect, mode)
195 try: 231 try:
196 if command not in self.excludeFromHistory: 232 if command not in self.excludeFromHistory:
197 self.history.append(statement) 233 self.history.append(statement)
198 finally: 234 finally:
199 if statekeeper: 235 if statekeeper:
236 if redirect == self._TO_PASTE_BUFFER:
237 self.stdout.seek(0)
238 writeToPasteBuffer(self.stdout.read())
200 self.stdout.close() 239 self.stdout.close()
201 statekeeper.restore() 240 statekeeper.restore()
202 return stop 241 return stop
203 242
204 statementEndPattern = re.compile(r'[%s]\s*$' % terminators) 243 statementEndPattern = re.compile(r'[%s]\s*$' % terminators)