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