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