##// END OF EJS Templates
Merge pull request #1784 from Carreau/loadpycat2...
Fernando Perez -
r7062:a0ab74e3 merge
parent child Browse files
Show More
@@ -1,478 +1,506 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
24 from IPython.core.error import TryNext
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.testing.skipdoctest import skip_doctest
27 from IPython.testing.skipdoctest import skip_doctest
28 from IPython.utils import openpy
28 from IPython.utils import openpy
29 from IPython.utils import py3compat
29 from IPython.utils import py3compat
30 from IPython.utils.io import file_read
30 from IPython.utils.io import file_read
31 from IPython.utils.path import get_py_filename, unquote_filename
31 from IPython.utils.path import get_py_filename, unquote_filename
32 from IPython.utils.warn import warn
32 from IPython.utils.warn import warn
33
33
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35 # Magic implementation classes
35 # Magic implementation classes
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37
37
38 # Used for exception handling in magic_edit
38 # Used for exception handling in magic_edit
39 class MacroToEdit(ValueError): pass
39 class MacroToEdit(ValueError): pass
40
40
41
41
42 @magics_class
42 @magics_class
43 class CodeMagics(Magics):
43 class CodeMagics(Magics):
44 """Magics related to code management (loading, saving, editing, ...)."""
44 """Magics related to code management (loading, saving, editing, ...)."""
45
45
46 @line_magic
46 @line_magic
47 def save(self, parameter_s=''):
47 def save(self, parameter_s=''):
48 """Save a set of lines or a macro to a given filename.
48 """Save a set of lines or a macro to a given filename.
49
49
50 Usage:\\
50 Usage:\\
51 %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...
51 %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...
52
52
53 Options:
53 Options:
54
54
55 -r: use 'raw' input. By default, the 'processed' history is used,
55 -r: use 'raw' input. By default, the 'processed' history is used,
56 so that magics are loaded in their transformed version to valid
56 so that magics are loaded in their transformed version to valid
57 Python. If this option is given, the raw input as typed as the
57 Python. If this option is given, the raw input as typed as the
58 command line is used instead.
58 command line is used instead.
59
59
60 This function uses the same syntax as %history for input ranges,
60 This function uses the same syntax as %history for input ranges,
61 then saves the lines to the filename you specify.
61 then saves the lines to the filename you specify.
62
62
63 It adds a '.py' extension to the file if you don't do so yourself, and
63 It adds a '.py' extension to the file if you don't do so yourself, and
64 it asks for confirmation before overwriting existing files."""
64 it asks for confirmation before overwriting existing files."""
65
65
66 opts,args = self.parse_options(parameter_s,'r',mode='list')
66 opts,args = self.parse_options(parameter_s,'r',mode='list')
67 fname, codefrom = unquote_filename(args[0]), " ".join(args[1:])
67 fname, codefrom = unquote_filename(args[0]), " ".join(args[1:])
68 if not fname.endswith('.py'):
68 if not fname.endswith('.py'):
69 fname += '.py'
69 fname += '.py'
70 if os.path.isfile(fname):
70 if os.path.isfile(fname):
71 ans = raw_input('File `%s` exists. Overwrite (y/[N])? ' % fname)
71 overwrite = self.shell.ask_yes_no('File `%s` exists. Overwrite (y/[N])? ' % fname, default='n')
72 if ans.lower() not in ['y','yes']:
72 if not overwrite :
73 print 'Operation cancelled.'
73 print 'Operation cancelled.'
74 return
74 return
75 try:
75 try:
76 cmds = self.shell.find_user_code(codefrom, 'r' in opts)
76 cmds = self.shell.find_user_code(codefrom, 'r' in opts)
77 except (TypeError, ValueError) as e:
77 except (TypeError, ValueError) as e:
78 print e.args[0]
78 print e.args[0]
79 return
79 return
80 with io.open(fname,'w', encoding="utf-8") as f:
80 with io.open(fname,'w', encoding="utf-8") as f:
81 f.write(u"# coding: utf-8\n")
81 f.write(u"# coding: utf-8\n")
82 f.write(py3compat.cast_unicode(cmds))
82 f.write(py3compat.cast_unicode(cmds))
83 print 'The following commands were written to file `%s`:' % fname
83 print 'The following commands were written to file `%s`:' % fname
84 print cmds
84 print cmds
85
85
86 @line_magic
86 @line_magic
87 def pastebin(self, parameter_s=''):
87 def pastebin(self, parameter_s=''):
88 """Upload code to Github's Gist paste bin, returning the URL.
88 """Upload code to Github's Gist paste bin, returning the URL.
89
89
90 Usage:\\
90 Usage:\\
91 %pastebin [-d "Custom description"] 1-7
91 %pastebin [-d "Custom description"] 1-7
92
92
93 The argument can be an input history range, a filename, or the name of a
93 The argument can be an input history range, a filename, or the name of a
94 string or macro.
94 string or macro.
95
95
96 Options:
96 Options:
97
97
98 -d: Pass a custom description for the gist. The default will say
98 -d: Pass a custom description for the gist. The default will say
99 "Pasted from IPython".
99 "Pasted from IPython".
100 """
100 """
101 opts, args = self.parse_options(parameter_s, 'd:')
101 opts, args = self.parse_options(parameter_s, 'd:')
102
102
103 try:
103 try:
104 code = self.shell.find_user_code(args)
104 code = self.shell.find_user_code(args)
105 except (ValueError, TypeError) as e:
105 except (ValueError, TypeError) as e:
106 print e.args[0]
106 print e.args[0]
107 return
107 return
108
108
109 post_data = json.dumps({
109 post_data = json.dumps({
110 "description": opts.get('d', "Pasted from IPython"),
110 "description": opts.get('d', "Pasted from IPython"),
111 "public": True,
111 "public": True,
112 "files": {
112 "files": {
113 "file1.py": {
113 "file1.py": {
114 "content": code
114 "content": code
115 }
115 }
116 }
116 }
117 }).encode('utf-8')
117 }).encode('utf-8')
118
118
119 response = urlopen("https://api.github.com/gists", post_data)
119 response = urlopen("https://api.github.com/gists", post_data)
120 response_data = json.loads(response.read().decode('utf-8'))
120 response_data = json.loads(response.read().decode('utf-8'))
121 return response_data['html_url']
121 return response_data['html_url']
122
122
123 @line_magic
123 @line_magic
124 def loadpy(self, arg_s):
124 def loadpy(self, arg_s):
125 """Load a .py python script into the GUI console.
125 """Alias of `%load`
126
126
127 This magic command can either take a local filename or a url::
127 `%loadpy` has gained some flexibility and droped the requirement of a `.py`
128 extension. So it has been renamed simply into %load. You can look at
129 `%load`'s docstring for more info.
130 """
131 self.magic_load(arg_s)
132
133 @line_magic
134 def load(self, arg_s):
135 """Load code into the current frontend.
128
136
129 %loadpy myscript.py
137 Usage:\\
130 %loadpy http://www.example.com/myscript.py
138 %load [options] source
139
140 where source can be a filename, URL, input history range or macro
141
142 Options:
143 --------
144 -y : Don't ask confirmation for loading source above 200 000 characters.
145
146 This magic command can either take a local filename, a URL, an history
147 range (see %history) or a macro as argument, it will prompt for
148 confirmation before loading source with more than 200 000 characters, unless
149 -y flag is passed or if the frontend does not support raw_input::
150
151 %load myscript.py
152 %load 7-27
153 %load myMacro
154 %load http://www.example.com/myscript.py
131 """
155 """
132 arg_s = unquote_filename(arg_s)
156 opts,args = self.parse_options(arg_s,'y')
133 remote_url = arg_s.startswith(('http://', 'https://'))
157
134 local_url = not remote_url
158 contents = self.shell.find_user_code(args)
135 if local_url and not arg_s.endswith('.py'):
159 l = len(contents)
136 # Local files must be .py; for remote URLs it's possible that the
160
137 # fetch URL doesn't have a .py in it (many servers have an opaque
161 # 200 000 is ~ 2500 full 80 caracter lines
138 # URL, such as scipy-central.org).
162 # so in average, more than 5000 lines
139 raise ValueError('%%loadpy only works with .py files: %s' % arg_s)
163 if l > 200000 and 'y' not in opts:
140
164 try:
141 # openpy takes care of finding the source encoding (per PEP 263)
165 ans = self.shell.ask_yes_no(("The text you're trying to load seems pretty big"\
142 if remote_url:
166 " (%d characters). Continue (y/[N]) ?" % l), default='n' )
143 contents = openpy.read_py_url(arg_s, skip_encoding_cookie=True)
167 except StdinNotImplementedError:
144 else:
168 #asume yes if raw input not implemented
145 contents = openpy.read_py_file(arg_s, skip_encoding_cookie=True)
169 ans = True
170
171 if ans is False :
172 print 'Operation cancelled.'
173 return
146
174
147 self.shell.set_next_input(contents)
175 self.shell.set_next_input(contents)
148
176
149 def _find_edit_target(self, args, opts, last_call):
177 def _find_edit_target(self, args, opts, last_call):
150 """Utility method used by magic_edit to find what to edit."""
178 """Utility method used by magic_edit to find what to edit."""
151
179
152 def make_filename(arg):
180 def make_filename(arg):
153 "Make a filename from the given args"
181 "Make a filename from the given args"
154 arg = unquote_filename(arg)
182 arg = unquote_filename(arg)
155 try:
183 try:
156 filename = get_py_filename(arg)
184 filename = get_py_filename(arg)
157 except IOError:
185 except IOError:
158 # If it ends with .py but doesn't already exist, assume we want
186 # If it ends with .py but doesn't already exist, assume we want
159 # a new file.
187 # a new file.
160 if arg.endswith('.py'):
188 if arg.endswith('.py'):
161 filename = arg
189 filename = arg
162 else:
190 else:
163 filename = None
191 filename = None
164 return filename
192 return filename
165
193
166 # Set a few locals from the options for convenience:
194 # Set a few locals from the options for convenience:
167 opts_prev = 'p' in opts
195 opts_prev = 'p' in opts
168 opts_raw = 'r' in opts
196 opts_raw = 'r' in opts
169
197
170 # custom exceptions
198 # custom exceptions
171 class DataIsObject(Exception): pass
199 class DataIsObject(Exception): pass
172
200
173 # Default line number value
201 # Default line number value
174 lineno = opts.get('n',None)
202 lineno = opts.get('n',None)
175
203
176 if opts_prev:
204 if opts_prev:
177 args = '_%s' % last_call[0]
205 args = '_%s' % last_call[0]
178 if not self.shell.user_ns.has_key(args):
206 if not self.shell.user_ns.has_key(args):
179 args = last_call[1]
207 args = last_call[1]
180
208
181 # use last_call to remember the state of the previous call, but don't
209 # use last_call to remember the state of the previous call, but don't
182 # let it be clobbered by successive '-p' calls.
210 # let it be clobbered by successive '-p' calls.
183 try:
211 try:
184 last_call[0] = self.shell.displayhook.prompt_count
212 last_call[0] = self.shell.displayhook.prompt_count
185 if not opts_prev:
213 if not opts_prev:
186 last_call[1] = args
214 last_call[1] = args
187 except:
215 except:
188 pass
216 pass
189
217
190 # by default this is done with temp files, except when the given
218 # by default this is done with temp files, except when the given
191 # arg is a filename
219 # arg is a filename
192 use_temp = True
220 use_temp = True
193
221
194 data = ''
222 data = ''
195
223
196 # First, see if the arguments should be a filename.
224 # First, see if the arguments should be a filename.
197 filename = make_filename(args)
225 filename = make_filename(args)
198 if filename:
226 if filename:
199 use_temp = False
227 use_temp = False
200 elif args:
228 elif args:
201 # Mode where user specifies ranges of lines, like in %macro.
229 # Mode where user specifies ranges of lines, like in %macro.
202 data = self.shell.extract_input_lines(args, opts_raw)
230 data = self.shell.extract_input_lines(args, opts_raw)
203 if not data:
231 if not data:
204 try:
232 try:
205 # Load the parameter given as a variable. If not a string,
233 # Load the parameter given as a variable. If not a string,
206 # process it as an object instead (below)
234 # process it as an object instead (below)
207
235
208 #print '*** args',args,'type',type(args) # dbg
236 #print '*** args',args,'type',type(args) # dbg
209 data = eval(args, self.shell.user_ns)
237 data = eval(args, self.shell.user_ns)
210 if not isinstance(data, basestring):
238 if not isinstance(data, basestring):
211 raise DataIsObject
239 raise DataIsObject
212
240
213 except (NameError,SyntaxError):
241 except (NameError,SyntaxError):
214 # given argument is not a variable, try as a filename
242 # given argument is not a variable, try as a filename
215 filename = make_filename(args)
243 filename = make_filename(args)
216 if filename is None:
244 if filename is None:
217 warn("Argument given (%s) can't be found as a variable "
245 warn("Argument given (%s) can't be found as a variable "
218 "or as a filename." % args)
246 "or as a filename." % args)
219 return
247 return
220 use_temp = False
248 use_temp = False
221
249
222 except DataIsObject:
250 except DataIsObject:
223 # macros have a special edit function
251 # macros have a special edit function
224 if isinstance(data, Macro):
252 if isinstance(data, Macro):
225 raise MacroToEdit(data)
253 raise MacroToEdit(data)
226
254
227 # For objects, try to edit the file where they are defined
255 # For objects, try to edit the file where they are defined
228 try:
256 try:
229 filename = inspect.getabsfile(data)
257 filename = inspect.getabsfile(data)
230 if 'fakemodule' in filename.lower() and \
258 if 'fakemodule' in filename.lower() and \
231 inspect.isclass(data):
259 inspect.isclass(data):
232 # class created by %edit? Try to find source
260 # class created by %edit? Try to find source
233 # by looking for method definitions instead, the
261 # by looking for method definitions instead, the
234 # __module__ in those classes is FakeModule.
262 # __module__ in those classes is FakeModule.
235 attrs = [getattr(data, aname) for aname in dir(data)]
263 attrs = [getattr(data, aname) for aname in dir(data)]
236 for attr in attrs:
264 for attr in attrs:
237 if not inspect.ismethod(attr):
265 if not inspect.ismethod(attr):
238 continue
266 continue
239 filename = inspect.getabsfile(attr)
267 filename = inspect.getabsfile(attr)
240 if filename and \
268 if filename and \
241 'fakemodule' not in filename.lower():
269 'fakemodule' not in filename.lower():
242 # change the attribute to be the edit
270 # change the attribute to be the edit
243 # target instead
271 # target instead
244 data = attr
272 data = attr
245 break
273 break
246
274
247 datafile = 1
275 datafile = 1
248 except TypeError:
276 except TypeError:
249 filename = make_filename(args)
277 filename = make_filename(args)
250 datafile = 1
278 datafile = 1
251 warn('Could not find file where `%s` is defined.\n'
279 warn('Could not find file where `%s` is defined.\n'
252 'Opening a file named `%s`' % (args, filename))
280 'Opening a file named `%s`' % (args, filename))
253 # Now, make sure we can actually read the source (if it was
281 # Now, make sure we can actually read the source (if it was
254 # in a temp file it's gone by now).
282 # in a temp file it's gone by now).
255 if datafile:
283 if datafile:
256 try:
284 try:
257 if lineno is None:
285 if lineno is None:
258 lineno = inspect.getsourcelines(data)[1]
286 lineno = inspect.getsourcelines(data)[1]
259 except IOError:
287 except IOError:
260 filename = make_filename(args)
288 filename = make_filename(args)
261 if filename is None:
289 if filename is None:
262 warn('The file `%s` where `%s` was defined '
290 warn('The file `%s` where `%s` was defined '
263 'cannot be read.' % (filename, data))
291 'cannot be read.' % (filename, data))
264 return
292 return
265 use_temp = False
293 use_temp = False
266
294
267 if use_temp:
295 if use_temp:
268 filename = self.shell.mktempfile(data)
296 filename = self.shell.mktempfile(data)
269 print 'IPython will make a temporary file named:',filename
297 print 'IPython will make a temporary file named:',filename
270
298
271 return filename, lineno, use_temp
299 return filename, lineno, use_temp
272
300
273 def _edit_macro(self,mname,macro):
301 def _edit_macro(self,mname,macro):
274 """open an editor with the macro data in a file"""
302 """open an editor with the macro data in a file"""
275 filename = self.shell.mktempfile(macro.value)
303 filename = self.shell.mktempfile(macro.value)
276 self.shell.hooks.editor(filename)
304 self.shell.hooks.editor(filename)
277
305
278 # and make a new macro object, to replace the old one
306 # and make a new macro object, to replace the old one
279 mfile = open(filename)
307 mfile = open(filename)
280 mvalue = mfile.read()
308 mvalue = mfile.read()
281 mfile.close()
309 mfile.close()
282 self.shell.user_ns[mname] = Macro(mvalue)
310 self.shell.user_ns[mname] = Macro(mvalue)
283
311
284 @line_magic
312 @line_magic
285 def ed(self, parameter_s=''):
313 def ed(self, parameter_s=''):
286 """Alias to %edit."""
314 """Alias to %edit."""
287 return self.edit(parameter_s)
315 return self.edit(parameter_s)
288
316
289 @skip_doctest
317 @skip_doctest
290 @line_magic
318 @line_magic
291 def edit(self, parameter_s='',last_call=['','']):
319 def edit(self, parameter_s='',last_call=['','']):
292 """Bring up an editor and execute the resulting code.
320 """Bring up an editor and execute the resulting code.
293
321
294 Usage:
322 Usage:
295 %edit [options] [args]
323 %edit [options] [args]
296
324
297 %edit runs IPython's editor hook. The default version of this hook is
325 %edit runs IPython's editor hook. The default version of this hook is
298 set to call the editor specified by your $EDITOR environment variable.
326 set to call the editor specified by your $EDITOR environment variable.
299 If this isn't found, it will default to vi under Linux/Unix and to
327 If this isn't found, it will default to vi under Linux/Unix and to
300 notepad under Windows. See the end of this docstring for how to change
328 notepad under Windows. See the end of this docstring for how to change
301 the editor hook.
329 the editor hook.
302
330
303 You can also set the value of this editor via the
331 You can also set the value of this editor via the
304 ``TerminalInteractiveShell.editor`` option in your configuration file.
332 ``TerminalInteractiveShell.editor`` option in your configuration file.
305 This is useful if you wish to use a different editor from your typical
333 This is useful if you wish to use a different editor from your typical
306 default with IPython (and for Windows users who typically don't set
334 default with IPython (and for Windows users who typically don't set
307 environment variables).
335 environment variables).
308
336
309 This command allows you to conveniently edit multi-line code right in
337 This command allows you to conveniently edit multi-line code right in
310 your IPython session.
338 your IPython session.
311
339
312 If called without arguments, %edit opens up an empty editor with a
340 If called without arguments, %edit opens up an empty editor with a
313 temporary file and will execute the contents of this file when you
341 temporary file and will execute the contents of this file when you
314 close it (don't forget to save it!).
342 close it (don't forget to save it!).
315
343
316
344
317 Options:
345 Options:
318
346
319 -n <number>: open the editor at a specified line number. By default,
347 -n <number>: open the editor at a specified line number. By default,
320 the IPython editor hook uses the unix syntax 'editor +N filename', but
348 the IPython editor hook uses the unix syntax 'editor +N filename', but
321 you can configure this by providing your own modified hook if your
349 you can configure this by providing your own modified hook if your
322 favorite editor supports line-number specifications with a different
350 favorite editor supports line-number specifications with a different
323 syntax.
351 syntax.
324
352
325 -p: this will call the editor with the same data as the previous time
353 -p: this will call the editor with the same data as the previous time
326 it was used, regardless of how long ago (in your current session) it
354 it was used, regardless of how long ago (in your current session) it
327 was.
355 was.
328
356
329 -r: use 'raw' input. This option only applies to input taken from the
357 -r: use 'raw' input. This option only applies to input taken from the
330 user's history. By default, the 'processed' history is used, so that
358 user's history. By default, the 'processed' history is used, so that
331 magics are loaded in their transformed version to valid Python. If
359 magics are loaded in their transformed version to valid Python. If
332 this option is given, the raw input as typed as the command line is
360 this option is given, the raw input as typed as the command line is
333 used instead. When you exit the editor, it will be executed by
361 used instead. When you exit the editor, it will be executed by
334 IPython's own processor.
362 IPython's own processor.
335
363
336 -x: do not execute the edited code immediately upon exit. This is
364 -x: do not execute the edited code immediately upon exit. This is
337 mainly useful if you are editing programs which need to be called with
365 mainly useful if you are editing programs which need to be called with
338 command line arguments, which you can then do using %run.
366 command line arguments, which you can then do using %run.
339
367
340
368
341 Arguments:
369 Arguments:
342
370
343 If arguments are given, the following possibilities exist:
371 If arguments are given, the following possibilities exist:
344
372
345 - If the argument is a filename, IPython will load that into the
373 - If the argument is a filename, IPython will load that into the
346 editor. It will execute its contents with execfile() when you exit,
374 editor. It will execute its contents with execfile() when you exit,
347 loading any code in the file into your interactive namespace.
375 loading any code in the file into your interactive namespace.
348
376
349 - The arguments are ranges of input history, e.g. "7 ~1/4-6".
377 - The arguments are ranges of input history, e.g. "7 ~1/4-6".
350 The syntax is the same as in the %history magic.
378 The syntax is the same as in the %history magic.
351
379
352 - If the argument is a string variable, its contents are loaded
380 - If the argument is a string variable, its contents are loaded
353 into the editor. You can thus edit any string which contains
381 into the editor. You can thus edit any string which contains
354 python code (including the result of previous edits).
382 python code (including the result of previous edits).
355
383
356 - If the argument is the name of an object (other than a string),
384 - If the argument is the name of an object (other than a string),
357 IPython will try to locate the file where it was defined and open the
385 IPython will try to locate the file where it was defined and open the
358 editor at the point where it is defined. You can use `%edit function`
386 editor at the point where it is defined. You can use `%edit function`
359 to load an editor exactly at the point where 'function' is defined,
387 to load an editor exactly at the point where 'function' is defined,
360 edit it and have the file be executed automatically.
388 edit it and have the file be executed automatically.
361
389
362 - If the object is a macro (see %macro for details), this opens up your
390 - If the object is a macro (see %macro for details), this opens up your
363 specified editor with a temporary file containing the macro's data.
391 specified editor with a temporary file containing the macro's data.
364 Upon exit, the macro is reloaded with the contents of the file.
392 Upon exit, the macro is reloaded with the contents of the file.
365
393
366 Note: opening at an exact line is only supported under Unix, and some
394 Note: opening at an exact line is only supported under Unix, and some
367 editors (like kedit and gedit up to Gnome 2.8) do not understand the
395 editors (like kedit and gedit up to Gnome 2.8) do not understand the
368 '+NUMBER' parameter necessary for this feature. Good editors like
396 '+NUMBER' parameter necessary for this feature. Good editors like
369 (X)Emacs, vi, jed, pico and joe all do.
397 (X)Emacs, vi, jed, pico and joe all do.
370
398
371 After executing your code, %edit will return as output the code you
399 After executing your code, %edit will return as output the code you
372 typed in the editor (except when it was an existing file). This way
400 typed in the editor (except when it was an existing file). This way
373 you can reload the code in further invocations of %edit as a variable,
401 you can reload the code in further invocations of %edit as a variable,
374 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
402 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
375 the output.
403 the output.
376
404
377 Note that %edit is also available through the alias %ed.
405 Note that %edit is also available through the alias %ed.
378
406
379 This is an example of creating a simple function inside the editor and
407 This is an example of creating a simple function inside the editor and
380 then modifying it. First, start up the editor::
408 then modifying it. First, start up the editor::
381
409
382 In [1]: ed
410 In [1]: ed
383 Editing... done. Executing edited code...
411 Editing... done. Executing edited code...
384 Out[1]: 'def foo():\\n print "foo() was defined in an editing
412 Out[1]: 'def foo():\\n print "foo() was defined in an editing
385 session"\\n'
413 session"\\n'
386
414
387 We can then call the function foo()::
415 We can then call the function foo()::
388
416
389 In [2]: foo()
417 In [2]: foo()
390 foo() was defined in an editing session
418 foo() was defined in an editing session
391
419
392 Now we edit foo. IPython automatically loads the editor with the
420 Now we edit foo. IPython automatically loads the editor with the
393 (temporary) file where foo() was previously defined::
421 (temporary) file where foo() was previously defined::
394
422
395 In [3]: ed foo
423 In [3]: ed foo
396 Editing... done. Executing edited code...
424 Editing... done. Executing edited code...
397
425
398 And if we call foo() again we get the modified version::
426 And if we call foo() again we get the modified version::
399
427
400 In [4]: foo()
428 In [4]: foo()
401 foo() has now been changed!
429 foo() has now been changed!
402
430
403 Here is an example of how to edit a code snippet successive
431 Here is an example of how to edit a code snippet successive
404 times. First we call the editor::
432 times. First we call the editor::
405
433
406 In [5]: ed
434 In [5]: ed
407 Editing... done. Executing edited code...
435 Editing... done. Executing edited code...
408 hello
436 hello
409 Out[5]: "print 'hello'\\n"
437 Out[5]: "print 'hello'\\n"
410
438
411 Now we call it again with the previous output (stored in _)::
439 Now we call it again with the previous output (stored in _)::
412
440
413 In [6]: ed _
441 In [6]: ed _
414 Editing... done. Executing edited code...
442 Editing... done. Executing edited code...
415 hello world
443 hello world
416 Out[6]: "print 'hello world'\\n"
444 Out[6]: "print 'hello world'\\n"
417
445
418 Now we call it with the output #8 (stored in _8, also as Out[8])::
446 Now we call it with the output #8 (stored in _8, also as Out[8])::
419
447
420 In [7]: ed _8
448 In [7]: ed _8
421 Editing... done. Executing edited code...
449 Editing... done. Executing edited code...
422 hello again
450 hello again
423 Out[7]: "print 'hello again'\\n"
451 Out[7]: "print 'hello again'\\n"
424
452
425
453
426 Changing the default editor hook:
454 Changing the default editor hook:
427
455
428 If you wish to write your own editor hook, you can put it in a
456 If you wish to write your own editor hook, you can put it in a
429 configuration file which you load at startup time. The default hook
457 configuration file which you load at startup time. The default hook
430 is defined in the IPython.core.hooks module, and you can use that as a
458 is defined in the IPython.core.hooks module, and you can use that as a
431 starting example for further modifications. That file also has
459 starting example for further modifications. That file also has
432 general instructions on how to set a new hook for use once you've
460 general instructions on how to set a new hook for use once you've
433 defined it."""
461 defined it."""
434 opts,args = self.parse_options(parameter_s,'prxn:')
462 opts,args = self.parse_options(parameter_s,'prxn:')
435
463
436 try:
464 try:
437 filename, lineno, is_temp = self._find_edit_target(args, opts, last_call)
465 filename, lineno, is_temp = self._find_edit_target(args, opts, last_call)
438 except MacroToEdit as e:
466 except MacroToEdit as e:
439 self._edit_macro(args, e.args[0])
467 self._edit_macro(args, e.args[0])
440 return
468 return
441
469
442 # do actual editing here
470 # do actual editing here
443 print 'Editing...',
471 print 'Editing...',
444 sys.stdout.flush()
472 sys.stdout.flush()
445 try:
473 try:
446 # Quote filenames that may have spaces in them
474 # Quote filenames that may have spaces in them
447 if ' ' in filename:
475 if ' ' in filename:
448 filename = "'%s'" % filename
476 filename = "'%s'" % filename
449 self.shell.hooks.editor(filename,lineno)
477 self.shell.hooks.editor(filename,lineno)
450 except TryNext:
478 except TryNext:
451 warn('Could not open editor')
479 warn('Could not open editor')
452 return
480 return
453
481
454 # XXX TODO: should this be generalized for all string vars?
482 # XXX TODO: should this be generalized for all string vars?
455 # For now, this is special-cased to blocks created by cpaste
483 # For now, this is special-cased to blocks created by cpaste
456 if args.strip() == 'pasted_block':
484 if args.strip() == 'pasted_block':
457 self.shell.user_ns['pasted_block'] = file_read(filename)
485 self.shell.user_ns['pasted_block'] = file_read(filename)
458
486
459 if 'x' in opts: # -x prevents actual execution
487 if 'x' in opts: # -x prevents actual execution
460 print
488 print
461 else:
489 else:
462 print 'done. Executing edited code...'
490 print 'done. Executing edited code...'
463 if 'r' in opts: # Untranslated IPython code
491 if 'r' in opts: # Untranslated IPython code
464 self.shell.run_cell(file_read(filename),
492 self.shell.run_cell(file_read(filename),
465 store_history=False)
493 store_history=False)
466 else:
494 else:
467 self.shell.safe_execfile(filename, self.shell.user_ns,
495 self.shell.safe_execfile(filename, self.shell.user_ns,
468 self.shell.user_ns)
496 self.shell.user_ns)
469
497
470 if is_temp:
498 if is_temp:
471 try:
499 try:
472 return open(filename).read()
500 return open(filename).read()
473 except IOError,msg:
501 except IOError,msg:
474 if msg.filename == filename:
502 if msg.filename == filename:
475 warn('File not found. Did you forget to save?')
503 warn('File not found. Did you forget to save?')
476 return
504 return
477 else:
505 else:
478 self.shell.showtraceback()
506 self.shell.showtraceback()
@@ -1,674 +1,677 b''
1 """Implementation of magic functions for interaction with the OS.
1 """Implementation of magic functions for interaction with the OS.
2
2
3 Note: this module is named 'osm' instead of 'os' to avoid a collision with the
3 Note: this module is named 'osm' instead of 'os' to avoid a collision with the
4 builtin.
4 builtin.
5 """
5 """
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Copyright (c) 2012 The IPython Development Team.
7 # Copyright (c) 2012 The IPython Development Team.
8 #
8 #
9 # Distributed under the terms of the Modified BSD License.
9 # Distributed under the terms of the Modified BSD License.
10 #
10 #
11 # The full license is in the file COPYING.txt, distributed with this software.
11 # The full license is in the file COPYING.txt, distributed with this software.
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13
13
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 # Imports
15 # Imports
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 # Stdlib
18 # Stdlib
19 import os
19 import os
20 import re
20 import re
21 import sys
21 import sys
22 from pprint import pformat
22 from pprint import pformat
23
23
24 # Our own packages
24 # Our own packages
25 from IPython.core import oinspect
25 from IPython.core import oinspect
26 from IPython.core import page
26 from IPython.core import page
27 from IPython.core.error import UsageError
27 from IPython.core.error import UsageError
28 from IPython.core.magic import (Magics, compress_dhist, magics_class,
28 from IPython.core.magic import (Magics, compress_dhist, magics_class,
29 line_magic)
29 line_magic)
30 from IPython.testing.skipdoctest import skip_doctest
30 from IPython.testing.skipdoctest import skip_doctest
31 from IPython.utils.io import file_read, nlprint
31 from IPython.utils.io import file_read, nlprint
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.process import abbrev_cwd
33 from IPython.utils.process import abbrev_cwd
34 from IPython.utils.terminal import set_term_title
34 from IPython.utils.terminal import set_term_title
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36 # Magic implementation classes
36 # Magic implementation classes
37 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
38 @magics_class
38 @magics_class
39 class OSMagics(Magics):
39 class OSMagics(Magics):
40 """Magics to interact with the underlying OS (shell-type functionality).
40 """Magics to interact with the underlying OS (shell-type functionality).
41 """
41 """
42
42
43 @skip_doctest
43 @skip_doctest
44 @line_magic
44 @line_magic
45 def alias(self, parameter_s=''):
45 def alias(self, parameter_s=''):
46 """Define an alias for a system command.
46 """Define an alias for a system command.
47
47
48 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
48 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
49
49
50 Then, typing 'alias_name params' will execute the system command 'cmd
50 Then, typing 'alias_name params' will execute the system command 'cmd
51 params' (from your underlying operating system).
51 params' (from your underlying operating system).
52
52
53 Aliases have lower precedence than magic functions and Python normal
53 Aliases have lower precedence than magic functions and Python normal
54 variables, so if 'foo' is both a Python variable and an alias, the
54 variables, so if 'foo' is both a Python variable and an alias, the
55 alias can not be executed until 'del foo' removes the Python variable.
55 alias can not be executed until 'del foo' removes the Python variable.
56
56
57 You can use the %l specifier in an alias definition to represent the
57 You can use the %l specifier in an alias definition to represent the
58 whole line when the alias is called. For example::
58 whole line when the alias is called. For example::
59
59
60 In [2]: alias bracket echo "Input in brackets: <%l>"
60 In [2]: alias bracket echo "Input in brackets: <%l>"
61 In [3]: bracket hello world
61 In [3]: bracket hello world
62 Input in brackets: <hello world>
62 Input in brackets: <hello world>
63
63
64 You can also define aliases with parameters using %s specifiers (one
64 You can also define aliases with parameters using %s specifiers (one
65 per parameter)::
65 per parameter)::
66
66
67 In [1]: alias parts echo first %s second %s
67 In [1]: alias parts echo first %s second %s
68 In [2]: %parts A B
68 In [2]: %parts A B
69 first A second B
69 first A second B
70 In [3]: %parts A
70 In [3]: %parts A
71 Incorrect number of arguments: 2 expected.
71 Incorrect number of arguments: 2 expected.
72 parts is an alias to: 'echo first %s second %s'
72 parts is an alias to: 'echo first %s second %s'
73
73
74 Note that %l and %s are mutually exclusive. You can only use one or
74 Note that %l and %s are mutually exclusive. You can only use one or
75 the other in your aliases.
75 the other in your aliases.
76
76
77 Aliases expand Python variables just like system calls using ! or !!
77 Aliases expand Python variables just like system calls using ! or !!
78 do: all expressions prefixed with '$' get expanded. For details of
78 do: all expressions prefixed with '$' get expanded. For details of
79 the semantic rules, see PEP-215:
79 the semantic rules, see PEP-215:
80 http://www.python.org/peps/pep-0215.html. This is the library used by
80 http://www.python.org/peps/pep-0215.html. This is the library used by
81 IPython for variable expansion. If you want to access a true shell
81 IPython for variable expansion. If you want to access a true shell
82 variable, an extra $ is necessary to prevent its expansion by
82 variable, an extra $ is necessary to prevent its expansion by
83 IPython::
83 IPython::
84
84
85 In [6]: alias show echo
85 In [6]: alias show echo
86 In [7]: PATH='A Python string'
86 In [7]: PATH='A Python string'
87 In [8]: show $PATH
87 In [8]: show $PATH
88 A Python string
88 A Python string
89 In [9]: show $$PATH
89 In [9]: show $$PATH
90 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
90 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
91
91
92 You can use the alias facility to acess all of $PATH. See the %rehash
92 You can use the alias facility to acess all of $PATH. See the %rehash
93 and %rehashx functions, which automatically create aliases for the
93 and %rehashx functions, which automatically create aliases for the
94 contents of your $PATH.
94 contents of your $PATH.
95
95
96 If called with no parameters, %alias prints the current alias table."""
96 If called with no parameters, %alias prints the current alias table."""
97
97
98 par = parameter_s.strip()
98 par = parameter_s.strip()
99 if not par:
99 if not par:
100 aliases = sorted(self.shell.alias_manager.aliases)
100 aliases = sorted(self.shell.alias_manager.aliases)
101 # stored = self.shell.db.get('stored_aliases', {} )
101 # stored = self.shell.db.get('stored_aliases', {} )
102 # for k, v in stored:
102 # for k, v in stored:
103 # atab.append(k, v[0])
103 # atab.append(k, v[0])
104
104
105 print "Total number of aliases:", len(aliases)
105 print "Total number of aliases:", len(aliases)
106 sys.stdout.flush()
106 sys.stdout.flush()
107 return aliases
107 return aliases
108
108
109 # Now try to define a new one
109 # Now try to define a new one
110 try:
110 try:
111 alias,cmd = par.split(None, 1)
111 alias,cmd = par.split(None, 1)
112 except:
112 except:
113 print oinspect.getdoc(self.alias)
113 print oinspect.getdoc(self.alias)
114 else:
114 else:
115 self.shell.alias_manager.soft_define_alias(alias, cmd)
115 self.shell.alias_manager.soft_define_alias(alias, cmd)
116 # end magic_alias
116 # end magic_alias
117
117
118 @line_magic
118 @line_magic
119 def unalias(self, parameter_s=''):
119 def unalias(self, parameter_s=''):
120 """Remove an alias"""
120 """Remove an alias"""
121
121
122 aname = parameter_s.strip()
122 aname = parameter_s.strip()
123 self.shell.alias_manager.undefine_alias(aname)
123 self.shell.alias_manager.undefine_alias(aname)
124 stored = self.shell.db.get('stored_aliases', {} )
124 stored = self.shell.db.get('stored_aliases', {} )
125 if aname in stored:
125 if aname in stored:
126 print "Removing %stored alias",aname
126 print "Removing %stored alias",aname
127 del stored[aname]
127 del stored[aname]
128 self.shell.db['stored_aliases'] = stored
128 self.shell.db['stored_aliases'] = stored
129
129
130 @line_magic
130 @line_magic
131 def rehashx(self, parameter_s=''):
131 def rehashx(self, parameter_s=''):
132 """Update the alias table with all executable files in $PATH.
132 """Update the alias table with all executable files in $PATH.
133
133
134 This version explicitly checks that every entry in $PATH is a file
134 This version explicitly checks that every entry in $PATH is a file
135 with execute access (os.X_OK), so it is much slower than %rehash.
135 with execute access (os.X_OK), so it is much slower than %rehash.
136
136
137 Under Windows, it checks executability as a match against a
137 Under Windows, it checks executability as a match against a
138 '|'-separated string of extensions, stored in the IPython config
138 '|'-separated string of extensions, stored in the IPython config
139 variable win_exec_ext. This defaults to 'exe|com|bat'.
139 variable win_exec_ext. This defaults to 'exe|com|bat'.
140
140
141 This function also resets the root module cache of module completer,
141 This function also resets the root module cache of module completer,
142 used on slow filesystems.
142 used on slow filesystems.
143 """
143 """
144 from IPython.core.alias import InvalidAliasError
144 from IPython.core.alias import InvalidAliasError
145
145
146 # for the benefit of module completer in ipy_completers.py
146 # for the benefit of module completer in ipy_completers.py
147 del self.shell.db['rootmodules']
147 del self.shell.db['rootmodules']
148
148
149 path = [os.path.abspath(os.path.expanduser(p)) for p in
149 path = [os.path.abspath(os.path.expanduser(p)) for p in
150 os.environ.get('PATH','').split(os.pathsep)]
150 os.environ.get('PATH','').split(os.pathsep)]
151 path = filter(os.path.isdir,path)
151 path = filter(os.path.isdir,path)
152
152
153 syscmdlist = []
153 syscmdlist = []
154 # Now define isexec in a cross platform manner.
154 # Now define isexec in a cross platform manner.
155 if os.name == 'posix':
155 if os.name == 'posix':
156 isexec = lambda fname:os.path.isfile(fname) and \
156 isexec = lambda fname:os.path.isfile(fname) and \
157 os.access(fname,os.X_OK)
157 os.access(fname,os.X_OK)
158 else:
158 else:
159 try:
159 try:
160 winext = os.environ['pathext'].replace(';','|').replace('.','')
160 winext = os.environ['pathext'].replace(';','|').replace('.','')
161 except KeyError:
161 except KeyError:
162 winext = 'exe|com|bat|py'
162 winext = 'exe|com|bat|py'
163 if 'py' not in winext:
163 if 'py' not in winext:
164 winext += '|py'
164 winext += '|py'
165 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
165 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
166 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
166 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
167 savedir = os.getcwdu()
167 savedir = os.getcwdu()
168
168
169 # Now walk the paths looking for executables to alias.
169 # Now walk the paths looking for executables to alias.
170 try:
170 try:
171 # write the whole loop for posix/Windows so we don't have an if in
171 # write the whole loop for posix/Windows so we don't have an if in
172 # the innermost part
172 # the innermost part
173 if os.name == 'posix':
173 if os.name == 'posix':
174 for pdir in path:
174 for pdir in path:
175 os.chdir(pdir)
175 os.chdir(pdir)
176 for ff in os.listdir(pdir):
176 for ff in os.listdir(pdir):
177 if isexec(ff):
177 if isexec(ff):
178 try:
178 try:
179 # Removes dots from the name since ipython
179 # Removes dots from the name since ipython
180 # will assume names with dots to be python.
180 # will assume names with dots to be python.
181 self.shell.alias_manager.define_alias(
181 self.shell.alias_manager.define_alias(
182 ff.replace('.',''), ff)
182 ff.replace('.',''), ff)
183 except InvalidAliasError:
183 except InvalidAliasError:
184 pass
184 pass
185 else:
185 else:
186 syscmdlist.append(ff)
186 syscmdlist.append(ff)
187 else:
187 else:
188 no_alias = self.shell.alias_manager.no_alias
188 no_alias = self.shell.alias_manager.no_alias
189 for pdir in path:
189 for pdir in path:
190 os.chdir(pdir)
190 os.chdir(pdir)
191 for ff in os.listdir(pdir):
191 for ff in os.listdir(pdir):
192 base, ext = os.path.splitext(ff)
192 base, ext = os.path.splitext(ff)
193 if isexec(ff) and base.lower() not in no_alias:
193 if isexec(ff) and base.lower() not in no_alias:
194 if ext.lower() == '.exe':
194 if ext.lower() == '.exe':
195 ff = base
195 ff = base
196 try:
196 try:
197 # Removes dots from the name since ipython
197 # Removes dots from the name since ipython
198 # will assume names with dots to be python.
198 # will assume names with dots to be python.
199 self.shell.alias_manager.define_alias(
199 self.shell.alias_manager.define_alias(
200 base.lower().replace('.',''), ff)
200 base.lower().replace('.',''), ff)
201 except InvalidAliasError:
201 except InvalidAliasError:
202 pass
202 pass
203 syscmdlist.append(ff)
203 syscmdlist.append(ff)
204 self.shell.db['syscmdlist'] = syscmdlist
204 self.shell.db['syscmdlist'] = syscmdlist
205 finally:
205 finally:
206 os.chdir(savedir)
206 os.chdir(savedir)
207
207
208 @skip_doctest
208 @skip_doctest
209 @line_magic
209 @line_magic
210 def pwd(self, parameter_s=''):
210 def pwd(self, parameter_s=''):
211 """Return the current working directory path.
211 """Return the current working directory path.
212
212
213 Examples
213 Examples
214 --------
214 --------
215 ::
215 ::
216
216
217 In [9]: pwd
217 In [9]: pwd
218 Out[9]: '/home/tsuser/sprint/ipython'
218 Out[9]: '/home/tsuser/sprint/ipython'
219 """
219 """
220 return os.getcwdu()
220 return os.getcwdu()
221
221
222 @skip_doctest
222 @skip_doctest
223 @line_magic
223 @line_magic
224 def cd(self, parameter_s=''):
224 def cd(self, parameter_s=''):
225 """Change the current working directory.
225 """Change the current working directory.
226
226
227 This command automatically maintains an internal list of directories
227 This command automatically maintains an internal list of directories
228 you visit during your IPython session, in the variable _dh. The
228 you visit during your IPython session, in the variable _dh. The
229 command %dhist shows this history nicely formatted. You can also
229 command %dhist shows this history nicely formatted. You can also
230 do 'cd -<tab>' to see directory history conveniently.
230 do 'cd -<tab>' to see directory history conveniently.
231
231
232 Usage:
232 Usage:
233
233
234 cd 'dir': changes to directory 'dir'.
234 cd 'dir': changes to directory 'dir'.
235
235
236 cd -: changes to the last visited directory.
236 cd -: changes to the last visited directory.
237
237
238 cd -<n>: changes to the n-th directory in the directory history.
238 cd -<n>: changes to the n-th directory in the directory history.
239
239
240 cd --foo: change to directory that matches 'foo' in history
240 cd --foo: change to directory that matches 'foo' in history
241
241
242 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
242 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
243 (note: cd <bookmark_name> is enough if there is no
243 (note: cd <bookmark_name> is enough if there is no
244 directory <bookmark_name>, but a bookmark with the name exists.)
244 directory <bookmark_name>, but a bookmark with the name exists.)
245 'cd -b <tab>' allows you to tab-complete bookmark names.
245 'cd -b <tab>' allows you to tab-complete bookmark names.
246
246
247 Options:
247 Options:
248
248
249 -q: quiet. Do not print the working directory after the cd command is
249 -q: quiet. Do not print the working directory after the cd command is
250 executed. By default IPython's cd command does print this directory,
250 executed. By default IPython's cd command does print this directory,
251 since the default prompts do not display path information.
251 since the default prompts do not display path information.
252
252
253 Note that !cd doesn't work for this purpose because the shell where
253 Note that !cd doesn't work for this purpose because the shell where
254 !command runs is immediately discarded after executing 'command'.
254 !command runs is immediately discarded after executing 'command'.
255
255
256 Examples
256 Examples
257 --------
257 --------
258 ::
258 ::
259
259
260 In [10]: cd parent/child
260 In [10]: cd parent/child
261 /home/tsuser/parent/child
261 /home/tsuser/parent/child
262 """
262 """
263
263
264 oldcwd = os.getcwdu()
264 oldcwd = os.getcwdu()
265 numcd = re.match(r'(-)(\d+)$',parameter_s)
265 numcd = re.match(r'(-)(\d+)$',parameter_s)
266 # jump in directory history by number
266 # jump in directory history by number
267 if numcd:
267 if numcd:
268 nn = int(numcd.group(2))
268 nn = int(numcd.group(2))
269 try:
269 try:
270 ps = self.shell.user_ns['_dh'][nn]
270 ps = self.shell.user_ns['_dh'][nn]
271 except IndexError:
271 except IndexError:
272 print 'The requested directory does not exist in history.'
272 print 'The requested directory does not exist in history.'
273 return
273 return
274 else:
274 else:
275 opts = {}
275 opts = {}
276 elif parameter_s.startswith('--'):
276 elif parameter_s.startswith('--'):
277 ps = None
277 ps = None
278 fallback = None
278 fallback = None
279 pat = parameter_s[2:]
279 pat = parameter_s[2:]
280 dh = self.shell.user_ns['_dh']
280 dh = self.shell.user_ns['_dh']
281 # first search only by basename (last component)
281 # first search only by basename (last component)
282 for ent in reversed(dh):
282 for ent in reversed(dh):
283 if pat in os.path.basename(ent) and os.path.isdir(ent):
283 if pat in os.path.basename(ent) and os.path.isdir(ent):
284 ps = ent
284 ps = ent
285 break
285 break
286
286
287 if fallback is None and pat in ent and os.path.isdir(ent):
287 if fallback is None and pat in ent and os.path.isdir(ent):
288 fallback = ent
288 fallback = ent
289
289
290 # if we have no last part match, pick the first full path match
290 # if we have no last part match, pick the first full path match
291 if ps is None:
291 if ps is None:
292 ps = fallback
292 ps = fallback
293
293
294 if ps is None:
294 if ps is None:
295 print "No matching entry in directory history"
295 print "No matching entry in directory history"
296 return
296 return
297 else:
297 else:
298 opts = {}
298 opts = {}
299
299
300
300
301 else:
301 else:
302 #turn all non-space-escaping backslashes to slashes,
302 #turn all non-space-escaping backslashes to slashes,
303 # for c:\windows\directory\names\
303 # for c:\windows\directory\names\
304 parameter_s = re.sub(r'\\(?! )','/', parameter_s)
304 parameter_s = re.sub(r'\\(?! )','/', parameter_s)
305 opts,ps = self.parse_options(parameter_s,'qb',mode='string')
305 opts,ps = self.parse_options(parameter_s,'qb',mode='string')
306 # jump to previous
306 # jump to previous
307 if ps == '-':
307 if ps == '-':
308 try:
308 try:
309 ps = self.shell.user_ns['_dh'][-2]
309 ps = self.shell.user_ns['_dh'][-2]
310 except IndexError:
310 except IndexError:
311 raise UsageError('%cd -: No previous directory to change to.')
311 raise UsageError('%cd -: No previous directory to change to.')
312 # jump to bookmark if needed
312 # jump to bookmark if needed
313 else:
313 else:
314 if not os.path.isdir(ps) or 'b' in opts:
314 if not os.path.isdir(ps) or 'b' in opts:
315 bkms = self.shell.db.get('bookmarks', {})
315 bkms = self.shell.db.get('bookmarks', {})
316
316
317 if ps in bkms:
317 if ps in bkms:
318 target = bkms[ps]
318 target = bkms[ps]
319 print '(bookmark:%s) -> %s' % (ps, target)
319 print '(bookmark:%s) -> %s' % (ps, target)
320 ps = target
320 ps = target
321 else:
321 else:
322 if 'b' in opts:
322 if 'b' in opts:
323 raise UsageError("Bookmark '%s' not found. "
323 raise UsageError("Bookmark '%s' not found. "
324 "Use '%%bookmark -l' to see your bookmarks." % ps)
324 "Use '%%bookmark -l' to see your bookmarks." % ps)
325
325
326 # strip extra quotes on Windows, because os.chdir doesn't like them
326 # strip extra quotes on Windows, because os.chdir doesn't like them
327 ps = unquote_filename(ps)
327 ps = unquote_filename(ps)
328 # at this point ps should point to the target dir
328 # at this point ps should point to the target dir
329 if ps:
329 if ps:
330 try:
330 try:
331 os.chdir(os.path.expanduser(ps))
331 os.chdir(os.path.expanduser(ps))
332 if hasattr(self.shell, 'term_title') and self.shell.term_title:
332 if hasattr(self.shell, 'term_title') and self.shell.term_title:
333 set_term_title('IPython: ' + abbrev_cwd())
333 set_term_title('IPython: ' + abbrev_cwd())
334 except OSError:
334 except OSError:
335 print sys.exc_info()[1]
335 print sys.exc_info()[1]
336 else:
336 else:
337 cwd = os.getcwdu()
337 cwd = os.getcwdu()
338 dhist = self.shell.user_ns['_dh']
338 dhist = self.shell.user_ns['_dh']
339 if oldcwd != cwd:
339 if oldcwd != cwd:
340 dhist.append(cwd)
340 dhist.append(cwd)
341 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
341 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
342
342
343 else:
343 else:
344 os.chdir(self.shell.home_dir)
344 os.chdir(self.shell.home_dir)
345 if hasattr(self.shell, 'term_title') and self.shell.term_title:
345 if hasattr(self.shell, 'term_title') and self.shell.term_title:
346 set_term_title('IPython: ' + '~')
346 set_term_title('IPython: ' + '~')
347 cwd = os.getcwdu()
347 cwd = os.getcwdu()
348 dhist = self.shell.user_ns['_dh']
348 dhist = self.shell.user_ns['_dh']
349
349
350 if oldcwd != cwd:
350 if oldcwd != cwd:
351 dhist.append(cwd)
351 dhist.append(cwd)
352 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
352 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
353 if not 'q' in opts and self.shell.user_ns['_dh']:
353 if not 'q' in opts and self.shell.user_ns['_dh']:
354 print self.shell.user_ns['_dh'][-1]
354 print self.shell.user_ns['_dh'][-1]
355
355
356
356
357 @line_magic
357 @line_magic
358 def env(self, parameter_s=''):
358 def env(self, parameter_s=''):
359 """List environment variables."""
359 """List environment variables."""
360
360
361 return dict(os.environ)
361 return dict(os.environ)
362
362
363 @line_magic
363 @line_magic
364 def pushd(self, parameter_s=''):
364 def pushd(self, parameter_s=''):
365 """Place the current dir on stack and change directory.
365 """Place the current dir on stack and change directory.
366
366
367 Usage:\\
367 Usage:\\
368 %pushd ['dirname']
368 %pushd ['dirname']
369 """
369 """
370
370
371 dir_s = self.shell.dir_stack
371 dir_s = self.shell.dir_stack
372 tgt = os.path.expanduser(unquote_filename(parameter_s))
372 tgt = os.path.expanduser(unquote_filename(parameter_s))
373 cwd = os.getcwdu().replace(self.shell.home_dir,'~')
373 cwd = os.getcwdu().replace(self.shell.home_dir,'~')
374 if tgt:
374 if tgt:
375 self.cd(parameter_s)
375 self.cd(parameter_s)
376 dir_s.insert(0,cwd)
376 dir_s.insert(0,cwd)
377 return self.shell.magic('dirs')
377 return self.shell.magic('dirs')
378
378
379 @line_magic
379 @line_magic
380 def popd(self, parameter_s=''):
380 def popd(self, parameter_s=''):
381 """Change to directory popped off the top of the stack.
381 """Change to directory popped off the top of the stack.
382 """
382 """
383 if not self.shell.dir_stack:
383 if not self.shell.dir_stack:
384 raise UsageError("%popd on empty stack")
384 raise UsageError("%popd on empty stack")
385 top = self.shell.dir_stack.pop(0)
385 top = self.shell.dir_stack.pop(0)
386 self.cd(top)
386 self.cd(top)
387 print "popd ->",top
387 print "popd ->",top
388
388
389 @line_magic
389 @line_magic
390 def dirs(self, parameter_s=''):
390 def dirs(self, parameter_s=''):
391 """Return the current directory stack."""
391 """Return the current directory stack."""
392
392
393 return self.shell.dir_stack
393 return self.shell.dir_stack
394
394
395 @line_magic
395 @line_magic
396 def dhist(self, parameter_s=''):
396 def dhist(self, parameter_s=''):
397 """Print your history of visited directories.
397 """Print your history of visited directories.
398
398
399 %dhist -> print full history\\
399 %dhist -> print full history\\
400 %dhist n -> print last n entries only\\
400 %dhist n -> print last n entries only\\
401 %dhist n1 n2 -> print entries between n1 and n2 (n1 not included)\\
401 %dhist n1 n2 -> print entries between n1 and n2 (n1 not included)\\
402
402
403 This history is automatically maintained by the %cd command, and
403 This history is automatically maintained by the %cd command, and
404 always available as the global list variable _dh. You can use %cd -<n>
404 always available as the global list variable _dh. You can use %cd -<n>
405 to go to directory number <n>.
405 to go to directory number <n>.
406
406
407 Note that most of time, you should view directory history by entering
407 Note that most of time, you should view directory history by entering
408 cd -<TAB>.
408 cd -<TAB>.
409
409
410 """
410 """
411
411
412 dh = self.shell.user_ns['_dh']
412 dh = self.shell.user_ns['_dh']
413 if parameter_s:
413 if parameter_s:
414 try:
414 try:
415 args = map(int,parameter_s.split())
415 args = map(int,parameter_s.split())
416 except:
416 except:
417 self.arg_err(self.dhist)
417 self.arg_err(self.dhist)
418 return
418 return
419 if len(args) == 1:
419 if len(args) == 1:
420 ini,fin = max(len(dh)-(args[0]),0),len(dh)
420 ini,fin = max(len(dh)-(args[0]),0),len(dh)
421 elif len(args) == 2:
421 elif len(args) == 2:
422 ini,fin = args
422 ini,fin = args
423 else:
423 else:
424 self.arg_err(self.dhist)
424 self.arg_err(self.dhist)
425 return
425 return
426 else:
426 else:
427 ini,fin = 0,len(dh)
427 ini,fin = 0,len(dh)
428 nlprint(dh,
428 nlprint(dh,
429 header = 'Directory history (kept in _dh)',
429 header = 'Directory history (kept in _dh)',
430 start=ini,stop=fin)
430 start=ini,stop=fin)
431
431
432 @skip_doctest
432 @skip_doctest
433 @line_magic
433 @line_magic
434 def sc(self, parameter_s=''):
434 def sc(self, parameter_s=''):
435 """Shell capture - execute a shell command and capture its output.
435 """Shell capture - execute a shell command and capture its output.
436
436
437 DEPRECATED. Suboptimal, retained for backwards compatibility.
437 DEPRECATED. Suboptimal, retained for backwards compatibility.
438
438
439 You should use the form 'var = !command' instead. Example:
439 You should use the form 'var = !command' instead. Example:
440
440
441 "%sc -l myfiles = ls ~" should now be written as
441 "%sc -l myfiles = ls ~" should now be written as
442
442
443 "myfiles = !ls ~"
443 "myfiles = !ls ~"
444
444
445 myfiles.s, myfiles.l and myfiles.n still apply as documented
445 myfiles.s, myfiles.l and myfiles.n still apply as documented
446 below.
446 below.
447
447
448 --
448 --
449 %sc [options] varname=command
449 %sc [options] varname=command
450
450
451 IPython will run the given command using commands.getoutput(), and
451 IPython will run the given command using commands.getoutput(), and
452 will then update the user's interactive namespace with a variable
452 will then update the user's interactive namespace with a variable
453 called varname, containing the value of the call. Your command can
453 called varname, containing the value of the call. Your command can
454 contain shell wildcards, pipes, etc.
454 contain shell wildcards, pipes, etc.
455
455
456 The '=' sign in the syntax is mandatory, and the variable name you
456 The '=' sign in the syntax is mandatory, and the variable name you
457 supply must follow Python's standard conventions for valid names.
457 supply must follow Python's standard conventions for valid names.
458
458
459 (A special format without variable name exists for internal use)
459 (A special format without variable name exists for internal use)
460
460
461 Options:
461 Options:
462
462
463 -l: list output. Split the output on newlines into a list before
463 -l: list output. Split the output on newlines into a list before
464 assigning it to the given variable. By default the output is stored
464 assigning it to the given variable. By default the output is stored
465 as a single string.
465 as a single string.
466
466
467 -v: verbose. Print the contents of the variable.
467 -v: verbose. Print the contents of the variable.
468
468
469 In most cases you should not need to split as a list, because the
469 In most cases you should not need to split as a list, because the
470 returned value is a special type of string which can automatically
470 returned value is a special type of string which can automatically
471 provide its contents either as a list (split on newlines) or as a
471 provide its contents either as a list (split on newlines) or as a
472 space-separated string. These are convenient, respectively, either
472 space-separated string. These are convenient, respectively, either
473 for sequential processing or to be passed to a shell command.
473 for sequential processing or to be passed to a shell command.
474
474
475 For example::
475 For example::
476
476
477 # Capture into variable a
477 # Capture into variable a
478 In [1]: sc a=ls *py
478 In [1]: sc a=ls *py
479
479
480 # a is a string with embedded newlines
480 # a is a string with embedded newlines
481 In [2]: a
481 In [2]: a
482 Out[2]: 'setup.py\\nwin32_manual_post_install.py'
482 Out[2]: 'setup.py\\nwin32_manual_post_install.py'
483
483
484 # which can be seen as a list:
484 # which can be seen as a list:
485 In [3]: a.l
485 In [3]: a.l
486 Out[3]: ['setup.py', 'win32_manual_post_install.py']
486 Out[3]: ['setup.py', 'win32_manual_post_install.py']
487
487
488 # or as a whitespace-separated string:
488 # or as a whitespace-separated string:
489 In [4]: a.s
489 In [4]: a.s
490 Out[4]: 'setup.py win32_manual_post_install.py'
490 Out[4]: 'setup.py win32_manual_post_install.py'
491
491
492 # a.s is useful to pass as a single command line:
492 # a.s is useful to pass as a single command line:
493 In [5]: !wc -l $a.s
493 In [5]: !wc -l $a.s
494 146 setup.py
494 146 setup.py
495 130 win32_manual_post_install.py
495 130 win32_manual_post_install.py
496 276 total
496 276 total
497
497
498 # while the list form is useful to loop over:
498 # while the list form is useful to loop over:
499 In [6]: for f in a.l:
499 In [6]: for f in a.l:
500 ...: !wc -l $f
500 ...: !wc -l $f
501 ...:
501 ...:
502 146 setup.py
502 146 setup.py
503 130 win32_manual_post_install.py
503 130 win32_manual_post_install.py
504
504
505 Similarly, the lists returned by the -l option are also special, in
505 Similarly, the lists returned by the -l option are also special, in
506 the sense that you can equally invoke the .s attribute on them to
506 the sense that you can equally invoke the .s attribute on them to
507 automatically get a whitespace-separated string from their contents::
507 automatically get a whitespace-separated string from their contents::
508
508
509 In [7]: sc -l b=ls *py
509 In [7]: sc -l b=ls *py
510
510
511 In [8]: b
511 In [8]: b
512 Out[8]: ['setup.py', 'win32_manual_post_install.py']
512 Out[8]: ['setup.py', 'win32_manual_post_install.py']
513
513
514 In [9]: b.s
514 In [9]: b.s
515 Out[9]: 'setup.py win32_manual_post_install.py'
515 Out[9]: 'setup.py win32_manual_post_install.py'
516
516
517 In summary, both the lists and strings used for output capture have
517 In summary, both the lists and strings used for output capture have
518 the following special attributes::
518 the following special attributes::
519
519
520 .l (or .list) : value as list.
520 .l (or .list) : value as list.
521 .n (or .nlstr): value as newline-separated string.
521 .n (or .nlstr): value as newline-separated string.
522 .s (or .spstr): value as space-separated string.
522 .s (or .spstr): value as space-separated string.
523 """
523 """
524
524
525 opts,args = self.parse_options(parameter_s, 'lv')
525 opts,args = self.parse_options(parameter_s, 'lv')
526 # Try to get a variable name and command to run
526 # Try to get a variable name and command to run
527 try:
527 try:
528 # the variable name must be obtained from the parse_options
528 # the variable name must be obtained from the parse_options
529 # output, which uses shlex.split to strip options out.
529 # output, which uses shlex.split to strip options out.
530 var,_ = args.split('=', 1)
530 var,_ = args.split('=', 1)
531 var = var.strip()
531 var = var.strip()
532 # But the command has to be extracted from the original input
532 # But the command has to be extracted from the original input
533 # parameter_s, not on what parse_options returns, to avoid the
533 # parameter_s, not on what parse_options returns, to avoid the
534 # quote stripping which shlex.split performs on it.
534 # quote stripping which shlex.split performs on it.
535 _,cmd = parameter_s.split('=', 1)
535 _,cmd = parameter_s.split('=', 1)
536 except ValueError:
536 except ValueError:
537 var,cmd = '',''
537 var,cmd = '',''
538 # If all looks ok, proceed
538 # If all looks ok, proceed
539 split = 'l' in opts
539 split = 'l' in opts
540 out = self.shell.getoutput(cmd, split=split)
540 out = self.shell.getoutput(cmd, split=split)
541 if 'v' in opts:
541 if 'v' in opts:
542 print '%s ==\n%s' % (var, pformat(out))
542 print '%s ==\n%s' % (var, pformat(out))
543 if var:
543 if var:
544 self.shell.user_ns.update({var:out})
544 self.shell.user_ns.update({var:out})
545 else:
545 else:
546 return out
546 return out
547
547
548 @line_magic
548 @line_magic
549 def sx(self, parameter_s=''):
549 def sx(self, parameter_s=''):
550 """Shell execute - run a shell command and capture its output.
550 """Shell execute - run a shell command and capture its output.
551
551
552 %sx command
552 %sx command
553
553
554 IPython will run the given command using commands.getoutput(), and
554 IPython will run the given command using commands.getoutput(), and
555 return the result formatted as a list (split on '\\n'). Since the
555 return the result formatted as a list (split on '\\n'). Since the
556 output is _returned_, it will be stored in ipython's regular output
556 output is _returned_, it will be stored in ipython's regular output
557 cache Out[N] and in the '_N' automatic variables.
557 cache Out[N] and in the '_N' automatic variables.
558
558
559 Notes:
559 Notes:
560
560
561 1) If an input line begins with '!!', then %sx is automatically
561 1) If an input line begins with '!!', then %sx is automatically
562 invoked. That is, while::
562 invoked. That is, while::
563
563
564 !ls
564 !ls
565
565
566 causes ipython to simply issue system('ls'), typing::
566 causes ipython to simply issue system('ls'), typing::
567
567
568 !!ls
568 !!ls
569
569
570 is a shorthand equivalent to::
570 is a shorthand equivalent to::
571
571
572 %sx ls
572 %sx ls
573
573
574 2) %sx differs from %sc in that %sx automatically splits into a list,
574 2) %sx differs from %sc in that %sx automatically splits into a list,
575 like '%sc -l'. The reason for this is to make it as easy as possible
575 like '%sc -l'. The reason for this is to make it as easy as possible
576 to process line-oriented shell output via further python commands.
576 to process line-oriented shell output via further python commands.
577 %sc is meant to provide much finer control, but requires more
577 %sc is meant to provide much finer control, but requires more
578 typing.
578 typing.
579
579
580 3) Just like %sc -l, this is a list with special attributes:
580 3) Just like %sc -l, this is a list with special attributes:
581 ::
581 ::
582
582
583 .l (or .list) : value as list.
583 .l (or .list) : value as list.
584 .n (or .nlstr): value as newline-separated string.
584 .n (or .nlstr): value as newline-separated string.
585 .s (or .spstr): value as whitespace-separated string.
585 .s (or .spstr): value as whitespace-separated string.
586
586
587 This is very useful when trying to use such lists as arguments to
587 This is very useful when trying to use such lists as arguments to
588 system commands."""
588 system commands."""
589
589
590 if parameter_s:
590 if parameter_s:
591 return self.shell.getoutput(parameter_s)
591 return self.shell.getoutput(parameter_s)
592
592
593
593
594 @line_magic
594 @line_magic
595 def bookmark(self, parameter_s=''):
595 def bookmark(self, parameter_s=''):
596 """Manage IPython's bookmark system.
596 """Manage IPython's bookmark system.
597
597
598 %bookmark <name> - set bookmark to current dir
598 %bookmark <name> - set bookmark to current dir
599 %bookmark <name> <dir> - set bookmark to <dir>
599 %bookmark <name> <dir> - set bookmark to <dir>
600 %bookmark -l - list all bookmarks
600 %bookmark -l - list all bookmarks
601 %bookmark -d <name> - remove bookmark
601 %bookmark -d <name> - remove bookmark
602 %bookmark -r - remove all bookmarks
602 %bookmark -r - remove all bookmarks
603
603
604 You can later on access a bookmarked folder with::
604 You can later on access a bookmarked folder with::
605
605
606 %cd -b <name>
606 %cd -b <name>
607
607
608 or simply '%cd <name>' if there is no directory called <name> AND
608 or simply '%cd <name>' if there is no directory called <name> AND
609 there is such a bookmark defined.
609 there is such a bookmark defined.
610
610
611 Your bookmarks persist through IPython sessions, but they are
611 Your bookmarks persist through IPython sessions, but they are
612 associated with each profile."""
612 associated with each profile."""
613
613
614 opts,args = self.parse_options(parameter_s,'drl',mode='list')
614 opts,args = self.parse_options(parameter_s,'drl',mode='list')
615 if len(args) > 2:
615 if len(args) > 2:
616 raise UsageError("%bookmark: too many arguments")
616 raise UsageError("%bookmark: too many arguments")
617
617
618 bkms = self.shell.db.get('bookmarks',{})
618 bkms = self.shell.db.get('bookmarks',{})
619
619
620 if 'd' in opts:
620 if 'd' in opts:
621 try:
621 try:
622 todel = args[0]
622 todel = args[0]
623 except IndexError:
623 except IndexError:
624 raise UsageError(
624 raise UsageError(
625 "%bookmark -d: must provide a bookmark to delete")
625 "%bookmark -d: must provide a bookmark to delete")
626 else:
626 else:
627 try:
627 try:
628 del bkms[todel]
628 del bkms[todel]
629 except KeyError:
629 except KeyError:
630 raise UsageError(
630 raise UsageError(
631 "%%bookmark -d: Can't delete bookmark '%s'" % todel)
631 "%%bookmark -d: Can't delete bookmark '%s'" % todel)
632
632
633 elif 'r' in opts:
633 elif 'r' in opts:
634 bkms = {}
634 bkms = {}
635 elif 'l' in opts:
635 elif 'l' in opts:
636 bks = bkms.keys()
636 bks = bkms.keys()
637 bks.sort()
637 bks.sort()
638 if bks:
638 if bks:
639 size = max(map(len, bks))
639 size = max(map(len, bks))
640 else:
640 else:
641 size = 0
641 size = 0
642 fmt = '%-'+str(size)+'s -> %s'
642 fmt = '%-'+str(size)+'s -> %s'
643 print 'Current bookmarks:'
643 print 'Current bookmarks:'
644 for bk in bks:
644 for bk in bks:
645 print fmt % (bk, bkms[bk])
645 print fmt % (bk, bkms[bk])
646 else:
646 else:
647 if not args:
647 if not args:
648 raise UsageError("%bookmark: You must specify the bookmark name")
648 raise UsageError("%bookmark: You must specify the bookmark name")
649 elif len(args)==1:
649 elif len(args)==1:
650 bkms[args[0]] = os.getcwdu()
650 bkms[args[0]] = os.getcwdu()
651 elif len(args)==2:
651 elif len(args)==2:
652 bkms[args[0]] = args[1]
652 bkms[args[0]] = args[1]
653 self.shell.db['bookmarks'] = bkms
653 self.shell.db['bookmarks'] = bkms
654
654
655 @line_magic
655 @line_magic
656 def pycat(self, parameter_s=''):
656 def pycat(self, parameter_s=''):
657 """Show a syntax-highlighted file through a pager.
657 """Show a syntax-highlighted file through a pager.
658
658
659 This magic is similar to the cat utility, but it will assume the file
659 This magic is similar to the cat utility, but it will assume the file
660 to be Python source and will show it with syntax highlighting. """
660 to be Python source and will show it with syntax highlighting.
661
661
662 try:
662 This magic command can either take a local filename, an url,
663 filename = get_py_filename(parameter_s)
663 an history range (see %history) or a macro as argument ::
664 cont = file_read(filename)
664
665 except IOError:
665 %pycat myscript.py
666 try:
666 %pycat 7-27
667 cont = eval(parameter_s, self.shell.user_ns)
667 %pycat myMacro
668 except NameError:
668 %pycat http://www.example.com/myscript.py
669 cont = None
669 """
670 if cont is None:
670
671 print "Error: no such file or variable"
671 try :
672 cont = self.shell.find_user_code(parameter_s)
673 except ValueError, IOError:
674 print "Error: no such file, variable, URL, history range or macro"
672 return
675 return
673
676
674 page.page(self.shell.pycolorize(cont))
677 page.page(self.shell.pycolorize(cont))
General Comments 0
You need to be logged in to leave comments. Login now