##// END OF EJS Templates
Initial implementation of latex->unicode completer.
Brian E. Granger -
Show More
@@ -1,1165 +1,1172 b''
1 1 # encoding: utf-8
2 2 """Word completion for IPython.
3 3
4 4 This module is a fork of the rlcompleter module in the Python standard
5 5 library. The original enhancements made to rlcompleter have been sent
6 6 upstream and were accepted as of Python 2.3, but we need a lot more
7 7 functionality specific to IPython, so this module will continue to live as an
8 8 IPython-specific utility.
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 # Since this file is essentially a minimally modified copy of the rlcompleter
53 53 # module which is part of the standard Python distribution, I assume that the
54 54 # proper procedure is to maintain its copyright as belonging to the Python
55 55 # Software Foundation (in addition to my own, for all new code).
56 56 #
57 57 # Copyright (C) 2008 IPython Development Team
58 58 # Copyright (C) 2001 Fernando Perez. <fperez@colorado.edu>
59 59 # Copyright (C) 2001 Python Software Foundation, www.python.org
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 #-----------------------------------------------------------------------------
67 67 # Imports
68 68 #-----------------------------------------------------------------------------
69 69
70 70 import __main__
71 71 import glob
72 72 import inspect
73 73 import itertools
74 74 import keyword
75 75 import os
76 76 import re
77 77 import sys
78 78
79 79 from IPython.config.configurable import Configurable
80 80 from IPython.core.error import TryNext
81 81 from IPython.core.inputsplitter import ESC_MAGIC
82 from IPython.core.latex_symbols import latex_symbols
82 83 from IPython.utils import generics
83 84 from IPython.utils import io
84 85 from IPython.utils.decorators import undoc
85 86 from IPython.utils.dir2 import dir2
86 87 from IPython.utils.process import arg_split
87 from IPython.utils.py3compat import builtin_mod, string_types
88 from IPython.utils.py3compat import builtin_mod, string_types, PY3
88 89 from IPython.utils.traitlets import CBool, Enum
89 90
90 91 #-----------------------------------------------------------------------------
91 92 # Globals
92 93 #-----------------------------------------------------------------------------
93 94
94 95 # Public API
95 96 __all__ = ['Completer','IPCompleter']
96 97
97 98 if sys.platform == 'win32':
98 99 PROTECTABLES = ' '
99 100 else:
100 101 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
101 102
102 103
103 104 #-----------------------------------------------------------------------------
104 105 # Main functions and classes
105 106 #-----------------------------------------------------------------------------
106 107
107 108 def has_open_quotes(s):
108 109 """Return whether a string has open quotes.
109 110
110 111 This simply counts whether the number of quote characters of either type in
111 112 the string is odd.
112 113
113 114 Returns
114 115 -------
115 116 If there is an open quote, the quote character is returned. Else, return
116 117 False.
117 118 """
118 119 # We check " first, then ', so complex cases with nested quotes will get
119 120 # the " to take precedence.
120 121 if s.count('"') % 2:
121 122 return '"'
122 123 elif s.count("'") % 2:
123 124 return "'"
124 125 else:
125 126 return False
126 127
127 128
128 129 def protect_filename(s):
129 130 """Escape a string to protect certain characters."""
130 131
131 132 return "".join([(ch in PROTECTABLES and '\\' + ch or ch)
132 133 for ch in s])
133 134
134 135 def expand_user(path):
135 136 """Expand '~'-style usernames in strings.
136 137
137 138 This is similar to :func:`os.path.expanduser`, but it computes and returns
138 139 extra information that will be useful if the input was being used in
139 140 computing completions, and you wish to return the completions with the
140 141 original '~' instead of its expanded value.
141 142
142 143 Parameters
143 144 ----------
144 145 path : str
145 146 String to be expanded. If no ~ is present, the output is the same as the
146 147 input.
147 148
148 149 Returns
149 150 -------
150 151 newpath : str
151 152 Result of ~ expansion in the input path.
152 153 tilde_expand : bool
153 154 Whether any expansion was performed or not.
154 155 tilde_val : str
155 156 The value that ~ was replaced with.
156 157 """
157 158 # Default values
158 159 tilde_expand = False
159 160 tilde_val = ''
160 161 newpath = path
161 162
162 163 if path.startswith('~'):
163 164 tilde_expand = True
164 165 rest = len(path)-1
165 166 newpath = os.path.expanduser(path)
166 167 if rest:
167 168 tilde_val = newpath[:-rest]
168 169 else:
169 170 tilde_val = newpath
170 171
171 172 return newpath, tilde_expand, tilde_val
172 173
173 174
174 175 def compress_user(path, tilde_expand, tilde_val):
175 176 """Does the opposite of expand_user, with its outputs.
176 177 """
177 178 if tilde_expand:
178 179 return path.replace(tilde_val, '~')
179 180 else:
180 181 return path
181 182
182 183
183 184
184 185 def penalize_magics_key(word):
185 186 """key for sorting that penalizes magic commands in the ordering
186 187
187 188 Normal words are left alone.
188 189
189 190 Magic commands have the initial % moved to the end, e.g.
190 191 %matplotlib is transformed as follows:
191 192
192 193 %matplotlib -> matplotlib%
193 194
194 195 [The choice of the final % is arbitrary.]
195 196
196 197 Since "matplotlib" < "matplotlib%" as strings,
197 198 "timeit" will appear before the magic "%timeit" in the ordering
198 199
199 200 For consistency, move "%%" to the end, so cell magics appear *after*
200 201 line magics with the same name.
201 202
202 203 A check is performed that there are no other "%" in the string;
203 204 if there are, then the string is not a magic command and is left unchanged.
204 205
205 206 """
206 207
207 208 # Move any % signs from start to end of the key
208 209 # provided there are no others elsewhere in the string
209 210
210 211 if word[:2] == "%%":
211 212 if not "%" in word[2:]:
212 213 return word[2:] + "%%"
213 214
214 215 if word[:1] == "%":
215 216 if not "%" in word[1:]:
216 217 return word[1:] + "%"
217 218
218 219 return word
219 220
220 221
221 222 @undoc
222 223 class Bunch(object): pass
223 224
224 225
225 226 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
226 227 GREEDY_DELIMS = ' =\r\n'
227 228
228 229
229 230 class CompletionSplitter(object):
230 231 """An object to split an input line in a manner similar to readline.
231 232
232 233 By having our own implementation, we can expose readline-like completion in
233 234 a uniform manner to all frontends. This object only needs to be given the
234 235 line of text to be split and the cursor position on said line, and it
235 236 returns the 'word' to be completed on at the cursor after splitting the
236 237 entire line.
237 238
238 239 What characters are used as splitting delimiters can be controlled by
239 240 setting the `delims` attribute (this is a property that internally
240 241 automatically builds the necessary regular expression)"""
241 242
242 243 # Private interface
243 244
244 245 # A string of delimiter characters. The default value makes sense for
245 246 # IPython's most typical usage patterns.
246 247 _delims = DELIMS
247 248
248 249 # The expression (a normal string) to be compiled into a regular expression
249 250 # for actual splitting. We store it as an attribute mostly for ease of
250 251 # debugging, since this type of code can be so tricky to debug.
251 252 _delim_expr = None
252 253
253 254 # The regular expression that does the actual splitting
254 255 _delim_re = None
255 256
256 257 def __init__(self, delims=None):
257 258 delims = CompletionSplitter._delims if delims is None else delims
258 259 self.delims = delims
259 260
260 261 @property
261 262 def delims(self):
262 263 """Return the string of delimiter characters."""
263 264 return self._delims
264 265
265 266 @delims.setter
266 267 def delims(self, delims):
267 268 """Set the delimiters for line splitting."""
268 269 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
269 270 self._delim_re = re.compile(expr)
270 271 self._delims = delims
271 272 self._delim_expr = expr
272 273
273 274 def split_line(self, line, cursor_pos=None):
274 275 """Split a line of text with a cursor at the given position.
275 276 """
276 277 l = line if cursor_pos is None else line[:cursor_pos]
277 278 return self._delim_re.split(l)[-1]
278 279
279 280
280 281 class Completer(Configurable):
281 282
282 283 greedy = CBool(False, config=True,
283 284 help="""Activate greedy completion
284 285
285 286 This will enable completion on elements of lists, results of function calls, etc.,
286 287 but can be unsafe because the code is actually evaluated on TAB.
287 288 """
288 289 )
289 290
290 291
291 292 def __init__(self, namespace=None, global_namespace=None, **kwargs):
292 293 """Create a new completer for the command line.
293 294
294 295 Completer(namespace=ns,global_namespace=ns2) -> completer instance.
295 296
296 297 If unspecified, the default namespace where completions are performed
297 298 is __main__ (technically, __main__.__dict__). Namespaces should be
298 299 given as dictionaries.
299 300
300 301 An optional second namespace can be given. This allows the completer
301 302 to handle cases where both the local and global scopes need to be
302 303 distinguished.
303 304
304 305 Completer instances should be used as the completion mechanism of
305 306 readline via the set_completer() call:
306 307
307 308 readline.set_completer(Completer(my_namespace).complete)
308 309 """
309 310
310 311 # Don't bind to namespace quite yet, but flag whether the user wants a
311 312 # specific namespace or to use __main__.__dict__. This will allow us
312 313 # to bind to __main__.__dict__ at completion time, not now.
313 314 if namespace is None:
314 315 self.use_main_ns = 1
315 316 else:
316 317 self.use_main_ns = 0
317 318 self.namespace = namespace
318 319
319 320 # The global namespace, if given, can be bound directly
320 321 if global_namespace is None:
321 322 self.global_namespace = {}
322 323 else:
323 324 self.global_namespace = global_namespace
324 325
325 326 super(Completer, self).__init__(**kwargs)
326 327
327 328 def complete(self, text, state):
328 329 """Return the next possible completion for 'text'.
329 330
330 331 This is called successively with state == 0, 1, 2, ... until it
331 332 returns None. The completion should begin with 'text'.
332 333
333 334 """
334 335 if self.use_main_ns:
335 336 self.namespace = __main__.__dict__
336 337
337 338 if state == 0:
338 339 if "." in text:
339 340 self.matches = self.attr_matches(text)
340 341 else:
341 342 self.matches = self.global_matches(text)
342 343 try:
343 344 return self.matches[state]
344 345 except IndexError:
345 346 return None
346 347
347 348 def global_matches(self, text):
348 349 """Compute matches when text is a simple name.
349 350
350 351 Return a list of all keywords, built-in functions and names currently
351 352 defined in self.namespace or self.global_namespace that match.
352 353
353 354 """
354 355 #print 'Completer->global_matches, txt=%r' % text # dbg
355 356 matches = []
356 357 match_append = matches.append
357 358 n = len(text)
358 359 for lst in [keyword.kwlist,
359 360 builtin_mod.__dict__.keys(),
360 361 self.namespace.keys(),
361 362 self.global_namespace.keys()]:
362 363 for word in lst:
363 364 if word[:n] == text and word != "__builtins__":
364 365 match_append(word)
365 366 return matches
366 367
367 368 def attr_matches(self, text):
368 369 """Compute matches when text contains a dot.
369 370
370 371 Assuming the text is of the form NAME.NAME....[NAME], and is
371 372 evaluatable in self.namespace or self.global_namespace, it will be
372 373 evaluated and its attributes (as revealed by dir()) are used as
373 374 possible completions. (For class instances, class members are are
374 375 also considered.)
375 376
376 377 WARNING: this can still invoke arbitrary C code, if an object
377 378 with a __getattr__ hook is evaluated.
378 379
379 380 """
380 381
381 382 #io.rprint('Completer->attr_matches, txt=%r' % text) # dbg
382 383 # Another option, seems to work great. Catches things like ''.<tab>
383 384 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
384 385
385 386 if m:
386 387 expr, attr = m.group(1, 3)
387 388 elif self.greedy:
388 389 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
389 390 if not m2:
390 391 return []
391 392 expr, attr = m2.group(1,2)
392 393 else:
393 394 return []
394 395
395 396 try:
396 397 obj = eval(expr, self.namespace)
397 398 except:
398 399 try:
399 400 obj = eval(expr, self.global_namespace)
400 401 except:
401 402 return []
402 403
403 404 if self.limit_to__all__ and hasattr(obj, '__all__'):
404 405 words = get__all__entries(obj)
405 406 else:
406 407 words = dir2(obj)
407 408
408 409 try:
409 410 words = generics.complete_object(obj, words)
410 411 except TryNext:
411 412 pass
412 413 except Exception:
413 414 # Silence errors from completion function
414 415 #raise # dbg
415 416 pass
416 417 # Build match list to return
417 418 n = len(attr)
418 419 res = ["%s.%s" % (expr, w) for w in words if w[:n] == attr ]
419 420 return res
420 421
421 422
422 423 def get__all__entries(obj):
423 424 """returns the strings in the __all__ attribute"""
424 425 try:
425 426 words = getattr(obj, '__all__')
426 427 except:
427 428 return []
428 429
429 430 return [w for w in words if isinstance(w, string_types)]
430 431
431 432
432 433 def match_dict_keys(keys, prefix):
433 434 """Used by dict_key_matches, matching the prefix to a list of keys"""
434 435 if not prefix:
435 436 return None, 0, [repr(k) for k in keys
436 437 if isinstance(k, (string_types, bytes))]
437 438 quote_match = re.search('["\']', prefix)
438 439 quote = quote_match.group()
439 440 try:
440 441 prefix_str = eval(prefix + quote, {})
441 442 except Exception:
442 443 return None, 0, []
443 444
444 445 token_match = re.search(r'\w*$', prefix, re.UNICODE)
445 446 token_start = token_match.start()
446 447 token_prefix = token_match.group()
447 448
448 449 # TODO: support bytes in Py3k
449 450 matched = []
450 451 for key in keys:
451 452 try:
452 453 if not key.startswith(prefix_str):
453 454 continue
454 455 except (AttributeError, TypeError, UnicodeError):
455 456 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
456 457 continue
457 458
458 459 # reformat remainder of key to begin with prefix
459 460 rem = key[len(prefix_str):]
460 461 # force repr wrapped in '
461 462 rem_repr = repr(rem + '"')
462 463 if rem_repr.startswith('u') and prefix[0] not in 'uU':
463 464 # Found key is unicode, but prefix is Py2 string.
464 465 # Therefore attempt to interpret key as string.
465 466 try:
466 467 rem_repr = repr(rem.encode('ascii') + '"')
467 468 except UnicodeEncodeError:
468 469 continue
469 470
470 471 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
471 472 if quote == '"':
472 473 # The entered prefix is quoted with ",
473 474 # but the match is quoted with '.
474 475 # A contained " hence needs escaping for comparison:
475 476 rem_repr = rem_repr.replace('"', '\\"')
476 477
477 478 # then reinsert prefix from start of token
478 479 matched.append('%s%s' % (token_prefix, rem_repr))
479 480 return quote, token_start, matched
480 481
481 482
482 483 def _safe_isinstance(obj, module, class_name):
483 484 """Checks if obj is an instance of module.class_name if loaded
484 485 """
485 486 return (module in sys.modules and
486 487 isinstance(obj, getattr(__import__(module), class_name)))
487 488
488 489
489 490
490 491 class IPCompleter(Completer):
491 492 """Extension of the completer class with IPython-specific features"""
492 493
493 494 def _greedy_changed(self, name, old, new):
494 495 """update the splitter and readline delims when greedy is changed"""
495 496 if new:
496 497 self.splitter.delims = GREEDY_DELIMS
497 498 else:
498 499 self.splitter.delims = DELIMS
499 500
500 501 if self.readline:
501 502 self.readline.set_completer_delims(self.splitter.delims)
502 503
503 504 merge_completions = CBool(True, config=True,
504 505 help="""Whether to merge completion results into a single list
505 506
506 507 If False, only the completion results from the first non-empty
507 508 completer will be returned.
508 509 """
509 510 )
510 511 omit__names = Enum((0,1,2), default_value=2, config=True,
511 512 help="""Instruct the completer to omit private method names
512 513
513 514 Specifically, when completing on ``object.<tab>``.
514 515
515 516 When 2 [default]: all names that start with '_' will be excluded.
516 517
517 518 When 1: all 'magic' names (``__foo__``) will be excluded.
518 519
519 520 When 0: nothing will be excluded.
520 521 """
521 522 )
522 523 limit_to__all__ = CBool(default_value=False, config=True,
523 524 help="""Instruct the completer to use __all__ for the completion
524 525
525 526 Specifically, when completing on ``object.<tab>``.
526 527
527 528 When True: only those names in obj.__all__ will be included.
528 529
529 530 When False [default]: the __all__ attribute is ignored
530 531 """
531 532 )
532 533
533 534 def __init__(self, shell=None, namespace=None, global_namespace=None,
534 535 use_readline=True, config=None, **kwargs):
535 536 """IPCompleter() -> completer
536 537
537 538 Return a completer object suitable for use by the readline library
538 539 via readline.set_completer().
539 540
540 541 Inputs:
541 542
542 543 - shell: a pointer to the ipython shell itself. This is needed
543 544 because this completer knows about magic functions, and those can
544 545 only be accessed via the ipython instance.
545 546
546 547 - namespace: an optional dict where completions are performed.
547 548
548 549 - global_namespace: secondary optional dict for completions, to
549 550 handle cases (such as IPython embedded inside functions) where
550 551 both Python scopes are visible.
551 552
552 553 use_readline : bool, optional
553 554 If true, use the readline library. This completer can still function
554 555 without readline, though in that case callers must provide some extra
555 556 information on each call about the current line."""
556 557
557 558 self.magic_escape = ESC_MAGIC
558 559 self.splitter = CompletionSplitter()
559 560
560 561 # Readline configuration, only used by the rlcompleter method.
561 562 if use_readline:
562 563 # We store the right version of readline so that later code
563 564 import IPython.utils.rlineimpl as readline
564 565 self.readline = readline
565 566 else:
566 567 self.readline = None
567 568
568 569 # _greedy_changed() depends on splitter and readline being defined:
569 570 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
570 571 config=config, **kwargs)
571 572
572 573 # List where completion matches will be stored
573 574 self.matches = []
574 575 self.shell = shell
575 576 # Regexp to split filenames with spaces in them
576 577 self.space_name_re = re.compile(r'([^\\] )')
577 578 # Hold a local ref. to glob.glob for speed
578 579 self.glob = glob.glob
579 580
580 581 # Determine if we are running on 'dumb' terminals, like (X)Emacs
581 582 # buffers, to avoid completion problems.
582 583 term = os.environ.get('TERM','xterm')
583 584 self.dumb_terminal = term in ['dumb','emacs']
584 585
585 586 # Special handling of backslashes needed in win32 platforms
586 587 if sys.platform == "win32":
587 588 self.clean_glob = self._clean_glob_win32
588 589 else:
589 590 self.clean_glob = self._clean_glob
590 591
591 592 #regexp to parse docstring for function signature
592 593 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
593 594 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
594 595 #use this if positional argument name is also needed
595 596 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
596 597
597 598 # All active matcher routines for completion
598 599 self.matchers = [
599 600 self.python_matches,
600 601 self.file_matches,
601 602 self.magic_matches,
602 603 self.python_func_kw_matches,
603 604 self.dict_key_matches,
604 self.latex_matches
605 605 ]
606 606
607 607 def all_completions(self, text):
608 608 """
609 609 Wrapper around the complete method for the benefit of emacs
610 610 and pydb.
611 611 """
612 612 return self.complete(text)[1]
613 613
614 614 def _clean_glob(self,text):
615 615 return self.glob("%s*" % text)
616 616
617 617 def _clean_glob_win32(self,text):
618 618 return [f.replace("\\","/")
619 619 for f in self.glob("%s*" % text)]
620 620
621 621 def file_matches(self, text):
622 622 """Match filenames, expanding ~USER type strings.
623 623
624 624 Most of the seemingly convoluted logic in this completer is an
625 625 attempt to handle filenames with spaces in them. And yet it's not
626 626 quite perfect, because Python's readline doesn't expose all of the
627 627 GNU readline details needed for this to be done correctly.
628 628
629 629 For a filename with a space in it, the printed completions will be
630 630 only the parts after what's already been typed (instead of the
631 631 full completions, as is normally done). I don't think with the
632 632 current (as of Python 2.3) Python readline it's possible to do
633 633 better."""
634 634
635 635 #io.rprint('Completer->file_matches: <%r>' % text) # dbg
636 636
637 637 # chars that require escaping with backslash - i.e. chars
638 638 # that readline treats incorrectly as delimiters, but we
639 639 # don't want to treat as delimiters in filename matching
640 640 # when escaped with backslash
641 641 if text.startswith('!'):
642 642 text = text[1:]
643 643 text_prefix = '!'
644 644 else:
645 645 text_prefix = ''
646 646
647 647 text_until_cursor = self.text_until_cursor
648 648 # track strings with open quotes
649 649 open_quotes = has_open_quotes(text_until_cursor)
650 650
651 651 if '(' in text_until_cursor or '[' in text_until_cursor:
652 652 lsplit = text
653 653 else:
654 654 try:
655 655 # arg_split ~ shlex.split, but with unicode bugs fixed by us
656 656 lsplit = arg_split(text_until_cursor)[-1]
657 657 except ValueError:
658 658 # typically an unmatched ", or backslash without escaped char.
659 659 if open_quotes:
660 660 lsplit = text_until_cursor.split(open_quotes)[-1]
661 661 else:
662 662 return []
663 663 except IndexError:
664 664 # tab pressed on empty line
665 665 lsplit = ""
666 666
667 667 if not open_quotes and lsplit != protect_filename(lsplit):
668 668 # if protectables are found, do matching on the whole escaped name
669 669 has_protectables = True
670 670 text0,text = text,lsplit
671 671 else:
672 672 has_protectables = False
673 673 text = os.path.expanduser(text)
674 674
675 675 if text == "":
676 676 return [text_prefix + protect_filename(f) for f in self.glob("*")]
677 677
678 678 # Compute the matches from the filesystem
679 679 m0 = self.clean_glob(text.replace('\\',''))
680 680
681 681 if has_protectables:
682 682 # If we had protectables, we need to revert our changes to the
683 683 # beginning of filename so that we don't double-write the part
684 684 # of the filename we have so far
685 685 len_lsplit = len(lsplit)
686 686 matches = [text_prefix + text0 +
687 687 protect_filename(f[len_lsplit:]) for f in m0]
688 688 else:
689 689 if open_quotes:
690 690 # if we have a string with an open quote, we don't need to
691 691 # protect the names at all (and we _shouldn't_, as it
692 692 # would cause bugs when the filesystem call is made).
693 693 matches = m0
694 694 else:
695 695 matches = [text_prefix +
696 696 protect_filename(f) for f in m0]
697 697
698 698 #io.rprint('mm', matches) # dbg
699 699
700 700 # Mark directories in input list by appending '/' to their names.
701 701 matches = [x+'/' if os.path.isdir(x) else x for x in matches]
702 702 return matches
703 703
704 704 def magic_matches(self, text):
705 705 """Match magics"""
706 706 #print 'Completer->magic_matches:',text,'lb',self.text_until_cursor # dbg
707 707 # Get all shell magics now rather than statically, so magics loaded at
708 708 # runtime show up too.
709 709 lsm = self.shell.magics_manager.lsmagic()
710 710 line_magics = lsm['line']
711 711 cell_magics = lsm['cell']
712 712 pre = self.magic_escape
713 713 pre2 = pre+pre
714 714
715 715 # Completion logic:
716 716 # - user gives %%: only do cell magics
717 717 # - user gives %: do both line and cell magics
718 718 # - no prefix: do both
719 719 # In other words, line magics are skipped if the user gives %% explicitly
720 720 bare_text = text.lstrip(pre)
721 721 comp = [ pre2+m for m in cell_magics if m.startswith(bare_text)]
722 722 if not text.startswith(pre2):
723 723 comp += [ pre+m for m in line_magics if m.startswith(bare_text)]
724 724 return comp
725 725
726 726 def python_matches(self,text):
727 727 """Match attributes or global python names"""
728 728
729 729 #io.rprint('Completer->python_matches, txt=%r' % text) # dbg
730 730 if "." in text:
731 731 try:
732 732 matches = self.attr_matches(text)
733 733 if text.endswith('.') and self.omit__names:
734 734 if self.omit__names == 1:
735 735 # true if txt is _not_ a __ name, false otherwise:
736 736 no__name = (lambda txt:
737 737 re.match(r'.*\.__.*?__',txt) is None)
738 738 else:
739 739 # true if txt is _not_ a _ name, false otherwise:
740 740 no__name = (lambda txt:
741 741 re.match(r'.*\._.*?',txt) is None)
742 742 matches = filter(no__name, matches)
743 743 except NameError:
744 744 # catches <undefined attributes>.<tab>
745 745 matches = []
746 746 else:
747 747 matches = self.global_matches(text)
748 748
749 749 return matches
750 750
751 751 def _default_arguments_from_docstring(self, doc):
752 752 """Parse the first line of docstring for call signature.
753 753
754 754 Docstring should be of the form 'min(iterable[, key=func])\n'.
755 755 It can also parse cython docstring of the form
756 756 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
757 757 """
758 758 if doc is None:
759 759 return []
760 760
761 761 #care only the firstline
762 762 line = doc.lstrip().splitlines()[0]
763 763
764 764 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
765 765 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
766 766 sig = self.docstring_sig_re.search(line)
767 767 if sig is None:
768 768 return []
769 769 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
770 770 sig = sig.groups()[0].split(',')
771 771 ret = []
772 772 for s in sig:
773 773 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
774 774 ret += self.docstring_kwd_re.findall(s)
775 775 return ret
776 776
777 777 def _default_arguments(self, obj):
778 778 """Return the list of default arguments of obj if it is callable,
779 779 or empty list otherwise."""
780 780 call_obj = obj
781 781 ret = []
782 782 if inspect.isbuiltin(obj):
783 783 pass
784 784 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
785 785 if inspect.isclass(obj):
786 786 #for cython embededsignature=True the constructor docstring
787 787 #belongs to the object itself not __init__
788 788 ret += self._default_arguments_from_docstring(
789 789 getattr(obj, '__doc__', ''))
790 790 # for classes, check for __init__,__new__
791 791 call_obj = (getattr(obj, '__init__', None) or
792 792 getattr(obj, '__new__', None))
793 793 # for all others, check if they are __call__able
794 794 elif hasattr(obj, '__call__'):
795 795 call_obj = obj.__call__
796 796
797 797 ret += self._default_arguments_from_docstring(
798 798 getattr(call_obj, '__doc__', ''))
799 799
800 800 try:
801 801 args,_,_1,defaults = inspect.getargspec(call_obj)
802 802 if defaults:
803 803 ret+=args[-len(defaults):]
804 804 except TypeError:
805 805 pass
806 806
807 807 return list(set(ret))
808 808
809 809 def python_func_kw_matches(self,text):
810 810 """Match named parameters (kwargs) of the last open function"""
811 811
812 812 if "." in text: # a parameter cannot be dotted
813 813 return []
814 814 try: regexp = self.__funcParamsRegex
815 815 except AttributeError:
816 816 regexp = self.__funcParamsRegex = re.compile(r'''
817 817 '.*?(?<!\\)' | # single quoted strings or
818 818 ".*?(?<!\\)" | # double quoted strings or
819 819 \w+ | # identifier
820 820 \S # other characters
821 821 ''', re.VERBOSE | re.DOTALL)
822 822 # 1. find the nearest identifier that comes before an unclosed
823 823 # parenthesis before the cursor
824 824 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
825 825 tokens = regexp.findall(self.text_until_cursor)
826 826 tokens.reverse()
827 827 iterTokens = iter(tokens); openPar = 0
828 828
829 829 for token in iterTokens:
830 830 if token == ')':
831 831 openPar -= 1
832 832 elif token == '(':
833 833 openPar += 1
834 834 if openPar > 0:
835 835 # found the last unclosed parenthesis
836 836 break
837 837 else:
838 838 return []
839 839 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
840 840 ids = []
841 841 isId = re.compile(r'\w+$').match
842 842
843 843 while True:
844 844 try:
845 845 ids.append(next(iterTokens))
846 846 if not isId(ids[-1]):
847 847 ids.pop(); break
848 848 if not next(iterTokens) == '.':
849 849 break
850 850 except StopIteration:
851 851 break
852 852 # lookup the candidate callable matches either using global_matches
853 853 # or attr_matches for dotted names
854 854 if len(ids) == 1:
855 855 callableMatches = self.global_matches(ids[0])
856 856 else:
857 857 callableMatches = self.attr_matches('.'.join(ids[::-1]))
858 858 argMatches = []
859 859 for callableMatch in callableMatches:
860 860 try:
861 861 namedArgs = self._default_arguments(eval(callableMatch,
862 862 self.namespace))
863 863 except:
864 864 continue
865 865
866 866 for namedArg in namedArgs:
867 867 if namedArg.startswith(text):
868 868 argMatches.append("%s=" %namedArg)
869 869 return argMatches
870 870
871 871 def dict_key_matches(self, text):
872 872 "Match string keys in a dictionary, after e.g. 'foo[' "
873 873 def get_keys(obj):
874 874 # Only allow completion for known in-memory dict-like types
875 875 if isinstance(obj, dict) or\
876 876 _safe_isinstance(obj, 'pandas', 'DataFrame'):
877 877 try:
878 878 return list(obj.keys())
879 879 except Exception:
880 880 return []
881 881 elif _safe_isinstance(obj, 'numpy', 'ndarray'):
882 882 return obj.dtype.names or []
883 883 return []
884 884
885 885 try:
886 886 regexps = self.__dict_key_regexps
887 887 except AttributeError:
888 888 dict_key_re_fmt = r'''(?x)
889 889 ( # match dict-referring expression wrt greedy setting
890 890 %s
891 891 )
892 892 \[ # open bracket
893 893 \s* # and optional whitespace
894 894 ([uUbB]? # string prefix (r not handled)
895 895 (?: # unclosed string
896 896 '(?:[^']|(?<!\\)\\')*
897 897 |
898 898 "(?:[^"]|(?<!\\)\\")*
899 899 )
900 900 )?
901 901 $
902 902 '''
903 903 regexps = self.__dict_key_regexps = {
904 904 False: re.compile(dict_key_re_fmt % '''
905 905 # identifiers separated by .
906 906 (?!\d)\w+
907 907 (?:\.(?!\d)\w+)*
908 908 '''),
909 909 True: re.compile(dict_key_re_fmt % '''
910 910 .+
911 911 ''')
912 912 }
913 913
914 914 match = regexps[self.greedy].search(self.text_until_cursor)
915 915 if match is None:
916 916 return []
917 917
918 918 expr, prefix = match.groups()
919 919 try:
920 920 obj = eval(expr, self.namespace)
921 921 except Exception:
922 922 try:
923 923 obj = eval(expr, self.global_namespace)
924 924 except Exception:
925 925 return []
926 926
927 927 keys = get_keys(obj)
928 928 if not keys:
929 929 return keys
930 930 closing_quote, token_offset, matches = match_dict_keys(keys, prefix)
931 931 if not matches:
932 932 return matches
933 933
934 934 # get the cursor position of
935 935 # - the text being completed
936 936 # - the start of the key text
937 937 # - the start of the completion
938 938 text_start = len(self.text_until_cursor) - len(text)
939 939 if prefix:
940 940 key_start = match.start(2)
941 941 completion_start = key_start + token_offset
942 942 else:
943 943 key_start = completion_start = match.end()
944 944
945 945 # grab the leading prefix, to make sure all completions start with `text`
946 946 if text_start > key_start:
947 947 leading = ''
948 948 else:
949 949 leading = text[text_start:completion_start]
950 950
951 951 # the index of the `[` character
952 952 bracket_idx = match.end(1)
953 953
954 954 # append closing quote and bracket as appropriate
955 955 # this is *not* appropriate if the opening quote or bracket is outside
956 956 # the text given to this method
957 957 suf = ''
958 958 continuation = self.line_buffer[len(self.text_until_cursor):]
959 959 if key_start > text_start and closing_quote:
960 960 # quotes were opened inside text, maybe close them
961 961 if continuation.startswith(closing_quote):
962 962 continuation = continuation[len(closing_quote):]
963 963 else:
964 964 suf += closing_quote
965 965 if bracket_idx > text_start:
966 966 # brackets were opened inside text, maybe close them
967 967 if not continuation.startswith(']'):
968 968 suf += ']'
969 969
970 970 return [leading + k + suf for k in matches]
971 971
972 972 def latex_matches(self, text):
973 if text.startswith('\\foo'):
974 return ['foo']
975 else:
976 return []
973 slashpos = text.rfind('\\')
974 if slashpos > -1:
975 s = text[slashpos:]
976 if s in latex_symbols:
977 return s, [latex_symbols[s]]
978 return u'', []
977 979
978 980 def dispatch_custom_completer(self, text):
979 981 #io.rprint("Custom! '%s' %s" % (text, self.custom_completers)) # dbg
980 982 line = self.line_buffer
981 983 if not line.strip():
982 984 return None
983 985
984 986 # Create a little structure to pass all the relevant information about
985 987 # the current completion to any custom completer.
986 988 event = Bunch()
987 989 event.line = line
988 990 event.symbol = text
989 991 cmd = line.split(None,1)[0]
990 992 event.command = cmd
991 993 event.text_until_cursor = self.text_until_cursor
992 994
993 995 #print "\ncustom:{%s]\n" % event # dbg
994 996
995 997 # for foo etc, try also to find completer for %foo
996 998 if not cmd.startswith(self.magic_escape):
997 999 try_magic = self.custom_completers.s_matches(
998 1000 self.magic_escape + cmd)
999 1001 else:
1000 1002 try_magic = []
1001 1003
1002 1004 for c in itertools.chain(self.custom_completers.s_matches(cmd),
1003 1005 try_magic,
1004 1006 self.custom_completers.flat_matches(self.text_until_cursor)):
1005 1007 #print "try",c # dbg
1006 1008 try:
1007 1009 res = c(event)
1008 1010 if res:
1009 1011 # first, try case sensitive match
1010 1012 withcase = [r for r in res if r.startswith(text)]
1011 1013 if withcase:
1012 1014 return withcase
1013 1015 # if none, then case insensitive ones are ok too
1014 1016 text_low = text.lower()
1015 1017 return [r for r in res if r.lower().startswith(text_low)]
1016 1018 except TryNext:
1017 1019 pass
1018 1020
1019 1021 return None
1020 1022
1021 1023 def complete(self, text=None, line_buffer=None, cursor_pos=None):
1022 1024 """Find completions for the given text and line context.
1023 1025
1024 1026 Note that both the text and the line_buffer are optional, but at least
1025 1027 one of them must be given.
1026 1028
1027 1029 Parameters
1028 1030 ----------
1029 1031 text : string, optional
1030 1032 Text to perform the completion on. If not given, the line buffer
1031 1033 is split using the instance's CompletionSplitter object.
1032 1034
1033 1035 line_buffer : string, optional
1034 1036 If not given, the completer attempts to obtain the current line
1035 1037 buffer via readline. This keyword allows clients which are
1036 1038 requesting for text completions in non-readline contexts to inform
1037 1039 the completer of the entire text.
1038 1040
1039 1041 cursor_pos : int, optional
1040 1042 Index of the cursor in the full line buffer. Should be provided by
1041 1043 remote frontends where kernel has no access to frontend state.
1042 1044
1043 1045 Returns
1044 1046 -------
1045 1047 text : str
1046 1048 Text that was actually used in the completion.
1047 1049
1048 1050 matches : list
1049 1051 A list of completion matches.
1050 1052 """
1051 io.rprint('\nCOMP1 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg
1053 # io.rprint('\nCOMP1 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg
1052 1054
1053 1055 # if the cursor position isn't given, the only sane assumption we can
1054 1056 # make is that it's at the end of the line (the common case)
1055 1057 if cursor_pos is None:
1056 1058 cursor_pos = len(line_buffer) if text is None else len(text)
1057 1059
1060 latex_text = text if not line_buffer else line_buffer[:cursor_pos]
1061 latex_text, latex_matches = self.latex_matches(latex_text)
1062 if latex_matches:
1063 return latex_text, latex_matches
1064
1058 1065 # if text is either None or an empty string, rely on the line buffer
1059 1066 if not text:
1060 1067 text = self.splitter.split_line(line_buffer, cursor_pos)
1061 1068
1062 1069 # If no line buffer is given, assume the input text is all there was
1063 1070 if line_buffer is None:
1064 1071 line_buffer = text
1065 1072
1066 1073 self.line_buffer = line_buffer
1067 1074 self.text_until_cursor = self.line_buffer[:cursor_pos]
1068 io.rprint('COMP2 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg
1075 # io.rprint('COMP2 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg
1069 1076
1070 1077 # Start with a clean slate of completions
1071 1078 self.matches[:] = []
1072 1079 custom_res = self.dispatch_custom_completer(text)
1073 1080 if custom_res is not None:
1074 1081 # did custom completers produce something?
1075 1082 self.matches = custom_res
1076 1083 else:
1077 1084 # Extend the list of completions with the results of each
1078 1085 # matcher, so we return results to the user from all
1079 1086 # namespaces.
1080 1087 if self.merge_completions:
1081 1088 self.matches = []
1082 1089 for matcher in self.matchers:
1083 1090 try:
1084 1091 self.matches.extend(matcher(text))
1085 1092 except:
1086 1093 # Show the ugly traceback if the matcher causes an
1087 1094 # exception, but do NOT crash the kernel!
1088 1095 sys.excepthook(*sys.exc_info())
1089 1096 else:
1090 1097 for matcher in self.matchers:
1091 1098 self.matches = matcher(text)
1092 1099 if self.matches:
1093 1100 break
1094 1101 # FIXME: we should extend our api to return a dict with completions for
1095 1102 # different types of objects. The rlcomplete() method could then
1096 1103 # simply collapse the dict into a list for readline, but we'd have
1097 1104 # richer completion semantics in other evironments.
1098 1105
1099 1106 # use penalize_magics_key to put magics after variables with same name
1100 1107 self.matches = sorted(set(self.matches), key=penalize_magics_key)
1101 1108
1102 1109 #io.rprint('COMP TEXT, MATCHES: %r, %r' % (text, self.matches)) # dbg
1103 1110 return text, self.matches
1104 1111
1105 1112 def rlcomplete(self, text, state):
1106 1113 """Return the state-th possible completion for 'text'.
1107 1114
1108 1115 This is called successively with state == 0, 1, 2, ... until it
1109 1116 returns None. The completion should begin with 'text'.
1110 1117
1111 1118 Parameters
1112 1119 ----------
1113 1120 text : string
1114 1121 Text to perform the completion on.
1115 1122
1116 1123 state : int
1117 1124 Counter used by readline.
1118 1125 """
1119 1126 if state==0:
1120 1127
1121 1128 self.line_buffer = line_buffer = self.readline.get_line_buffer()
1122 1129 cursor_pos = self.readline.get_endidx()
1123 1130
1124 1131 #io.rprint("\nRLCOMPLETE: %r %r %r" %
1125 1132 # (text, line_buffer, cursor_pos) ) # dbg
1126 1133
1127 1134 # if there is only a tab on a line with only whitespace, instead of
1128 1135 # the mostly useless 'do you want to see all million completions'
1129 1136 # message, just do the right thing and give the user his tab!
1130 1137 # Incidentally, this enables pasting of tabbed text from an editor
1131 1138 # (as long as autoindent is off).
1132 1139
1133 1140 # It should be noted that at least pyreadline still shows file
1134 1141 # completions - is there a way around it?
1135 1142
1136 1143 # don't apply this on 'dumb' terminals, such as emacs buffers, so
1137 1144 # we don't interfere with their own tab-completion mechanism.
1138 1145 if not (self.dumb_terminal or line_buffer.strip()):
1139 1146 self.readline.insert_text('\t')
1140 1147 sys.stdout.flush()
1141 1148 return None
1142 1149
1143 1150 # Note: debugging exceptions that may occur in completion is very
1144 1151 # tricky, because readline unconditionally silences them. So if
1145 1152 # during development you suspect a bug in the completion code, turn
1146 1153 # this flag on temporarily by uncommenting the second form (don't
1147 1154 # flip the value in the first line, as the '# dbg' marker can be
1148 1155 # automatically detected and is used elsewhere).
1149 1156 DEBUG = False
1150 1157 #DEBUG = True # dbg
1151 1158 if DEBUG:
1152 1159 try:
1153 1160 self.complete(text, line_buffer, cursor_pos)
1154 1161 except:
1155 1162 import traceback; traceback.print_exc()
1156 1163 else:
1157 1164 # The normal production version is here
1158 1165
1159 1166 # This method computes the self.matches array
1160 1167 self.complete(text, line_buffer, cursor_pos)
1161 1168
1162 1169 try:
1163 1170 return self.matches[state]
1164 1171 except IndexError:
1165 1172 return None
General Comments 0
You need to be logged in to leave comments. Login now