DebugClients/Python/FlexCompleter.py

changeset 6185
7f00d906e653
parent 5179
5f56410e7624
child 6891
93f82da09f22
equal deleted inserted replaced
6184:789e88d94899 6185:7f00d906e653
123 123
124 @param val value to check (object) 124 @param val value to check (object)
125 @param word word to ammend (string) 125 @param word word to ammend (string)
126 @return ammended word (string) 126 @return ammended word (string)
127 """ 127 """
128 if hasattr(val, '__call__'): 128 if callable(val):
129 word = word + "(" 129 word = word + "("
130 return word 130 return word
131 131
132 def global_matches(self, text): 132 def global_matches(self, text):
133 """ 133 """
137 @return A list of all keywords, built-in functions and names currently 137 @return A list of all keywords, built-in functions and names currently
138 defined in self.namespace that match. 138 defined in self.namespace that match.
139 """ 139 """
140 import keyword 140 import keyword
141 matches = [] 141 matches = []
142 seen = {"__builtins__"}
142 n = len(text) 143 n = len(text)
143 for word in keyword.kwlist: 144 for word in keyword.kwlist:
144 if word[:n] == text: 145 if word[:n] == text:
146 seen.add(word)
147 if word in {'finally', 'try'}:
148 word = word + ':'
149 elif word not in {'False', 'None', 'True',
150 'break', 'continue', 'pass',
151 'else'}:
152 word = word + ' '
145 matches.append(word) 153 matches.append(word)
146 for nspace in [builtins.__dict__, self.namespace]: 154 for nspace in [builtins.__dict__, self.namespace]:
147 for word, val in nspace.items(): 155 for word, val in nspace.items():
148 if word[:n] == text and word != "__builtins__": 156 if word[:n] == text and word not in seen:
157 seen.add(word)
149 matches.append(self._callable_postfix(val, word)) 158 matches.append(self._callable_postfix(val, word))
150 return matches 159 return matches
151 160
152 def attr_matches(self, text): 161 def attr_matches(self, text):
153 """ 162 """
164 @param text The text to be completed. (string) 173 @param text The text to be completed. (string)
165 @return A list of all matches. 174 @return A list of all matches.
166 """ 175 """
167 import re 176 import re
168 177
169 # Another option, seems to work great. Catches things like ''.<tab> 178 m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text)
170 m = re.match(r"(\S+(\.\w+)*)\.(\w*)", text)
171
172 if not m: 179 if not m:
173 return 180 return
174 expr, attr = m.group(1, 3) 181 expr, attr = m.group(1, 3)
175 try: 182 try:
176 thisobject = eval(expr, self.namespace) 183 thisobject = eval(expr, self.namespace)
177 except Exception: 184 except Exception:
178 return [] 185 return []
179 186
180 # get the content of the object, except __builtins__ 187 # get the content of the object, except __builtins__
181 words = dir(thisobject) 188 words = set(dir(thisobject))
182 if "__builtins__" in words: 189 words.discard("__builtins__")
183 words.remove("__builtins__")
184 190
185 if hasattr(object, '__class__'): 191 if hasattr(object, '__class__'):
186 words.append('__class__') 192 words.add('__class__')
187 words = words + get_class_members(object.__class__) 193 words.update(get_class_members(thisobject.__class__))
188 matches = [] 194 matches = []
189 n = len(attr) 195 n = len(attr)
190 for word in words: 196 if attr == '':
191 try: 197 noprefix = '_'
192 if word[:n] == attr and hasattr(thisobject, word): 198 elif attr == '_':
193 val = getattr(thisobject, word) 199 noprefix = '__'
194 word = self._callable_postfix( 200 else:
195 val, "{0}.{1}".format(expr, word)) 201 noprefix = None
196 matches.append(word) 202 while True:
197 except Exception: 203 for word in words:
198 # some badly behaved objects pollute dir() with non-strings, 204 if word[:n] == attr and \
199 # which cause the completion to fail. This way we skip the 205 not (noprefix and word[:n + 1] == noprefix):
200 # bad entries and can still continue processing the others. 206 match = "{0}.{1}".format(expr, word)
201 pass 207 try:
208 val = getattr(thisobject, word)
209 except Exception:
210 pass # Include even if attribute not set
211 else:
212 match = self._callable_postfix(val, match)
213 matches.append(match)
214 if matches or not noprefix:
215 break
216 if noprefix == '_':
217 noprefix = '__'
218 else:
219 noprefix = None
220 matches.sort()
202 return matches 221 return matches
203 222
204 223
205 def get_class_members(klass): 224 def get_class_members(klass):
206 """ 225 """

eric ide

mercurial