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