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