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