##// END OF EJS Templates
Create core.magics.code according to new API.
Fernando Perez -
Show More
@@ -0,0 +1,478 b''
1 """Implementation of basic magic functions.
2 """
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2012 The IPython Development Team.
5 #
6 # Distributed under the terms of the Modified BSD License.
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
10
11 #-----------------------------------------------------------------------------
12 # Imports
13 #-----------------------------------------------------------------------------
14
15 # Stdlib
16 import inspect
17 import io
18 import json
19 import os
20 import sys
21 from urllib2 import urlopen
22
23 # Our own packages
24 from IPython.core.error import TryNext
25 from IPython.core.macro import Macro
26 from IPython.core.magic import Magics, register_magics, line_magic
27 from IPython.testing.skipdoctest import skip_doctest
28 from IPython.utils import openpy
29 from IPython.utils import py3compat
30 from IPython.utils.io import file_read
31 from IPython.utils.path import get_py_filename, unquote_filename
32 from IPython.utils.warn import warn
33
34 #-----------------------------------------------------------------------------
35 # Magic implementation classes
36 #-----------------------------------------------------------------------------
37
38 # Used for exception handling in magic_edit
39 class MacroToEdit(ValueError): pass
40
41
42 @register_magics
43 class CodeMagics(Magics):
44 """Magics related to code management (loading, saving, editing, ...)."""
45
46 @line_magic
47 def save(self, parameter_s=''):
48 """Save a set of lines or a macro to a given filename.
49
50 Usage:\\
51 %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...
52
53 Options:
54
55 -r: use 'raw' input. By default, the 'processed' history is used,
56 so that magics are loaded in their transformed version to valid
57 Python. If this option is given, the raw input as typed as the
58 command line is used instead.
59
60 This function uses the same syntax as %history for input ranges,
61 then saves the lines to the filename you specify.
62
63 It adds a '.py' extension to the file if you don't do so yourself, and
64 it asks for confirmation before overwriting existing files."""
65
66 opts,args = self.parse_options(parameter_s,'r',mode='list')
67 fname, codefrom = unquote_filename(args[0]), " ".join(args[1:])
68 if not fname.endswith('.py'):
69 fname += '.py'
70 if os.path.isfile(fname):
71 ans = raw_input('File `%s` exists. Overwrite (y/[N])? ' % fname)
72 if ans.lower() not in ['y','yes']:
73 print 'Operation cancelled.'
74 return
75 try:
76 cmds = self.shell.find_user_code(codefrom, 'r' in opts)
77 except (TypeError, ValueError) as e:
78 print e.args[0]
79 return
80 with io.open(fname,'w', encoding="utf-8") as f:
81 f.write(u"# coding: utf-8\n")
82 f.write(py3compat.cast_unicode(cmds))
83 print 'The following commands were written to file `%s`:' % fname
84 print cmds
85
86 @line_magic
87 def pastebin(self, parameter_s=''):
88 """Upload code to Github's Gist paste bin, returning the URL.
89
90 Usage:\\
91 %pastebin [-d "Custom description"] 1-7
92
93 The argument can be an input history range, a filename, or the name of a
94 string or macro.
95
96 Options:
97
98 -d: Pass a custom description for the gist. The default will say
99 "Pasted from IPython".
100 """
101 opts, args = self.parse_options(parameter_s, 'd:')
102
103 try:
104 code = self.shell.find_user_code(args)
105 except (ValueError, TypeError) as e:
106 print e.args[0]
107 return
108
109 post_data = json.dumps({
110 "description": opts.get('d', "Pasted from IPython"),
111 "public": True,
112 "files": {
113 "file1.py": {
114 "content": code
115 }
116 }
117 }).encode('utf-8')
118
119 response = urlopen("https://api.github.com/gists", post_data)
120 response_data = json.loads(response.read().decode('utf-8'))
121 return response_data['html_url']
122
123 @line_magic
124 def loadpy(self, arg_s):
125 """Load a .py python script into the GUI console.
126
127 This magic command can either take a local filename or a url::
128
129 %loadpy myscript.py
130 %loadpy http://www.example.com/myscript.py
131 """
132 arg_s = unquote_filename(arg_s)
133 remote_url = arg_s.startswith(('http://', 'https://'))
134 local_url = not remote_url
135 if local_url and not arg_s.endswith('.py'):
136 # Local files must be .py; for remote URLs it's possible that the
137 # fetch URL doesn't have a .py in it (many servers have an opaque
138 # URL, such as scipy-central.org).
139 raise ValueError('%%loadpy only works with .py files: %s' % arg_s)
140
141 # openpy takes care of finding the source encoding (per PEP 263)
142 if remote_url:
143 contents = openpy.read_py_url(arg_s, skip_encoding_cookie=True)
144 else:
145 contents = openpy.read_py_file(arg_s, skip_encoding_cookie=True)
146
147 self.shell.set_next_input(contents)
148
149 def _find_edit_target(self, args, opts, last_call):
150 """Utility method used by magic_edit to find what to edit."""
151
152 def make_filename(arg):
153 "Make a filename from the given args"
154 arg = unquote_filename(arg)
155 try:
156 filename = get_py_filename(arg)
157 except IOError:
158 # If it ends with .py but doesn't already exist, assume we want
159 # a new file.
160 if arg.endswith('.py'):
161 filename = arg
162 else:
163 filename = None
164 return filename
165
166 # Set a few locals from the options for convenience:
167 opts_prev = 'p' in opts
168 opts_raw = 'r' in opts
169
170 # custom exceptions
171 class DataIsObject(Exception): pass
172
173 # Default line number value
174 lineno = opts.get('n',None)
175
176 if opts_prev:
177 args = '_%s' % last_call[0]
178 if not self.shell.user_ns.has_key(args):
179 args = last_call[1]
180
181 # use last_call to remember the state of the previous call, but don't
182 # let it be clobbered by successive '-p' calls.
183 try:
184 last_call[0] = self.shell.displayhook.prompt_count
185 if not opts_prev:
186 last_call[1] = args
187 except:
188 pass
189
190 # by default this is done with temp files, except when the given
191 # arg is a filename
192 use_temp = True
193
194 data = ''
195
196 # First, see if the arguments should be a filename.
197 filename = make_filename(args)
198 if filename:
199 use_temp = False
200 elif args:
201 # Mode where user specifies ranges of lines, like in %macro.
202 data = self.shell.extract_input_lines(args, opts_raw)
203 if not data:
204 try:
205 # Load the parameter given as a variable. If not a string,
206 # process it as an object instead (below)
207
208 #print '*** args',args,'type',type(args) # dbg
209 data = eval(args, self.shell.user_ns)
210 if not isinstance(data, basestring):
211 raise DataIsObject
212
213 except (NameError,SyntaxError):
214 # given argument is not a variable, try as a filename
215 filename = make_filename(args)
216 if filename is None:
217 warn("Argument given (%s) can't be found as a variable "
218 "or as a filename." % args)
219 return
220 use_temp = False
221
222 except DataIsObject:
223 # macros have a special edit function
224 if isinstance(data, Macro):
225 raise MacroToEdit(data)
226
227 # For objects, try to edit the file where they are defined
228 try:
229 filename = inspect.getabsfile(data)
230 if 'fakemodule' in filename.lower() and \
231 inspect.isclass(data):
232 # class created by %edit? Try to find source
233 # by looking for method definitions instead, the
234 # __module__ in those classes is FakeModule.
235 attrs = [getattr(data, aname) for aname in dir(data)]
236 for attr in attrs:
237 if not inspect.ismethod(attr):
238 continue
239 filename = inspect.getabsfile(attr)
240 if filename and \
241 'fakemodule' not in filename.lower():
242 # change the attribute to be the edit
243 # target instead
244 data = attr
245 break
246
247 datafile = 1
248 except TypeError:
249 filename = make_filename(args)
250 datafile = 1
251 warn('Could not find file where `%s` is defined.\n'
252 'Opening a file named `%s`' % (args,filename))
253 # Now, make sure we can actually read the source (if it was
254 # in a temp file it's gone by now).
255 if datafile:
256 try:
257 if lineno is None:
258 lineno = inspect.getsourcelines(data)[1]
259 except IOError:
260 filename = make_filename(args)
261 if filename is None:
262 warn('The file `%s` where `%s` was defined cannot '
263 'be read.' % (filename,data))
264 return
265 use_temp = False
266
267 if use_temp:
268 filename = self.shell.mktempfile(data)
269 print 'IPython will make a temporary file named:',filename
270
271 return filename, lineno, use_temp
272
273 def _edit_macro(self,mname,macro):
274 """open an editor with the macro data in a file"""
275 filename = self.shell.mktempfile(macro.value)
276 self.shell.hooks.editor(filename)
277
278 # and make a new macro object, to replace the old one
279 mfile = open(filename)
280 mvalue = mfile.read()
281 mfile.close()
282 self.shell.user_ns[mname] = Macro(mvalue)
283
284 @line_magic
285 def ed(self, parameter_s=''):
286 """Alias to %edit."""
287 return self.edit(parameter_s)
288
289 @skip_doctest
290 @line_magic
291 def edit(self, parameter_s='',last_call=['','']):
292 """Bring up an editor and execute the resulting code.
293
294 Usage:
295 %edit [options] [args]
296
297 %edit runs IPython's editor hook. The default version of this hook is
298 set to call the editor specified by your $EDITOR environment variable.
299 If this isn't found, it will default to vi under Linux/Unix and to
300 notepad under Windows. See the end of this docstring for how to change
301 the editor hook.
302
303 You can also set the value of this editor via the
304 ``TerminalInteractiveShell.editor`` option in your configuration file.
305 This is useful if you wish to use a different editor from your typical
306 default with IPython (and for Windows users who typically don't set
307 environment variables).
308
309 This command allows you to conveniently edit multi-line code right in
310 your IPython session.
311
312 If called without arguments, %edit opens up an empty editor with a
313 temporary file and will execute the contents of this file when you
314 close it (don't forget to save it!).
315
316
317 Options:
318
319 -n <number>: open the editor at a specified line number. By default,
320 the IPython editor hook uses the unix syntax 'editor +N filename', but
321 you can configure this by providing your own modified hook if your
322 favorite editor supports line-number specifications with a different
323 syntax.
324
325 -p: this will call the editor with the same data as the previous time
326 it was used, regardless of how long ago (in your current session) it
327 was.
328
329 -r: use 'raw' input. This option only applies to input taken from the
330 user's history. By default, the 'processed' history is used, so that
331 magics are loaded in their transformed version to valid Python. If
332 this option is given, the raw input as typed as the command line is
333 used instead. When you exit the editor, it will be executed by
334 IPython's own processor.
335
336 -x: do not execute the edited code immediately upon exit. This is
337 mainly useful if you are editing programs which need to be called with
338 command line arguments, which you can then do using %run.
339
340
341 Arguments:
342
343 If arguments are given, the following possibilities exist:
344
345 - If the argument is a filename, IPython will load that into the
346 editor. It will execute its contents with execfile() when you exit,
347 loading any code in the file into your interactive namespace.
348
349 - The arguments are ranges of input history, e.g. "7 ~1/4-6".
350 The syntax is the same as in the %history magic.
351
352 - If the argument is a string variable, its contents are loaded
353 into the editor. You can thus edit any string which contains
354 python code (including the result of previous edits).
355
356 - If the argument is the name of an object (other than a string),
357 IPython will try to locate the file where it was defined and open the
358 editor at the point where it is defined. You can use `%edit function`
359 to load an editor exactly at the point where 'function' is defined,
360 edit it and have the file be executed automatically.
361
362 - If the object is a macro (see %macro for details), this opens up your
363 specified editor with a temporary file containing the macro's data.
364 Upon exit, the macro is reloaded with the contents of the file.
365
366 Note: opening at an exact line is only supported under Unix, and some
367 editors (like kedit and gedit up to Gnome 2.8) do not understand the
368 '+NUMBER' parameter necessary for this feature. Good editors like
369 (X)Emacs, vi, jed, pico and joe all do.
370
371 After executing your code, %edit will return as output the code you
372 typed in the editor (except when it was an existing file). This way
373 you can reload the code in further invocations of %edit as a variable,
374 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
375 the output.
376
377 Note that %edit is also available through the alias %ed.
378
379 This is an example of creating a simple function inside the editor and
380 then modifying it. First, start up the editor::
381
382 In [1]: ed
383 Editing... done. Executing edited code...
384 Out[1]: 'def foo():\\n print "foo() was defined in an editing
385 session"\\n'
386
387 We can then call the function foo()::
388
389 In [2]: foo()
390 foo() was defined in an editing session
391
392 Now we edit foo. IPython automatically loads the editor with the
393 (temporary) file where foo() was previously defined::
394
395 In [3]: ed foo
396 Editing... done. Executing edited code...
397
398 And if we call foo() again we get the modified version::
399
400 In [4]: foo()
401 foo() has now been changed!
402
403 Here is an example of how to edit a code snippet successive
404 times. First we call the editor::
405
406 In [5]: ed
407 Editing... done. Executing edited code...
408 hello
409 Out[5]: "print 'hello'\\n"
410
411 Now we call it again with the previous output (stored in _)::
412
413 In [6]: ed _
414 Editing... done. Executing edited code...
415 hello world
416 Out[6]: "print 'hello world'\\n"
417
418 Now we call it with the output #8 (stored in _8, also as Out[8])::
419
420 In [7]: ed _8
421 Editing... done. Executing edited code...
422 hello again
423 Out[7]: "print 'hello again'\\n"
424
425
426 Changing the default editor hook:
427
428 If you wish to write your own editor hook, you can put it in a
429 configuration file which you load at startup time. The default hook
430 is defined in the IPython.core.hooks module, and you can use that as a
431 starting example for further modifications. That file also has
432 general instructions on how to set a new hook for use once you've
433 defined it."""
434 opts,args = self.parse_options(parameter_s,'prxn:')
435
436 try:
437 filename, lineno, is_temp = self._find_edit_target(args, opts, last_call)
438 except MacroToEdit as e:
439 self._edit_macro(args, e.args[0])
440 return
441
442 # do actual editing here
443 print 'Editing...',
444 sys.stdout.flush()
445 try:
446 # Quote filenames that may have spaces in them
447 if ' ' in filename:
448 filename = "'%s'" % filename
449 self.shell.hooks.editor(filename,lineno)
450 except TryNext:
451 warn('Could not open editor')
452 return
453
454 # XXX TODO: should this be generalized for all string vars?
455 # For now, this is special-cased to blocks created by cpaste
456 if args.strip() == 'pasted_block':
457 self.shell.user_ns['pasted_block'] = file_read(filename)
458
459 if 'x' in opts: # -x prevents actual execution
460 print
461 else:
462 print 'done. Executing edited code...'
463 if 'r' in opts: # Untranslated IPython code
464 self.shell.run_cell(file_read(filename),
465 store_history=False)
466 else:
467 self.shell.safe_execfile(filename, self.shell.user_ns,
468 self.shell.user_ns)
469
470 if is_temp:
471 try:
472 return open(filename).read()
473 except IOError,msg:
474 if msg.filename == filename:
475 warn('File not found. Did you forget to save?')
476 return
477 else:
478 self.shell.showtraceback()
@@ -2005,7 +2005,7 b' class InteractiveShell(SingletonConfigurable):'
2005 self.register_magic_function = self.magics_manager.register_function
2005 self.register_magic_function = self.magics_manager.register_function
2006 self.define_magic = self.magics_manager.define_magic
2006 self.define_magic = self.magics_manager.define_magic
2007
2007
2008 self.register_magics(m.BasicMagics, mf.CodeMagics, mf.ConfigMagics,
2008 self.register_magics(m.BasicMagics, m.CodeMagics, mf.ConfigMagics,
2009 mf.ExecutionMagics, mf.NamespaceMagics, mf.AutoMagics,
2009 mf.ExecutionMagics, mf.NamespaceMagics, mf.AutoMagics,
2010 mf.OSMagics, mf.LoggingMagics, mf.ExtensionsMagics,
2010 mf.OSMagics, mf.LoggingMagics, mf.ExtensionsMagics,
2011 mf.PylabMagics, m.HistoryMagics, mf.DeprecatedMagics)
2011 mf.PylabMagics, m.HistoryMagics, mf.DeprecatedMagics)
@@ -12,7 +12,7 b''
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15 # Stdlib
16 import __builtin__ as builtin_mod
16 import __builtin__ as builtin_mod
17 import bdb
17 import bdb
18 import gc
18 import gc
@@ -38,6 +38,7 b' except ImportError:'
38 except ImportError:
38 except ImportError:
39 profile = pstats = None
39 profile = pstats = None
40
40
41 # Our own packages
41 from IPython.config.application import Application
42 from IPython.config.application import Application
42 from IPython.core import debugger, oinspect
43 from IPython.core import debugger, oinspect
43 from IPython.core import page
44 from IPython.core import page
@@ -59,449 +60,9 b' from IPython.utils.terminal import set_term_title'
59 from IPython.utils.timing import clock, clock2
60 from IPython.utils.timing import clock, clock2
60 from IPython.utils.warn import warn, error
61 from IPython.utils.warn import warn, error
61
62
62
63 #-----------------------------------------------------------------------------
63 # Used for exception handling in magic_edit
64 # Magic implementation classes
64 class MacroToEdit(ValueError): pass
65 #-----------------------------------------------------------------------------
65
66
67 @register_magics
68 class CodeMagics(Magics):
69 """Magics related to code management (loading, saving, editing, ...)."""
70
71 @line_magic
72 def save(self, parameter_s=''):
73 """Save a set of lines or a macro to a given filename.
74
75 Usage:\\
76 %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...
77
78 Options:
79
80 -r: use 'raw' input. By default, the 'processed' history is used,
81 so that magics are loaded in their transformed version to valid
82 Python. If this option is given, the raw input as typed as the
83 command line is used instead.
84
85 This function uses the same syntax as %history for input ranges,
86 then saves the lines to the filename you specify.
87
88 It adds a '.py' extension to the file if you don't do so yourself, and
89 it asks for confirmation before overwriting existing files."""
90
91 opts,args = self.parse_options(parameter_s,'r',mode='list')
92 fname, codefrom = unquote_filename(args[0]), " ".join(args[1:])
93 if not fname.endswith('.py'):
94 fname += '.py'
95 if os.path.isfile(fname):
96 ans = raw_input('File `%s` exists. Overwrite (y/[N])? ' % fname)
97 if ans.lower() not in ['y','yes']:
98 print 'Operation cancelled.'
99 return
100 try:
101 cmds = self.shell.find_user_code(codefrom, 'r' in opts)
102 except (TypeError, ValueError) as e:
103 print e.args[0]
104 return
105 with io.open(fname,'w', encoding="utf-8") as f:
106 f.write(u"# coding: utf-8\n")
107 f.write(py3compat.cast_unicode(cmds))
108 print 'The following commands were written to file `%s`:' % fname
109 print cmds
110
111 @line_magic
112 def pastebin(self, parameter_s=''):
113 """Upload code to Github's Gist paste bin, returning the URL.
114
115 Usage:\\
116 %pastebin [-d "Custom description"] 1-7
117
118 The argument can be an input history range, a filename, or the name of a
119 string or macro.
120
121 Options:
122
123 -d: Pass a custom description for the gist. The default will say
124 "Pasted from IPython".
125 """
126 opts, args = self.parse_options(parameter_s, 'd:')
127
128 try:
129 code = self.shell.find_user_code(args)
130 except (ValueError, TypeError) as e:
131 print e.args[0]
132 return
133
134 post_data = json.dumps({
135 "description": opts.get('d', "Pasted from IPython"),
136 "public": True,
137 "files": {
138 "file1.py": {
139 "content": code
140 }
141 }
142 }).encode('utf-8')
143
144 response = urlopen("https://api.github.com/gists", post_data)
145 response_data = json.loads(response.read().decode('utf-8'))
146 return response_data['html_url']
147
148 @line_magic
149 def loadpy(self, arg_s):
150 """Load a .py python script into the GUI console.
151
152 This magic command can either take a local filename or a url::
153
154 %loadpy myscript.py
155 %loadpy http://www.example.com/myscript.py
156 """
157 arg_s = unquote_filename(arg_s)
158 remote_url = arg_s.startswith(('http://', 'https://'))
159 local_url = not remote_url
160 if local_url and not arg_s.endswith('.py'):
161 # Local files must be .py; for remote URLs it's possible that the
162 # fetch URL doesn't have a .py in it (many servers have an opaque
163 # URL, such as scipy-central.org).
164 raise ValueError('%%loadpy only works with .py files: %s' % arg_s)
165
166 # openpy takes care of finding the source encoding (per PEP 263)
167 if remote_url:
168 contents = openpy.read_py_url(arg_s, skip_encoding_cookie=True)
169 else:
170 contents = openpy.read_py_file(arg_s, skip_encoding_cookie=True)
171
172 self.shell.set_next_input(contents)
173
174 def _find_edit_target(self, args, opts, last_call):
175 """Utility method used by magic_edit to find what to edit."""
176
177 def make_filename(arg):
178 "Make a filename from the given args"
179 arg = unquote_filename(arg)
180 try:
181 filename = get_py_filename(arg)
182 except IOError:
183 # If it ends with .py but doesn't already exist, assume we want
184 # a new file.
185 if arg.endswith('.py'):
186 filename = arg
187 else:
188 filename = None
189 return filename
190
191 # Set a few locals from the options for convenience:
192 opts_prev = 'p' in opts
193 opts_raw = 'r' in opts
194
195 # custom exceptions
196 class DataIsObject(Exception): pass
197
198 # Default line number value
199 lineno = opts.get('n',None)
200
201 if opts_prev:
202 args = '_%s' % last_call[0]
203 if not self.shell.user_ns.has_key(args):
204 args = last_call[1]
205
206 # use last_call to remember the state of the previous call, but don't
207 # let it be clobbered by successive '-p' calls.
208 try:
209 last_call[0] = self.shell.displayhook.prompt_count
210 if not opts_prev:
211 last_call[1] = args
212 except:
213 pass
214
215 # by default this is done with temp files, except when the given
216 # arg is a filename
217 use_temp = True
218
219 data = ''
220
221 # First, see if the arguments should be a filename.
222 filename = make_filename(args)
223 if filename:
224 use_temp = False
225 elif args:
226 # Mode where user specifies ranges of lines, like in %macro.
227 data = self.shell.extract_input_lines(args, opts_raw)
228 if not data:
229 try:
230 # Load the parameter given as a variable. If not a string,
231 # process it as an object instead (below)
232
233 #print '*** args',args,'type',type(args) # dbg
234 data = eval(args, self.shell.user_ns)
235 if not isinstance(data, basestring):
236 raise DataIsObject
237
238 except (NameError,SyntaxError):
239 # given argument is not a variable, try as a filename
240 filename = make_filename(args)
241 if filename is None:
242 warn("Argument given (%s) can't be found as a variable "
243 "or as a filename." % args)
244 return
245 use_temp = False
246
247 except DataIsObject:
248 # macros have a special edit function
249 if isinstance(data, Macro):
250 raise MacroToEdit(data)
251
252 # For objects, try to edit the file where they are defined
253 try:
254 filename = inspect.getabsfile(data)
255 if 'fakemodule' in filename.lower() and \
256 inspect.isclass(data):
257 # class created by %edit? Try to find source
258 # by looking for method definitions instead, the
259 # __module__ in those classes is FakeModule.
260 attrs = [getattr(data, aname) for aname in dir(data)]
261 for attr in attrs:
262 if not inspect.ismethod(attr):
263 continue
264 filename = inspect.getabsfile(attr)
265 if filename and \
266 'fakemodule' not in filename.lower():
267 # change the attribute to be the edit
268 # target instead
269 data = attr
270 break
271
272 datafile = 1
273 except TypeError:
274 filename = make_filename(args)
275 datafile = 1
276 warn('Could not find file where `%s` is defined.\n'
277 'Opening a file named `%s`' % (args,filename))
278 # Now, make sure we can actually read the source (if it was
279 # in a temp file it's gone by now).
280 if datafile:
281 try:
282 if lineno is None:
283 lineno = inspect.getsourcelines(data)[1]
284 except IOError:
285 filename = make_filename(args)
286 if filename is None:
287 warn('The file `%s` where `%s` was defined cannot '
288 'be read.' % (filename,data))
289 return
290 use_temp = False
291
292 if use_temp:
293 filename = self.shell.mktempfile(data)
294 print 'IPython will make a temporary file named:',filename
295
296 return filename, lineno, use_temp
297
298 def _edit_macro(self,mname,macro):
299 """open an editor with the macro data in a file"""
300 filename = self.shell.mktempfile(macro.value)
301 self.shell.hooks.editor(filename)
302
303 # and make a new macro object, to replace the old one
304 mfile = open(filename)
305 mvalue = mfile.read()
306 mfile.close()
307 self.shell.user_ns[mname] = Macro(mvalue)
308
309 @line_magic
310 def ed(self, parameter_s=''):
311 """Alias to %edit."""
312 return self.edit(parameter_s)
313
314 @skip_doctest
315 @line_magic
316 def edit(self, parameter_s='',last_call=['','']):
317 """Bring up an editor and execute the resulting code.
318
319 Usage:
320 %edit [options] [args]
321
322 %edit runs IPython's editor hook. The default version of this hook is
323 set to call the editor specified by your $EDITOR environment variable.
324 If this isn't found, it will default to vi under Linux/Unix and to
325 notepad under Windows. See the end of this docstring for how to change
326 the editor hook.
327
328 You can also set the value of this editor via the
329 ``TerminalInteractiveShell.editor`` option in your configuration file.
330 This is useful if you wish to use a different editor from your typical
331 default with IPython (and for Windows users who typically don't set
332 environment variables).
333
334 This command allows you to conveniently edit multi-line code right in
335 your IPython session.
336
337 If called without arguments, %edit opens up an empty editor with a
338 temporary file and will execute the contents of this file when you
339 close it (don't forget to save it!).
340
341
342 Options:
343
344 -n <number>: open the editor at a specified line number. By default,
345 the IPython editor hook uses the unix syntax 'editor +N filename', but
346 you can configure this by providing your own modified hook if your
347 favorite editor supports line-number specifications with a different
348 syntax.
349
350 -p: this will call the editor with the same data as the previous time
351 it was used, regardless of how long ago (in your current session) it
352 was.
353
354 -r: use 'raw' input. This option only applies to input taken from the
355 user's history. By default, the 'processed' history is used, so that
356 magics are loaded in their transformed version to valid Python. If
357 this option is given, the raw input as typed as the command line is
358 used instead. When you exit the editor, it will be executed by
359 IPython's own processor.
360
361 -x: do not execute the edited code immediately upon exit. This is
362 mainly useful if you are editing programs which need to be called with
363 command line arguments, which you can then do using %run.
364
365
366 Arguments:
367
368 If arguments are given, the following possibilities exist:
369
370 - If the argument is a filename, IPython will load that into the
371 editor. It will execute its contents with execfile() when you exit,
372 loading any code in the file into your interactive namespace.
373
374 - The arguments are ranges of input history, e.g. "7 ~1/4-6".
375 The syntax is the same as in the %history magic.
376
377 - If the argument is a string variable, its contents are loaded
378 into the editor. You can thus edit any string which contains
379 python code (including the result of previous edits).
380
381 - If the argument is the name of an object (other than a string),
382 IPython will try to locate the file where it was defined and open the
383 editor at the point where it is defined. You can use `%edit function`
384 to load an editor exactly at the point where 'function' is defined,
385 edit it and have the file be executed automatically.
386
387 - If the object is a macro (see %macro for details), this opens up your
388 specified editor with a temporary file containing the macro's data.
389 Upon exit, the macro is reloaded with the contents of the file.
390
391 Note: opening at an exact line is only supported under Unix, and some
392 editors (like kedit and gedit up to Gnome 2.8) do not understand the
393 '+NUMBER' parameter necessary for this feature. Good editors like
394 (X)Emacs, vi, jed, pico and joe all do.
395
396 After executing your code, %edit will return as output the code you
397 typed in the editor (except when it was an existing file). This way
398 you can reload the code in further invocations of %edit as a variable,
399 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
400 the output.
401
402 Note that %edit is also available through the alias %ed.
403
404 This is an example of creating a simple function inside the editor and
405 then modifying it. First, start up the editor::
406
407 In [1]: ed
408 Editing... done. Executing edited code...
409 Out[1]: 'def foo():\\n print "foo() was defined in an editing
410 session"\\n'
411
412 We can then call the function foo()::
413
414 In [2]: foo()
415 foo() was defined in an editing session
416
417 Now we edit foo. IPython automatically loads the editor with the
418 (temporary) file where foo() was previously defined::
419
420 In [3]: ed foo
421 Editing... done. Executing edited code...
422
423 And if we call foo() again we get the modified version::
424
425 In [4]: foo()
426 foo() has now been changed!
427
428 Here is an example of how to edit a code snippet successive
429 times. First we call the editor::
430
431 In [5]: ed
432 Editing... done. Executing edited code...
433 hello
434 Out[5]: "print 'hello'\\n"
435
436 Now we call it again with the previous output (stored in _)::
437
438 In [6]: ed _
439 Editing... done. Executing edited code...
440 hello world
441 Out[6]: "print 'hello world'\\n"
442
443 Now we call it with the output #8 (stored in _8, also as Out[8])::
444
445 In [7]: ed _8
446 Editing... done. Executing edited code...
447 hello again
448 Out[7]: "print 'hello again'\\n"
449
450
451 Changing the default editor hook:
452
453 If you wish to write your own editor hook, you can put it in a
454 configuration file which you load at startup time. The default hook
455 is defined in the IPython.core.hooks module, and you can use that as a
456 starting example for further modifications. That file also has
457 general instructions on how to set a new hook for use once you've
458 defined it."""
459 opts,args = self.parse_options(parameter_s,'prxn:')
460
461 try:
462 filename, lineno, is_temp = self._find_edit_target(args, opts, last_call)
463 except MacroToEdit as e:
464 self._edit_macro(args, e.args[0])
465 return
466
467 # do actual editing here
468 print 'Editing...',
469 sys.stdout.flush()
470 try:
471 # Quote filenames that may have spaces in them
472 if ' ' in filename:
473 filename = "'%s'" % filename
474 self.shell.hooks.editor(filename,lineno)
475 except TryNext:
476 warn('Could not open editor')
477 return
478
479 # XXX TODO: should this be generalized for all string vars?
480 # For now, this is special-cased to blocks created by cpaste
481 if args.strip() == 'pasted_block':
482 self.shell.user_ns['pasted_block'] = file_read(filename)
483
484 if 'x' in opts: # -x prevents actual execution
485 print
486 else:
487 print 'done. Executing edited code...'
488 if 'r' in opts: # Untranslated IPython code
489 self.shell.run_cell(file_read(filename),
490 store_history=False)
491 else:
492 self.shell.safe_execfile(filename, self.shell.user_ns,
493 self.shell.user_ns)
494
495 if is_temp:
496 try:
497 return open(filename).read()
498 except IOError,msg:
499 if msg.filename == filename:
500 warn('File not found. Did you forget to save?')
501 return
502 else:
503 self.shell.showtraceback()
504
505
66
506 @register_magics
67 @register_magics
507 class ConfigMagics(Magics):
68 class ConfigMagics(Magics):
@@ -13,8 +13,9 b''
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 from IPython.core.magic import Magics, register_magics
15 from IPython.core.magic import Magics, register_magics
16 from basic import BasicMagics
16 from .basic import BasicMagics
17 from history import HistoryMagics
17 from .code import CodeMagics, MacroToEdit
18 from .history import HistoryMagics
18
19
19 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
20 # Magic implementation classes
21 # Magic implementation classes
General Comments 0
You need to be logged in to leave comments. Login now