##// END OF EJS Templates
Close http://www.scipy.net/roundup/ipython/issue34 with slightly modified...
fperez -
r3:22db71d2
parent child Browse files
Show More
@@ -1,198 +1,199 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Word completion for GNU readline 2.0.
2 """Word completion for GNU readline 2.0.
3
3
4 ---------------------------------------------------------------------------
4 ---------------------------------------------------------------------------
5 NOTE: This version is a re-implementation of rlcompleter with selectable
5 NOTE: This version is a re-implementation of rlcompleter with selectable
6 namespace.
6 namespace.
7
7
8 The problem with rlcompleter is that it's hardwired to work with
8 The problem with rlcompleter is that it's hardwired to work with
9 __main__.__dict__, and in some cases one may have 'sandboxed' namespaces. So
9 __main__.__dict__, and in some cases one may have 'sandboxed' namespaces. So
10 this class is a ripoff of rlcompleter, with the namespace to work in as an
10 this class is a ripoff of rlcompleter, with the namespace to work in as an
11 optional parameter.
11 optional parameter.
12
12
13 This class can be used just like rlcompleter, but the Completer class now has
13 This class can be used just like rlcompleter, but the Completer class now has
14 a constructor with the optional 'namespace' parameter.
14 a constructor with the optional 'namespace' parameter.
15
15
16 A patch has been submitted to Python@sourceforge for these changes to go in
16 A patch has been submitted to Python@sourceforge for these changes to go in
17 the standard Python distribution.
17 the standard Python distribution.
18
18
19 The patch went in for Python 2.3. Once IPython drops support for Python 2.2,
19 The patch went in for Python 2.3. Once IPython drops support for Python 2.2,
20 this file can be significantly reduced.
20 this file can be significantly reduced.
21 ---------------------------------------------------------------------------
21 ---------------------------------------------------------------------------
22
22
23 Original rlcompleter documentation:
23 Original rlcompleter documentation:
24
24
25 This requires the latest extension to the readline module (the
25 This requires the latest extension to the readline module (the
26 completes keywords, built-ins and globals in __main__; when completing
26 completes keywords, built-ins and globals in __main__; when completing
27 NAME.NAME..., it evaluates (!) the expression up to the last dot and
27 NAME.NAME..., it evaluates (!) the expression up to the last dot and
28 completes its attributes.
28 completes its attributes.
29
29
30 It's very cool to do "import string" type "string.", hit the
30 It's very cool to do "import string" type "string.", hit the
31 completion key (twice), and see the list of names defined by the
31 completion key (twice), and see the list of names defined by the
32 string module!
32 string module!
33
33
34 Tip: to use the tab key as the completion key, call
34 Tip: to use the tab key as the completion key, call
35
35
36 readline.parse_and_bind("tab: complete")
36 readline.parse_and_bind("tab: complete")
37
37
38 Notes:
38 Notes:
39
39
40 - Exceptions raised by the completer function are *ignored* (and
40 - Exceptions raised by the completer function are *ignored* (and
41 generally cause the completion to fail). This is a feature -- since
41 generally cause the completion to fail). This is a feature -- since
42 readline sets the tty device in raw (or cbreak) mode, printing a
42 readline sets the tty device in raw (or cbreak) mode, printing a
43 traceback wouldn't work well without some complicated hoopla to save,
43 traceback wouldn't work well without some complicated hoopla to save,
44 reset and restore the tty state.
44 reset and restore the tty state.
45
45
46 - The evaluation of the NAME.NAME... form may cause arbitrary
46 - The evaluation of the NAME.NAME... form may cause arbitrary
47 application defined code to be executed if an object with a
47 application defined code to be executed if an object with a
48 __getattr__ hook is found. Since it is the responsibility of the
48 __getattr__ hook is found. Since it is the responsibility of the
49 application (or the user) to enable this feature, I consider this an
49 application (or the user) to enable this feature, I consider this an
50 acceptable risk. More complicated expressions (e.g. function calls or
50 acceptable risk. More complicated expressions (e.g. function calls or
51 indexing operations) are *not* evaluated.
51 indexing operations) are *not* evaluated.
52
52
53 - GNU readline is also used by the built-in functions input() and
53 - GNU readline is also used by the built-in functions input() and
54 raw_input(), and thus these also benefit/suffer from the completer
54 raw_input(), and thus these also benefit/suffer from the completer
55 features. Clearly an interactive application can benefit by
55 features. Clearly an interactive application can benefit by
56 specifying its own completer function and using raw_input() for all
56 specifying its own completer function and using raw_input() for all
57 its input.
57 its input.
58
58
59 - When the original stdin is not a tty device, GNU readline is never
59 - When the original stdin is not a tty device, GNU readline is never
60 used, and this module (and the readline module) are silently inactive.
60 used, and this module (and the readline module) are silently inactive.
61
61
62 """
62 """
63
63
64 #*****************************************************************************
64 #*****************************************************************************
65 #
65 #
66 # Since this file is essentially a minimally modified copy of the rlcompleter
66 # Since this file is essentially a minimally modified copy of the rlcompleter
67 # module which is part of the standard Python distribution, I assume that the
67 # module which is part of the standard Python distribution, I assume that the
68 # proper procedure is to maintain its copyright as belonging to the Python
68 # proper procedure is to maintain its copyright as belonging to the Python
69 # Software Foundation:
69 # Software Foundation:
70 #
70 #
71 # Copyright (C) 2001 Python Software Foundation, www.python.org
71 # Copyright (C) 2001 Python Software Foundation, www.python.org
72 #
72 #
73 # Distributed under the terms of the Python Software Foundation license.
73 # Distributed under the terms of the Python Software Foundation license.
74 #
74 #
75 # Full text available at:
75 # Full text available at:
76 #
76 #
77 # http://www.python.org/2.1/license.html
77 # http://www.python.org/2.1/license.html
78 #
78 #
79 #*****************************************************************************
79 #*****************************************************************************
80
80
81 import readline
81 import readline
82 import __builtin__
82 import __builtin__
83 import __main__
83 import __main__
84
84
85 __all__ = ["Completer"]
85 __all__ = ["Completer"]
86
86
87 # declares Python 2.2 compatibility symbols:
88 try:
89 basestring
90 except NameError:
91 import types
92 basestring = (types.StringType, types.UnicodeType)
93
87 class Completer:
94 class Completer:
88 def __init__(self, namespace = None):
95 def __init__(self, namespace = None):
89 """Create a new completer for the command line.
96 """Create a new completer for the command line.
90
97
91 Completer([namespace]) -> completer instance.
98 Completer([namespace]) -> completer instance.
92
99
93 If unspecified, the default namespace where completions are performed
100 If unspecified, the default namespace where completions are performed
94 is __main__ (technically, __main__.__dict__). Namespaces should be
101 is __main__ (technically, __main__.__dict__). Namespaces should be
95 given as dictionaries.
102 given as dictionaries.
96
103
97 Completer instances should be used as the completion mechanism of
104 Completer instances should be used as the completion mechanism of
98 readline via the set_completer() call:
105 readline via the set_completer() call:
99
106
100 readline.set_completer(Completer(my_namespace).complete)
107 readline.set_completer(Completer(my_namespace).complete)
101 """
108 """
102
109
103 if namespace and type(namespace) != type({}):
110 if namespace and type(namespace) != type({}):
104 raise TypeError,'namespace must be a dictionary'
111 raise TypeError,'namespace must be a dictionary'
105
112
106 # Don't bind to namespace quite yet, but flag whether the user wants a
113 # Don't bind to namespace quite yet, but flag whether the user wants a
107 # specific namespace or to use __main__.__dict__. This will allow us
114 # specific namespace or to use __main__.__dict__. This will allow us
108 # to bind to __main__.__dict__ at completion time, not now.
115 # to bind to __main__.__dict__ at completion time, not now.
109 if namespace is None:
116 if namespace is None:
110 self.use_main_ns = 1
117 self.use_main_ns = 1
111 else:
118 else:
112 self.use_main_ns = 0
119 self.use_main_ns = 0
113 self.namespace = namespace
120 self.namespace = namespace
114
121
115 def complete(self, text, state):
122 def complete(self, text, state):
116 """Return the next possible completion for 'text'.
123 """Return the next possible completion for 'text'.
117
124
118 This is called successively with state == 0, 1, 2, ... until it
125 This is called successively with state == 0, 1, 2, ... until it
119 returns None. The completion should begin with 'text'.
126 returns None. The completion should begin with 'text'.
120
127
121 """
128 """
122 if self.use_main_ns:
129 if self.use_main_ns:
123 self.namespace = __main__.__dict__
130 self.namespace = __main__.__dict__
124
131
125 if state == 0:
132 if state == 0:
126 if "." in text:
133 if "." in text:
127 self.matches = self.attr_matches(text)
134 self.matches = self.attr_matches(text)
128 else:
135 else:
129 self.matches = self.global_matches(text)
136 self.matches = self.global_matches(text)
130 try:
137 try:
131 return self.matches[state]
138 return self.matches[state]
132 except IndexError:
139 except IndexError:
133 return None
140 return None
134
141
135 def global_matches(self, text):
142 def global_matches(self, text):
136 """Compute matches when text is a simple name.
143 """Compute matches when text is a simple name.
137
144
138 Return a list of all keywords, built-in functions and names currently
145 Return a list of all keywords, built-in functions and names currently
139 defined in self.namespace that match.
146 defined in self.namespace that match.
140
147
141 """
148 """
142 import keyword
149 import keyword
143 matches = []
150 matches = []
144 n = len(text)
151 n = len(text)
145 for list in [keyword.kwlist,
152 for list in [keyword.kwlist,
146 __builtin__.__dict__.keys(),
153 __builtin__.__dict__.keys(),
147 self.namespace.keys()]:
154 self.namespace.keys()]:
148 for word in list:
155 for word in list:
149 if word[:n] == text and word != "__builtins__":
156 if word[:n] == text and word != "__builtins__":
150 matches.append(word)
157 matches.append(word)
151 return matches
158 return matches
152
159
153 def attr_matches(self, text):
160 def attr_matches(self, text):
154 """Compute matches when text contains a dot.
161 """Compute matches when text contains a dot.
155
162
156 Assuming the text is of the form NAME.NAME....[NAME], and is
163 Assuming the text is of the form NAME.NAME....[NAME], and is
157 evaluatable in self.namespace, it will be evaluated and its attributes
164 evaluatable in self.namespace, it will be evaluated and its attributes
158 (as revealed by dir()) are used as possible completions. (For class
165 (as revealed by dir()) are used as possible completions. (For class
159 instances, class members are are also considered.)
166 instances, class members are are also considered.)
160
167
161 WARNING: this can still invoke arbitrary C code, if an object
168 WARNING: this can still invoke arbitrary C code, if an object
162 with a __getattr__ hook is evaluated.
169 with a __getattr__ hook is evaluated.
163
170
164 """
171 """
165 import re
172 import re
166
173
167 # Another option, seems to work great. Catches things like ''.<tab>
174 # Another option, seems to work great. Catches things like ''.<tab>
168 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
175 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
169
176
170 if not m:
177 if not m:
171 return []
178 return []
172 expr, attr = m.group(1, 3)
179 expr, attr = m.group(1, 3)
173 object = eval(expr, self.namespace)
180 object = eval(expr, self.namespace)
174 words = dir(object)
181 words = [w for w in dir(object) if isinstance(w, basestring)]
175 if hasattr(object,'__class__'):
182 if hasattr(object,'__class__'):
176 words.append('__class__')
183 words.append('__class__')
177 words.extend(get_class_members(object.__class__))
184 words.extend(get_class_members(object.__class__))
178 n = len(attr)
185 n = len(attr)
179 matches = []
186 matches = []
180 for word in words:
187 for word in words:
181 try:
188 if word[:n] == attr and word != "__builtins__":
182 if word[:n] == attr and word != "__builtins__":
189 matches.append("%s.%s" % (expr, word))
183 matches.append("%s.%s" % (expr, word))
184 except:
185 # some badly behaved objects pollute dir() with non-strings,
186 # which cause the completion to fail. This way we skip the
187 # bad entries and can still continue processing the others.
188 pass
189 return matches
190 return matches
190
191
191 def get_class_members(klass):
192 def get_class_members(klass):
192 ret = dir(klass)
193 ret = dir(klass)
193 if hasattr(klass,'__bases__'):
194 if hasattr(klass,'__bases__'):
194 for base in klass.__bases__:
195 for base in klass.__bases__:
195 ret.extend(get_class_members(base))
196 ret.extend(get_class_members(base))
196 return ret
197 return ret
197
198
198 readline.set_completer(Completer().complete)
199 readline.set_completer(Completer().complete)
General Comments 0
You need to be logged in to leave comments. Login now