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