##// END OF EJS Templates
Add line splitting for text completion (like readline does internally)....
Fernando Perez -
Show More
@@ -1,722 +1,774 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 Original rlcompleter documentation:
10 10
11 11 This requires the latest extension to the readline module (the
12 12 completes keywords, built-ins and globals in __main__; when completing
13 13 NAME.NAME..., it evaluates (!) the expression up to the last dot and
14 14 completes its attributes.
15 15
16 16 It's very cool to do "import string" type "string.", hit the
17 17 completion key (twice), and see the list of names defined by the
18 18 string module!
19 19
20 20 Tip: to use the tab key as the completion key, call
21 21
22 22 readline.parse_and_bind("tab: complete")
23 23
24 24 Notes:
25 25
26 26 - Exceptions raised by the completer function are *ignored* (and
27 27 generally cause the completion to fail). This is a feature -- since
28 28 readline sets the tty device in raw (or cbreak) mode, printing a
29 29 traceback wouldn't work well without some complicated hoopla to save,
30 30 reset and restore the tty state.
31 31
32 32 - The evaluation of the NAME.NAME... form may cause arbitrary
33 33 application defined code to be executed if an object with a
34 34 __getattr__ hook is found. Since it is the responsibility of the
35 35 application (or the user) to enable this feature, I consider this an
36 36 acceptable risk. More complicated expressions (e.g. function calls or
37 37 indexing operations) are *not* evaluated.
38 38
39 39 - GNU readline is also used by the built-in functions input() and
40 40 raw_input(), and thus these also benefit/suffer from the completer
41 41 features. Clearly an interactive application can benefit by
42 42 specifying its own completer function and using raw_input() for all
43 43 its input.
44 44
45 45 - When the original stdin is not a tty device, GNU readline is never
46 46 used, and this module (and the readline module) are silently inactive.
47 47 """
48 48
49 49 #*****************************************************************************
50 50 #
51 51 # Since this file is essentially a minimally modified copy of the rlcompleter
52 52 # module which is part of the standard Python distribution, I assume that the
53 53 # proper procedure is to maintain its copyright as belonging to the Python
54 54 # Software Foundation (in addition to my own, for all new code).
55 55 #
56 56 # Copyright (C) 2008-2010 IPython Development Team
57 57 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
58 58 # Copyright (C) 2001 Python Software Foundation, www.python.org
59 59 #
60 60 # Distributed under the terms of the BSD License. The full license is in
61 61 # the file COPYING, distributed as part of this software.
62 62 #
63 63 #*****************************************************************************
64 from __future__ import print_function
64 65
65 66 #-----------------------------------------------------------------------------
66 67 # Imports
67 68 #-----------------------------------------------------------------------------
68 69
69 70 import __builtin__
70 71 import __main__
71 72 import glob
72 73 import inspect
73 74 import itertools
74 75 import keyword
75 76 import os
76 77 import re
77 78 import shlex
78 79 import sys
79 80
80 81 from IPython.core.error import TryNext
81 82 from IPython.core.prefilter import ESC_MAGIC
82 from IPython.utils import generics
83 from IPython.utils import generics, io
83 84 from IPython.utils.frame import debugx
84 85 from IPython.utils.dir2 import dir2
85 86
86 87 #-----------------------------------------------------------------------------
87 88 # Globals
88 89 #-----------------------------------------------------------------------------
89 90
90 91 # Public API
91 92 __all__ = ['Completer','IPCompleter']
92 93
93 94 if sys.platform == 'win32':
94 95 PROTECTABLES = ' '
95 96 else:
96 97 PROTECTABLES = ' ()'
97 98
98 99 #-----------------------------------------------------------------------------
99 100 # Main functions and classes
100 101 #-----------------------------------------------------------------------------
101 102
102 103 def protect_filename(s):
103 104 """Escape a string to protect certain characters."""
104 105
105 106 return "".join([(ch in PROTECTABLES and '\\' + ch or ch)
106 107 for ch in s])
107 108
108 109
109 110 def mark_dirs(matches):
110 111 """Mark directories in input list by appending '/' to their names."""
111 112 out = []
112 113 isdir = os.path.isdir
113 114 for x in matches:
114 115 if isdir(x):
115 116 out.append(x+'/')
116 117 else:
117 118 out.append(x)
118 119 return out
119 120
120 121
121 122 def single_dir_expand(matches):
122 123 "Recursively expand match lists containing a single dir."
123 124
124 125 if len(matches) == 1 and os.path.isdir(matches[0]):
125 126 # Takes care of links to directories also. Use '/'
126 127 # explicitly, even under Windows, so that name completions
127 128 # don't end up escaped.
128 129 d = matches[0]
129 130 if d[-1] in ['/','\\']:
130 131 d = d[:-1]
131 132
132 133 subdirs = os.listdir(d)
133 134 if subdirs:
134 135 matches = [ (d + '/' + p) for p in subdirs]
135 136 return single_dir_expand(matches)
136 137 else:
137 138 return matches
138 139 else:
139 140 return matches
140 141
141 class Bunch: pass
142 142
143 class Completer:
143 class Bunch(object): pass
144
145
146 class CompletionSplitter(object):
147 """An object to split an input line in a manner similar to readline.
148
149 By having our own implementation, we can expose readline-like completion in
150 a uniform manner to all frontends. This object only needs to be given the
151 line of text to be split and the cursor position on said line, and it
152 returns the 'word' to be completed on at the cursor after splitting the
153 entire line.
154
155 What characters are used as splitting delimiters can be controlled by
156 setting the `delims` attribute (this is a property that internally
157 automatically builds the necessary """
158
159 # Private interface
160
161 # A string of delimiter characters. The default value makes sense for
162 # IPython's most typical usage patterns.
163 _delims = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
164
165 # The expression (a normal string) to be compiled into a regular expression
166 # for actual splitting. We store it as an attribute mostly for ease of
167 # debugging, since this type of code can be so tricky to debug.
168 _delim_expr = None
169
170 # The regular expression that does the actual splitting
171 _delim_re = None
172
173 def __init__(self, delims=None):
174 delims = CompletionSplitter._delims if delims is None else delims
175 self.set_delims(delims)
176
177 def set_delims(self, delims):
178 """Set the delimiters for line splitting."""
179 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
180 self._delim_re = re.compile(expr)
181 self._delims = delims
182 self._delim_expr = expr
183
184 def get_delims(self):
185 """Return the string of delimiter characters."""
186 return self._delims
187
188 def split_line(self, line, cursor_pos=None):
189 """Split a line of text with a cursor at the given position.
190 """
191 l = line if cursor_pos is None else line[:cursor_pos]
192 return self._delim_re.split(l)[-1]
193
194
195 class Completer(object):
144 196 def __init__(self,namespace=None,global_namespace=None):
145 197 """Create a new completer for the command line.
146 198
147 199 Completer([namespace,global_namespace]) -> completer instance.
148 200
149 201 If unspecified, the default namespace where completions are performed
150 202 is __main__ (technically, __main__.__dict__). Namespaces should be
151 203 given as dictionaries.
152 204
153 205 An optional second namespace can be given. This allows the completer
154 206 to handle cases where both the local and global scopes need to be
155 207 distinguished.
156 208
157 209 Completer instances should be used as the completion mechanism of
158 210 readline via the set_completer() call:
159 211
160 212 readline.set_completer(Completer(my_namespace).complete)
161 213 """
162 214
163 215 # Don't bind to namespace quite yet, but flag whether the user wants a
164 216 # specific namespace or to use __main__.__dict__. This will allow us
165 217 # to bind to __main__.__dict__ at completion time, not now.
166 218 if namespace is None:
167 219 self.use_main_ns = 1
168 220 else:
169 221 self.use_main_ns = 0
170 222 self.namespace = namespace
171 223
172 224 # The global namespace, if given, can be bound directly
173 225 if global_namespace is None:
174 226 self.global_namespace = {}
175 227 else:
176 228 self.global_namespace = global_namespace
177 229
178 230 def complete(self, text, state):
179 231 """Return the next possible completion for 'text'.
180 232
181 233 This is called successively with state == 0, 1, 2, ... until it
182 234 returns None. The completion should begin with 'text'.
183 235
184 236 """
185 237 if self.use_main_ns:
186 238 self.namespace = __main__.__dict__
187 239
188 240 if state == 0:
189 241 if "." in text:
190 242 self.matches = self.attr_matches(text)
191 243 else:
192 244 self.matches = self.global_matches(text)
193 245 try:
194 246 return self.matches[state]
195 247 except IndexError:
196 248 return None
197 249
198 250 def global_matches(self, text):
199 251 """Compute matches when text is a simple name.
200 252
201 253 Return a list of all keywords, built-in functions and names currently
202 254 defined in self.namespace or self.global_namespace that match.
203 255
204 256 """
205 257 #print 'Completer->global_matches, txt=%r' % text # dbg
206 258 matches = []
207 259 match_append = matches.append
208 260 n = len(text)
209 261 for lst in [keyword.kwlist,
210 262 __builtin__.__dict__.keys(),
211 263 self.namespace.keys(),
212 264 self.global_namespace.keys()]:
213 265 for word in lst:
214 266 if word[:n] == text and word != "__builtins__":
215 267 match_append(word)
216 268 return matches
217 269
218 270 def attr_matches(self, text):
219 271 """Compute matches when text contains a dot.
220 272
221 273 Assuming the text is of the form NAME.NAME....[NAME], and is
222 274 evaluatable in self.namespace or self.global_namespace, it will be
223 275 evaluated and its attributes (as revealed by dir()) are used as
224 276 possible completions. (For class instances, class members are are
225 277 also considered.)
226 278
227 279 WARNING: this can still invoke arbitrary C code, if an object
228 280 with a __getattr__ hook is evaluated.
229 281
230 282 """
231 283
232 284 #print 'Completer->attr_matches, txt=%r' % text # dbg
233 285 # Another option, seems to work great. Catches things like ''.<tab>
234 286 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
235 287
236 288 if not m:
237 289 return []
238 290
239 291 expr, attr = m.group(1, 3)
240 292 try:
241 293 obj = eval(expr, self.namespace)
242 294 except:
243 295 try:
244 296 obj = eval(expr, self.global_namespace)
245 297 except:
246 298 return []
247 299
248 300 words = dir2(obj)
249 301
250 302 try:
251 303 words = generics.complete_object(obj, words)
252 304 except TryNext:
253 305 pass
254 306 # Build match list to return
255 307 n = len(attr)
256 308 res = ["%s.%s" % (expr, w) for w in words if w[:n] == attr ]
257 309 return res
258 310
259 311
260 312 class IPCompleter(Completer):
261 313 """Extension of the completer class with IPython-specific features"""
262 314
263 315 def __init__(self, shell, namespace=None, global_namespace=None,
264 316 omit__names=0, alias_table=None, use_readline=True):
265 317 """IPCompleter() -> completer
266 318
267 319 Return a completer object suitable for use by the readline library
268 320 via readline.set_completer().
269 321
270 322 Inputs:
271 323
272 324 - shell: a pointer to the ipython shell itself. This is needed
273 325 because this completer knows about magic functions, and those can
274 326 only be accessed via the ipython instance.
275 327
276 328 - namespace: an optional dict where completions are performed.
277 329
278 330 - global_namespace: secondary optional dict for completions, to
279 331 handle cases (such as IPython embedded inside functions) where
280 332 both Python scopes are visible.
281 333
282 334 - The optional omit__names parameter sets the completer to omit the
283 335 'magic' names (__magicname__) for python objects unless the text
284 336 to be completed explicitly starts with one or more underscores.
285 337
286 338 - If alias_table is supplied, it should be a dictionary of aliases
287 339 to complete.
288 340
289 341 use_readline : bool, optional
290 342 If true, use the readline library. This completer can still function
291 343 without readline, though in that case callers must provide some extra
292 344 information on each call about the current line."""
293 345
294 346 Completer.__init__(self,namespace,global_namespace)
295 347
296 348 self.magic_escape = ESC_MAGIC
297 349
298 350 # Readline-dependent code
299 351 self.use_readline = use_readline
300 352 if use_readline:
301 353 import IPython.utils.rlineimpl as readline
302 354 self.readline = readline
303 355 delims = self.readline.get_completer_delims()
304 356 delims = delims.replace(self.magic_escape,'')
305 357 self.readline.set_completer_delims(delims)
306 358 self.get_line_buffer = self.readline.get_line_buffer
307 359 self.get_endidx = self.readline.get_endidx
308 360 # /end readline-dependent code
309 361
310 362 # List where completion matches will be stored
311 363 self.matches = []
312 364 self.omit__names = omit__names
313 365 self.merge_completions = shell.readline_merge_completions
314 366 self.shell = shell.shell
315 367 if alias_table is None:
316 368 alias_table = {}
317 369 self.alias_table = alias_table
318 370 # Regexp to split filenames with spaces in them
319 371 self.space_name_re = re.compile(r'([^\\] )')
320 372 # Hold a local ref. to glob.glob for speed
321 373 self.glob = glob.glob
322 374
323 375 # Determine if we are running on 'dumb' terminals, like (X)Emacs
324 376 # buffers, to avoid completion problems.
325 377 term = os.environ.get('TERM','xterm')
326 378 self.dumb_terminal = term in ['dumb','emacs']
327 379
328 380 # Special handling of backslashes needed in win32 platforms
329 381 if sys.platform == "win32":
330 382 self.clean_glob = self._clean_glob_win32
331 383 else:
332 384 self.clean_glob = self._clean_glob
333 385
334 386 # All active matcher routines for completion
335 387 self.matchers = [self.python_matches,
336 388 self.file_matches,
337 389 self.magic_matches,
338 390 self.alias_matches,
339 391 self.python_func_kw_matches,
340 392 ]
341 393
342 394 # Code contributed by Alex Schmolck, for ipython/emacs integration
343 395 def all_completions(self, text):
344 396 """Return all possible completions for the benefit of emacs."""
345 397
346 398 completions = []
347 399 comp_append = completions.append
348 400 try:
349 401 for i in xrange(sys.maxint):
350 402 res = self.complete(text, i, text)
351 403 if not res:
352 404 break
353 405 comp_append(res)
354 406 #XXX workaround for ``notDefined.<tab>``
355 407 except NameError:
356 408 pass
357 409 return completions
358 410 # /end Alex Schmolck code.
359 411
360 412 def _clean_glob(self,text):
361 413 return self.glob("%s*" % text)
362 414
363 415 def _clean_glob_win32(self,text):
364 416 return [f.replace("\\","/")
365 417 for f in self.glob("%s*" % text)]
366 418
367 419 def file_matches(self, text):
368 420 """Match filenames, expanding ~USER type strings.
369 421
370 422 Most of the seemingly convoluted logic in this completer is an
371 423 attempt to handle filenames with spaces in them. And yet it's not
372 424 quite perfect, because Python's readline doesn't expose all of the
373 425 GNU readline details needed for this to be done correctly.
374 426
375 427 For a filename with a space in it, the printed completions will be
376 428 only the parts after what's already been typed (instead of the
377 429 full completions, as is normally done). I don't think with the
378 430 current (as of Python 2.3) Python readline it's possible to do
379 431 better."""
380 432
381 433 #print 'Completer->file_matches: <%s>' % text # dbg
382 434
383 435 # chars that require escaping with backslash - i.e. chars
384 436 # that readline treats incorrectly as delimiters, but we
385 437 # don't want to treat as delimiters in filename matching
386 438 # when escaped with backslash
387 439
388 440 if text.startswith('!'):
389 441 text = text[1:]
390 442 text_prefix = '!'
391 443 else:
392 444 text_prefix = ''
393 445
394 446 lbuf = self.lbuf
395 447 open_quotes = 0 # track strings with open quotes
396 448 try:
397 449 lsplit = shlex.split(lbuf)[-1]
398 450 except ValueError:
399 451 # typically an unmatched ", or backslash without escaped char.
400 452 if lbuf.count('"')==1:
401 453 open_quotes = 1
402 454 lsplit = lbuf.split('"')[-1]
403 455 elif lbuf.count("'")==1:
404 456 open_quotes = 1
405 457 lsplit = lbuf.split("'")[-1]
406 458 else:
407 459 return []
408 460 except IndexError:
409 461 # tab pressed on empty line
410 462 lsplit = ""
411 463
412 464 if lsplit != protect_filename(lsplit):
413 465 # if protectables are found, do matching on the whole escaped
414 466 # name
415 467 has_protectables = 1
416 468 text0,text = text,lsplit
417 469 else:
418 470 has_protectables = 0
419 471 text = os.path.expanduser(text)
420 472
421 473 if text == "":
422 474 return [text_prefix + protect_filename(f) for f in self.glob("*")]
423 475
424 476 m0 = self.clean_glob(text.replace('\\',''))
425 477 if has_protectables:
426 478 # If we had protectables, we need to revert our changes to the
427 479 # beginning of filename so that we don't double-write the part
428 480 # of the filename we have so far
429 481 len_lsplit = len(lsplit)
430 482 matches = [text_prefix + text0 +
431 483 protect_filename(f[len_lsplit:]) for f in m0]
432 484 else:
433 485 if open_quotes:
434 486 # if we have a string with an open quote, we don't need to
435 487 # protect the names at all (and we _shouldn't_, as it
436 488 # would cause bugs when the filesystem call is made).
437 489 matches = m0
438 490 else:
439 491 matches = [text_prefix +
440 492 protect_filename(f) for f in m0]
441 493
442 494 #print 'mm',matches # dbg
443 495 #return single_dir_expand(matches)
444 496 return mark_dirs(matches)
445 497
446 498 def magic_matches(self, text):
447 499 """Match magics"""
448 500 #print 'Completer->magic_matches:',text,'lb',self.lbuf # dbg
449 501 # Get all shell magics now rather than statically, so magics loaded at
450 502 # runtime show up too
451 503 magics = self.shell.lsmagic()
452 504 pre = self.magic_escape
453 505 baretext = text.lstrip(pre)
454 506 return [ pre+m for m in magics if m.startswith(baretext)]
455 507
456 508 def alias_matches(self, text):
457 509 """Match internal system aliases"""
458 510 #print 'Completer->alias_matches:',text,'lb',self.lbuf # dbg
459 511
460 512 # if we are not in the first 'item', alias matching
461 513 # doesn't make sense - unless we are starting with 'sudo' command.
462 514 if ' ' in self.lbuf.lstrip() and \
463 515 not self.lbuf.lstrip().startswith('sudo'):
464 516 return []
465 517 text = os.path.expanduser(text)
466 518 aliases = self.alias_table.keys()
467 519 if text == "":
468 520 return aliases
469 521 else:
470 522 return [alias for alias in aliases if alias.startswith(text)]
471 523
472 524 def python_matches(self,text):
473 525 """Match attributes or global python names"""
474 526
475 527 #print 'Completer->python_matches, txt=%r' % text # dbg
476 528 if "." in text:
477 529 try:
478 530 matches = self.attr_matches(text)
479 531 if text.endswith('.') and self.omit__names:
480 532 if self.omit__names == 1:
481 533 # true if txt is _not_ a __ name, false otherwise:
482 534 no__name = (lambda txt:
483 535 re.match(r'.*\.__.*?__',txt) is None)
484 536 else:
485 537 # true if txt is _not_ a _ name, false otherwise:
486 538 no__name = (lambda txt:
487 539 re.match(r'.*\._.*?',txt) is None)
488 540 matches = filter(no__name, matches)
489 541 except NameError:
490 542 # catches <undefined attributes>.<tab>
491 543 matches = []
492 544 else:
493 545 matches = self.global_matches(text)
494 546
495 547 return matches
496 548
497 549 def _default_arguments(self, obj):
498 550 """Return the list of default arguments of obj if it is callable,
499 551 or empty list otherwise."""
500 552
501 553 if not (inspect.isfunction(obj) or inspect.ismethod(obj)):
502 554 # for classes, check for __init__,__new__
503 555 if inspect.isclass(obj):
504 556 obj = (getattr(obj,'__init__',None) or
505 557 getattr(obj,'__new__',None))
506 558 # for all others, check if they are __call__able
507 559 elif hasattr(obj, '__call__'):
508 560 obj = obj.__call__
509 561 # XXX: is there a way to handle the builtins ?
510 562 try:
511 563 args,_,_1,defaults = inspect.getargspec(obj)
512 564 if defaults:
513 565 return args[-len(defaults):]
514 566 except TypeError: pass
515 567 return []
516 568
517 569 def python_func_kw_matches(self,text):
518 570 """Match named parameters (kwargs) of the last open function"""
519 571
520 572 if "." in text: # a parameter cannot be dotted
521 573 return []
522 574 try: regexp = self.__funcParamsRegex
523 575 except AttributeError:
524 576 regexp = self.__funcParamsRegex = re.compile(r'''
525 577 '.*?' | # single quoted strings or
526 578 ".*?" | # double quoted strings or
527 579 \w+ | # identifier
528 580 \S # other characters
529 581 ''', re.VERBOSE | re.DOTALL)
530 582 # 1. find the nearest identifier that comes before an unclosed
531 583 # parenthesis e.g. for "foo (1+bar(x), pa", the candidate is "foo"
532 584 tokens = regexp.findall(self.get_line_buffer())
533 585 tokens.reverse()
534 586 iterTokens = iter(tokens); openPar = 0
535 587 for token in iterTokens:
536 588 if token == ')':
537 589 openPar -= 1
538 590 elif token == '(':
539 591 openPar += 1
540 592 if openPar > 0:
541 593 # found the last unclosed parenthesis
542 594 break
543 595 else:
544 596 return []
545 597 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
546 598 ids = []
547 599 isId = re.compile(r'\w+$').match
548 600 while True:
549 601 try:
550 602 ids.append(iterTokens.next())
551 603 if not isId(ids[-1]):
552 604 ids.pop(); break
553 605 if not iterTokens.next() == '.':
554 606 break
555 607 except StopIteration:
556 608 break
557 609 # lookup the candidate callable matches either using global_matches
558 610 # or attr_matches for dotted names
559 611 if len(ids) == 1:
560 612 callableMatches = self.global_matches(ids[0])
561 613 else:
562 614 callableMatches = self.attr_matches('.'.join(ids[::-1]))
563 615 argMatches = []
564 616 for callableMatch in callableMatches:
565 617 try:
566 618 namedArgs = self._default_arguments(eval(callableMatch,
567 619 self.namespace))
568 620 except:
569 621 continue
570 622 for namedArg in namedArgs:
571 623 if namedArg.startswith(text):
572 624 argMatches.append("%s=" %namedArg)
573 625 return argMatches
574 626
575 627 def dispatch_custom_completer(self,text):
576 628 #print "Custom! '%s' %s" % (text, self.custom_completers) # dbg
577 629 line = self.full_lbuf
578 630 if not line.strip():
579 631 return None
580 632
581 633 event = Bunch()
582 634 event.line = line
583 635 event.symbol = text
584 636 cmd = line.split(None,1)[0]
585 637 event.command = cmd
586 638 #print "\ncustom:{%s]\n" % event # dbg
587 639
588 640 # for foo etc, try also to find completer for %foo
589 641 if not cmd.startswith(self.magic_escape):
590 642 try_magic = self.custom_completers.s_matches(
591 643 self.magic_escape + cmd)
592 644 else:
593 645 try_magic = []
594 646
595 647 for c in itertools.chain(self.custom_completers.s_matches(cmd),
596 648 try_magic,
597 649 self.custom_completers.flat_matches(self.lbuf)):
598 650 #print "try",c # dbg
599 651 try:
600 652 res = c(event)
601 653 # first, try case sensitive match
602 654 withcase = [r for r in res if r.startswith(text)]
603 655 if withcase:
604 656 return withcase
605 657 # if none, then case insensitive ones are ok too
606 658 text_low = text.lower()
607 659 return [r for r in res if r.lower().startswith(text_low)]
608 660 except TryNext:
609 661 pass
610 662
611 663 return None
612 664
613 665 def complete(self, text, line_buffer, cursor_pos=None):
614 666 """Return the state-th possible completion for 'text'.
615 667
616 668 This is called successively with state == 0, 1, 2, ... until it
617 669 returns None. The completion should begin with 'text'.
618 670
619 671 Parameters
620 672 ----------
621 673 text : string
622 674 Text to perform the completion on.
623 675
624 676 line_buffer : string, optional
625 677 If not given, the completer attempts to obtain the current line
626 678 buffer via readline. This keyword allows clients which are
627 679 requesting for text completions in non-readline contexts to inform
628 680 the completer of the entire text.
629 681
630 682 cursor_pos : int, optional
631 683 Index of the cursor in the full line buffer. Should be provided by
632 684 remote frontends where kernel has no access to frontend state.
633 685 """
634
686 #io.rprint('COMP', text, line_buffer, cursor_pos) # dbg
687
635 688 magic_escape = self.magic_escape
636 689 self.full_lbuf = line_buffer
637 690 self.lbuf = self.full_lbuf[:cursor_pos]
638 691
639 692 if text.startswith('~'):
640 693 text = os.path.expanduser(text)
641 694
642 695 # Start with a clean slate of completions
643 696 self.matches[:] = []
644 697 custom_res = self.dispatch_custom_completer(text)
645 698 if custom_res is not None:
646 699 # did custom completers produce something?
647 700 self.matches = custom_res
648 701 else:
649 702 # Extend the list of completions with the results of each
650 703 # matcher, so we return results to the user from all
651 704 # namespaces.
652 705 if self.merge_completions:
653 706 self.matches = []
654 707 for matcher in self.matchers:
655 708 self.matches.extend(matcher(text))
656 709 else:
657 710 for matcher in self.matchers:
658 711 self.matches = matcher(text)
659 712 if self.matches:
660 713 break
661 714 # FIXME: we should extend our api to return a dict with completions for
662 715 # different types of objects. The rlcomplete() method could then
663 716 # simply collapse the dict into a list for readline, but we'd have
664 717 # richer completion semantics in other evironments.
665 718 self.matches = sorted(set(self.matches))
666 #from IPython.utils.io import rprint; rprint(self.matches) # dbg
719 #io.rprint('MATCHES', self.matches) # dbg
667 720 return self.matches
668 721
669 722 def rlcomplete(self, text, state):
670 723 """Return the state-th possible completion for 'text'.
671 724
672 725 This is called successively with state == 0, 1, 2, ... until it
673 726 returns None. The completion should begin with 'text'.
674 727
675 728 Parameters
676 729 ----------
677 730 text : string
678 731 Text to perform the completion on.
679 732
680 733 state : int
681 734 Counter used by readline.
682
683 735 """
684
685 #print "rlcomplete! '%s' %s" % (text, state) # dbg
686
687 736 if state==0:
737
688 738 self.full_lbuf = line_buffer = self.get_line_buffer()
689 739 cursor_pos = self.get_endidx()
690 740
741 #io.rprint("\nRLCOMPLETE: %r %r %r" %
742 # (text, line_buffer, cursor_pos) ) # dbg
743
691 744 # if there is only a tab on a line with only whitespace, instead of
692 745 # the mostly useless 'do you want to see all million completions'
693 746 # message, just do the right thing and give the user his tab!
694 747 # Incidentally, this enables pasting of tabbed text from an editor
695 748 # (as long as autoindent is off).
696 749
697 750 # It should be noted that at least pyreadline still shows file
698 751 # completions - is there a way around it?
699 752
700 753 # don't apply this on 'dumb' terminals, such as emacs buffers, so
701 754 # we don't interfere with their own tab-completion mechanism.
702 if not (self.dumb_terminal or self.full_lbuf.strip()):
755 if not (self.dumb_terminal or line_buffer.strip()):
703 756 self.readline.insert_text('\t')
704 757 sys.stdout.flush()
705 758 return None
706 759
707 760 # This method computes the self.matches array
708 761 self.complete(text, line_buffer, cursor_pos)
709 762
710 763 # Debug version, since readline silences all exceptions making it
711 764 # impossible to debug any problem in the above code
712 765
713 766 ## try:
714 767 ## self.complete(text, line_buffer, cursor_pos)
715 768 ## except:
716 769 ## import traceback; traceback.print_exc()
717 770
718 771 try:
719 772 return self.matches[state]
720 773 except IndexError:
721 774 return None
722
@@ -1,35 +1,84 b''
1 1 """Tests for the IPython tab-completion machinery.
2 2 """
3 3 #-----------------------------------------------------------------------------
4 4 # Module imports
5 5 #-----------------------------------------------------------------------------
6 6
7 7 # stdlib
8 8 import sys
9 import unittest
9 10
10 11 # third party
11 12 import nose.tools as nt
12 13
13 14 # our own packages
14 15 from IPython.core import completer
15 16
16 17 #-----------------------------------------------------------------------------
17 18 # Test functions
18 19 #-----------------------------------------------------------------------------
19 20 def test_protect_filename():
20 21 pairs = [ ('abc','abc'),
21 22 (' abc',r'\ abc'),
22 23 ('a bc',r'a\ bc'),
23 24 ('a bc',r'a\ \ bc'),
24 25 (' bc',r'\ \ bc'),
25 26 ]
26 27 # On posix, we also protect parens
27 28 if sys.platform != 'win32':
28 29 pairs.extend( [('a(bc',r'a\(bc'),
29 30 ('a)bc',r'a\)bc'),
30 31 ('a( )bc',r'a\(\ \)bc'),
31 32 ] )
32 33 # run the actual tests
33 34 for s1, s2 in pairs:
34 35 s1p = completer.protect_filename(s1)
35 36 nt.assert_equals(s1p, s2)
37
38
39 def check_line_split(splitter, test_specs):
40 for part1, part2, split in test_specs:
41 cursor_pos = len(part1)
42 line = part1+part2
43 out = splitter.split_line(line, cursor_pos)
44 nt.assert_equal(out, split)
45
46
47 def test_line_split():
48 """Basice line splitter test with default specs."""
49 sp = completer.CompletionSplitter()
50 # The format of the test specs is: part1, part2, expected answer. Parts 1
51 # and 2 are joined into the 'line' sent to the splitter, as if the cursor
52 # was at the end of part1. So an empty part2 represents someone hitting
53 # tab at the end of the line, the most common case.
54 t = [('run some/scrip', '', 'some/scrip'),
55 ('run scripts/er', 'ror.py foo', 'scripts/er'),
56 ('echo $HOM', '', 'HOM'),
57 ('print sys.pa', '', 'sys.pa'),
58 ('print(sys.pa', '', 'sys.pa'),
59 ("execfile('scripts/er", '', 'scripts/er'),
60 ('a[x.', '', 'x.'),
61 ('a[x.', 'y', 'x.'),
62 ('cd "some_file/', '', 'some_file/'),
63 ]
64 check_line_split(sp, t)
65
66
67 class CompletionSplitterTestCase(unittest.TestCase):
68 def setUp(self):
69 self.sp = completer.CompletionSplitter()
70
71 def test_delim_setting(self):
72 self.sp.delims = ' '
73 # Validate that property handling works ok
74 nt.assert_equal(self.sp.delims, ' ')
75 nt.assert_equal(self.sp.delim_expr, '[\ ]')
76
77 def test_spaces(self):
78 """Test with only spaces as split chars."""
79 self.sp.delims = ' '
80 t = [('foo', '', 'foo'),
81 ('run foo', '', 'foo'),
82 ('run foo', 'bar', 'foo'),
83 ]
84 check_line_split(self.sp, t)
General Comments 0
You need to be logged in to leave comments. Login now