##// END OF EJS Templates
Remove -i options from mv, rm and cp aliases...
Steve Chan -
Show More
@@ -1,238 +1,238 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 os
23 import os
24 import re
24 import re
25 import sys
25 import sys
26
26
27 from IPython.config.configurable import Configurable
27 from IPython.config.configurable import Configurable
28 from IPython.core.error import UsageError
28 from IPython.core.error import UsageError
29
29
30 from IPython.utils.py3compat import string_types
30 from IPython.utils.py3compat import string_types
31 from IPython.utils.traitlets import List, Instance
31 from IPython.utils.traitlets import List, Instance
32 from IPython.utils.warn import error
32 from IPython.utils.warn import error
33
33
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35 # Utilities
35 # Utilities
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37
37
38 # This is used as the pattern for calls to split_user_input.
38 # This is used as the pattern for calls to split_user_input.
39 shell_line_split = re.compile(r'^(\s*)()(\S+)(.*$)')
39 shell_line_split = re.compile(r'^(\s*)()(\S+)(.*$)')
40
40
41 def default_aliases():
41 def default_aliases():
42 """Return list of shell aliases to auto-define.
42 """Return list of shell aliases to auto-define.
43 """
43 """
44 # Note: the aliases defined here should be safe to use on a kernel
44 # Note: the aliases defined here should be safe to use on a kernel
45 # regardless of what frontend it is attached to. Frontends that use a
45 # regardless of what frontend it is attached to. Frontends that use a
46 # kernel in-process can define additional aliases that will only work in
46 # kernel in-process can define additional aliases that will only work in
47 # their case. For example, things like 'less' or 'clear' that manipulate
47 # their case. For example, things like 'less' or 'clear' that manipulate
48 # the terminal should NOT be declared here, as they will only work if the
48 # the terminal should NOT be declared here, as they will only work if the
49 # kernel is running inside a true terminal, and not over the network.
49 # kernel is running inside a true terminal, and not over the network.
50
50
51 if os.name == 'posix':
51 if os.name == 'posix':
52 default_aliases = [('mkdir', 'mkdir'), ('rmdir', 'rmdir'),
52 default_aliases = [('mkdir', 'mkdir'), ('rmdir', 'rmdir'),
53 ('mv', 'mv -i'), ('rm', 'rm -i'), ('cp', 'cp -i'),
53 ('mv', 'mv'), ('rm', 'rm'), ('cp', 'cp'),
54 ('cat', 'cat'),
54 ('cat', 'cat'),
55 ]
55 ]
56 # Useful set of ls aliases. The GNU and BSD options are a little
56 # Useful set of ls aliases. The GNU and BSD options are a little
57 # different, so we make aliases that provide as similar as possible
57 # different, so we make aliases that provide as similar as possible
58 # behavior in ipython, by passing the right flags for each platform
58 # behavior in ipython, by passing the right flags for each platform
59 if sys.platform.startswith('linux'):
59 if sys.platform.startswith('linux'):
60 ls_aliases = [('ls', 'ls -F --color'),
60 ls_aliases = [('ls', 'ls -F --color'),
61 # long ls
61 # long ls
62 ('ll', 'ls -F -o --color'),
62 ('ll', 'ls -F -o --color'),
63 # ls normal files only
63 # ls normal files only
64 ('lf', 'ls -F -o --color %l | grep ^-'),
64 ('lf', 'ls -F -o --color %l | grep ^-'),
65 # ls symbolic links
65 # ls symbolic links
66 ('lk', 'ls -F -o --color %l | grep ^l'),
66 ('lk', 'ls -F -o --color %l | grep ^l'),
67 # directories or links to directories,
67 # directories or links to directories,
68 ('ldir', 'ls -F -o --color %l | grep /$'),
68 ('ldir', 'ls -F -o --color %l | grep /$'),
69 # things which are executable
69 # things which are executable
70 ('lx', 'ls -F -o --color %l | grep ^-..x'),
70 ('lx', 'ls -F -o --color %l | grep ^-..x'),
71 ]
71 ]
72 else:
72 else:
73 # BSD, OSX, etc.
73 # BSD, OSX, etc.
74 ls_aliases = [('ls', 'ls -F -G'),
74 ls_aliases = [('ls', 'ls -F -G'),
75 # long ls
75 # long ls
76 ('ll', 'ls -F -l -G'),
76 ('ll', 'ls -F -l -G'),
77 # ls normal files only
77 # ls normal files only
78 ('lf', 'ls -F -l -G %l | grep ^-'),
78 ('lf', 'ls -F -l -G %l | grep ^-'),
79 # ls symbolic links
79 # ls symbolic links
80 ('lk', 'ls -F -l -G %l | grep ^l'),
80 ('lk', 'ls -F -l -G %l | grep ^l'),
81 # directories or links to directories,
81 # directories or links to directories,
82 ('ldir', 'ls -F -G -l %l | grep /$'),
82 ('ldir', 'ls -F -G -l %l | grep /$'),
83 # things which are executable
83 # things which are executable
84 ('lx', 'ls -F -l -G %l | grep ^-..x'),
84 ('lx', 'ls -F -l -G %l | grep ^-..x'),
85 ]
85 ]
86 default_aliases = default_aliases + ls_aliases
86 default_aliases = default_aliases + ls_aliases
87 elif os.name in ['nt', 'dos']:
87 elif os.name in ['nt', 'dos']:
88 default_aliases = [('ls', 'dir /on'),
88 default_aliases = [('ls', 'dir /on'),
89 ('ddir', 'dir /ad /on'), ('ldir', 'dir /ad /on'),
89 ('ddir', 'dir /ad /on'), ('ldir', 'dir /ad /on'),
90 ('mkdir', 'mkdir'), ('rmdir', 'rmdir'),
90 ('mkdir', 'mkdir'), ('rmdir', 'rmdir'),
91 ('echo', 'echo'), ('ren', 'ren'), ('copy', 'copy'),
91 ('echo', 'echo'), ('ren', 'ren'), ('copy', 'copy'),
92 ]
92 ]
93 else:
93 else:
94 default_aliases = []
94 default_aliases = []
95
95
96 return default_aliases
96 return default_aliases
97
97
98
98
99 class AliasError(Exception):
99 class AliasError(Exception):
100 pass
100 pass
101
101
102
102
103 class InvalidAliasError(AliasError):
103 class InvalidAliasError(AliasError):
104 pass
104 pass
105
105
106 class Alias(object):
106 class Alias(object):
107 """Callable object storing the details of one alias.
107 """Callable object storing the details of one alias.
108
108
109 Instances are registered as magic functions to allow use of aliases.
109 Instances are registered as magic functions to allow use of aliases.
110 """
110 """
111
111
112 # Prepare blacklist
112 # Prepare blacklist
113 blacklist = {'cd','popd','pushd','dhist','alias','unalias'}
113 blacklist = {'cd','popd','pushd','dhist','alias','unalias'}
114
114
115 def __init__(self, shell, name, cmd):
115 def __init__(self, shell, name, cmd):
116 self.shell = shell
116 self.shell = shell
117 self.name = name
117 self.name = name
118 self.cmd = cmd
118 self.cmd = cmd
119 self.nargs = self.validate()
119 self.nargs = self.validate()
120
120
121 def validate(self):
121 def validate(self):
122 """Validate the alias, and return the number of arguments."""
122 """Validate the alias, and return the number of arguments."""
123 if self.name in self.blacklist:
123 if self.name in self.blacklist:
124 raise InvalidAliasError("The name %s can't be aliased "
124 raise InvalidAliasError("The name %s can't be aliased "
125 "because it is a keyword or builtin." % self.name)
125 "because it is a keyword or builtin." % self.name)
126 try:
126 try:
127 caller = self.shell.magics_manager.magics['line'][self.name]
127 caller = self.shell.magics_manager.magics['line'][self.name]
128 except KeyError:
128 except KeyError:
129 pass
129 pass
130 else:
130 else:
131 if not isinstance(caller, Alias):
131 if not isinstance(caller, Alias):
132 raise InvalidAliasError("The name %s can't be aliased "
132 raise InvalidAliasError("The name %s can't be aliased "
133 "because it is another magic command." % self.name)
133 "because it is another magic command." % self.name)
134
134
135 if not (isinstance(self.cmd, string_types)):
135 if not (isinstance(self.cmd, string_types)):
136 raise InvalidAliasError("An alias command must be a string, "
136 raise InvalidAliasError("An alias command must be a string, "
137 "got: %r" % self.cmd)
137 "got: %r" % self.cmd)
138
138
139 nargs = self.cmd.count('%s')
139 nargs = self.cmd.count('%s')
140
140
141 if (nargs > 0) and (self.cmd.find('%l') >= 0):
141 if (nargs > 0) and (self.cmd.find('%l') >= 0):
142 raise InvalidAliasError('The %s and %l specifiers are mutually '
142 raise InvalidAliasError('The %s and %l specifiers are mutually '
143 'exclusive in alias definitions.')
143 'exclusive in alias definitions.')
144
144
145 return nargs
145 return nargs
146
146
147 def __repr__(self):
147 def __repr__(self):
148 return "<alias {} for {!r}>".format(self.name, self.cmd)
148 return "<alias {} for {!r}>".format(self.name, self.cmd)
149
149
150 def __call__(self, rest=''):
150 def __call__(self, rest=''):
151 cmd = self.cmd
151 cmd = self.cmd
152 nargs = self.nargs
152 nargs = self.nargs
153 # Expand the %l special to be the user's input line
153 # Expand the %l special to be the user's input line
154 if cmd.find('%l') >= 0:
154 if cmd.find('%l') >= 0:
155 cmd = cmd.replace('%l', rest)
155 cmd = cmd.replace('%l', rest)
156 rest = ''
156 rest = ''
157 if nargs==0:
157 if nargs==0:
158 # Simple, argument-less aliases
158 # Simple, argument-less aliases
159 cmd = '%s %s' % (cmd, rest)
159 cmd = '%s %s' % (cmd, rest)
160 else:
160 else:
161 # Handle aliases with positional arguments
161 # Handle aliases with positional arguments
162 args = rest.split(None, nargs)
162 args = rest.split(None, nargs)
163 if len(args) < nargs:
163 if len(args) < nargs:
164 raise UsageError('Alias <%s> requires %s arguments, %s given.' %
164 raise UsageError('Alias <%s> requires %s arguments, %s given.' %
165 (self.name, nargs, len(args)))
165 (self.name, nargs, len(args)))
166 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
166 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
167
167
168 self.shell.system(cmd)
168 self.shell.system(cmd)
169
169
170 #-----------------------------------------------------------------------------
170 #-----------------------------------------------------------------------------
171 # Main AliasManager class
171 # Main AliasManager class
172 #-----------------------------------------------------------------------------
172 #-----------------------------------------------------------------------------
173
173
174 class AliasManager(Configurable):
174 class AliasManager(Configurable):
175
175
176 default_aliases = List(default_aliases(), config=True)
176 default_aliases = List(default_aliases(), config=True)
177 user_aliases = List(default_value=[], config=True)
177 user_aliases = List(default_value=[], config=True)
178 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
178 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
179
179
180 def __init__(self, shell=None, **kwargs):
180 def __init__(self, shell=None, **kwargs):
181 super(AliasManager, self).__init__(shell=shell, **kwargs)
181 super(AliasManager, self).__init__(shell=shell, **kwargs)
182 # For convenient access
182 # For convenient access
183 self.linemagics = self.shell.magics_manager.magics['line']
183 self.linemagics = self.shell.magics_manager.magics['line']
184 self.init_aliases()
184 self.init_aliases()
185
185
186 def init_aliases(self):
186 def init_aliases(self):
187 # Load default & user aliases
187 # Load default & user aliases
188 for name, cmd in self.default_aliases + self.user_aliases:
188 for name, cmd in self.default_aliases + self.user_aliases:
189 self.soft_define_alias(name, cmd)
189 self.soft_define_alias(name, cmd)
190
190
191 @property
191 @property
192 def aliases(self):
192 def aliases(self):
193 return [(n, func.cmd) for (n, func) in self.linemagics.items()
193 return [(n, func.cmd) for (n, func) in self.linemagics.items()
194 if isinstance(func, Alias)]
194 if isinstance(func, Alias)]
195
195
196 def soft_define_alias(self, name, cmd):
196 def soft_define_alias(self, name, cmd):
197 """Define an alias, but don't raise on an AliasError."""
197 """Define an alias, but don't raise on an AliasError."""
198 try:
198 try:
199 self.define_alias(name, cmd)
199 self.define_alias(name, cmd)
200 except AliasError as e:
200 except AliasError as e:
201 error("Invalid alias: %s" % e)
201 error("Invalid alias: %s" % e)
202
202
203 def define_alias(self, name, cmd):
203 def define_alias(self, name, cmd):
204 """Define a new alias after validating it.
204 """Define a new alias after validating it.
205
205
206 This will raise an :exc:`AliasError` if there are validation
206 This will raise an :exc:`AliasError` if there are validation
207 problems.
207 problems.
208 """
208 """
209 caller = Alias(shell=self.shell, name=name, cmd=cmd)
209 caller = Alias(shell=self.shell, name=name, cmd=cmd)
210 self.shell.magics_manager.register_function(caller, magic_kind='line',
210 self.shell.magics_manager.register_function(caller, magic_kind='line',
211 magic_name=name)
211 magic_name=name)
212
212
213 def get_alias(self, name):
213 def get_alias(self, name):
214 """Return an alias, or None if no alias by that name exists."""
214 """Return an alias, or None if no alias by that name exists."""
215 aname = self.linemagics.get(name, None)
215 aname = self.linemagics.get(name, None)
216 return aname if isinstance(aname, Alias) else None
216 return aname if isinstance(aname, Alias) else None
217
217
218 def is_alias(self, name):
218 def is_alias(self, name):
219 """Return whether or not a given name has been defined as an alias"""
219 """Return whether or not a given name has been defined as an alias"""
220 return self.get_alias(name) is not None
220 return self.get_alias(name) is not None
221
221
222 def undefine_alias(self, name):
222 def undefine_alias(self, name):
223 if self.is_alias(name):
223 if self.is_alias(name):
224 del self.linemagics[name]
224 del self.linemagics[name]
225 else:
225 else:
226 raise ValueError('%s is not an alias' % name)
226 raise ValueError('%s is not an alias' % name)
227
227
228 def clear_aliases(self):
228 def clear_aliases(self):
229 for name, cmd in self.aliases:
229 for name, cmd in self.aliases:
230 self.undefine_alias(name)
230 self.undefine_alias(name)
231
231
232 def retrieve_alias(self, name):
232 def retrieve_alias(self, name):
233 """Retrieve the command to which an alias expands."""
233 """Retrieve the command to which an alias expands."""
234 caller = self.get_alias(name)
234 caller = self.get_alias(name)
235 if caller:
235 if caller:
236 return caller.cmd
236 return caller.cmd
237 else:
237 else:
238 raise ValueError('%s is not an alias' % name)
238 raise ValueError('%s is not an alias' % name)
General Comments 0
You need to be logged in to leave comments. Login now