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