Show More
@@ -0,0 +1,191 b'' | |||
|
1 | #!/usr/bin/env python | |
|
2 | # encoding: utf-8 | |
|
3 | """ | |
|
4 | IPython's alias component | |
|
5 | ||
|
6 | Authors: | |
|
7 | ||
|
8 | * Brian Granger | |
|
9 | """ | |
|
10 | ||
|
11 | #----------------------------------------------------------------------------- | |
|
12 | # Copyright (C) 2008-2009 The IPython Development Team | |
|
13 | # | |
|
14 | # Distributed under the terms of the BSD License. The full license is in | |
|
15 | # the file COPYING, distributed as part of this software. | |
|
16 | #----------------------------------------------------------------------------- | |
|
17 | ||
|
18 | #----------------------------------------------------------------------------- | |
|
19 | # Imports | |
|
20 | #----------------------------------------------------------------------------- | |
|
21 | ||
|
22 | import __builtin__ | |
|
23 | import keyword | |
|
24 | import os | |
|
25 | import sys | |
|
26 | ||
|
27 | from IPython.core.component import Component | |
|
28 | ||
|
29 | from IPython.utils.traitlets import CBool, List, Instance | |
|
30 | from IPython.utils.genutils import error | |
|
31 | ||
|
32 | #----------------------------------------------------------------------------- | |
|
33 | # Functions and classes | |
|
34 | #----------------------------------------------------------------------------- | |
|
35 | ||
|
36 | def default_aliases(): | |
|
37 | # Make some aliases automatically | |
|
38 | # Prepare list of shell aliases to auto-define | |
|
39 | if os.name == 'posix': | |
|
40 | auto_alias = ('mkdir mkdir', 'rmdir rmdir', | |
|
41 | 'mv mv -i','rm rm -i','cp cp -i', | |
|
42 | 'cat cat','less less','clear clear', | |
|
43 | # a better ls | |
|
44 | 'ls ls -F', | |
|
45 | # long ls | |
|
46 | 'll ls -lF') | |
|
47 | # Extra ls aliases with color, which need special treatment on BSD | |
|
48 | # variants | |
|
49 | ls_extra = ( # color ls | |
|
50 | 'lc ls -F -o --color', | |
|
51 | # ls normal files only | |
|
52 | 'lf ls -F -o --color %l | grep ^-', | |
|
53 | # ls symbolic links | |
|
54 | 'lk ls -F -o --color %l | grep ^l', | |
|
55 | # directories or links to directories, | |
|
56 | 'ldir ls -F -o --color %l | grep /$', | |
|
57 | # things which are executable | |
|
58 | 'lx ls -F -o --color %l | grep ^-..x', | |
|
59 | ) | |
|
60 | # The BSDs don't ship GNU ls, so they don't understand the | |
|
61 | # --color switch out of the box | |
|
62 | if 'bsd' in sys.platform: | |
|
63 | ls_extra = ( # ls normal files only | |
|
64 | 'lf ls -lF | grep ^-', | |
|
65 | # ls symbolic links | |
|
66 | 'lk ls -lF | grep ^l', | |
|
67 | # directories or links to directories, | |
|
68 | 'ldir ls -lF | grep /$', | |
|
69 | # things which are executable | |
|
70 | 'lx ls -lF | grep ^-..x', | |
|
71 | ) | |
|
72 | auto_alias = auto_alias + ls_extra | |
|
73 | elif os.name in ['nt','dos']: | |
|
74 | auto_alias = ('ls dir /on', | |
|
75 | 'ddir dir /ad /on', 'ldir dir /ad /on', | |
|
76 | 'mkdir mkdir','rmdir rmdir','echo echo', | |
|
77 | 'ren ren','cls cls','copy copy') | |
|
78 | else: | |
|
79 | auto_alias = () | |
|
80 | return [s.split(None,1) for s in auto_alias] | |
|
81 | ||
|
82 | ||
|
83 | class AliasError(Exception): | |
|
84 | pass | |
|
85 | ||
|
86 | ||
|
87 | class InvalidAliasError(AliasError): | |
|
88 | pass | |
|
89 | ||
|
90 | ||
|
91 | class AliasManager(Component): | |
|
92 | ||
|
93 | auto_alias = List(default_aliases()) | |
|
94 | user_alias = List(default_value=[], config_key='USER_ALIAS') | |
|
95 | ||
|
96 | def __init__(self, parent, config=None): | |
|
97 | super(AliasManager, self).__init__(parent, config=config) | |
|
98 | self.shell = Component.get_instances( | |
|
99 | root=self.root, | |
|
100 | klass='IPython.core.iplib.InteractiveShell' | |
|
101 | )[0] | |
|
102 | self.alias_table = {} | |
|
103 | self.exclude_aliases() | |
|
104 | self.init_aliases() | |
|
105 | ||
|
106 | def __contains__(self, name): | |
|
107 | if name in self.alias_table: | |
|
108 | return True | |
|
109 | else: | |
|
110 | return False | |
|
111 | ||
|
112 | @property | |
|
113 | def aliases(self): | |
|
114 | return [(item[0], item[1][1]) for item in self.alias_table.iteritems()] | |
|
115 | ||
|
116 | def exclude_aliases(self): | |
|
117 | # set of things NOT to alias (keywords, builtins and some magics) | |
|
118 | no_alias = set(['cd','popd','pushd','dhist','alias','unalias']) | |
|
119 | no_alias.update(set(keyword.kwlist)) | |
|
120 | no_alias.update(set(__builtin__.__dict__.keys())) | |
|
121 | self.no_alias = no_alias | |
|
122 | ||
|
123 | def init_aliases(self): | |
|
124 | # Load default aliases | |
|
125 | for name, cmd in self.auto_alias: | |
|
126 | self.soft_define_alias(name, cmd) | |
|
127 | ||
|
128 | # Load user aliases | |
|
129 | for name, cmd in self.user_alias: | |
|
130 | self.soft_define_alias(name, cmd) | |
|
131 | ||
|
132 | def soft_define_alias(self, name, cmd): | |
|
133 | """Define an alias, but don't raise on an AliasError.""" | |
|
134 | try: | |
|
135 | self.define_alias(name, cmd) | |
|
136 | except AliasError, e: | |
|
137 | error("Invalid alias: %s" % e) | |
|
138 | ||
|
139 | def define_alias(self, name, cmd): | |
|
140 | """Define a new alias after validating it. | |
|
141 | ||
|
142 | This will raise an :exc:`AliasError` if there are validation | |
|
143 | problems. | |
|
144 | """ | |
|
145 | nargs = self.validate_alias(name, cmd) | |
|
146 | self.alias_table[name] = (nargs, cmd) | |
|
147 | ||
|
148 | def validate_alias(self, name, cmd): | |
|
149 | """Validate an alias and return the its number of arguments.""" | |
|
150 | if name in self.no_alias: | |
|
151 | raise InvalidAliasError("The name %s can't be aliased " | |
|
152 | "because it is a keyword or builtin." % name) | |
|
153 | if not (isinstance(cmd, basestring)): | |
|
154 | raise InvalidAliasError("An alias command must be a string, " | |
|
155 | "got: %r" % name) | |
|
156 | nargs = cmd.count('%s') | |
|
157 | if nargs>0 and cmd.find('%l')>=0: | |
|
158 | raise InvalidAliasError('The %s and %l specifiers are mutually ' | |
|
159 | 'exclusive in alias definitions.') | |
|
160 | return nargs | |
|
161 | ||
|
162 | def call_alias(self, alias, rest=''): | |
|
163 | """Call an alias given its name and the rest of the line.""" | |
|
164 | cmd = self.transform_alias(alias, rest) | |
|
165 | try: | |
|
166 | self.shell.system(cmd) | |
|
167 | except: | |
|
168 | self.shell.showtraceback() | |
|
169 | ||
|
170 | def transform_alias(self, alias,rest=''): | |
|
171 | """Transform alias to system command string.""" | |
|
172 | nargs, cmd = self.alias_table[alias] | |
|
173 | ||
|
174 | if ' ' in cmd and os.path.isfile(cmd): | |
|
175 | cmd = '"%s"' % cmd | |
|
176 | ||
|
177 | # Expand the %l special to be the user's input line | |
|
178 | if cmd.find('%l') >= 0: | |
|
179 | cmd = cmd.replace('%l', rest) | |
|
180 | rest = '' | |
|
181 | if nargs==0: | |
|
182 | # Simple, argument-less aliases | |
|
183 | cmd = '%s %s' % (cmd, rest) | |
|
184 | else: | |
|
185 | # Handle aliases with positional arguments | |
|
186 | args = rest.split(None, nargs) | |
|
187 | if len(args) < nargs: | |
|
188 | raise AliasError('Alias <%s> requires %s arguments, %s given.' % | |
|
189 | (alias, nargs, len(args))) | |
|
190 | cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:])) | |
|
191 | return cmd |
@@ -228,6 +228,7 b' class Application(object):' | |||
|
228 | 228 | self.print_traceback() |
|
229 | 229 | self.abort() |
|
230 | 230 | elif action == 'exit': |
|
231 | self.print_traceback() | |
|
231 | 232 | self.exit() |
|
232 | 233 | |
|
233 | 234 | def print_traceback(self): |
@@ -36,13 +36,14 b' BuiltinUndefined = BuiltinUndefined()' | |||
|
36 | 36 | |
|
37 | 37 | |
|
38 | 38 | class BuiltinTrap(Component): |
|
39 | shell = Instance('IPython.core.iplib.InteractiveShell') | |
|
40 | 39 | |
|
41 | 40 | def __init__(self, parent): |
|
42 | 41 | super(BuiltinTrap, self).__init__(parent, None, None) |
|
43 | 42 | # Don't just grab parent!!! |
|
44 |
self.shell = Component.get_instances( |
|
|
45 | klass='IPython.core.iplib.InteractiveShell')[0] | |
|
43 | self.shell = Component.get_instances( | |
|
44 | root=self.root, | |
|
45 | klass='IPython.core.iplib.InteractiveShell' | |
|
46 | )[0] | |
|
46 | 47 | self._orig_builtins = {} |
|
47 | 48 | |
|
48 | 49 | def __enter__(self): |
@@ -48,22 +48,55 b' class MetaComponentTracker(type):' | |||
|
48 | 48 | cls.__numcreated = 0 |
|
49 | 49 | |
|
50 | 50 | def __call__(cls, *args, **kw): |
|
51 |
"""Called when |
|
|
51 | """Called when a class is called (instantiated)!!! | |
|
52 | 52 | |
|
53 | 53 | When a Component or subclass is instantiated, this is called and |
|
54 | 54 | the instance is saved in a WeakValueDictionary for tracking. |
|
55 | 55 | """ |
|
56 | 56 | instance = cls.__new__(cls, *args, **kw) |
|
57 | # Do this before __init__ is called so get_instances works inside | |
|
58 | # __init__ methods! | |
|
57 | ||
|
58 | # Register the instance before __init__ is called so get_instances | |
|
59 | # works inside __init__ methods! | |
|
60 | indices = cls.register_instance(instance) | |
|
61 | ||
|
62 | # This is in a try/except because of the __init__ method fails, the | |
|
63 | # instance is discarded and shouldn't be tracked. | |
|
64 | try: | |
|
65 | if isinstance(instance, cls): | |
|
66 | cls.__init__(instance, *args, **kw) | |
|
67 | except: | |
|
68 | # Unregister the instance because __init__ failed! | |
|
69 | cls.unregister_instances(indices) | |
|
70 | raise | |
|
71 | else: | |
|
72 | return instance | |
|
73 | ||
|
74 | def register_instance(cls, instance): | |
|
75 | """Register instance with cls and its subclasses.""" | |
|
76 | # indices is a list of the keys used to register the instance | |
|
77 | # with. This list is needed if the instance needs to be unregistered. | |
|
78 | indices = [] | |
|
59 | 79 | for c in cls.__mro__: |
|
60 | 80 | if issubclass(cls, c) and issubclass(c, Component): |
|
61 | 81 | c.__numcreated += 1 |
|
82 | indices.append(c.__numcreated) | |
|
62 | 83 | c.__instance_refs[c.__numcreated] = instance |
|
63 | if isinstance(instance, cls): | |
|
64 | cls.__init__(instance, *args, **kw) | |
|
84 | else: | |
|
85 | break | |
|
86 | return indices | |
|
87 | ||
|
88 | def unregister_instances(cls, indices): | |
|
89 | """Unregister instance with cls and its subclasses.""" | |
|
90 | for c, index in zip(cls.__mro__, indices): | |
|
91 | try: | |
|
92 | del c.__instance_refs[index] | |
|
93 | except KeyError: | |
|
94 | pass | |
|
65 | 95 | |
|
66 | return instance | |
|
96 | def clear_instances(cls): | |
|
97 | """Clear all instances tracked by cls.""" | |
|
98 | cls.__instance_refs.clear() | |
|
99 | cls.__numcreated = 0 | |
|
67 | 100 | |
|
68 | 101 | def get_instances(cls, name=None, root=None, klass=None): |
|
69 | 102 | """Get all instances of cls and its subclasses. |
@@ -82,6 +115,9 b' class MetaComponentTracker(type):' | |||
|
82 | 115 | if klass is not None: |
|
83 | 116 | if isinstance(klass, basestring): |
|
84 | 117 | klass = import_item(klass) |
|
118 | # Limit search to instances of klass for performance | |
|
119 | if issubclass(klass, Component): | |
|
120 | return klass.get_instances(name=name, root=root) | |
|
85 | 121 | instances = cls.__instance_refs.values() |
|
86 | 122 | if name is not None: |
|
87 | 123 | instances = [i for i in instances if i.name == name] |
@@ -101,6 +137,26 b' class MetaComponentTracker(type):' | |||
|
101 | 137 | return [i for i in cls.get_instances(name, root, klass) if call(i)] |
|
102 | 138 | |
|
103 | 139 | |
|
140 | def masquerade_as(instance, cls): | |
|
141 | """Let instance masquerade as an instance of cls. | |
|
142 | ||
|
143 | Sometimes, such as in testing code, it is useful to let a class | |
|
144 | masquerade as another. Python, being duck typed, allows this by | |
|
145 | default. But, instances of components are tracked by their class type. | |
|
146 | ||
|
147 | After calling this, cls.get_instances() will return ``instance``. This | |
|
148 | does not, however, cause isinstance(instance, cls) to return ``True``. | |
|
149 | ||
|
150 | Parameters | |
|
151 | ---------- | |
|
152 | instance : an instance of a Component or Component subclass | |
|
153 | The instance that will pretend to be a cls. | |
|
154 | cls : subclass of Component | |
|
155 | The Component subclass that instance will pretend to be. | |
|
156 | """ | |
|
157 | cls.register_instance(instance) | |
|
158 | ||
|
159 | ||
|
104 | 160 | class ComponentNameGenerator(object): |
|
105 | 161 | """A Singleton to generate unique component names.""" |
|
106 | 162 | |
@@ -245,4 +301,5 b' class Component(HasTraitlets):' | |||
|
245 | 301 | self._children.append(child) |
|
246 | 302 | |
|
247 | 303 | def __repr__(self): |
|
248 |
return "< |
|
|
304 | return "<%s('%s')>" % (self.__class__.__name__, "DummyName") | |
|
305 | # return "<Component('%s')>" % self.name |
@@ -307,7 +307,8 b' class IPythonApp(Application):' | |||
|
307 | 307 | parent=None, |
|
308 | 308 | config=self.master_config |
|
309 | 309 | ) |
|
310 | ||
|
310 | print self.shell | |
|
311 | ||
|
311 | 312 | def start_app(self): |
|
312 | 313 | self.shell.mainloop() |
|
313 | 314 |
@@ -40,6 +40,7 b' from IPython.core import debugger, oinspect' | |||
|
40 | 40 | from IPython.core import shadowns |
|
41 | 41 | from IPython.core import history as ipcorehist |
|
42 | 42 | from IPython.core import prefilter |
|
43 | from IPython.core.alias import AliasManager | |
|
43 | 44 | from IPython.core.autocall import IPyAutocall |
|
44 | 45 | from IPython.core.builtin_trap import BuiltinTrap |
|
45 | 46 | from IPython.core.display_trap import DisplayTrap |
@@ -62,6 +63,9 b' from IPython.utils.genutils import *' | |||
|
62 | 63 | from IPython.utils.strdispatch import StrDispatch |
|
63 | 64 | from IPython.utils.platutils import toggle_set_term_title, set_term_title |
|
64 | 65 | |
|
66 | from IPython.utils import growl | |
|
67 | growl.start("IPython") | |
|
68 | ||
|
65 | 69 | from IPython.utils.traitlets import ( |
|
66 | 70 | Int, Float, Str, CBool, CaselessStrEnum, Enum, List, Unicode |
|
67 | 71 | ) |
@@ -303,7 +307,7 b' class InteractiveShell(Component, Magic):' | |||
|
303 | 307 | self.init_traceback_handlers(custom_exceptions) |
|
304 | 308 | self.init_user_ns() |
|
305 | 309 | self.init_logger() |
|
306 |
self.init_alias |
|
|
310 | self.init_alias() | |
|
307 | 311 | self.init_builtins() |
|
308 | 312 | |
|
309 | 313 | # pre_config_initialization |
@@ -1660,129 +1664,8 b' class InteractiveShell(Component, Magic):' | |||
|
1660 | 1664 | # Things related to aliases |
|
1661 | 1665 | #------------------------------------------------------------------------- |
|
1662 | 1666 | |
|
1663 |
def init_alias |
|
|
1664 | # dict of things NOT to alias (keywords, builtins and some magics) | |
|
1665 | no_alias = {} | |
|
1666 | no_alias_magics = ['cd','popd','pushd','dhist','alias','unalias'] | |
|
1667 | for key in keyword.kwlist + no_alias_magics: | |
|
1668 | no_alias[key] = 1 | |
|
1669 | no_alias.update(__builtin__.__dict__) | |
|
1670 | self.no_alias = no_alias | |
|
1671 | ||
|
1672 | # Make some aliases automatically | |
|
1673 | # Prepare list of shell aliases to auto-define | |
|
1674 | if os.name == 'posix': | |
|
1675 | auto_alias = ('mkdir mkdir', 'rmdir rmdir', | |
|
1676 | 'mv mv -i','rm rm -i','cp cp -i', | |
|
1677 | 'cat cat','less less','clear clear', | |
|
1678 | # a better ls | |
|
1679 | 'ls ls -F', | |
|
1680 | # long ls | |
|
1681 | 'll ls -lF') | |
|
1682 | # Extra ls aliases with color, which need special treatment on BSD | |
|
1683 | # variants | |
|
1684 | ls_extra = ( # color ls | |
|
1685 | 'lc ls -F -o --color', | |
|
1686 | # ls normal files only | |
|
1687 | 'lf ls -F -o --color %l | grep ^-', | |
|
1688 | # ls symbolic links | |
|
1689 | 'lk ls -F -o --color %l | grep ^l', | |
|
1690 | # directories or links to directories, | |
|
1691 | 'ldir ls -F -o --color %l | grep /$', | |
|
1692 | # things which are executable | |
|
1693 | 'lx ls -F -o --color %l | grep ^-..x', | |
|
1694 | ) | |
|
1695 | # The BSDs don't ship GNU ls, so they don't understand the | |
|
1696 | # --color switch out of the box | |
|
1697 | if 'bsd' in sys.platform: | |
|
1698 | ls_extra = ( # ls normal files only | |
|
1699 | 'lf ls -lF | grep ^-', | |
|
1700 | # ls symbolic links | |
|
1701 | 'lk ls -lF | grep ^l', | |
|
1702 | # directories or links to directories, | |
|
1703 | 'ldir ls -lF | grep /$', | |
|
1704 | # things which are executable | |
|
1705 | 'lx ls -lF | grep ^-..x', | |
|
1706 | ) | |
|
1707 | auto_alias = auto_alias + ls_extra | |
|
1708 | elif os.name in ['nt','dos']: | |
|
1709 | auto_alias = ('ls dir /on', | |
|
1710 | 'ddir dir /ad /on', 'ldir dir /ad /on', | |
|
1711 | 'mkdir mkdir','rmdir rmdir','echo echo', | |
|
1712 | 'ren ren','cls cls','copy copy') | |
|
1713 | else: | |
|
1714 | auto_alias = () | |
|
1715 | self.auto_alias = [s.split(None,1) for s in auto_alias] | |
|
1716 | ||
|
1717 | # Load default aliases | |
|
1718 | for alias, cmd in self.auto_alias: | |
|
1719 | self.define_alias(alias,cmd) | |
|
1720 | ||
|
1721 | # Load user aliases | |
|
1722 | for alias in self.alias: | |
|
1723 | self.magic_alias(alias) | |
|
1724 | ||
|
1725 | def call_alias(self,alias,rest=''): | |
|
1726 | """Call an alias given its name and the rest of the line. | |
|
1727 | ||
|
1728 | This is only used to provide backwards compatibility for users of | |
|
1729 | ipalias(), use of which is not recommended for anymore.""" | |
|
1730 | ||
|
1731 | # Now call the macro, evaluating in the user's namespace | |
|
1732 | cmd = self.transform_alias(alias, rest) | |
|
1733 | try: | |
|
1734 | self.system(cmd) | |
|
1735 | except: | |
|
1736 | self.showtraceback() | |
|
1737 | ||
|
1738 | def define_alias(self, name, cmd): | |
|
1739 | """ Define a new alias.""" | |
|
1740 | ||
|
1741 | if callable(cmd): | |
|
1742 | self.alias_table[name] = cmd | |
|
1743 | from IPython.core import shadowns | |
|
1744 | setattr(shadowns, name, cmd) | |
|
1745 | return | |
|
1746 | ||
|
1747 | if isinstance(cmd, basestring): | |
|
1748 | nargs = cmd.count('%s') | |
|
1749 | if nargs>0 and cmd.find('%l')>=0: | |
|
1750 | raise Exception('The %s and %l specifiers are mutually ' | |
|
1751 | 'exclusive in alias definitions.') | |
|
1752 | ||
|
1753 | self.alias_table[name] = (nargs,cmd) | |
|
1754 | return | |
|
1755 | ||
|
1756 | self.alias_table[name] = cmd | |
|
1757 | ||
|
1758 | def ipalias(self,arg_s): | |
|
1759 | """Call an alias by name. | |
|
1760 | ||
|
1761 | Input: a string containing the name of the alias to call and any | |
|
1762 | additional arguments to be passed to the magic. | |
|
1763 | ||
|
1764 | ipalias('name -opt foo bar') is equivalent to typing at the ipython | |
|
1765 | prompt: | |
|
1766 | ||
|
1767 | In[1]: name -opt foo bar | |
|
1768 | ||
|
1769 | To call an alias without arguments, simply use ipalias('name'). | |
|
1770 | ||
|
1771 | This provides a proper Python function to call IPython's aliases in any | |
|
1772 | valid Python code you can type at the interpreter, including loops and | |
|
1773 | compound statements. It is added by IPython to the Python builtin | |
|
1774 | namespace upon initialization.""" | |
|
1775 | ||
|
1776 | args = arg_s.split(' ',1) | |
|
1777 | alias_name = args[0] | |
|
1778 | try: | |
|
1779 | alias_args = args[1] | |
|
1780 | except IndexError: | |
|
1781 | alias_args = '' | |
|
1782 | if alias_name in self.alias_table: | |
|
1783 | self.call_alias(alias_name,alias_args) | |
|
1784 | else: | |
|
1785 | error("Alias `%s` not found." % alias_name) | |
|
1667 | def init_alias(self): | |
|
1668 | self.alias_manager = AliasManager(self, config=self.config) | |
|
1786 | 1669 | |
|
1787 | 1670 | def expand_alias(self, line): |
|
1788 | 1671 | """ Expand an alias in the command line |
@@ -1817,81 +1700,25 b' class InteractiveShell(Component, Magic):' | |||
|
1817 | 1700 | while 1: |
|
1818 | 1701 | pre,fn,rest = prefilter.splitUserInput(line, |
|
1819 | 1702 | prefilter.shell_line_split) |
|
1820 | if fn in self.alias_table: | |
|
1703 | if fn in self.alias_manager.alias_table: | |
|
1821 | 1704 | if fn in done: |
|
1822 | 1705 | warn("Cyclic alias definition, repeated '%s'" % fn) |
|
1823 | 1706 | return "" |
|
1824 | 1707 | done.add(fn) |
|
1825 | 1708 | |
|
1826 | l2 = self.transform_alias(fn,rest) | |
|
1827 | # dir -> dir | |
|
1828 | # print "alias",line, "->",l2 #dbg | |
|
1709 | l2 = self.alias_manager.transform_alias(fn, rest) | |
|
1829 | 1710 | if l2 == line: |
|
1830 | 1711 | break |
|
1831 | 1712 | # ls -> ls -F should not recurse forever |
|
1832 | 1713 | if l2.split(None,1)[0] == line.split(None,1)[0]: |
|
1833 | 1714 | line = l2 |
|
1834 | 1715 | break |
|
1835 | ||
|
1836 | 1716 | line=l2 |
|
1837 | ||
|
1838 | ||
|
1839 | # print "al expand to",line #dbg | |
|
1840 | 1717 | else: |
|
1841 | 1718 | break |
|
1842 | 1719 | |
|
1843 | 1720 | return line |
|
1844 | 1721 | |
|
1845 | def transform_alias(self, alias,rest=''): | |
|
1846 | """ Transform alias to system command string. | |
|
1847 | """ | |
|
1848 | trg = self.alias_table[alias] | |
|
1849 | ||
|
1850 | nargs,cmd = trg | |
|
1851 | # print trg #dbg | |
|
1852 | if ' ' in cmd and os.path.isfile(cmd): | |
|
1853 | cmd = '"%s"' % cmd | |
|
1854 | ||
|
1855 | # Expand the %l special to be the user's input line | |
|
1856 | if cmd.find('%l') >= 0: | |
|
1857 | cmd = cmd.replace('%l',rest) | |
|
1858 | rest = '' | |
|
1859 | if nargs==0: | |
|
1860 | # Simple, argument-less aliases | |
|
1861 | cmd = '%s %s' % (cmd,rest) | |
|
1862 | else: | |
|
1863 | # Handle aliases with positional arguments | |
|
1864 | args = rest.split(None,nargs) | |
|
1865 | if len(args)< nargs: | |
|
1866 | error('Alias <%s> requires %s arguments, %s given.' % | |
|
1867 | (alias,nargs,len(args))) | |
|
1868 | return None | |
|
1869 | cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:])) | |
|
1870 | # Now call the macro, evaluating in the user's namespace | |
|
1871 | #print 'new command: <%r>' % cmd # dbg | |
|
1872 | return cmd | |
|
1873 | ||
|
1874 | def init_auto_alias(self): | |
|
1875 | """Define some aliases automatically. | |
|
1876 | ||
|
1877 | These are ALL parameter-less aliases""" | |
|
1878 | ||
|
1879 | for alias,cmd in self.auto_alias: | |
|
1880 | self.define_alias(alias,cmd) | |
|
1881 | ||
|
1882 | def alias_table_validate(self,verbose=0): | |
|
1883 | """Update information about the alias table. | |
|
1884 | ||
|
1885 | In particular, make sure no Python keywords/builtins are in it.""" | |
|
1886 | ||
|
1887 | no_alias = self.no_alias | |
|
1888 | for k in self.alias_table.keys(): | |
|
1889 | if k in no_alias: | |
|
1890 | del self.alias_table[k] | |
|
1891 | if verbose: | |
|
1892 | print ("Deleting alias <%s>, it's a Python " | |
|
1893 | "keyword or builtin." % k) | |
|
1894 | ||
|
1895 | 1722 | #------------------------------------------------------------------------- |
|
1896 | 1723 | # Things related to the running of code |
|
1897 | 1724 | #------------------------------------------------------------------------- |
@@ -2513,9 +2340,10 b' class InteractiveShell(Component, Magic):' | |||
|
2513 | 2340 | - continue_prompt(False): whether this line is the first one or a |
|
2514 | 2341 | continuation in a sequence of inputs. |
|
2515 | 2342 | """ |
|
2516 | ||
|
2343 | growl.notify("raw_input: ", "prompt = %r\ncontinue_prompt = %s" % (prompt, continue_prompt)) | |
|
2517 | 2344 | # Code run by the user may have modified the readline completer state. |
|
2518 | 2345 | # We must ensure that our completer is back in place. |
|
2346 | ||
|
2519 | 2347 | if self.has_readline: |
|
2520 | 2348 | self.set_completer() |
|
2521 | 2349 | |
@@ -2659,6 +2487,8 b' class InteractiveShell(Component, Magic):' | |||
|
2659 | 2487 | |
|
2660 | 2488 | # save the line away in case we crash, so the post-mortem handler can |
|
2661 | 2489 | # record it |
|
2490 | growl.notify("_prefilter: ", "line = %s\ncontinue_prompt = %s" % (line, continue_prompt)) | |
|
2491 | ||
|
2662 | 2492 | self._last_input_line = line |
|
2663 | 2493 | |
|
2664 | 2494 | #print '***line: <%s>' % line # dbg |
@@ -2715,15 +2545,17 b' class InteractiveShell(Component, Magic):' | |||
|
2715 | 2545 | entry and presses enter. |
|
2716 | 2546 | |
|
2717 | 2547 | """ |
|
2548 | growl.notify("multiline_prefilter: ", "%s\n%s" % (line, continue_prompt)) | |
|
2718 | 2549 | out = [] |
|
2719 | 2550 | for l in line.rstrip('\n').split('\n'): |
|
2720 | 2551 | out.append(self._prefilter(l, continue_prompt)) |
|
2552 | growl.notify("multiline_prefilter return: ", '\n'.join(out)) | |
|
2721 | 2553 | return '\n'.join(out) |
|
2722 | 2554 | |
|
2723 | 2555 | # Set the default prefilter() function (this can be user-overridden) |
|
2724 | 2556 | prefilter = multiline_prefilter |
|
2725 | 2557 | |
|
2726 | def handle_normal(self,line_info): | |
|
2558 | def handle_normal(self, line_info): | |
|
2727 | 2559 | """Handle normal input lines. Use as a template for handlers.""" |
|
2728 | 2560 | |
|
2729 | 2561 | # With autoindent on, we need some way to exit the input loop, and I |
@@ -2742,10 +2574,9 b' class InteractiveShell(Component, Magic):' | |||
|
2742 | 2574 | self.log(line,line,continue_prompt) |
|
2743 | 2575 | return line |
|
2744 | 2576 | |
|
2745 | def handle_alias(self,line_info): | |
|
2577 | def handle_alias(self, line_info): | |
|
2746 | 2578 | """Handle alias input lines. """ |
|
2747 | tgt = self.alias_table[line_info.iFun] | |
|
2748 | # print "=>",tgt #dbg | |
|
2579 | tgt = self.alias_manager.alias_table[line_info.iFun] | |
|
2749 | 2580 | if callable(tgt): |
|
2750 | 2581 | if '$' in line_info.line: |
|
2751 | 2582 | call_meth = '(_ip, _ip.var_expand(%s))' |
@@ -251,8 +251,8 b' def checkAlias(l_info,ip):' | |||
|
251 | 251 | # Note: aliases can not contain '.' |
|
252 | 252 | head = l_info.iFun.split('.',1)[0] |
|
253 | 253 | |
|
254 |
if l_info.iFun not in ip.alias_ |
|
|
255 |
or head not in ip.alias_ |
|
|
254 | if l_info.iFun not in ip.alias_manager \ | |
|
255 | or head not in ip.alias_manager \ | |
|
256 | 256 | or isShadowed(head,ip): |
|
257 | 257 | return None |
|
258 | 258 |
General Comments 0
You need to be logged in to leave comments.
Login now