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