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