##// END OF EJS Templates
Add %paste magic for direct pasting from the clipboard.
Robert Kern -
Show More
@@ -0,0 +1,56 b''
1 """ Utilities for accessing the platform's clipboard.
2 """
3
4 import subprocess
5 import sys
6
7 from IPython.ipapi import TryNext
8
9
10 def win32_clipboard_get():
11 """ Get the current clipboard's text on Windows.
12
13 Requires Mark Hammond's pywin32 extensions.
14 """
15 try:
16 import win32clipboard
17 except ImportError:
18 message = ("Getting text from the clipboard requires the pywin32 "
19 "extensions: http://sourceforge.net/projects/pywin32/")
20 raise TryNext(message)
21 win32clipboard.OpenClipboard()
22 text = win32clipboard.GetClipboardData(win32clipboard.CF_TEXT)
23 # FIXME: convert \r\n to \n?
24 win32clipboard.CloseClipboard()
25 return text
26
27 def osx_clipboard_get():
28 """ Get the clipboard's text on OS X.
29 """
30 p = subprocess.Popen(['pbpaste', '-Prefer', 'ascii'],
31 stdout=subprocess.PIPE)
32 text, stderr = p.communicate()
33 # Text comes in with old Mac \r line endings. Change them to \n.
34 text = text.replace('\r', '\n')
35 return text
36
37 def tkinter_clipboard_get():
38 """ Get the clipboard's text using Tkinter.
39
40 This is the default on systems that are not Windows or OS X. It may
41 interfere with other UI toolkits and should be replaced with an
42 implementation that uses that toolkit.
43 """
44 try:
45 import Tkinter
46 except ImportError:
47 message = ("Getting text from the clipboard on this platform "
48 "requires Tkinter.")
49 raise TryNext(message)
50 root = Tkinter.Tk()
51 root.withdraw()
52 text = root.clipboard_get()
53 root.destroy()
54 return text
55
56
@@ -3210,6 +3210,61 b' Defaulting color scheme to \'NoColor\'"""'
3210 page(self.shell.pycolorize(cont),
3210 page(self.shell.pycolorize(cont),
3211 screen_lines=self.shell.rc.screen_length)
3211 screen_lines=self.shell.rc.screen_length)
3212
3212
3213 def _rerun_pasted(self):
3214 """ Rerun a previously pasted command.
3215 """
3216 b = self.user_ns.get('pasted_block', None)
3217 if b is None:
3218 raise UsageError('No previous pasted block available')
3219 print "Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b))
3220 exec b in self.user_ns
3221
3222 def _get_pasted_lines(self, sentinel):
3223 """ Yield pasted lines until the user enters the given sentinel value.
3224 """
3225 from IPython import iplib
3226 print "Pasting code; enter '%s' alone on the line to stop." % sentinel
3227 while True:
3228 l = iplib.raw_input_original(':')
3229 if l == sentinel:
3230 return
3231 else:
3232 yield l
3233
3234 def _strip_pasted_lines_for_code(self, raw_lines):
3235 """ Strip non-code parts of a sequence of lines to return a block of
3236 code.
3237 """
3238 # Regular expressions that declare text we strip from the input:
3239 strip_re = [r'^\s*In \[\d+\]:', # IPython input prompt
3240 r'^\s*(\s?>)+', # Python input prompt
3241 r'^\s*\.{3,}', # Continuation prompts
3242 r'^\++',
3243 ]
3244
3245 strip_from_start = map(re.compile,strip_re)
3246
3247 lines = []
3248 for l in raw_lines:
3249 for pat in strip_from_start:
3250 l = pat.sub('',l)
3251 lines.append(l)
3252
3253 block = "\n".join(lines) + '\n'
3254 #print "block:\n",block
3255 return block
3256
3257 def _execute_block(self, block, par):
3258 """ Execute a block, or store it in a variable, per the user's request.
3259 """
3260 if not par:
3261 b = textwrap.dedent(block)
3262 self.user_ns['pasted_block'] = b
3263 exec b in self.user_ns
3264 else:
3265 self.user_ns[par] = SList(block.splitlines())
3266 print "Block assigned to '%s'" % par
3267
3213 def magic_cpaste(self, parameter_s=''):
3268 def magic_cpaste(self, parameter_s=''):
3214 """Allows you to paste & execute a pre-formatted code block from clipboard.
3269 """Allows you to paste & execute a pre-formatted code block from clipboard.
3215
3270
@@ -3239,46 +3294,47 b' Defaulting color scheme to \'NoColor\'"""'
3239 opts,args = self.parse_options(parameter_s,'rs:',mode='string')
3294 opts,args = self.parse_options(parameter_s,'rs:',mode='string')
3240 par = args.strip()
3295 par = args.strip()
3241 if opts.has_key('r'):
3296 if opts.has_key('r'):
3242 b = self.user_ns.get('pasted_block', None)
3297 self._rerun_pasted()
3243 if b is None:
3244 raise UsageError('No previous pasted block available')
3245 print "Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b))
3246 exec b in self.user_ns
3247 return
3298 return
3248
3299
3249 sentinel = opts.get('s','--')
3300 sentinel = opts.get('s','--')
3250
3301
3251 # Regular expressions that declare text we strip from the input:
3302 block = self._strip_pasted_lines_for_code(
3252 strip_re = [r'^\s*In \[\d+\]:', # IPython input prompt
3303 self._get_pasted_lines(sentinel))
3253 r'^\s*(\s?>)+', # Python input prompt
3254 r'^\s*\.{3,}', # Continuation prompts
3255 r'^\++',
3256 ]
3257
3304
3258 strip_from_start = map(re.compile,strip_re)
3305 self._execute_block(block, par)
3306
3307 def magic_paste(self, parameter_s=''):
3308 """Allows you to paste & execute a pre-formatted code block from clipboard.
3259
3309
3260 from IPython import iplib
3310 The text is pulled directly from the clipboard without user
3261 lines = []
3311 intervention.
3262 print "Pasting code; enter '%s' alone on the line to stop." % sentinel
3312
3263 while 1:
3313 The block is dedented prior to execution to enable execution of method
3264 l = iplib.raw_input_original(':')
3314 definitions. '>' and '+' characters at the beginning of a line are
3265 if l ==sentinel:
3315 ignored, to allow pasting directly from e-mails, diff files and
3266 break
3316 doctests (the '...' continuation prompt is also stripped). The
3267
3317 executed block is also assigned to variable named 'pasted_block' for
3268 for pat in strip_from_start:
3318 later editing with '%edit pasted_block'.
3269 l = pat.sub('',l)
3319
3270 lines.append(l)
3320 You can also pass a variable name as an argument, e.g. '%paste foo'.
3271
3321 This assigns the pasted block to variable 'foo' as string, without
3272 block = "\n".join(lines) + '\n'
3322 dedenting or executing it (preceding >>> and + is still stripped)
3273 #print "block:\n",block
3323
3274 if not par:
3324 '%paste -r' re-executes the block previously entered by cpaste.
3275 b = textwrap.dedent(block)
3325
3276 self.user_ns['pasted_block'] = b
3326 IPython statements (magics, shell escapes) are not supported (yet).
3277 exec b in self.user_ns
3327 """
3278 else:
3328 opts,args = self.parse_options(parameter_s,'r:',mode='string')
3279 self.user_ns[par] = SList(block.splitlines())
3329 par = args.strip()
3280 print "Block assigned to '%s'" % par
3330 if opts.has_key('r'):
3281
3331 self._rerun_pasted()
3332 return
3333
3334 text = self.shell.hooks.clipboard_get()
3335 block = self._strip_pasted_lines_for_code(text.splitlines())
3336 self._execute_block(block, par)
3337
3282 def magic_quickref(self,arg):
3338 def magic_quickref(self,arg):
3283 """ Show a quick reference sheet """
3339 """ Show a quick reference sheet """
3284 import IPython.usage
3340 import IPython.usage
@@ -49,6 +49,7 b' __license__ = Release.license'
49 __version__ = Release.version
49 __version__ = Release.version
50
50
51 import os,bisect
51 import os,bisect
52 import sys
52 from genutils import Term,shell
53 from genutils import Term,shell
53 from pprint import PrettyPrinter
54 from pprint import PrettyPrinter
54
55
@@ -58,7 +59,8 b' from pprint import PrettyPrinter'
58 __all__ = ['editor', 'fix_error_editor', 'synchronize_with_editor', 'result_display',
59 __all__ = ['editor', 'fix_error_editor', 'synchronize_with_editor', 'result_display',
59 'input_prefilter', 'shutdown_hook', 'late_startup_hook',
60 'input_prefilter', 'shutdown_hook', 'late_startup_hook',
60 'generate_prompt', 'generate_output_prompt','shell_hook',
61 'generate_prompt', 'generate_output_prompt','shell_hook',
61 'show_in_pager','pre_prompt_hook', 'pre_runcode_hook']
62 'show_in_pager','pre_prompt_hook', 'pre_runcode_hook',
63 'clipboard_get']
62 # vds: <<
64 # vds: <<
63
65
64 pformat = PrettyPrinter().pformat
66 pformat = PrettyPrinter().pformat
@@ -248,5 +250,20 b' def pre_prompt_hook(self):'
248 def pre_runcode_hook(self):
250 def pre_runcode_hook(self):
249 """ Executed before running the (prefiltered) code in IPython """
251 """ Executed before running the (prefiltered) code in IPython """
250 return None
252 return None
251
252
253
254 def clipboard_get(self):
255 """ Get text from the clipboard.
256 """
257 from IPython.clipboard import (osx_clipboard_get, tkinter_clipboard_get,
258 win32_clipboard_get)
259 if sys.platform == 'win32':
260 chain = [win32_clipboard_get, tkinter_clipboard_get]
261 elif sys.platform == 'darwin':
262 chain = [osx_clipboard_get, tkinter_clipboard_get]
263 else:
264 chain = [tkinter_clipboard_get]
265 dispatcher = CommandChainDispatcher()
266 for func in chain:
267 dispatcher.add(func)
268 text = dispatcher()
269 return text
General Comments 0
You need to be logged in to leave comments. Login now