##// END OF EJS Templates
Even better docstrings for %%file...
MinRK -
Show More
@@ -1,728 +1,728 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 io
19 import io
20 import os
20 import os
21 import re
21 import re
22 import sys
22 import sys
23 from pprint import pformat
23 from pprint import pformat
24
24
25 # Our own packages
25 # Our own packages
26 from IPython.core import magic_arguments
26 from IPython.core import magic_arguments
27 from IPython.core import oinspect
27 from IPython.core import oinspect
28 from IPython.core import page
28 from IPython.core import page
29 from IPython.core.error import UsageError
29 from IPython.core.error import UsageError
30 from IPython.core.magic import (
30 from IPython.core.magic import (
31 Magics, compress_dhist, magics_class, line_magic, cell_magic, line_cell_magic
31 Magics, compress_dhist, magics_class, line_magic, cell_magic, line_cell_magic
32 )
32 )
33 from IPython.testing.skipdoctest import skip_doctest
33 from IPython.testing.skipdoctest import skip_doctest
34 from IPython.utils.openpy import source_to_unicode
34 from IPython.utils.openpy import source_to_unicode
35 from IPython.utils.path import unquote_filename
35 from IPython.utils.path import unquote_filename
36 from IPython.utils.process import abbrev_cwd
36 from IPython.utils.process import abbrev_cwd
37 from IPython.utils.terminal import set_term_title
37 from IPython.utils.terminal import set_term_title
38
38
39 #-----------------------------------------------------------------------------
39 #-----------------------------------------------------------------------------
40 # Magic implementation classes
40 # Magic implementation classes
41 #-----------------------------------------------------------------------------
41 #-----------------------------------------------------------------------------
42 @magics_class
42 @magics_class
43 class OSMagics(Magics):
43 class OSMagics(Magics):
44 """Magics to interact with the underlying OS (shell-type functionality).
44 """Magics to interact with the underlying OS (shell-type functionality).
45 """
45 """
46
46
47 @skip_doctest
47 @skip_doctest
48 @line_magic
48 @line_magic
49 def alias(self, parameter_s=''):
49 def alias(self, parameter_s=''):
50 """Define an alias for a system command.
50 """Define an alias for a system command.
51
51
52 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
52 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
53
53
54 Then, typing 'alias_name params' will execute the system command 'cmd
54 Then, typing 'alias_name params' will execute the system command 'cmd
55 params' (from your underlying operating system).
55 params' (from your underlying operating system).
56
56
57 Aliases have lower precedence than magic functions and Python normal
57 Aliases have lower precedence than magic functions and Python normal
58 variables, so if 'foo' is both a Python variable and an alias, the
58 variables, so if 'foo' is both a Python variable and an alias, the
59 alias can not be executed until 'del foo' removes the Python variable.
59 alias can not be executed until 'del foo' removes the Python variable.
60
60
61 You can use the %l specifier in an alias definition to represent the
61 You can use the %l specifier in an alias definition to represent the
62 whole line when the alias is called. For example::
62 whole line when the alias is called. For example::
63
63
64 In [2]: alias bracket echo "Input in brackets: <%l>"
64 In [2]: alias bracket echo "Input in brackets: <%l>"
65 In [3]: bracket hello world
65 In [3]: bracket hello world
66 Input in brackets: <hello world>
66 Input in brackets: <hello world>
67
67
68 You can also define aliases with parameters using %s specifiers (one
68 You can also define aliases with parameters using %s specifiers (one
69 per parameter)::
69 per parameter)::
70
70
71 In [1]: alias parts echo first %s second %s
71 In [1]: alias parts echo first %s second %s
72 In [2]: %parts A B
72 In [2]: %parts A B
73 first A second B
73 first A second B
74 In [3]: %parts A
74 In [3]: %parts A
75 Incorrect number of arguments: 2 expected.
75 Incorrect number of arguments: 2 expected.
76 parts is an alias to: 'echo first %s second %s'
76 parts is an alias to: 'echo first %s second %s'
77
77
78 Note that %l and %s are mutually exclusive. You can only use one or
78 Note that %l and %s are mutually exclusive. You can only use one or
79 the other in your aliases.
79 the other in your aliases.
80
80
81 Aliases expand Python variables just like system calls using ! or !!
81 Aliases expand Python variables just like system calls using ! or !!
82 do: all expressions prefixed with '$' get expanded. For details of
82 do: all expressions prefixed with '$' get expanded. For details of
83 the semantic rules, see PEP-215:
83 the semantic rules, see PEP-215:
84 http://www.python.org/peps/pep-0215.html. This is the library used by
84 http://www.python.org/peps/pep-0215.html. This is the library used by
85 IPython for variable expansion. If you want to access a true shell
85 IPython for variable expansion. If you want to access a true shell
86 variable, an extra $ is necessary to prevent its expansion by
86 variable, an extra $ is necessary to prevent its expansion by
87 IPython::
87 IPython::
88
88
89 In [6]: alias show echo
89 In [6]: alias show echo
90 In [7]: PATH='A Python string'
90 In [7]: PATH='A Python string'
91 In [8]: show $PATH
91 In [8]: show $PATH
92 A Python string
92 A Python string
93 In [9]: show $$PATH
93 In [9]: show $$PATH
94 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
94 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
95
95
96 You can use the alias facility to acess all of $PATH. See the %rehash
96 You can use the alias facility to acess all of $PATH. See the %rehash
97 and %rehashx functions, which automatically create aliases for the
97 and %rehashx functions, which automatically create aliases for the
98 contents of your $PATH.
98 contents of your $PATH.
99
99
100 If called with no parameters, %alias prints the current alias table."""
100 If called with no parameters, %alias prints the current alias table."""
101
101
102 par = parameter_s.strip()
102 par = parameter_s.strip()
103 if not par:
103 if not par:
104 aliases = sorted(self.shell.alias_manager.aliases)
104 aliases = sorted(self.shell.alias_manager.aliases)
105 # stored = self.shell.db.get('stored_aliases', {} )
105 # stored = self.shell.db.get('stored_aliases', {} )
106 # for k, v in stored:
106 # for k, v in stored:
107 # atab.append(k, v[0])
107 # atab.append(k, v[0])
108
108
109 print "Total number of aliases:", len(aliases)
109 print "Total number of aliases:", len(aliases)
110 sys.stdout.flush()
110 sys.stdout.flush()
111 return aliases
111 return aliases
112
112
113 # Now try to define a new one
113 # Now try to define a new one
114 try:
114 try:
115 alias,cmd = par.split(None, 1)
115 alias,cmd = par.split(None, 1)
116 except:
116 except:
117 print oinspect.getdoc(self.alias)
117 print oinspect.getdoc(self.alias)
118 else:
118 else:
119 self.shell.alias_manager.soft_define_alias(alias, cmd)
119 self.shell.alias_manager.soft_define_alias(alias, cmd)
120 # end magic_alias
120 # end magic_alias
121
121
122 @line_magic
122 @line_magic
123 def unalias(self, parameter_s=''):
123 def unalias(self, parameter_s=''):
124 """Remove an alias"""
124 """Remove an alias"""
125
125
126 aname = parameter_s.strip()
126 aname = parameter_s.strip()
127 self.shell.alias_manager.undefine_alias(aname)
127 self.shell.alias_manager.undefine_alias(aname)
128 stored = self.shell.db.get('stored_aliases', {} )
128 stored = self.shell.db.get('stored_aliases', {} )
129 if aname in stored:
129 if aname in stored:
130 print "Removing %stored alias",aname
130 print "Removing %stored alias",aname
131 del stored[aname]
131 del stored[aname]
132 self.shell.db['stored_aliases'] = stored
132 self.shell.db['stored_aliases'] = stored
133
133
134 @line_magic
134 @line_magic
135 def rehashx(self, parameter_s=''):
135 def rehashx(self, parameter_s=''):
136 """Update the alias table with all executable files in $PATH.
136 """Update the alias table with all executable files in $PATH.
137
137
138 This version explicitly checks that every entry in $PATH is a file
138 This version explicitly checks that every entry in $PATH is a file
139 with execute access (os.X_OK), so it is much slower than %rehash.
139 with execute access (os.X_OK), so it is much slower than %rehash.
140
140
141 Under Windows, it checks executability as a match against a
141 Under Windows, it checks executability as a match against a
142 '|'-separated string of extensions, stored in the IPython config
142 '|'-separated string of extensions, stored in the IPython config
143 variable win_exec_ext. This defaults to 'exe|com|bat'.
143 variable win_exec_ext. This defaults to 'exe|com|bat'.
144
144
145 This function also resets the root module cache of module completer,
145 This function also resets the root module cache of module completer,
146 used on slow filesystems.
146 used on slow filesystems.
147 """
147 """
148 from IPython.core.alias import InvalidAliasError
148 from IPython.core.alias import InvalidAliasError
149
149
150 # for the benefit of module completer in ipy_completers.py
150 # for the benefit of module completer in ipy_completers.py
151 del self.shell.db['rootmodules']
151 del self.shell.db['rootmodules']
152
152
153 path = [os.path.abspath(os.path.expanduser(p)) for p in
153 path = [os.path.abspath(os.path.expanduser(p)) for p in
154 os.environ.get('PATH','').split(os.pathsep)]
154 os.environ.get('PATH','').split(os.pathsep)]
155 path = filter(os.path.isdir,path)
155 path = filter(os.path.isdir,path)
156
156
157 syscmdlist = []
157 syscmdlist = []
158 # Now define isexec in a cross platform manner.
158 # Now define isexec in a cross platform manner.
159 if os.name == 'posix':
159 if os.name == 'posix':
160 isexec = lambda fname:os.path.isfile(fname) and \
160 isexec = lambda fname:os.path.isfile(fname) and \
161 os.access(fname,os.X_OK)
161 os.access(fname,os.X_OK)
162 else:
162 else:
163 try:
163 try:
164 winext = os.environ['pathext'].replace(';','|').replace('.','')
164 winext = os.environ['pathext'].replace(';','|').replace('.','')
165 except KeyError:
165 except KeyError:
166 winext = 'exe|com|bat|py'
166 winext = 'exe|com|bat|py'
167 if 'py' not in winext:
167 if 'py' not in winext:
168 winext += '|py'
168 winext += '|py'
169 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
169 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
170 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
170 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
171 savedir = os.getcwdu()
171 savedir = os.getcwdu()
172
172
173 # Now walk the paths looking for executables to alias.
173 # Now walk the paths looking for executables to alias.
174 try:
174 try:
175 # write the whole loop for posix/Windows so we don't have an if in
175 # write the whole loop for posix/Windows so we don't have an if in
176 # the innermost part
176 # the innermost part
177 if os.name == 'posix':
177 if os.name == 'posix':
178 for pdir in path:
178 for pdir in path:
179 os.chdir(pdir)
179 os.chdir(pdir)
180 for ff in os.listdir(pdir):
180 for ff in os.listdir(pdir):
181 if isexec(ff):
181 if isexec(ff):
182 try:
182 try:
183 # Removes dots from the name since ipython
183 # Removes dots from the name since ipython
184 # will assume names with dots to be python.
184 # will assume names with dots to be python.
185 if ff not in self.shell.alias_manager:
185 if ff not in self.shell.alias_manager:
186 self.shell.alias_manager.define_alias(
186 self.shell.alias_manager.define_alias(
187 ff.replace('.',''), ff)
187 ff.replace('.',''), ff)
188 except InvalidAliasError:
188 except InvalidAliasError:
189 pass
189 pass
190 else:
190 else:
191 syscmdlist.append(ff)
191 syscmdlist.append(ff)
192 else:
192 else:
193 no_alias = self.shell.alias_manager.no_alias
193 no_alias = self.shell.alias_manager.no_alias
194 for pdir in path:
194 for pdir in path:
195 os.chdir(pdir)
195 os.chdir(pdir)
196 for ff in os.listdir(pdir):
196 for ff in os.listdir(pdir):
197 base, ext = os.path.splitext(ff)
197 base, ext = os.path.splitext(ff)
198 if isexec(ff) and base.lower() not in no_alias:
198 if isexec(ff) and base.lower() not in no_alias:
199 if ext.lower() == '.exe':
199 if ext.lower() == '.exe':
200 ff = base
200 ff = base
201 try:
201 try:
202 # Removes dots from the name since ipython
202 # Removes dots from the name since ipython
203 # will assume names with dots to be python.
203 # will assume names with dots to be python.
204 self.shell.alias_manager.define_alias(
204 self.shell.alias_manager.define_alias(
205 base.lower().replace('.',''), ff)
205 base.lower().replace('.',''), ff)
206 except InvalidAliasError:
206 except InvalidAliasError:
207 pass
207 pass
208 syscmdlist.append(ff)
208 syscmdlist.append(ff)
209 self.shell.db['syscmdlist'] = syscmdlist
209 self.shell.db['syscmdlist'] = syscmdlist
210 finally:
210 finally:
211 os.chdir(savedir)
211 os.chdir(savedir)
212
212
213 @skip_doctest
213 @skip_doctest
214 @line_magic
214 @line_magic
215 def pwd(self, parameter_s=''):
215 def pwd(self, parameter_s=''):
216 """Return the current working directory path.
216 """Return the current working directory path.
217
217
218 Examples
218 Examples
219 --------
219 --------
220 ::
220 ::
221
221
222 In [9]: pwd
222 In [9]: pwd
223 Out[9]: '/home/tsuser/sprint/ipython'
223 Out[9]: '/home/tsuser/sprint/ipython'
224 """
224 """
225 return os.getcwdu()
225 return os.getcwdu()
226
226
227 @skip_doctest
227 @skip_doctest
228 @line_magic
228 @line_magic
229 def cd(self, parameter_s=''):
229 def cd(self, parameter_s=''):
230 """Change the current working directory.
230 """Change the current working directory.
231
231
232 This command automatically maintains an internal list of directories
232 This command automatically maintains an internal list of directories
233 you visit during your IPython session, in the variable _dh. The
233 you visit during your IPython session, in the variable _dh. The
234 command %dhist shows this history nicely formatted. You can also
234 command %dhist shows this history nicely formatted. You can also
235 do 'cd -<tab>' to see directory history conveniently.
235 do 'cd -<tab>' to see directory history conveniently.
236
236
237 Usage:
237 Usage:
238
238
239 cd 'dir': changes to directory 'dir'.
239 cd 'dir': changes to directory 'dir'.
240
240
241 cd -: changes to the last visited directory.
241 cd -: changes to the last visited directory.
242
242
243 cd -<n>: changes to the n-th directory in the directory history.
243 cd -<n>: changes to the n-th directory in the directory history.
244
244
245 cd --foo: change to directory that matches 'foo' in history
245 cd --foo: change to directory that matches 'foo' in history
246
246
247 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
247 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
248 (note: cd <bookmark_name> is enough if there is no
248 (note: cd <bookmark_name> is enough if there is no
249 directory <bookmark_name>, but a bookmark with the name exists.)
249 directory <bookmark_name>, but a bookmark with the name exists.)
250 'cd -b <tab>' allows you to tab-complete bookmark names.
250 'cd -b <tab>' allows you to tab-complete bookmark names.
251
251
252 Options:
252 Options:
253
253
254 -q: quiet. Do not print the working directory after the cd command is
254 -q: quiet. Do not print the working directory after the cd command is
255 executed. By default IPython's cd command does print this directory,
255 executed. By default IPython's cd command does print this directory,
256 since the default prompts do not display path information.
256 since the default prompts do not display path information.
257
257
258 Note that !cd doesn't work for this purpose because the shell where
258 Note that !cd doesn't work for this purpose because the shell where
259 !command runs is immediately discarded after executing 'command'.
259 !command runs is immediately discarded after executing 'command'.
260
260
261 Examples
261 Examples
262 --------
262 --------
263 ::
263 ::
264
264
265 In [10]: cd parent/child
265 In [10]: cd parent/child
266 /home/tsuser/parent/child
266 /home/tsuser/parent/child
267 """
267 """
268
268
269 oldcwd = os.getcwdu()
269 oldcwd = os.getcwdu()
270 numcd = re.match(r'(-)(\d+)$',parameter_s)
270 numcd = re.match(r'(-)(\d+)$',parameter_s)
271 # jump in directory history by number
271 # jump in directory history by number
272 if numcd:
272 if numcd:
273 nn = int(numcd.group(2))
273 nn = int(numcd.group(2))
274 try:
274 try:
275 ps = self.shell.user_ns['_dh'][nn]
275 ps = self.shell.user_ns['_dh'][nn]
276 except IndexError:
276 except IndexError:
277 print 'The requested directory does not exist in history.'
277 print 'The requested directory does not exist in history.'
278 return
278 return
279 else:
279 else:
280 opts = {}
280 opts = {}
281 elif parameter_s.startswith('--'):
281 elif parameter_s.startswith('--'):
282 ps = None
282 ps = None
283 fallback = None
283 fallback = None
284 pat = parameter_s[2:]
284 pat = parameter_s[2:]
285 dh = self.shell.user_ns['_dh']
285 dh = self.shell.user_ns['_dh']
286 # first search only by basename (last component)
286 # first search only by basename (last component)
287 for ent in reversed(dh):
287 for ent in reversed(dh):
288 if pat in os.path.basename(ent) and os.path.isdir(ent):
288 if pat in os.path.basename(ent) and os.path.isdir(ent):
289 ps = ent
289 ps = ent
290 break
290 break
291
291
292 if fallback is None and pat in ent and os.path.isdir(ent):
292 if fallback is None and pat in ent and os.path.isdir(ent):
293 fallback = ent
293 fallback = ent
294
294
295 # if we have no last part match, pick the first full path match
295 # if we have no last part match, pick the first full path match
296 if ps is None:
296 if ps is None:
297 ps = fallback
297 ps = fallback
298
298
299 if ps is None:
299 if ps is None:
300 print "No matching entry in directory history"
300 print "No matching entry in directory history"
301 return
301 return
302 else:
302 else:
303 opts = {}
303 opts = {}
304
304
305
305
306 else:
306 else:
307 #turn all non-space-escaping backslashes to slashes,
307 #turn all non-space-escaping backslashes to slashes,
308 # for c:\windows\directory\names\
308 # for c:\windows\directory\names\
309 parameter_s = re.sub(r'\\(?! )','/', parameter_s)
309 parameter_s = re.sub(r'\\(?! )','/', parameter_s)
310 opts,ps = self.parse_options(parameter_s,'qb',mode='string')
310 opts,ps = self.parse_options(parameter_s,'qb',mode='string')
311 # jump to previous
311 # jump to previous
312 if ps == '-':
312 if ps == '-':
313 try:
313 try:
314 ps = self.shell.user_ns['_dh'][-2]
314 ps = self.shell.user_ns['_dh'][-2]
315 except IndexError:
315 except IndexError:
316 raise UsageError('%cd -: No previous directory to change to.')
316 raise UsageError('%cd -: No previous directory to change to.')
317 # jump to bookmark if needed
317 # jump to bookmark if needed
318 else:
318 else:
319 if not os.path.isdir(ps) or 'b' in opts:
319 if not os.path.isdir(ps) or 'b' in opts:
320 bkms = self.shell.db.get('bookmarks', {})
320 bkms = self.shell.db.get('bookmarks', {})
321
321
322 if ps in bkms:
322 if ps in bkms:
323 target = bkms[ps]
323 target = bkms[ps]
324 print '(bookmark:%s) -> %s' % (ps, target)
324 print '(bookmark:%s) -> %s' % (ps, target)
325 ps = target
325 ps = target
326 else:
326 else:
327 if 'b' in opts:
327 if 'b' in opts:
328 raise UsageError("Bookmark '%s' not found. "
328 raise UsageError("Bookmark '%s' not found. "
329 "Use '%%bookmark -l' to see your bookmarks." % ps)
329 "Use '%%bookmark -l' to see your bookmarks." % ps)
330
330
331 # strip extra quotes on Windows, because os.chdir doesn't like them
331 # strip extra quotes on Windows, because os.chdir doesn't like them
332 ps = unquote_filename(ps)
332 ps = unquote_filename(ps)
333 # at this point ps should point to the target dir
333 # at this point ps should point to the target dir
334 if ps:
334 if ps:
335 try:
335 try:
336 os.chdir(os.path.expanduser(ps))
336 os.chdir(os.path.expanduser(ps))
337 if hasattr(self.shell, 'term_title') and self.shell.term_title:
337 if hasattr(self.shell, 'term_title') and self.shell.term_title:
338 set_term_title('IPython: ' + abbrev_cwd())
338 set_term_title('IPython: ' + abbrev_cwd())
339 except OSError:
339 except OSError:
340 print sys.exc_info()[1]
340 print sys.exc_info()[1]
341 else:
341 else:
342 cwd = os.getcwdu()
342 cwd = os.getcwdu()
343 dhist = self.shell.user_ns['_dh']
343 dhist = self.shell.user_ns['_dh']
344 if oldcwd != cwd:
344 if oldcwd != cwd:
345 dhist.append(cwd)
345 dhist.append(cwd)
346 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
346 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
347
347
348 else:
348 else:
349 os.chdir(self.shell.home_dir)
349 os.chdir(self.shell.home_dir)
350 if hasattr(self.shell, 'term_title') and self.shell.term_title:
350 if hasattr(self.shell, 'term_title') and self.shell.term_title:
351 set_term_title('IPython: ' + '~')
351 set_term_title('IPython: ' + '~')
352 cwd = os.getcwdu()
352 cwd = os.getcwdu()
353 dhist = self.shell.user_ns['_dh']
353 dhist = self.shell.user_ns['_dh']
354
354
355 if oldcwd != cwd:
355 if oldcwd != cwd:
356 dhist.append(cwd)
356 dhist.append(cwd)
357 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
357 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
358 if not 'q' in opts and self.shell.user_ns['_dh']:
358 if not 'q' in opts and self.shell.user_ns['_dh']:
359 print self.shell.user_ns['_dh'][-1]
359 print self.shell.user_ns['_dh'][-1]
360
360
361
361
362 @line_magic
362 @line_magic
363 def env(self, parameter_s=''):
363 def env(self, parameter_s=''):
364 """List environment variables."""
364 """List environment variables."""
365
365
366 return dict(os.environ)
366 return dict(os.environ)
367
367
368 @line_magic
368 @line_magic
369 def pushd(self, parameter_s=''):
369 def pushd(self, parameter_s=''):
370 """Place the current dir on stack and change directory.
370 """Place the current dir on stack and change directory.
371
371
372 Usage:\\
372 Usage:\\
373 %pushd ['dirname']
373 %pushd ['dirname']
374 """
374 """
375
375
376 dir_s = self.shell.dir_stack
376 dir_s = self.shell.dir_stack
377 tgt = os.path.expanduser(unquote_filename(parameter_s))
377 tgt = os.path.expanduser(unquote_filename(parameter_s))
378 cwd = os.getcwdu().replace(self.shell.home_dir,'~')
378 cwd = os.getcwdu().replace(self.shell.home_dir,'~')
379 if tgt:
379 if tgt:
380 self.cd(parameter_s)
380 self.cd(parameter_s)
381 dir_s.insert(0,cwd)
381 dir_s.insert(0,cwd)
382 return self.shell.magic('dirs')
382 return self.shell.magic('dirs')
383
383
384 @line_magic
384 @line_magic
385 def popd(self, parameter_s=''):
385 def popd(self, parameter_s=''):
386 """Change to directory popped off the top of the stack.
386 """Change to directory popped off the top of the stack.
387 """
387 """
388 if not self.shell.dir_stack:
388 if not self.shell.dir_stack:
389 raise UsageError("%popd on empty stack")
389 raise UsageError("%popd on empty stack")
390 top = self.shell.dir_stack.pop(0)
390 top = self.shell.dir_stack.pop(0)
391 self.cd(top)
391 self.cd(top)
392 print "popd ->",top
392 print "popd ->",top
393
393
394 @line_magic
394 @line_magic
395 def dirs(self, parameter_s=''):
395 def dirs(self, parameter_s=''):
396 """Return the current directory stack."""
396 """Return the current directory stack."""
397
397
398 return self.shell.dir_stack
398 return self.shell.dir_stack
399
399
400 @line_magic
400 @line_magic
401 def dhist(self, parameter_s=''):
401 def dhist(self, parameter_s=''):
402 """Print your history of visited directories.
402 """Print your history of visited directories.
403
403
404 %dhist -> print full history\\
404 %dhist -> print full history\\
405 %dhist n -> print last n entries only\\
405 %dhist n -> print last n entries only\\
406 %dhist n1 n2 -> print entries between n1 and n2 (n2 not included)\\
406 %dhist n1 n2 -> print entries between n1 and n2 (n2 not included)\\
407
407
408 This history is automatically maintained by the %cd command, and
408 This history is automatically maintained by the %cd command, and
409 always available as the global list variable _dh. You can use %cd -<n>
409 always available as the global list variable _dh. You can use %cd -<n>
410 to go to directory number <n>.
410 to go to directory number <n>.
411
411
412 Note that most of time, you should view directory history by entering
412 Note that most of time, you should view directory history by entering
413 cd -<TAB>.
413 cd -<TAB>.
414
414
415 """
415 """
416
416
417 dh = self.shell.user_ns['_dh']
417 dh = self.shell.user_ns['_dh']
418 if parameter_s:
418 if parameter_s:
419 try:
419 try:
420 args = map(int,parameter_s.split())
420 args = map(int,parameter_s.split())
421 except:
421 except:
422 self.arg_err(self.dhist)
422 self.arg_err(self.dhist)
423 return
423 return
424 if len(args) == 1:
424 if len(args) == 1:
425 ini,fin = max(len(dh)-(args[0]),0),len(dh)
425 ini,fin = max(len(dh)-(args[0]),0),len(dh)
426 elif len(args) == 2:
426 elif len(args) == 2:
427 ini,fin = args
427 ini,fin = args
428 fin = min(fin, len(dh))
428 fin = min(fin, len(dh))
429 else:
429 else:
430 self.arg_err(self.dhist)
430 self.arg_err(self.dhist)
431 return
431 return
432 else:
432 else:
433 ini,fin = 0,len(dh)
433 ini,fin = 0,len(dh)
434 print 'Directory history (kept in _dh)'
434 print 'Directory history (kept in _dh)'
435 for i in range(ini, fin):
435 for i in range(ini, fin):
436 print "%d: %s" % (i, dh[i])
436 print "%d: %s" % (i, dh[i])
437
437
438 @skip_doctest
438 @skip_doctest
439 @line_magic
439 @line_magic
440 def sc(self, parameter_s=''):
440 def sc(self, parameter_s=''):
441 """Shell capture - run shell command and capture output (DEPRECATED use !).
441 """Shell capture - run shell command and capture output (DEPRECATED use !).
442
442
443 DEPRECATED. Suboptimal, retained for backwards compatibility.
443 DEPRECATED. Suboptimal, retained for backwards compatibility.
444
444
445 You should use the form 'var = !command' instead. Example:
445 You should use the form 'var = !command' instead. Example:
446
446
447 "%sc -l myfiles = ls ~" should now be written as
447 "%sc -l myfiles = ls ~" should now be written as
448
448
449 "myfiles = !ls ~"
449 "myfiles = !ls ~"
450
450
451 myfiles.s, myfiles.l and myfiles.n still apply as documented
451 myfiles.s, myfiles.l and myfiles.n still apply as documented
452 below.
452 below.
453
453
454 --
454 --
455 %sc [options] varname=command
455 %sc [options] varname=command
456
456
457 IPython will run the given command using commands.getoutput(), and
457 IPython will run the given command using commands.getoutput(), and
458 will then update the user's interactive namespace with a variable
458 will then update the user's interactive namespace with a variable
459 called varname, containing the value of the call. Your command can
459 called varname, containing the value of the call. Your command can
460 contain shell wildcards, pipes, etc.
460 contain shell wildcards, pipes, etc.
461
461
462 The '=' sign in the syntax is mandatory, and the variable name you
462 The '=' sign in the syntax is mandatory, and the variable name you
463 supply must follow Python's standard conventions for valid names.
463 supply must follow Python's standard conventions for valid names.
464
464
465 (A special format without variable name exists for internal use)
465 (A special format without variable name exists for internal use)
466
466
467 Options:
467 Options:
468
468
469 -l: list output. Split the output on newlines into a list before
469 -l: list output. Split the output on newlines into a list before
470 assigning it to the given variable. By default the output is stored
470 assigning it to the given variable. By default the output is stored
471 as a single string.
471 as a single string.
472
472
473 -v: verbose. Print the contents of the variable.
473 -v: verbose. Print the contents of the variable.
474
474
475 In most cases you should not need to split as a list, because the
475 In most cases you should not need to split as a list, because the
476 returned value is a special type of string which can automatically
476 returned value is a special type of string which can automatically
477 provide its contents either as a list (split on newlines) or as a
477 provide its contents either as a list (split on newlines) or as a
478 space-separated string. These are convenient, respectively, either
478 space-separated string. These are convenient, respectively, either
479 for sequential processing or to be passed to a shell command.
479 for sequential processing or to be passed to a shell command.
480
480
481 For example::
481 For example::
482
482
483 # Capture into variable a
483 # Capture into variable a
484 In [1]: sc a=ls *py
484 In [1]: sc a=ls *py
485
485
486 # a is a string with embedded newlines
486 # a is a string with embedded newlines
487 In [2]: a
487 In [2]: a
488 Out[2]: 'setup.py\\nwin32_manual_post_install.py'
488 Out[2]: 'setup.py\\nwin32_manual_post_install.py'
489
489
490 # which can be seen as a list:
490 # which can be seen as a list:
491 In [3]: a.l
491 In [3]: a.l
492 Out[3]: ['setup.py', 'win32_manual_post_install.py']
492 Out[3]: ['setup.py', 'win32_manual_post_install.py']
493
493
494 # or as a whitespace-separated string:
494 # or as a whitespace-separated string:
495 In [4]: a.s
495 In [4]: a.s
496 Out[4]: 'setup.py win32_manual_post_install.py'
496 Out[4]: 'setup.py win32_manual_post_install.py'
497
497
498 # a.s is useful to pass as a single command line:
498 # a.s is useful to pass as a single command line:
499 In [5]: !wc -l $a.s
499 In [5]: !wc -l $a.s
500 146 setup.py
500 146 setup.py
501 130 win32_manual_post_install.py
501 130 win32_manual_post_install.py
502 276 total
502 276 total
503
503
504 # while the list form is useful to loop over:
504 # while the list form is useful to loop over:
505 In [6]: for f in a.l:
505 In [6]: for f in a.l:
506 ...: !wc -l $f
506 ...: !wc -l $f
507 ...:
507 ...:
508 146 setup.py
508 146 setup.py
509 130 win32_manual_post_install.py
509 130 win32_manual_post_install.py
510
510
511 Similarly, the lists returned by the -l option are also special, in
511 Similarly, the lists returned by the -l option are also special, in
512 the sense that you can equally invoke the .s attribute on them to
512 the sense that you can equally invoke the .s attribute on them to
513 automatically get a whitespace-separated string from their contents::
513 automatically get a whitespace-separated string from their contents::
514
514
515 In [7]: sc -l b=ls *py
515 In [7]: sc -l b=ls *py
516
516
517 In [8]: b
517 In [8]: b
518 Out[8]: ['setup.py', 'win32_manual_post_install.py']
518 Out[8]: ['setup.py', 'win32_manual_post_install.py']
519
519
520 In [9]: b.s
520 In [9]: b.s
521 Out[9]: 'setup.py win32_manual_post_install.py'
521 Out[9]: 'setup.py win32_manual_post_install.py'
522
522
523 In summary, both the lists and strings used for output capture have
523 In summary, both the lists and strings used for output capture have
524 the following special attributes::
524 the following special attributes::
525
525
526 .l (or .list) : value as list.
526 .l (or .list) : value as list.
527 .n (or .nlstr): value as newline-separated string.
527 .n (or .nlstr): value as newline-separated string.
528 .s (or .spstr): value as space-separated string.
528 .s (or .spstr): value as space-separated string.
529 """
529 """
530
530
531 opts,args = self.parse_options(parameter_s, 'lv')
531 opts,args = self.parse_options(parameter_s, 'lv')
532 # Try to get a variable name and command to run
532 # Try to get a variable name and command to run
533 try:
533 try:
534 # the variable name must be obtained from the parse_options
534 # the variable name must be obtained from the parse_options
535 # output, which uses shlex.split to strip options out.
535 # output, which uses shlex.split to strip options out.
536 var,_ = args.split('=', 1)
536 var,_ = args.split('=', 1)
537 var = var.strip()
537 var = var.strip()
538 # But the command has to be extracted from the original input
538 # But the command has to be extracted from the original input
539 # parameter_s, not on what parse_options returns, to avoid the
539 # parameter_s, not on what parse_options returns, to avoid the
540 # quote stripping which shlex.split performs on it.
540 # quote stripping which shlex.split performs on it.
541 _,cmd = parameter_s.split('=', 1)
541 _,cmd = parameter_s.split('=', 1)
542 except ValueError:
542 except ValueError:
543 var,cmd = '',''
543 var,cmd = '',''
544 # If all looks ok, proceed
544 # If all looks ok, proceed
545 split = 'l' in opts
545 split = 'l' in opts
546 out = self.shell.getoutput(cmd, split=split)
546 out = self.shell.getoutput(cmd, split=split)
547 if 'v' in opts:
547 if 'v' in opts:
548 print '%s ==\n%s' % (var, pformat(out))
548 print '%s ==\n%s' % (var, pformat(out))
549 if var:
549 if var:
550 self.shell.user_ns.update({var:out})
550 self.shell.user_ns.update({var:out})
551 else:
551 else:
552 return out
552 return out
553
553
554 @line_cell_magic
554 @line_cell_magic
555 def sx(self, line='', cell=None):
555 def sx(self, line='', cell=None):
556 """Shell execute - run shell command and capture output (!! is short-hand).
556 """Shell execute - run shell command and capture output (!! is short-hand).
557
557
558 %sx command
558 %sx command
559
559
560 IPython will run the given command using commands.getoutput(), and
560 IPython will run the given command using commands.getoutput(), and
561 return the result formatted as a list (split on '\\n'). Since the
561 return the result formatted as a list (split on '\\n'). Since the
562 output is _returned_, it will be stored in ipython's regular output
562 output is _returned_, it will be stored in ipython's regular output
563 cache Out[N] and in the '_N' automatic variables.
563 cache Out[N] and in the '_N' automatic variables.
564
564
565 Notes:
565 Notes:
566
566
567 1) If an input line begins with '!!', then %sx is automatically
567 1) If an input line begins with '!!', then %sx is automatically
568 invoked. That is, while::
568 invoked. That is, while::
569
569
570 !ls
570 !ls
571
571
572 causes ipython to simply issue system('ls'), typing::
572 causes ipython to simply issue system('ls'), typing::
573
573
574 !!ls
574 !!ls
575
575
576 is a shorthand equivalent to::
576 is a shorthand equivalent to::
577
577
578 %sx ls
578 %sx ls
579
579
580 2) %sx differs from %sc in that %sx automatically splits into a list,
580 2) %sx differs from %sc in that %sx automatically splits into a list,
581 like '%sc -l'. The reason for this is to make it as easy as possible
581 like '%sc -l'. The reason for this is to make it as easy as possible
582 to process line-oriented shell output via further python commands.
582 to process line-oriented shell output via further python commands.
583 %sc is meant to provide much finer control, but requires more
583 %sc is meant to provide much finer control, but requires more
584 typing.
584 typing.
585
585
586 3) Just like %sc -l, this is a list with special attributes:
586 3) Just like %sc -l, this is a list with special attributes:
587 ::
587 ::
588
588
589 .l (or .list) : value as list.
589 .l (or .list) : value as list.
590 .n (or .nlstr): value as newline-separated string.
590 .n (or .nlstr): value as newline-separated string.
591 .s (or .spstr): value as whitespace-separated string.
591 .s (or .spstr): value as whitespace-separated string.
592
592
593 This is very useful when trying to use such lists as arguments to
593 This is very useful when trying to use such lists as arguments to
594 system commands."""
594 system commands."""
595
595
596 if cell is None:
596 if cell is None:
597 # line magic
597 # line magic
598 return self.shell.getoutput(line)
598 return self.shell.getoutput(line)
599 else:
599 else:
600 opts,args = self.parse_options(line, '', 'out=')
600 opts,args = self.parse_options(line, '', 'out=')
601 output = self.shell.getoutput(cell)
601 output = self.shell.getoutput(cell)
602 out_name = opts.get('out', opts.get('o'))
602 out_name = opts.get('out', opts.get('o'))
603 if out_name:
603 if out_name:
604 self.shell.user_ns[out_name] = output
604 self.shell.user_ns[out_name] = output
605 else:
605 else:
606 return output
606 return output
607
607
608 system = line_cell_magic('system')(sx)
608 system = line_cell_magic('system')(sx)
609 bang = cell_magic('!')(sx)
609 bang = cell_magic('!')(sx)
610
610
611 @line_magic
611 @line_magic
612 def bookmark(self, parameter_s=''):
612 def bookmark(self, parameter_s=''):
613 """Manage IPython's bookmark system.
613 """Manage IPython's bookmark system.
614
614
615 %bookmark <name> - set bookmark to current dir
615 %bookmark <name> - set bookmark to current dir
616 %bookmark <name> <dir> - set bookmark to <dir>
616 %bookmark <name> <dir> - set bookmark to <dir>
617 %bookmark -l - list all bookmarks
617 %bookmark -l - list all bookmarks
618 %bookmark -d <name> - remove bookmark
618 %bookmark -d <name> - remove bookmark
619 %bookmark -r - remove all bookmarks
619 %bookmark -r - remove all bookmarks
620
620
621 You can later on access a bookmarked folder with::
621 You can later on access a bookmarked folder with::
622
622
623 %cd -b <name>
623 %cd -b <name>
624
624
625 or simply '%cd <name>' if there is no directory called <name> AND
625 or simply '%cd <name>' if there is no directory called <name> AND
626 there is such a bookmark defined.
626 there is such a bookmark defined.
627
627
628 Your bookmarks persist through IPython sessions, but they are
628 Your bookmarks persist through IPython sessions, but they are
629 associated with each profile."""
629 associated with each profile."""
630
630
631 opts,args = self.parse_options(parameter_s,'drl',mode='list')
631 opts,args = self.parse_options(parameter_s,'drl',mode='list')
632 if len(args) > 2:
632 if len(args) > 2:
633 raise UsageError("%bookmark: too many arguments")
633 raise UsageError("%bookmark: too many arguments")
634
634
635 bkms = self.shell.db.get('bookmarks',{})
635 bkms = self.shell.db.get('bookmarks',{})
636
636
637 if 'd' in opts:
637 if 'd' in opts:
638 try:
638 try:
639 todel = args[0]
639 todel = args[0]
640 except IndexError:
640 except IndexError:
641 raise UsageError(
641 raise UsageError(
642 "%bookmark -d: must provide a bookmark to delete")
642 "%bookmark -d: must provide a bookmark to delete")
643 else:
643 else:
644 try:
644 try:
645 del bkms[todel]
645 del bkms[todel]
646 except KeyError:
646 except KeyError:
647 raise UsageError(
647 raise UsageError(
648 "%%bookmark -d: Can't delete bookmark '%s'" % todel)
648 "%%bookmark -d: Can't delete bookmark '%s'" % todel)
649
649
650 elif 'r' in opts:
650 elif 'r' in opts:
651 bkms = {}
651 bkms = {}
652 elif 'l' in opts:
652 elif 'l' in opts:
653 bks = bkms.keys()
653 bks = bkms.keys()
654 bks.sort()
654 bks.sort()
655 if bks:
655 if bks:
656 size = max(map(len, bks))
656 size = max(map(len, bks))
657 else:
657 else:
658 size = 0
658 size = 0
659 fmt = '%-'+str(size)+'s -> %s'
659 fmt = '%-'+str(size)+'s -> %s'
660 print 'Current bookmarks:'
660 print 'Current bookmarks:'
661 for bk in bks:
661 for bk in bks:
662 print fmt % (bk, bkms[bk])
662 print fmt % (bk, bkms[bk])
663 else:
663 else:
664 if not args:
664 if not args:
665 raise UsageError("%bookmark: You must specify the bookmark name")
665 raise UsageError("%bookmark: You must specify the bookmark name")
666 elif len(args)==1:
666 elif len(args)==1:
667 bkms[args[0]] = os.getcwdu()
667 bkms[args[0]] = os.getcwdu()
668 elif len(args)==2:
668 elif len(args)==2:
669 bkms[args[0]] = args[1]
669 bkms[args[0]] = args[1]
670 self.shell.db['bookmarks'] = bkms
670 self.shell.db['bookmarks'] = bkms
671
671
672 @line_magic
672 @line_magic
673 def pycat(self, parameter_s=''):
673 def pycat(self, parameter_s=''):
674 """Show a syntax-highlighted file through a pager.
674 """Show a syntax-highlighted file through a pager.
675
675
676 This magic is similar to the cat utility, but it will assume the file
676 This magic is similar to the cat utility, but it will assume the file
677 to be Python source and will show it with syntax highlighting.
677 to be Python source and will show it with syntax highlighting.
678
678
679 This magic command can either take a local filename, an url,
679 This magic command can either take a local filename, an url,
680 an history range (see %history) or a macro as argument ::
680 an history range (see %history) or a macro as argument ::
681
681
682 %pycat myscript.py
682 %pycat myscript.py
683 %pycat 7-27
683 %pycat 7-27
684 %pycat myMacro
684 %pycat myMacro
685 %pycat http://www.example.com/myscript.py
685 %pycat http://www.example.com/myscript.py
686 """
686 """
687 if not parameter_s:
687 if not parameter_s:
688 raise UsageError('Missing filename, URL, input history range, '
688 raise UsageError('Missing filename, URL, input history range, '
689 'or macro.')
689 'or macro.')
690
690
691 try :
691 try :
692 cont = self.shell.find_user_code(parameter_s, skip_encoding_cookie=False)
692 cont = self.shell.find_user_code(parameter_s, skip_encoding_cookie=False)
693 except (ValueError, IOError):
693 except (ValueError, IOError):
694 print "Error: no such file, variable, URL, history range or macro"
694 print "Error: no such file, variable, URL, history range or macro"
695 return
695 return
696
696
697 page.page(self.shell.pycolorize(source_to_unicode(cont)))
697 page.page(self.shell.pycolorize(source_to_unicode(cont)))
698
698
699 @magic_arguments.magic_arguments()
699 @magic_arguments.magic_arguments()
700 @magic_arguments.argument(
700 @magic_arguments.argument(
701 '-a', '--amend', action='store_true', default=False,
701 '-a', '--append', action='store_true', default=False,
702 help='Open file for amending if it exists, instead of overwriting.'
702 help='Append contents of the cell to an existing file. '
703 'The file will be created if it does not exist.'
703 )
704 )
704 @magic_arguments.argument(
705 @magic_arguments.argument(
705 'filename', type=unicode,
706 'filename', type=unicode,
706 help='file to write'
707 help='file to write'
707 )
708 )
708 @cell_magic
709 @cell_magic
709 def file(self, line, cell):
710 def file(self, line, cell):
710 """Write the contents of the cell to a file.
711 """Write the contents of the cell to a file.
711
712
712 The file will be overwritten if it exists, unless the `-a` flag is passed,
713 The file will be overwritten unless the -a (--append) flag is specified.
713 in which case the file will be amended.
714 """
714 """
715 args = magic_arguments.parse_argstring(self.file, line)
715 args = magic_arguments.parse_argstring(self.file, line)
716 filename = os.path.expanduser(unquote_filename(args.filename))
716 filename = os.path.expanduser(unquote_filename(args.filename))
717
717
718 if os.path.exists(filename):
718 if os.path.exists(filename):
719 if args.amend:
719 if args.append:
720 print "Amending to %s" % filename
720 print "Appending to %s" % filename
721 else:
721 else:
722 print "Overwriting %s" % filename
722 print "Overwriting %s" % filename
723 else:
723 else:
724 print "Writing %s" % filename
724 print "Writing %s" % filename
725
725
726 mode = 'a' if args.amend else 'w'
726 mode = 'a' if args.append else 'w'
727 with io.open(filename, mode, encoding='utf-8') as f:
727 with io.open(filename, mode, encoding='utf-8') as f:
728 f.write(cell)
728 f.write(cell)
General Comments 0
You need to be logged in to leave comments. Login now