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