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