##// END OF EJS Templates
Apply Prabhu's patch for traits tab completion.
fperez -
Show More
@@ -1,558 +1,562 b''
1 1 """Word completion for IPython.
2 2
3 3 This module is a fork of the rlcompleter module in the Python standard
4 4 library. The original enhancements made to rlcompleter have been sent
5 5 upstream and were accepted as of Python 2.3, but we need a lot more
6 6 functionality specific to IPython, so this module will continue to live as an
7 7 IPython-specific utility.
8 8
9 9 ---------------------------------------------------------------------------
10 10 Original rlcompleter documentation:
11 11
12 12 This requires the latest extension to the readline module (the
13 13 completes keywords, built-ins and globals in __main__; when completing
14 14 NAME.NAME..., it evaluates (!) the expression up to the last dot and
15 15 completes its attributes.
16 16
17 17 It's very cool to do "import string" type "string.", hit the
18 18 completion key (twice), and see the list of names defined by the
19 19 string module!
20 20
21 21 Tip: to use the tab key as the completion key, call
22 22
23 23 readline.parse_and_bind("tab: complete")
24 24
25 25 Notes:
26 26
27 27 - Exceptions raised by the completer function are *ignored* (and
28 28 generally cause the completion to fail). This is a feature -- since
29 29 readline sets the tty device in raw (or cbreak) mode, printing a
30 30 traceback wouldn't work well without some complicated hoopla to save,
31 31 reset and restore the tty state.
32 32
33 33 - The evaluation of the NAME.NAME... form may cause arbitrary
34 34 application defined code to be executed if an object with a
35 35 __getattr__ hook is found. Since it is the responsibility of the
36 36 application (or the user) to enable this feature, I consider this an
37 37 acceptable risk. More complicated expressions (e.g. function calls or
38 38 indexing operations) are *not* evaluated.
39 39
40 40 - GNU readline is also used by the built-in functions input() and
41 41 raw_input(), and thus these also benefit/suffer from the completer
42 42 features. Clearly an interactive application can benefit by
43 43 specifying its own completer function and using raw_input() for all
44 44 its input.
45 45
46 46 - When the original stdin is not a tty device, GNU readline is never
47 47 used, and this module (and the readline module) are silently inactive.
48 48
49 49 """
50 50
51 51 #*****************************************************************************
52 52 #
53 53 # Since this file is essentially a minimally modified copy of the rlcompleter
54 54 # module which is part of the standard Python distribution, I assume that the
55 55 # proper procedure is to maintain its copyright as belonging to the Python
56 56 # Software Foundation (in addition to my own, for all new code).
57 57 #
58 58 # Copyright (C) 2001 Python Software Foundation, www.python.org
59 59 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
60 60 #
61 61 # Distributed under the terms of the BSD License. The full license is in
62 62 # the file COPYING, distributed as part of this software.
63 63 #
64 64 #*****************************************************************************
65 65
66 66 import __builtin__
67 67 import __main__
68 68 import glob
69 69 import keyword
70 70 import os
71 71 import re
72 72 import readline
73 73 import sys
74 74 import types
75 75
76 76 # Python 2.4 offers sets as a builtin
77 77 try:
78 78 set([1,2])
79 79 except NameError:
80 80 from sets import Set as set
81 81
82 82
83 83 from IPython.genutils import shlex_split,debugp
84 84
85 85 __all__ = ['Completer','IPCompleter']
86 86
87 87 def get_class_members(cls):
88 88 ret = dir(cls)
89 89 if hasattr(cls,'__bases__'):
90 90 for base in cls.__bases__:
91 91 ret.extend(get_class_members(base))
92 92 return ret
93 93
94 94 class Completer:
95 95 def __init__(self,namespace=None,global_namespace=None):
96 96 """Create a new completer for the command line.
97 97
98 98 Completer([namespace,global_namespace]) -> completer instance.
99 99
100 100 If unspecified, the default namespace where completions are performed
101 101 is __main__ (technically, __main__.__dict__). Namespaces should be
102 102 given as dictionaries.
103 103
104 104 An optional second namespace can be given. This allows the completer
105 105 to handle cases where both the local and global scopes need to be
106 106 distinguished.
107 107
108 108 Completer instances should be used as the completion mechanism of
109 109 readline via the set_completer() call:
110 110
111 111 readline.set_completer(Completer(my_namespace).complete)
112 112 """
113 113
114 114 # some minimal strict typechecks. For some core data structures, I
115 115 # want actual basic python types, not just anything that looks like
116 116 # one. This is especially true for namespaces.
117 117 for ns in (namespace,global_namespace):
118 118 if ns is not None and type(ns) != types.DictType:
119 119 raise TypeError,'namespace must be a dictionary'
120 120
121 121 # Don't bind to namespace quite yet, but flag whether the user wants a
122 122 # specific namespace or to use __main__.__dict__. This will allow us
123 123 # to bind to __main__.__dict__ at completion time, not now.
124 124 if namespace is None:
125 125 self.use_main_ns = 1
126 126 else:
127 127 self.use_main_ns = 0
128 128 self.namespace = namespace
129 129
130 130 # The global namespace, if given, can be bound directly
131 131 if global_namespace is None:
132 132 self.global_namespace = {}
133 133 else:
134 134 self.global_namespace = global_namespace
135 135
136 136 def complete(self, text, state):
137 137 """Return the next possible completion for 'text'.
138 138
139 139 This is called successively with state == 0, 1, 2, ... until it
140 140 returns None. The completion should begin with 'text'.
141 141
142 142 """
143 143 if self.use_main_ns:
144 144 self.namespace = __main__.__dict__
145 145
146 146 if state == 0:
147 147 if "." in text:
148 148 self.matches = self.attr_matches(text)
149 149 else:
150 150 self.matches = self.global_matches(text)
151 151 try:
152 152 return self.matches[state]
153 153 except IndexError:
154 154 return None
155 155
156 156 def global_matches(self, text):
157 157 """Compute matches when text is a simple name.
158 158
159 159 Return a list of all keywords, built-in functions and names currently
160 160 defined in self.namespace or self.global_namespace that match.
161 161
162 162 """
163 163 matches = []
164 164 match_append = matches.append
165 165 n = len(text)
166 166 for lst in [keyword.kwlist,
167 167 __builtin__.__dict__.keys(),
168 168 self.namespace.keys(),
169 169 self.global_namespace.keys()]:
170 170 for word in lst:
171 171 if word[:n] == text and word != "__builtins__":
172 172 match_append(word)
173 173 return matches
174 174
175 175 def attr_matches(self, text):
176 176 """Compute matches when text contains a dot.
177 177
178 178 Assuming the text is of the form NAME.NAME....[NAME], and is
179 179 evaluatable in self.namespace or self.global_namespace, it will be
180 180 evaluated and its attributes (as revealed by dir()) are used as
181 181 possible completions. (For class instances, class members are are
182 182 also considered.)
183 183
184 184 WARNING: this can still invoke arbitrary C code, if an object
185 185 with a __getattr__ hook is evaluated.
186 186
187 187 """
188 188 import re
189 189
190 190 # Another option, seems to work great. Catches things like ''.<tab>
191 191 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
192 192
193 193 if not m:
194 194 return []
195 195
196 196 expr, attr = m.group(1, 3)
197 197 try:
198 198 object = eval(expr, self.namespace)
199 199 except:
200 200 object = eval(expr, self.global_namespace)
201 201
202 202 # Start building the attribute list via dir(), and then complete it
203 203 # with a few extra special-purpose calls.
204 204 words = dir(object)
205 205
206 206 if hasattr(object,'__class__'):
207 207 words.append('__class__')
208 208 words.extend(get_class_members(object.__class__))
209 209
210 210 # this is the 'dir' function for objects with Enthought's traits
211 211 if hasattr(object, 'trait_names'):
212 words.extend(object.trait_names())
213 # eliminate possible duplicates, as some traits may also appear as
214 # normal attributes in the dir() call.
215 words = set(words)
212 try:
213 words.extend(object.trait_names())
214 # eliminate possible duplicates, as some traits may also
215 # appear as normal attributes in the dir() call.
216 words = set(words)
217 except TypeError:
218 # This will happen if `object` is a class and not an instance.
219 pass
216 220
217 221 # filter out non-string attributes which may be stuffed by dir() calls
218 222 # and poor coding in third-party modules
219 223 words = [w for w in words
220 224 if isinstance(w, basestring) and w != "__builtins__"]
221 225 # Build match list to return
222 226 n = len(attr)
223 227 return ["%s.%s" % (expr, w) for w in words if w[:n] == attr ]
224 228
225 229 class IPCompleter(Completer):
226 230 """Extension of the completer class with IPython-specific features"""
227 231
228 232 def __init__(self,shell,namespace=None,global_namespace=None,
229 233 omit__names=0,alias_table=None):
230 234 """IPCompleter() -> completer
231 235
232 236 Return a completer object suitable for use by the readline library
233 237 via readline.set_completer().
234 238
235 239 Inputs:
236 240
237 241 - shell: a pointer to the ipython shell itself. This is needed
238 242 because this completer knows about magic functions, and those can
239 243 only be accessed via the ipython instance.
240 244
241 245 - namespace: an optional dict where completions are performed.
242 246
243 247 - global_namespace: secondary optional dict for completions, to
244 248 handle cases (such as IPython embedded inside functions) where
245 249 both Python scopes are visible.
246 250
247 251 - The optional omit__names parameter sets the completer to omit the
248 252 'magic' names (__magicname__) for python objects unless the text
249 253 to be completed explicitly starts with one or more underscores.
250 254
251 255 - If alias_table is supplied, it should be a dictionary of aliases
252 256 to complete. """
253 257
254 258 Completer.__init__(self,namespace,global_namespace)
255 259 self.magic_prefix = shell.name+'.magic_'
256 260 self.magic_escape = shell.ESC_MAGIC
257 261 self.readline = readline
258 262 delims = self.readline.get_completer_delims()
259 263 delims = delims.replace(self.magic_escape,'')
260 264 self.readline.set_completer_delims(delims)
261 265 self.get_line_buffer = self.readline.get_line_buffer
262 266 self.omit__names = omit__names
263 267 self.merge_completions = shell.rc.readline_merge_completions
264 268
265 269 if alias_table is None:
266 270 alias_table = {}
267 271 self.alias_table = alias_table
268 272 # Regexp to split filenames with spaces in them
269 273 self.space_name_re = re.compile(r'([^\\] )')
270 274 # Hold a local ref. to glob.glob for speed
271 275 self.glob = glob.glob
272 276
273 277 # Determine if we are running on 'dumb' terminals, like (X)Emacs
274 278 # buffers, to avoid completion problems.
275 279 term = os.environ.get('TERM','xterm')
276 280 self.dumb_terminal = term in ['dumb','emacs']
277 281
278 282 # Special handling of backslashes needed in win32 platforms
279 283 if sys.platform == "win32":
280 284 self.clean_glob = self._clean_glob_win32
281 285 else:
282 286 self.clean_glob = self._clean_glob
283 287 self.matchers = [self.python_matches,
284 288 self.file_matches,
285 289 self.alias_matches,
286 290 self.python_func_kw_matches]
287 291
288 292 # Code contributed by Alex Schmolck, for ipython/emacs integration
289 293 def all_completions(self, text):
290 294 """Return all possible completions for the benefit of emacs."""
291 295
292 296 completions = []
293 297 comp_append = completions.append
294 298 try:
295 299 for i in xrange(sys.maxint):
296 300 res = self.complete(text, i)
297 301
298 302 if not res: break
299 303
300 304 comp_append(res)
301 305 #XXX workaround for ``notDefined.<tab>``
302 306 except NameError:
303 307 pass
304 308 return completions
305 309 # /end Alex Schmolck code.
306 310
307 311 def _clean_glob(self,text):
308 312 return self.glob("%s*" % text)
309 313
310 314 def _clean_glob_win32(self,text):
311 315 return [f.replace("\\","/")
312 316 for f in self.glob("%s*" % text)]
313 317
314 318 def file_matches(self, text):
315 319 """Match filneames, expanding ~USER type strings.
316 320
317 321 Most of the seemingly convoluted logic in this completer is an
318 322 attempt to handle filenames with spaces in them. And yet it's not
319 323 quite perfect, because Python's readline doesn't expose all of the
320 324 GNU readline details needed for this to be done correctly.
321 325
322 326 For a filename with a space in it, the printed completions will be
323 327 only the parts after what's already been typed (instead of the
324 328 full completions, as is normally done). I don't think with the
325 329 current (as of Python 2.3) Python readline it's possible to do
326 330 better."""
327 331
328 332 #print 'Completer->file_matches: <%s>' % text # dbg
329 333
330 334 # chars that require escaping with backslash - i.e. chars
331 335 # that readline treats incorrectly as delimiters, but we
332 336 # don't want to treat as delimiters in filename matching
333 337 # when escaped with backslash
334 338
335 339 protectables = ' ()[]{}'
336 340
337 341 def protect_filename(s):
338 342 return "".join([(ch in protectables and '\\' + ch or ch)
339 343 for ch in s])
340 344
341 345 lbuf = self.get_line_buffer()[:self.readline.get_endidx()]
342 346 open_quotes = 0 # track strings with open quotes
343 347 try:
344 348 lsplit = shlex_split(lbuf)[-1]
345 349 except ValueError:
346 350 # typically an unmatched ", or backslash without escaped char.
347 351 if lbuf.count('"')==1:
348 352 open_quotes = 1
349 353 lsplit = lbuf.split('"')[-1]
350 354 elif lbuf.count("'")==1:
351 355 open_quotes = 1
352 356 lsplit = lbuf.split("'")[-1]
353 357 else:
354 358 return None
355 359 except IndexError:
356 360 # tab pressed on empty line
357 361 lsplit = ""
358 362
359 363 if lsplit != protect_filename(lsplit):
360 364 # if protectables are found, do matching on the whole escaped
361 365 # name
362 366 has_protectables = 1
363 367 text0,text = text,lsplit
364 368 else:
365 369 has_protectables = 0
366 370 text = os.path.expanduser(text)
367 371
368 372 if text == "":
369 373 return [protect_filename(f) for f in self.glob("*")]
370 374
371 375 m0 = self.clean_glob(text.replace('\\',''))
372 376 if has_protectables:
373 377 # If we had protectables, we need to revert our changes to the
374 378 # beginning of filename so that we don't double-write the part
375 379 # of the filename we have so far
376 380 len_lsplit = len(lsplit)
377 381 matches = [text0 + protect_filename(f[len_lsplit:]) for f in m0]
378 382 else:
379 383 if open_quotes:
380 384 # if we have a string with an open quote, we don't need to
381 385 # protect the names at all (and we _shouldn't_, as it
382 386 # would cause bugs when the filesystem call is made).
383 387 matches = m0
384 388 else:
385 389 matches = [protect_filename(f) for f in m0]
386 390 if len(matches) == 1 and os.path.isdir(matches[0]):
387 391 # Takes care of links to directories also. Use '/'
388 392 # explicitly, even under Windows, so that name completions
389 393 # don't end up escaped.
390 394 matches[0] += '/'
391 395 return matches
392 396
393 397 def alias_matches(self, text):
394 398 """Match internal system aliases"""
395 399
396 400 #print 'Completer->alias_matches:',text # dbg
397 401 text = os.path.expanduser(text)
398 402 aliases = self.alias_table.keys()
399 403 if text == "":
400 404 return aliases
401 405 else:
402 406 return [alias for alias in aliases if alias.startswith(text)]
403 407
404 408 def python_matches(self,text):
405 409 """Match attributes or global python names"""
406 410
407 411 #print 'Completer->python_matches, txt=<%s>' % text # dbg
408 412 if "." in text:
409 413 try:
410 414 matches = self.attr_matches(text)
411 415 if text.endswith('.') and self.omit__names:
412 416 if self.omit__names == 1:
413 417 # true if txt is _not_ a __ name, false otherwise:
414 418 no__name = (lambda txt:
415 419 re.match(r'.*\.__.*?__',txt) is None)
416 420 else:
417 421 # true if txt is _not_ a _ name, false otherwise:
418 422 no__name = (lambda txt:
419 423 re.match(r'.*\._.*?',txt) is None)
420 424 matches = filter(no__name, matches)
421 425 except NameError:
422 426 # catches <undefined attributes>.<tab>
423 427 matches = []
424 428 else:
425 429 matches = self.global_matches(text)
426 430 # this is so completion finds magics when automagic is on:
427 431 if matches == [] and not text.startswith(os.sep):
428 432 matches = self.attr_matches(self.magic_prefix+text)
429 433 return matches
430 434
431 435 def _default_arguments(self, obj):
432 436 """Return the list of default arguments of obj if it is callable,
433 437 or empty list otherwise."""
434 438
435 439 if not (inspect.isfunction(obj) or inspect.ismethod(obj)):
436 440 # for classes, check for __init__,__new__
437 441 if inspect.isclass(obj):
438 442 obj = (getattr(obj,'__init__',None) or
439 443 getattr(obj,'__new__',None))
440 444 # for all others, check if they are __call__able
441 445 elif hasattr(obj, '__call__'):
442 446 obj = obj.__call__
443 447 # XXX: is there a way to handle the builtins ?
444 448 try:
445 449 args,_,_1,defaults = inspect.getargspec(obj)
446 450 if defaults:
447 451 return args[-len(defaults):]
448 452 except TypeError: pass
449 453 return []
450 454
451 455 def python_func_kw_matches(self,text):
452 456 """Match named parameters (kwargs) of the last open function"""
453 457
454 458 if "." in text: # a parameter cannot be dotted
455 459 return []
456 460 try: regexp = self.__funcParamsRegex
457 461 except AttributeError:
458 462 regexp = self.__funcParamsRegex = re.compile(r'''
459 463 '.*?' | # single quoted strings or
460 464 ".*?" | # double quoted strings or
461 465 \w+ | # identifier
462 466 \S # other characters
463 467 ''', re.VERBOSE | re.DOTALL)
464 468 # 1. find the nearest identifier that comes before an unclosed
465 469 # parenthesis e.g. for "foo (1+bar(x), pa", the candidate is "foo"
466 470 tokens = regexp.findall(self.get_line_buffer())
467 471 tokens.reverse()
468 472 iterTokens = iter(tokens); openPar = 0
469 473 for token in iterTokens:
470 474 if token == ')':
471 475 openPar -= 1
472 476 elif token == '(':
473 477 openPar += 1
474 478 if openPar > 0:
475 479 # found the last unclosed parenthesis
476 480 break
477 481 else:
478 482 return []
479 483 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
480 484 ids = []
481 485 isId = re.compile(r'\w+$').match
482 486 while True:
483 487 try:
484 488 ids.append(iterTokens.next())
485 489 if not isId(ids[-1]):
486 490 ids.pop(); break
487 491 if not iterTokens.next() == '.':
488 492 break
489 493 except StopIteration:
490 494 break
491 495 # lookup the candidate callable matches either using global_matches
492 496 # or attr_matches for dotted names
493 497 if len(ids) == 1:
494 498 callableMatches = self.global_matches(ids[0])
495 499 else:
496 500 callableMatches = self.attr_matches('.'.join(ids[::-1]))
497 501 argMatches = []
498 502 for callableMatch in callableMatches:
499 503 try: namedArgs = self._default_arguments(eval(callableMatch,
500 504 self.namespace))
501 505 except: continue
502 506 for namedArg in namedArgs:
503 507 if namedArg.startswith(text):
504 508 argMatches.append("%s=" %namedArg)
505 509 return argMatches
506 510
507 511 def complete(self, text, state):
508 512 """Return the next possible completion for 'text'.
509 513
510 514 This is called successively with state == 0, 1, 2, ... until it
511 515 returns None. The completion should begin with 'text'. """
512 516
513 517 #print '\n*** COMPLETE: <%s> (%s)' % (text,state) # dbg
514 518
515 519 # if there is only a tab on a line with only whitespace, instead
516 520 # of the mostly useless 'do you want to see all million
517 521 # completions' message, just do the right thing and give the user
518 522 # his tab! Incidentally, this enables pasting of tabbed text from
519 523 # an editor (as long as autoindent is off).
520 524
521 525 # don't apply this on 'dumb' terminals, such as emacs buffers, so we
522 526 # don't interfere with their own tab-completion mechanism.
523 527 if not (self.dumb_terminal or self.get_line_buffer().strip()):
524 528 self.readline.insert_text('\t')
525 529 return None
526 530
527 531 magic_escape = self.magic_escape
528 532 magic_prefix = self.magic_prefix
529 533
530 534 try:
531 535 if text.startswith(magic_escape):
532 536 text = text.replace(magic_escape,magic_prefix)
533 537 elif text.startswith('~'):
534 538 text = os.path.expanduser(text)
535 539 if state == 0:
536 540 # Extend the list of completions with the results of each
537 541 # matcher, so we return results to the user from all
538 542 # namespaces.
539 543 if self.merge_completions:
540 544 self.matches = []
541 545 for matcher in self.matchers:
542 546 self.matches.extend(matcher(text))
543 547 else:
544 548 for matcher in self.matchers:
545 549 self.matches = matcher(text)
546 550 if self.matches:
547 551 break
548 552
549 553 try:
550 554 return self.matches[state].replace(magic_prefix,magic_escape)
551 555 except IndexError:
552 556 return None
553 557 except:
554 558 #from IPython.ultraTB import AutoFormattedTB; # dbg
555 559 #tb=AutoFormattedTB('Verbose');tb() #dbg
556 560
557 561 # If completion fails, don't annoy the user.
558 562 return None
General Comments 0
You need to be logged in to leave comments. Login now