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