##// END OF EJS Templates
ENH: Add configuration for profiling completions....
Scott Sanderson -
Show More
@@ -1,2101 +1,2126 b''
1 1 """Completion for IPython.
2 2
3 3 This module started as 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,
6 6
7 7 This module now support a wide variety of completion mechanism both available
8 8 for normal classic Python code, as well as completer for IPython specific
9 9 Syntax like magics.
10 10
11 11 Latex and Unicode completion
12 12 ============================
13 13
14 14 IPython and compatible frontends not only can complete your code, but can help
15 15 you to input a wide range of characters. In particular we allow you to insert
16 16 a unicode character using the tab completion mechanism.
17 17
18 18 Forward latex/unicode completion
19 19 --------------------------------
20 20
21 21 Forward completion allows you to easily type a unicode character using its latex
22 22 name, or unicode long description. To do so type a backslash follow by the
23 23 relevant name and press tab:
24 24
25 25
26 26 Using latex completion:
27 27
28 28 .. code::
29 29
30 30 \\alpha<tab>
31 31 Ξ±
32 32
33 33 or using unicode completion:
34 34
35 35
36 36 .. code::
37 37
38 38 \\greek small letter alpha<tab>
39 39 Ξ±
40 40
41 41
42 42 Only valid Python identifiers will complete. Combining characters (like arrow or
43 43 dots) are also available, unlike latex they need to be put after the their
44 44 counterpart that is to say, `F\\\\vec<tab>` is correct, not `\\\\vec<tab>F`.
45 45
46 46 Some browsers are known to display combining characters incorrectly.
47 47
48 48 Backward latex completion
49 49 -------------------------
50 50
51 51 It is sometime challenging to know how to type a character, if you are using
52 52 IPython, or any compatible frontend you can prepend backslash to the character
53 53 and press `<tab>` to expand it to its latex form.
54 54
55 55 .. code::
56 56
57 57 \\Ξ±<tab>
58 58 \\alpha
59 59
60 60
61 61 Both forward and backward completions can be deactivated by setting the
62 62 ``Completer.backslash_combining_completions`` option to ``False``.
63 63
64 64
65 65 Experimental
66 66 ============
67 67
68 68 Starting with IPython 6.0, this module can make use of the Jedi library to
69 69 generate completions both using static analysis of the code, and dynamically
70 70 inspecting multiple namespaces. Jedi is an autocompletion and static analysis
71 71 for Python. The APIs attached to this new mechanism is unstable and will
72 72 raise unless use in an :any:`provisionalcompleter` context manager.
73 73
74 74 You will find that the following are experimental:
75 75
76 76 - :any:`provisionalcompleter`
77 77 - :any:`IPCompleter.completions`
78 78 - :any:`Completion`
79 79 - :any:`rectify_completions`
80 80
81 81 .. note::
82 82
83 83 better name for :any:`rectify_completions` ?
84 84
85 85 We welcome any feedback on these new API, and we also encourage you to try this
86 86 module in debug mode (start IPython with ``--Completer.debug=True``) in order
87 87 to have extra logging information if :any:`jedi` is crashing, or if current
88 88 IPython completer pending deprecations are returning results not yet handled
89 89 by :any:`jedi`
90 90
91 91 Using Jedi for tab completion allow snippets like the following to work without
92 92 having to execute any code:
93 93
94 94 >>> myvar = ['hello', 42]
95 95 ... myvar[1].bi<tab>
96 96
97 97 Tab completion will be able to infer that ``myvar[1]`` is a real number without
98 98 executing any code unlike the previously available ``IPCompleter.greedy``
99 99 option.
100 100
101 101 Be sure to update :any:`jedi` to the latest stable version or to try the
102 102 current development version to get better completions.
103 103 """
104 104
105 105
106 106 # Copyright (c) IPython Development Team.
107 107 # Distributed under the terms of the Modified BSD License.
108 108 #
109 109 # Some of this code originated from rlcompleter in the Python standard library
110 110 # Copyright (C) 2001 Python Software Foundation, www.python.org
111 111
112 112
113 113 import builtins as builtin_mod
114 114 import glob
115 115 import inspect
116 116 import itertools
117 117 import keyword
118 118 import os
119 119 import re
120 120 import string
121 121 import sys
122 122 import time
123 123 import unicodedata
124 import uuid
124 125 import warnings
125 126 from contextlib import contextmanager
126 127 from importlib import import_module
127 128 from types import SimpleNamespace
128 129 from typing import Iterable, Iterator, List, Tuple
129 130
130 131 from IPython.core.error import TryNext
131 132 from IPython.core.inputtransformer2 import ESC_MAGIC
132 133 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
133 134 from IPython.core.oinspect import InspectColors
134 135 from IPython.utils import generics
135 136 from IPython.utils.dir2 import dir2, get_real_method
137 from IPython.utils.path import ensure_dir_exists
136 138 from IPython.utils.process import arg_split
137 from traitlets import Bool, Enum, Int, observe
139 from traitlets import Bool, Enum, Int, Unicode, observe
138 140 from traitlets.config.configurable import Configurable
139 141
140 142 import __main__
141 143
142 144 # skip module docstests
143 145 skip_doctest = True
144 146
145 147 try:
146 148 import jedi
147 149 jedi.settings.case_insensitive_completion = False
148 150 import jedi.api.helpers
149 151 import jedi.api.classes
150 152 JEDI_INSTALLED = True
151 153 except ImportError:
152 154 JEDI_INSTALLED = False
153 155 #-----------------------------------------------------------------------------
154 156 # Globals
155 157 #-----------------------------------------------------------------------------
156 158
157 159 # Public API
158 160 __all__ = ['Completer','IPCompleter']
159 161
160 162 if sys.platform == 'win32':
161 163 PROTECTABLES = ' '
162 164 else:
163 165 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
164 166
165 167 # Protect against returning an enormous number of completions which the frontend
166 168 # may have trouble processing.
167 169 MATCHES_LIMIT = 500
168 170
169 171 _deprecation_readline_sentinel = object()
170 172
171 173
172 174 class ProvisionalCompleterWarning(FutureWarning):
173 175 """
174 176 Exception raise by an experimental feature in this module.
175 177
176 178 Wrap code in :any:`provisionalcompleter` context manager if you
177 179 are certain you want to use an unstable feature.
178 180 """
179 181 pass
180 182
181 183 warnings.filterwarnings('error', category=ProvisionalCompleterWarning)
182 184
183 185 @contextmanager
184 186 def provisionalcompleter(action='ignore'):
185 187 """
186 188
187 189
188 190 This context manager has to be used in any place where unstable completer
189 191 behavior and API may be called.
190 192
191 193 >>> with provisionalcompleter():
192 194 ... completer.do_experimental_things() # works
193 195
194 196 >>> completer.do_experimental_things() # raises.
195 197
196 198 .. note:: Unstable
197 199
198 200 By using this context manager you agree that the API in use may change
199 201 without warning, and that you won't complain if they do so.
200 202
201 203 You also understand that, if the API is not to your liking, you should report
202 204 a bug to explain your use case upstream.
203 205
204 206 We'll be happy to get your feedback, feature requests, and improvements on
205 207 any of the unstable APIs!
206 208 """
207 209 with warnings.catch_warnings():
208 210 warnings.filterwarnings(action, category=ProvisionalCompleterWarning)
209 211 yield
210 212
211 213
212 214 def has_open_quotes(s):
213 215 """Return whether a string has open quotes.
214 216
215 217 This simply counts whether the number of quote characters of either type in
216 218 the string is odd.
217 219
218 220 Returns
219 221 -------
220 222 If there is an open quote, the quote character is returned. Else, return
221 223 False.
222 224 """
223 225 # We check " first, then ', so complex cases with nested quotes will get
224 226 # the " to take precedence.
225 227 if s.count('"') % 2:
226 228 return '"'
227 229 elif s.count("'") % 2:
228 230 return "'"
229 231 else:
230 232 return False
231 233
232 234
233 235 def protect_filename(s, protectables=PROTECTABLES):
234 236 """Escape a string to protect certain characters."""
235 237 if set(s) & set(protectables):
236 238 if sys.platform == "win32":
237 239 return '"' + s + '"'
238 240 else:
239 241 return "".join(("\\" + c if c in protectables else c) for c in s)
240 242 else:
241 243 return s
242 244
243 245
244 246 def expand_user(path:str) -> Tuple[str, bool, str]:
245 247 """Expand ``~``-style usernames in strings.
246 248
247 249 This is similar to :func:`os.path.expanduser`, but it computes and returns
248 250 extra information that will be useful if the input was being used in
249 251 computing completions, and you wish to return the completions with the
250 252 original '~' instead of its expanded value.
251 253
252 254 Parameters
253 255 ----------
254 256 path : str
255 257 String to be expanded. If no ~ is present, the output is the same as the
256 258 input.
257 259
258 260 Returns
259 261 -------
260 262 newpath : str
261 263 Result of ~ expansion in the input path.
262 264 tilde_expand : bool
263 265 Whether any expansion was performed or not.
264 266 tilde_val : str
265 267 The value that ~ was replaced with.
266 268 """
267 269 # Default values
268 270 tilde_expand = False
269 271 tilde_val = ''
270 272 newpath = path
271 273
272 274 if path.startswith('~'):
273 275 tilde_expand = True
274 276 rest = len(path)-1
275 277 newpath = os.path.expanduser(path)
276 278 if rest:
277 279 tilde_val = newpath[:-rest]
278 280 else:
279 281 tilde_val = newpath
280 282
281 283 return newpath, tilde_expand, tilde_val
282 284
283 285
284 286 def compress_user(path:str, tilde_expand:bool, tilde_val:str) -> str:
285 287 """Does the opposite of expand_user, with its outputs.
286 288 """
287 289 if tilde_expand:
288 290 return path.replace(tilde_val, '~')
289 291 else:
290 292 return path
291 293
292 294
293 295 def completions_sorting_key(word):
294 296 """key for sorting completions
295 297
296 298 This does several things:
297 299
298 300 - Demote any completions starting with underscores to the end
299 301 - Insert any %magic and %%cellmagic completions in the alphabetical order
300 302 by their name
301 303 """
302 304 prio1, prio2 = 0, 0
303 305
304 306 if word.startswith('__'):
305 307 prio1 = 2
306 308 elif word.startswith('_'):
307 309 prio1 = 1
308 310
309 311 if word.endswith('='):
310 312 prio1 = -1
311 313
312 314 if word.startswith('%%'):
313 315 # If there's another % in there, this is something else, so leave it alone
314 316 if not "%" in word[2:]:
315 317 word = word[2:]
316 318 prio2 = 2
317 319 elif word.startswith('%'):
318 320 if not "%" in word[1:]:
319 321 word = word[1:]
320 322 prio2 = 1
321 323
322 324 return prio1, word, prio2
323 325
324 326
325 327 class _FakeJediCompletion:
326 328 """
327 329 This is a workaround to communicate to the UI that Jedi has crashed and to
328 330 report a bug. Will be used only id :any:`IPCompleter.debug` is set to true.
329 331
330 332 Added in IPython 6.0 so should likely be removed for 7.0
331 333
332 334 """
333 335
334 336 def __init__(self, name):
335 337
336 338 self.name = name
337 339 self.complete = name
338 340 self.type = 'crashed'
339 341 self.name_with_symbols = name
340 342 self.signature = ''
341 343 self._origin = 'fake'
342 344
343 345 def __repr__(self):
344 346 return '<Fake completion object jedi has crashed>'
345 347
346 348
347 349 class Completion:
348 350 """
349 351 Completion object used and return by IPython completers.
350 352
351 353 .. warning:: Unstable
352 354
353 355 This function is unstable, API may change without warning.
354 356 It will also raise unless use in proper context manager.
355 357
356 358 This act as a middle ground :any:`Completion` object between the
357 359 :any:`jedi.api.classes.Completion` object and the Prompt Toolkit completion
358 360 object. While Jedi need a lot of information about evaluator and how the
359 361 code should be ran/inspected, PromptToolkit (and other frontend) mostly
360 362 need user facing information.
361 363
362 364 - Which range should be replaced replaced by what.
363 365 - Some metadata (like completion type), or meta information to displayed to
364 366 the use user.
365 367
366 368 For debugging purpose we can also store the origin of the completion (``jedi``,
367 369 ``IPython.python_matches``, ``IPython.magics_matches``...).
368 370 """
369 371
370 372 __slots__ = ['start', 'end', 'text', 'type', 'signature', '_origin']
371 373
372 374 def __init__(self, start: int, end: int, text: str, *, type: str=None, _origin='', signature='') -> None:
373 375 warnings.warn("``Completion`` is a provisional API (as of IPython 6.0). "
374 376 "It may change without warnings. "
375 377 "Use in corresponding context manager.",
376 378 category=ProvisionalCompleterWarning, stacklevel=2)
377 379
378 380 self.start = start
379 381 self.end = end
380 382 self.text = text
381 383 self.type = type
382 384 self.signature = signature
383 385 self._origin = _origin
384 386
385 387 def __repr__(self):
386 388 return '<Completion start=%s end=%s text=%r type=%r, signature=%r,>' % \
387 389 (self.start, self.end, self.text, self.type or '?', self.signature or '?')
388 390
389 391 def __eq__(self, other)->Bool:
390 392 """
391 393 Equality and hash do not hash the type (as some completer may not be
392 394 able to infer the type), but are use to (partially) de-duplicate
393 395 completion.
394 396
395 397 Completely de-duplicating completion is a bit tricker that just
396 398 comparing as it depends on surrounding text, which Completions are not
397 399 aware of.
398 400 """
399 401 return self.start == other.start and \
400 402 self.end == other.end and \
401 403 self.text == other.text
402 404
403 405 def __hash__(self):
404 406 return hash((self.start, self.end, self.text))
405 407
406 408
407 409 _IC = Iterable[Completion]
408 410
409 411
410 412 def _deduplicate_completions(text: str, completions: _IC)-> _IC:
411 413 """
412 414 Deduplicate a set of completions.
413 415
414 416 .. warning:: Unstable
415 417
416 418 This function is unstable, API may change without warning.
417 419
418 420 Parameters
419 421 ----------
420 422 text: str
421 423 text that should be completed.
422 424 completions: Iterator[Completion]
423 425 iterator over the completions to deduplicate
424 426
425 427 Yields
426 428 ------
427 429 `Completions` objects
428 430
429 431
430 432 Completions coming from multiple sources, may be different but end up having
431 433 the same effect when applied to ``text``. If this is the case, this will
432 434 consider completions as equal and only emit the first encountered.
433 435
434 436 Not folded in `completions()` yet for debugging purpose, and to detect when
435 437 the IPython completer does return things that Jedi does not, but should be
436 438 at some point.
437 439 """
438 440 completions = list(completions)
439 441 if not completions:
440 442 return
441 443
442 444 new_start = min(c.start for c in completions)
443 445 new_end = max(c.end for c in completions)
444 446
445 447 seen = set()
446 448 for c in completions:
447 449 new_text = text[new_start:c.start] + c.text + text[c.end:new_end]
448 450 if new_text not in seen:
449 451 yield c
450 452 seen.add(new_text)
451 453
452 454
453 455 def rectify_completions(text: str, completions: _IC, *, _debug=False)->_IC:
454 456 """
455 457 Rectify a set of completions to all have the same ``start`` and ``end``
456 458
457 459 .. warning:: Unstable
458 460
459 461 This function is unstable, API may change without warning.
460 462 It will also raise unless use in proper context manager.
461 463
462 464 Parameters
463 465 ----------
464 466 text: str
465 467 text that should be completed.
466 468 completions: Iterator[Completion]
467 469 iterator over the completions to rectify
468 470
469 471
470 472 :any:`jedi.api.classes.Completion` s returned by Jedi may not have the same start and end, though
471 473 the Jupyter Protocol requires them to behave like so. This will readjust
472 474 the completion to have the same ``start`` and ``end`` by padding both
473 475 extremities with surrounding text.
474 476
475 477 During stabilisation should support a ``_debug`` option to log which
476 478 completion are return by the IPython completer and not found in Jedi in
477 479 order to make upstream bug report.
478 480 """
479 481 warnings.warn("`rectify_completions` is a provisional API (as of IPython 6.0). "
480 482 "It may change without warnings. "
481 483 "Use in corresponding context manager.",
482 484 category=ProvisionalCompleterWarning, stacklevel=2)
483 485
484 486 completions = list(completions)
485 487 if not completions:
486 488 return
487 489 starts = (c.start for c in completions)
488 490 ends = (c.end for c in completions)
489 491
490 492 new_start = min(starts)
491 493 new_end = max(ends)
492 494
493 495 seen_jedi = set()
494 496 seen_python_matches = set()
495 497 for c in completions:
496 498 new_text = text[new_start:c.start] + c.text + text[c.end:new_end]
497 499 if c._origin == 'jedi':
498 500 seen_jedi.add(new_text)
499 501 elif c._origin == 'IPCompleter.python_matches':
500 502 seen_python_matches.add(new_text)
501 503 yield Completion(new_start, new_end, new_text, type=c.type, _origin=c._origin, signature=c.signature)
502 504 diff = seen_python_matches.difference(seen_jedi)
503 505 if diff and _debug:
504 506 print('IPython.python matches have extras:', diff)
505 507
506 508
507 509 if sys.platform == 'win32':
508 510 DELIMS = ' \t\n`!@#$^&*()=+[{]}|;\'",<>?'
509 511 else:
510 512 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
511 513
512 514 GREEDY_DELIMS = ' =\r\n'
513 515
514 516
515 517 class CompletionSplitter(object):
516 518 """An object to split an input line in a manner similar to readline.
517 519
518 520 By having our own implementation, we can expose readline-like completion in
519 521 a uniform manner to all frontends. This object only needs to be given the
520 522 line of text to be split and the cursor position on said line, and it
521 523 returns the 'word' to be completed on at the cursor after splitting the
522 524 entire line.
523 525
524 526 What characters are used as splitting delimiters can be controlled by
525 527 setting the ``delims`` attribute (this is a property that internally
526 528 automatically builds the necessary regular expression)"""
527 529
528 530 # Private interface
529 531
530 532 # A string of delimiter characters. The default value makes sense for
531 533 # IPython's most typical usage patterns.
532 534 _delims = DELIMS
533 535
534 536 # The expression (a normal string) to be compiled into a regular expression
535 537 # for actual splitting. We store it as an attribute mostly for ease of
536 538 # debugging, since this type of code can be so tricky to debug.
537 539 _delim_expr = None
538 540
539 541 # The regular expression that does the actual splitting
540 542 _delim_re = None
541 543
542 544 def __init__(self, delims=None):
543 545 delims = CompletionSplitter._delims if delims is None else delims
544 546 self.delims = delims
545 547
546 548 @property
547 549 def delims(self):
548 550 """Return the string of delimiter characters."""
549 551 return self._delims
550 552
551 553 @delims.setter
552 554 def delims(self, delims):
553 555 """Set the delimiters for line splitting."""
554 556 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
555 557 self._delim_re = re.compile(expr)
556 558 self._delims = delims
557 559 self._delim_expr = expr
558 560
559 561 def split_line(self, line, cursor_pos=None):
560 562 """Split a line of text with a cursor at the given position.
561 563 """
562 564 l = line if cursor_pos is None else line[:cursor_pos]
563 565 return self._delim_re.split(l)[-1]
564 566
565 567
566 568
567 569 class Completer(Configurable):
568 570
569 571 greedy = Bool(False,
570 572 help="""Activate greedy completion
571 573 PENDING DEPRECTION. this is now mostly taken care of with Jedi.
572 574
573 575 This will enable completion on elements of lists, results of function calls, etc.,
574 576 but can be unsafe because the code is actually evaluated on TAB.
575 577 """
576 578 ).tag(config=True)
577 579
578 580 use_jedi = Bool(default_value=JEDI_INSTALLED,
579 581 help="Experimental: Use Jedi to generate autocompletions. "
580 582 "Default to True if jedi is installed.").tag(config=True)
581 583
582 584 jedi_compute_type_timeout = Int(default_value=400,
583 585 help="""Experimental: restrict time (in milliseconds) during which Jedi can compute types.
584 586 Set to 0 to stop computing types. Non-zero value lower than 100ms may hurt
585 587 performance by preventing jedi to build its cache.
586 588 """).tag(config=True)
587 589
588 590 debug = Bool(default_value=False,
589 591 help='Enable debug for the Completer. Mostly print extra '
590 592 'information for experimental jedi integration.')\
591 593 .tag(config=True)
592 594
593 595 backslash_combining_completions = Bool(True,
594 596 help="Enable unicode completions, e.g. \\alpha<tab> . "
595 597 "Includes completion of latex commands, unicode names, and expanding "
596 598 "unicode characters back to latex commands.").tag(config=True)
597 599
598 600
599 601
600 602 def __init__(self, namespace=None, global_namespace=None, **kwargs):
601 603 """Create a new completer for the command line.
602 604
603 605 Completer(namespace=ns, global_namespace=ns2) -> completer instance.
604 606
605 607 If unspecified, the default namespace where completions are performed
606 608 is __main__ (technically, __main__.__dict__). Namespaces should be
607 609 given as dictionaries.
608 610
609 611 An optional second namespace can be given. This allows the completer
610 612 to handle cases where both the local and global scopes need to be
611 613 distinguished.
612 614 """
613 615
614 616 # Don't bind to namespace quite yet, but flag whether the user wants a
615 617 # specific namespace or to use __main__.__dict__. This will allow us
616 618 # to bind to __main__.__dict__ at completion time, not now.
617 619 if namespace is None:
618 620 self.use_main_ns = True
619 621 else:
620 622 self.use_main_ns = False
621 623 self.namespace = namespace
622 624
623 625 # The global namespace, if given, can be bound directly
624 626 if global_namespace is None:
625 627 self.global_namespace = {}
626 628 else:
627 629 self.global_namespace = global_namespace
628 630
629 631 self.custom_matchers = []
630 632
631 633 super(Completer, self).__init__(**kwargs)
632 634
633 635 def complete(self, text, state):
634 636 """Return the next possible completion for 'text'.
635 637
636 638 This is called successively with state == 0, 1, 2, ... until it
637 639 returns None. The completion should begin with 'text'.
638 640
639 641 """
640 642 if self.use_main_ns:
641 643 self.namespace = __main__.__dict__
642 644
643 645 if state == 0:
644 646 if "." in text:
645 647 self.matches = self.attr_matches(text)
646 648 else:
647 649 self.matches = self.global_matches(text)
648 650 try:
649 651 return self.matches[state]
650 652 except IndexError:
651 653 return None
652 654
653 655 def global_matches(self, text):
654 656 """Compute matches when text is a simple name.
655 657
656 658 Return a list of all keywords, built-in functions and names currently
657 659 defined in self.namespace or self.global_namespace that match.
658 660
659 661 """
660 662 matches = []
661 663 match_append = matches.append
662 664 n = len(text)
663 665 for lst in [keyword.kwlist,
664 666 builtin_mod.__dict__.keys(),
665 667 self.namespace.keys(),
666 668 self.global_namespace.keys()]:
667 669 for word in lst:
668 670 if word[:n] == text and word != "__builtins__":
669 671 match_append(word)
670 672
671 673 snake_case_re = re.compile(r"[^_]+(_[^_]+)+?\Z")
672 674 for lst in [self.namespace.keys(),
673 675 self.global_namespace.keys()]:
674 676 shortened = {"_".join([sub[0] for sub in word.split('_')]) : word
675 677 for word in lst if snake_case_re.match(word)}
676 678 for word in shortened.keys():
677 679 if word[:n] == text and word != "__builtins__":
678 680 match_append(shortened[word])
679 681 return matches
680 682
681 683 def attr_matches(self, text):
682 684 """Compute matches when text contains a dot.
683 685
684 686 Assuming the text is of the form NAME.NAME....[NAME], and is
685 687 evaluatable in self.namespace or self.global_namespace, it will be
686 688 evaluated and its attributes (as revealed by dir()) are used as
687 689 possible completions. (For class instances, class members are
688 690 also considered.)
689 691
690 692 WARNING: this can still invoke arbitrary C code, if an object
691 693 with a __getattr__ hook is evaluated.
692 694
693 695 """
694 696
695 697 # Another option, seems to work great. Catches things like ''.<tab>
696 698 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
697 699
698 700 if m:
699 701 expr, attr = m.group(1, 3)
700 702 elif self.greedy:
701 703 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
702 704 if not m2:
703 705 return []
704 706 expr, attr = m2.group(1,2)
705 707 else:
706 708 return []
707 709
708 710 try:
709 711 obj = eval(expr, self.namespace)
710 712 except:
711 713 try:
712 714 obj = eval(expr, self.global_namespace)
713 715 except:
714 716 return []
715 717
716 718 if self.limit_to__all__ and hasattr(obj, '__all__'):
717 719 words = get__all__entries(obj)
718 720 else:
719 721 words = dir2(obj)
720 722
721 723 try:
722 724 words = generics.complete_object(obj, words)
723 725 except TryNext:
724 726 pass
725 727 except AssertionError:
726 728 raise
727 729 except Exception:
728 730 # Silence errors from completion function
729 731 #raise # dbg
730 732 pass
731 733 # Build match list to return
732 734 n = len(attr)
733 735 return [u"%s.%s" % (expr, w) for w in words if w[:n] == attr ]
734 736
735 737
736 738 def get__all__entries(obj):
737 739 """returns the strings in the __all__ attribute"""
738 740 try:
739 741 words = getattr(obj, '__all__')
740 742 except:
741 743 return []
742 744
743 745 return [w for w in words if isinstance(w, str)]
744 746
745 747
746 748 def match_dict_keys(keys: List[str], prefix: str, delims: str):
747 749 """Used by dict_key_matches, matching the prefix to a list of keys
748 750
749 751 Parameters
750 752 ==========
751 753 keys:
752 754 list of keys in dictionary currently being completed.
753 755 prefix:
754 756 Part of the text already typed by the user. e.g. `mydict[b'fo`
755 757 delims:
756 758 String of delimiters to consider when finding the current key.
757 759
758 760 Returns
759 761 =======
760 762
761 763 A tuple of three elements: ``quote``, ``token_start``, ``matched``, with
762 764 ``quote`` being the quote that need to be used to close current string.
763 765 ``token_start`` the position where the replacement should start occurring,
764 766 ``matches`` a list of replacement/completion
765 767
766 768 """
767 769 if not prefix:
768 770 return None, 0, [repr(k) for k in keys
769 771 if isinstance(k, (str, bytes))]
770 772 quote_match = re.search('["\']', prefix)
771 773 quote = quote_match.group()
772 774 try:
773 775 prefix_str = eval(prefix + quote, {})
774 776 except Exception:
775 777 return None, 0, []
776 778
777 779 pattern = '[^' + ''.join('\\' + c for c in delims) + ']*$'
778 780 token_match = re.search(pattern, prefix, re.UNICODE)
779 781 token_start = token_match.start()
780 782 token_prefix = token_match.group()
781 783
782 784 matched = []
783 785 for key in keys:
784 786 try:
785 787 if not key.startswith(prefix_str):
786 788 continue
787 789 except (AttributeError, TypeError, UnicodeError):
788 790 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
789 791 continue
790 792
791 793 # reformat remainder of key to begin with prefix
792 794 rem = key[len(prefix_str):]
793 795 # force repr wrapped in '
794 796 rem_repr = repr(rem + '"') if isinstance(rem, str) else repr(rem + b'"')
795 797 if rem_repr.startswith('u') and prefix[0] not in 'uU':
796 798 # Found key is unicode, but prefix is Py2 string.
797 799 # Therefore attempt to interpret key as string.
798 800 try:
799 801 rem_repr = repr(rem.encode('ascii') + '"')
800 802 except UnicodeEncodeError:
801 803 continue
802 804
803 805 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
804 806 if quote == '"':
805 807 # The entered prefix is quoted with ",
806 808 # but the match is quoted with '.
807 809 # A contained " hence needs escaping for comparison:
808 810 rem_repr = rem_repr.replace('"', '\\"')
809 811
810 812 # then reinsert prefix from start of token
811 813 matched.append('%s%s' % (token_prefix, rem_repr))
812 814 return quote, token_start, matched
813 815
814 816
815 817 def cursor_to_position(text:str, line:int, column:int)->int:
816 818 """
817 819
818 820 Convert the (line,column) position of the cursor in text to an offset in a
819 821 string.
820 822
821 823 Parameters
822 824 ----------
823 825
824 826 text : str
825 827 The text in which to calculate the cursor offset
826 828 line : int
827 829 Line of the cursor; 0-indexed
828 830 column : int
829 831 Column of the cursor 0-indexed
830 832
831 833 Return
832 834 ------
833 835 Position of the cursor in ``text``, 0-indexed.
834 836
835 837 See Also
836 838 --------
837 839 position_to_cursor: reciprocal of this function
838 840
839 841 """
840 842 lines = text.split('\n')
841 843 assert line <= len(lines), '{} <= {}'.format(str(line), str(len(lines)))
842 844
843 845 return sum(len(l) + 1 for l in lines[:line]) + column
844 846
845 847 def position_to_cursor(text:str, offset:int)->Tuple[int, int]:
846 848 """
847 849 Convert the position of the cursor in text (0 indexed) to a line
848 850 number(0-indexed) and a column number (0-indexed) pair
849 851
850 852 Position should be a valid position in ``text``.
851 853
852 854 Parameters
853 855 ----------
854 856
855 857 text : str
856 858 The text in which to calculate the cursor offset
857 859 offset : int
858 860 Position of the cursor in ``text``, 0-indexed.
859 861
860 862 Return
861 863 ------
862 864 (line, column) : (int, int)
863 865 Line of the cursor; 0-indexed, column of the cursor 0-indexed
864 866
865 867
866 868 See Also
867 869 --------
868 870 cursor_to_position : reciprocal of this function
869 871
870 872
871 873 """
872 874
873 875 assert 0 <= offset <= len(text) , "0 <= %s <= %s" % (offset , len(text))
874 876
875 877 before = text[:offset]
876 878 blines = before.split('\n') # ! splitnes trim trailing \n
877 879 line = before.count('\n')
878 880 col = len(blines[-1])
879 881 return line, col
880 882
881 883
882 884 def _safe_isinstance(obj, module, class_name):
883 885 """Checks if obj is an instance of module.class_name if loaded
884 886 """
885 887 return (module in sys.modules and
886 888 isinstance(obj, getattr(import_module(module), class_name)))
887 889
888 890
889 891 def back_unicode_name_matches(text):
890 892 u"""Match unicode characters back to unicode name
891 893
892 894 This does ``β˜ƒ`` -> ``\\snowman``
893 895
894 896 Note that snowman is not a valid python3 combining character but will be expanded.
895 897 Though it will not recombine back to the snowman character by the completion machinery.
896 898
897 899 This will not either back-complete standard sequences like \\n, \\b ...
898 900
899 901 Used on Python 3 only.
900 902 """
901 903 if len(text)<2:
902 904 return u'', ()
903 905 maybe_slash = text[-2]
904 906 if maybe_slash != '\\':
905 907 return u'', ()
906 908
907 909 char = text[-1]
908 910 # no expand on quote for completion in strings.
909 911 # nor backcomplete standard ascii keys
910 912 if char in string.ascii_letters or char in ['"',"'"]:
911 913 return u'', ()
912 914 try :
913 915 unic = unicodedata.name(char)
914 916 return '\\'+char,['\\'+unic]
915 917 except KeyError:
916 918 pass
917 919 return u'', ()
918 920
919 921 def back_latex_name_matches(text:str):
920 922 """Match latex characters back to unicode name
921 923
922 924 This does ``\\β„΅`` -> ``\\aleph``
923 925
924 926 Used on Python 3 only.
925 927 """
926 928 if len(text)<2:
927 929 return u'', ()
928 930 maybe_slash = text[-2]
929 931 if maybe_slash != '\\':
930 932 return u'', ()
931 933
932 934
933 935 char = text[-1]
934 936 # no expand on quote for completion in strings.
935 937 # nor backcomplete standard ascii keys
936 938 if char in string.ascii_letters or char in ['"',"'"]:
937 939 return u'', ()
938 940 try :
939 941 latex = reverse_latex_symbol[char]
940 942 # '\\' replace the \ as well
941 943 return '\\'+char,[latex]
942 944 except KeyError:
943 945 pass
944 946 return u'', ()
945 947
946 948
947 949 def _formatparamchildren(parameter) -> str:
948 950 """
949 951 Get parameter name and value from Jedi Private API
950 952
951 953 Jedi does not expose a simple way to get `param=value` from its API.
952 954
953 955 Parameter
954 956 =========
955 957
956 958 parameter:
957 959 Jedi's function `Param`
958 960
959 961 Returns
960 962 =======
961 963
962 964 A string like 'a', 'b=1', '*args', '**kwargs'
963 965
964 966
965 967 """
966 968 description = parameter.description
967 969 if not description.startswith('param '):
968 970 raise ValueError('Jedi function parameter description have change format.'
969 971 'Expected "param ...", found %r".' % description)
970 972 return description[6:]
971 973
972 974 def _make_signature(completion)-> str:
973 975 """
974 976 Make the signature from a jedi completion
975 977
976 978 Parameter
977 979 =========
978 980
979 981 completion: jedi.Completion
980 982 object does not complete a function type
981 983
982 984 Returns
983 985 =======
984 986
985 987 a string consisting of the function signature, with the parenthesis but
986 988 without the function name. example:
987 989 `(a, *args, b=1, **kwargs)`
988 990
989 991 """
990 992
991 993 # it looks like this might work on jedi 0.17
992 994 if hasattr(completion, 'get_signatures'):
993 995 signatures = completion.get_signatures()
994 996 if not signatures:
995 997 return '(?)'
996 998
997 999 c0 = completion.get_signatures()[0]
998 1000 return '('+c0.to_string().split('(', maxsplit=1)[1]
999 1001
1000 1002 return '(%s)'% ', '.join([f for f in (_formatparamchildren(p) for signature in completion.get_signatures()
1001 1003 for p in signature.defined_names()) if f])
1002 1004
1003 1005 class IPCompleter(Completer):
1004 1006 """Extension of the completer class with IPython-specific features"""
1005 1007
1006 1008 _names = None
1007 1009
1008 1010 @observe('greedy')
1009 1011 def _greedy_changed(self, change):
1010 1012 """update the splitter and readline delims when greedy is changed"""
1011 1013 if change['new']:
1012 1014 self.splitter.delims = GREEDY_DELIMS
1013 1015 else:
1014 1016 self.splitter.delims = DELIMS
1015 1017
1016 1018 dict_keys_only = Bool(False,
1017 1019 help="""Whether to show dict key matches only""")
1018 1020
1019 1021 merge_completions = Bool(True,
1020 1022 help="""Whether to merge completion results into a single list
1021 1023
1022 1024 If False, only the completion results from the first non-empty
1023 1025 completer will be returned.
1024 1026 """
1025 1027 ).tag(config=True)
1026 1028 omit__names = Enum((0,1,2), default_value=2,
1027 1029 help="""Instruct the completer to omit private method names
1028 1030
1029 1031 Specifically, when completing on ``object.<tab>``.
1030 1032
1031 1033 When 2 [default]: all names that start with '_' will be excluded.
1032 1034
1033 1035 When 1: all 'magic' names (``__foo__``) will be excluded.
1034 1036
1035 1037 When 0: nothing will be excluded.
1036 1038 """
1037 1039 ).tag(config=True)
1038 1040 limit_to__all__ = Bool(False,
1039 1041 help="""
1040 1042 DEPRECATED as of version 5.0.
1041 1043
1042 1044 Instruct the completer to use __all__ for the completion
1043 1045
1044 1046 Specifically, when completing on ``object.<tab>``.
1045 1047
1046 1048 When True: only those names in obj.__all__ will be included.
1047 1049
1048 1050 When False [default]: the __all__ attribute is ignored
1049 1051 """,
1050 1052 ).tag(config=True)
1051 1053
1054 profile_completions = Bool(
1055 default_value=False,
1056 help="If True, emit profiling data for completion subsystem using cProfile."
1057 ).tag(config=True)
1058
1059 profiler_output_dir = Unicode(
1060 default_value=".completion_profiles",
1061 help="Template for path at which to output profile data for completions."
1062 ).tag(config=True)
1052 1063 @observe('limit_to__all__')
1053 1064 def _limit_to_all_changed(self, change):
1054 1065 warnings.warn('`IPython.core.IPCompleter.limit_to__all__` configuration '
1055 1066 'value has been deprecated since IPython 5.0, will be made to have '
1056 1067 'no effects and then removed in future version of IPython.',
1057 1068 UserWarning)
1058 1069
1059 1070 def __init__(self, shell=None, namespace=None, global_namespace=None,
1060 1071 use_readline=_deprecation_readline_sentinel, config=None, **kwargs):
1061 1072 """IPCompleter() -> completer
1062 1073
1063 1074 Return a completer object.
1064 1075
1065 1076 Parameters
1066 1077 ----------
1067 1078
1068 1079 shell
1069 1080 a pointer to the ipython shell itself. This is needed
1070 1081 because this completer knows about magic functions, and those can
1071 1082 only be accessed via the ipython instance.
1072 1083
1073 1084 namespace : dict, optional
1074 1085 an optional dict where completions are performed.
1075 1086
1076 1087 global_namespace : dict, optional
1077 1088 secondary optional dict for completions, to
1078 1089 handle cases (such as IPython embedded inside functions) where
1079 1090 both Python scopes are visible.
1080 1091
1081 1092 use_readline : bool, optional
1082 1093 DEPRECATED, ignored since IPython 6.0, will have no effects
1083 1094 """
1084 1095
1085 1096 self.magic_escape = ESC_MAGIC
1086 1097 self.splitter = CompletionSplitter()
1087 1098
1088 1099 if use_readline is not _deprecation_readline_sentinel:
1089 1100 warnings.warn('The `use_readline` parameter is deprecated and ignored since IPython 6.0.',
1090 1101 DeprecationWarning, stacklevel=2)
1091 1102
1092 1103 # _greedy_changed() depends on splitter and readline being defined:
1093 1104 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
1094 1105 config=config, **kwargs)
1095 1106
1096 1107 # List where completion matches will be stored
1097 1108 self.matches = []
1098 1109 self.shell = shell
1099 1110 # Regexp to split filenames with spaces in them
1100 1111 self.space_name_re = re.compile(r'([^\\] )')
1101 1112 # Hold a local ref. to glob.glob for speed
1102 1113 self.glob = glob.glob
1103 1114
1104 1115 # Determine if we are running on 'dumb' terminals, like (X)Emacs
1105 1116 # buffers, to avoid completion problems.
1106 1117 term = os.environ.get('TERM','xterm')
1107 1118 self.dumb_terminal = term in ['dumb','emacs']
1108 1119
1109 1120 # Special handling of backslashes needed in win32 platforms
1110 1121 if sys.platform == "win32":
1111 1122 self.clean_glob = self._clean_glob_win32
1112 1123 else:
1113 1124 self.clean_glob = self._clean_glob
1114 1125
1115 1126 #regexp to parse docstring for function signature
1116 1127 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
1117 1128 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
1118 1129 #use this if positional argument name is also needed
1119 1130 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
1120 1131
1121 1132 self.magic_arg_matchers = [
1122 1133 self.magic_config_matches,
1123 1134 self.magic_color_matches,
1124 1135 ]
1125 1136
1126 1137 # This is set externally by InteractiveShell
1127 1138 self.custom_completers = None
1128 1139
1129 1140 @property
1130 1141 def matchers(self):
1131 1142 """All active matcher routines for completion"""
1132 1143 if self.dict_keys_only:
1133 1144 return [self.dict_key_matches]
1134 1145
1135 1146 if self.use_jedi:
1136 1147 return [
1137 1148 *self.custom_matchers,
1138 1149 self.file_matches,
1139 1150 self.magic_matches,
1140 1151 self.dict_key_matches,
1141 1152 ]
1142 1153 else:
1143 1154 return [
1144 1155 *self.custom_matchers,
1145 1156 self.python_matches,
1146 1157 self.file_matches,
1147 1158 self.magic_matches,
1148 1159 self.python_func_kw_matches,
1149 1160 self.dict_key_matches,
1150 1161 ]
1151 1162
1152 1163 def all_completions(self, text) -> List[str]:
1153 1164 """
1154 1165 Wrapper around the completion methods for the benefit of emacs.
1155 1166 """
1156 1167 prefix = text.rpartition('.')[0]
1157 1168 with provisionalcompleter():
1158 1169 return ['.'.join([prefix, c.text]) if prefix and self.use_jedi else c.text
1159 1170 for c in self.completions(text, len(text))]
1160 1171
1161 1172 return self.complete(text)[1]
1162 1173
1163 1174 def _clean_glob(self, text):
1164 1175 return self.glob("%s*" % text)
1165 1176
1166 1177 def _clean_glob_win32(self,text):
1167 1178 return [f.replace("\\","/")
1168 1179 for f in self.glob("%s*" % text)]
1169 1180
1170 1181 def file_matches(self, text):
1171 1182 """Match filenames, expanding ~USER type strings.
1172 1183
1173 1184 Most of the seemingly convoluted logic in this completer is an
1174 1185 attempt to handle filenames with spaces in them. And yet it's not
1175 1186 quite perfect, because Python's readline doesn't expose all of the
1176 1187 GNU readline details needed for this to be done correctly.
1177 1188
1178 1189 For a filename with a space in it, the printed completions will be
1179 1190 only the parts after what's already been typed (instead of the
1180 1191 full completions, as is normally done). I don't think with the
1181 1192 current (as of Python 2.3) Python readline it's possible to do
1182 1193 better."""
1183 1194
1184 1195 # chars that require escaping with backslash - i.e. chars
1185 1196 # that readline treats incorrectly as delimiters, but we
1186 1197 # don't want to treat as delimiters in filename matching
1187 1198 # when escaped with backslash
1188 1199 if text.startswith('!'):
1189 1200 text = text[1:]
1190 1201 text_prefix = u'!'
1191 1202 else:
1192 1203 text_prefix = u''
1193 1204
1194 1205 text_until_cursor = self.text_until_cursor
1195 1206 # track strings with open quotes
1196 1207 open_quotes = has_open_quotes(text_until_cursor)
1197 1208
1198 1209 if '(' in text_until_cursor or '[' in text_until_cursor:
1199 1210 lsplit = text
1200 1211 else:
1201 1212 try:
1202 1213 # arg_split ~ shlex.split, but with unicode bugs fixed by us
1203 1214 lsplit = arg_split(text_until_cursor)[-1]
1204 1215 except ValueError:
1205 1216 # typically an unmatched ", or backslash without escaped char.
1206 1217 if open_quotes:
1207 1218 lsplit = text_until_cursor.split(open_quotes)[-1]
1208 1219 else:
1209 1220 return []
1210 1221 except IndexError:
1211 1222 # tab pressed on empty line
1212 1223 lsplit = ""
1213 1224
1214 1225 if not open_quotes and lsplit != protect_filename(lsplit):
1215 1226 # if protectables are found, do matching on the whole escaped name
1216 1227 has_protectables = True
1217 1228 text0,text = text,lsplit
1218 1229 else:
1219 1230 has_protectables = False
1220 1231 text = os.path.expanduser(text)
1221 1232
1222 1233 if text == "":
1223 1234 return [text_prefix + protect_filename(f) for f in self.glob("*")]
1224 1235
1225 1236 # Compute the matches from the filesystem
1226 1237 if sys.platform == 'win32':
1227 1238 m0 = self.clean_glob(text)
1228 1239 else:
1229 1240 m0 = self.clean_glob(text.replace('\\', ''))
1230 1241
1231 1242 if has_protectables:
1232 1243 # If we had protectables, we need to revert our changes to the
1233 1244 # beginning of filename so that we don't double-write the part
1234 1245 # of the filename we have so far
1235 1246 len_lsplit = len(lsplit)
1236 1247 matches = [text_prefix + text0 +
1237 1248 protect_filename(f[len_lsplit:]) for f in m0]
1238 1249 else:
1239 1250 if open_quotes:
1240 1251 # if we have a string with an open quote, we don't need to
1241 1252 # protect the names beyond the quote (and we _shouldn't_, as
1242 1253 # it would cause bugs when the filesystem call is made).
1243 1254 matches = m0 if sys.platform == "win32" else\
1244 1255 [protect_filename(f, open_quotes) for f in m0]
1245 1256 else:
1246 1257 matches = [text_prefix +
1247 1258 protect_filename(f) for f in m0]
1248 1259
1249 1260 # Mark directories in input list by appending '/' to their names.
1250 1261 return [x+'/' if os.path.isdir(x) else x for x in matches]
1251 1262
1252 1263 def magic_matches(self, text):
1253 1264 """Match magics"""
1254 1265 # Get all shell magics now rather than statically, so magics loaded at
1255 1266 # runtime show up too.
1256 1267 lsm = self.shell.magics_manager.lsmagic()
1257 1268 line_magics = lsm['line']
1258 1269 cell_magics = lsm['cell']
1259 1270 pre = self.magic_escape
1260 1271 pre2 = pre+pre
1261 1272
1262 1273 explicit_magic = text.startswith(pre)
1263 1274
1264 1275 # Completion logic:
1265 1276 # - user gives %%: only do cell magics
1266 1277 # - user gives %: do both line and cell magics
1267 1278 # - no prefix: do both
1268 1279 # In other words, line magics are skipped if the user gives %% explicitly
1269 1280 #
1270 1281 # We also exclude magics that match any currently visible names:
1271 1282 # https://github.com/ipython/ipython/issues/4877, unless the user has
1272 1283 # typed a %:
1273 1284 # https://github.com/ipython/ipython/issues/10754
1274 1285 bare_text = text.lstrip(pre)
1275 1286 global_matches = self.global_matches(bare_text)
1276 1287 if not explicit_magic:
1277 1288 def matches(magic):
1278 1289 """
1279 1290 Filter magics, in particular remove magics that match
1280 1291 a name present in global namespace.
1281 1292 """
1282 1293 return ( magic.startswith(bare_text) and
1283 1294 magic not in global_matches )
1284 1295 else:
1285 1296 def matches(magic):
1286 1297 return magic.startswith(bare_text)
1287 1298
1288 1299 comp = [ pre2+m for m in cell_magics if matches(m)]
1289 1300 if not text.startswith(pre2):
1290 1301 comp += [ pre+m for m in line_magics if matches(m)]
1291 1302
1292 1303 return comp
1293 1304
1294 1305 def magic_config_matches(self, text:str) -> List[str]:
1295 1306 """ Match class names and attributes for %config magic """
1296 1307 texts = text.strip().split()
1297 1308
1298 1309 if len(texts) > 0 and (texts[0] == 'config' or texts[0] == '%config'):
1299 1310 # get all configuration classes
1300 1311 classes = sorted(set([ c for c in self.shell.configurables
1301 1312 if c.__class__.class_traits(config=True)
1302 1313 ]), key=lambda x: x.__class__.__name__)
1303 1314 classnames = [ c.__class__.__name__ for c in classes ]
1304 1315
1305 1316 # return all classnames if config or %config is given
1306 1317 if len(texts) == 1:
1307 1318 return classnames
1308 1319
1309 1320 # match classname
1310 1321 classname_texts = texts[1].split('.')
1311 1322 classname = classname_texts[0]
1312 1323 classname_matches = [ c for c in classnames
1313 1324 if c.startswith(classname) ]
1314 1325
1315 1326 # return matched classes or the matched class with attributes
1316 1327 if texts[1].find('.') < 0:
1317 1328 return classname_matches
1318 1329 elif len(classname_matches) == 1 and \
1319 1330 classname_matches[0] == classname:
1320 1331 cls = classes[classnames.index(classname)].__class__
1321 1332 help = cls.class_get_help()
1322 1333 # strip leading '--' from cl-args:
1323 1334 help = re.sub(re.compile(r'^--', re.MULTILINE), '', help)
1324 1335 return [ attr.split('=')[0]
1325 1336 for attr in help.strip().splitlines()
1326 1337 if attr.startswith(texts[1]) ]
1327 1338 return []
1328 1339
1329 1340 def magic_color_matches(self, text:str) -> List[str] :
1330 1341 """ Match color schemes for %colors magic"""
1331 1342 texts = text.split()
1332 1343 if text.endswith(' '):
1333 1344 # .split() strips off the trailing whitespace. Add '' back
1334 1345 # so that: '%colors ' -> ['%colors', '']
1335 1346 texts.append('')
1336 1347
1337 1348 if len(texts) == 2 and (texts[0] == 'colors' or texts[0] == '%colors'):
1338 1349 prefix = texts[1]
1339 1350 return [ color for color in InspectColors.keys()
1340 1351 if color.startswith(prefix) ]
1341 1352 return []
1342 1353
1343 1354 def _jedi_matches(self, cursor_column:int, cursor_line:int, text:str):
1344 1355 """
1345 1356
1346 1357 Return a list of :any:`jedi.api.Completions` object from a ``text`` and
1347 1358 cursor position.
1348 1359
1349 1360 Parameters
1350 1361 ----------
1351 1362 cursor_column : int
1352 1363 column position of the cursor in ``text``, 0-indexed.
1353 1364 cursor_line : int
1354 1365 line position of the cursor in ``text``, 0-indexed
1355 1366 text : str
1356 1367 text to complete
1357 1368
1358 1369 Debugging
1359 1370 ---------
1360 1371
1361 1372 If ``IPCompleter.debug`` is ``True`` may return a :any:`_FakeJediCompletion`
1362 1373 object containing a string with the Jedi debug information attached.
1363 1374 """
1364 1375 namespaces = [self.namespace]
1365 1376 if self.global_namespace is not None:
1366 1377 namespaces.append(self.global_namespace)
1367 1378
1368 1379 completion_filter = lambda x:x
1369 1380 offset = cursor_to_position(text, cursor_line, cursor_column)
1370 1381 # filter output if we are completing for object members
1371 1382 if offset:
1372 1383 pre = text[offset-1]
1373 1384 if pre == '.':
1374 1385 if self.omit__names == 2:
1375 1386 completion_filter = lambda c:not c.name.startswith('_')
1376 1387 elif self.omit__names == 1:
1377 1388 completion_filter = lambda c:not (c.name.startswith('__') and c.name.endswith('__'))
1378 1389 elif self.omit__names == 0:
1379 1390 completion_filter = lambda x:x
1380 1391 else:
1381 1392 raise ValueError("Don't understand self.omit__names == {}".format(self.omit__names))
1382 1393
1383 1394 interpreter = jedi.Interpreter(text[:offset], namespaces)
1384 1395 try_jedi = True
1385 1396
1386 1397 try:
1387 1398 # find the first token in the current tree -- if it is a ' or " then we are in a string
1388 1399 completing_string = False
1389 1400 try:
1390 1401 first_child = next(c for c in interpreter._get_module().tree_node.children if hasattr(c, 'value'))
1391 1402 except StopIteration:
1392 1403 pass
1393 1404 else:
1394 1405 # note the value may be ', ", or it may also be ''' or """, or
1395 1406 # in some cases, """what/you/typed..., but all of these are
1396 1407 # strings.
1397 1408 completing_string = len(first_child.value) > 0 and first_child.value[0] in {"'", '"'}
1398 1409
1399 1410 # if we are in a string jedi is likely not the right candidate for
1400 1411 # now. Skip it.
1401 1412 try_jedi = not completing_string
1402 1413 except Exception as e:
1403 1414 # many of things can go wrong, we are using private API just don't crash.
1404 1415 if self.debug:
1405 1416 print("Error detecting if completing a non-finished string :", e, '|')
1406 1417
1407 1418 if not try_jedi:
1408 1419 return []
1409 1420 try:
1410 1421 return filter(completion_filter, interpreter.complete(column=cursor_column, line=cursor_line + 1))
1411 1422 except Exception as e:
1412 1423 if self.debug:
1413 1424 return [_FakeJediCompletion('Oops Jedi has crashed, please report a bug with the following:\n"""\n%s\ns"""' % (e))]
1414 1425 else:
1415 1426 return []
1416 1427
1417 1428 def python_matches(self, text):
1418 1429 """Match attributes or global python names"""
1419 1430 if "." in text:
1420 1431 try:
1421 1432 matches = self.attr_matches(text)
1422 1433 if text.endswith('.') and self.omit__names:
1423 1434 if self.omit__names == 1:
1424 1435 # true if txt is _not_ a __ name, false otherwise:
1425 1436 no__name = (lambda txt:
1426 1437 re.match(r'.*\.__.*?__',txt) is None)
1427 1438 else:
1428 1439 # true if txt is _not_ a _ name, false otherwise:
1429 1440 no__name = (lambda txt:
1430 1441 re.match(r'\._.*?',txt[txt.rindex('.'):]) is None)
1431 1442 matches = filter(no__name, matches)
1432 1443 except NameError:
1433 1444 # catches <undefined attributes>.<tab>
1434 1445 matches = []
1435 1446 else:
1436 1447 matches = self.global_matches(text)
1437 1448 return matches
1438 1449
1439 1450 def _default_arguments_from_docstring(self, doc):
1440 1451 """Parse the first line of docstring for call signature.
1441 1452
1442 1453 Docstring should be of the form 'min(iterable[, key=func])\n'.
1443 1454 It can also parse cython docstring of the form
1444 1455 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
1445 1456 """
1446 1457 if doc is None:
1447 1458 return []
1448 1459
1449 1460 #care only the firstline
1450 1461 line = doc.lstrip().splitlines()[0]
1451 1462
1452 1463 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
1453 1464 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
1454 1465 sig = self.docstring_sig_re.search(line)
1455 1466 if sig is None:
1456 1467 return []
1457 1468 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
1458 1469 sig = sig.groups()[0].split(',')
1459 1470 ret = []
1460 1471 for s in sig:
1461 1472 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
1462 1473 ret += self.docstring_kwd_re.findall(s)
1463 1474 return ret
1464 1475
1465 1476 def _default_arguments(self, obj):
1466 1477 """Return the list of default arguments of obj if it is callable,
1467 1478 or empty list otherwise."""
1468 1479 call_obj = obj
1469 1480 ret = []
1470 1481 if inspect.isbuiltin(obj):
1471 1482 pass
1472 1483 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
1473 1484 if inspect.isclass(obj):
1474 1485 #for cython embedsignature=True the constructor docstring
1475 1486 #belongs to the object itself not __init__
1476 1487 ret += self._default_arguments_from_docstring(
1477 1488 getattr(obj, '__doc__', ''))
1478 1489 # for classes, check for __init__,__new__
1479 1490 call_obj = (getattr(obj, '__init__', None) or
1480 1491 getattr(obj, '__new__', None))
1481 1492 # for all others, check if they are __call__able
1482 1493 elif hasattr(obj, '__call__'):
1483 1494 call_obj = obj.__call__
1484 1495 ret += self._default_arguments_from_docstring(
1485 1496 getattr(call_obj, '__doc__', ''))
1486 1497
1487 1498 _keeps = (inspect.Parameter.KEYWORD_ONLY,
1488 1499 inspect.Parameter.POSITIONAL_OR_KEYWORD)
1489 1500
1490 1501 try:
1491 1502 sig = inspect.signature(call_obj)
1492 1503 ret.extend(k for k, v in sig.parameters.items() if
1493 1504 v.kind in _keeps)
1494 1505 except ValueError:
1495 1506 pass
1496 1507
1497 1508 return list(set(ret))
1498 1509
1499 1510 def python_func_kw_matches(self,text):
1500 1511 """Match named parameters (kwargs) of the last open function"""
1501 1512
1502 1513 if "." in text: # a parameter cannot be dotted
1503 1514 return []
1504 1515 try: regexp = self.__funcParamsRegex
1505 1516 except AttributeError:
1506 1517 regexp = self.__funcParamsRegex = re.compile(r'''
1507 1518 '.*?(?<!\\)' | # single quoted strings or
1508 1519 ".*?(?<!\\)" | # double quoted strings or
1509 1520 \w+ | # identifier
1510 1521 \S # other characters
1511 1522 ''', re.VERBOSE | re.DOTALL)
1512 1523 # 1. find the nearest identifier that comes before an unclosed
1513 1524 # parenthesis before the cursor
1514 1525 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
1515 1526 tokens = regexp.findall(self.text_until_cursor)
1516 1527 iterTokens = reversed(tokens); openPar = 0
1517 1528
1518 1529 for token in iterTokens:
1519 1530 if token == ')':
1520 1531 openPar -= 1
1521 1532 elif token == '(':
1522 1533 openPar += 1
1523 1534 if openPar > 0:
1524 1535 # found the last unclosed parenthesis
1525 1536 break
1526 1537 else:
1527 1538 return []
1528 1539 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
1529 1540 ids = []
1530 1541 isId = re.compile(r'\w+$').match
1531 1542
1532 1543 while True:
1533 1544 try:
1534 1545 ids.append(next(iterTokens))
1535 1546 if not isId(ids[-1]):
1536 1547 ids.pop(); break
1537 1548 if not next(iterTokens) == '.':
1538 1549 break
1539 1550 except StopIteration:
1540 1551 break
1541 1552
1542 1553 # Find all named arguments already assigned to, as to avoid suggesting
1543 1554 # them again
1544 1555 usedNamedArgs = set()
1545 1556 par_level = -1
1546 1557 for token, next_token in zip(tokens, tokens[1:]):
1547 1558 if token == '(':
1548 1559 par_level += 1
1549 1560 elif token == ')':
1550 1561 par_level -= 1
1551 1562
1552 1563 if par_level != 0:
1553 1564 continue
1554 1565
1555 1566 if next_token != '=':
1556 1567 continue
1557 1568
1558 1569 usedNamedArgs.add(token)
1559 1570
1560 1571 argMatches = []
1561 1572 try:
1562 1573 callableObj = '.'.join(ids[::-1])
1563 1574 namedArgs = self._default_arguments(eval(callableObj,
1564 1575 self.namespace))
1565 1576
1566 1577 # Remove used named arguments from the list, no need to show twice
1567 1578 for namedArg in set(namedArgs) - usedNamedArgs:
1568 1579 if namedArg.startswith(text):
1569 1580 argMatches.append(u"%s=" %namedArg)
1570 1581 except:
1571 1582 pass
1572 1583
1573 1584 return argMatches
1574 1585
1575 1586 def dict_key_matches(self, text):
1576 1587 "Match string keys in a dictionary, after e.g. 'foo[' "
1577 1588 def get_keys(obj):
1578 1589 # Objects can define their own completions by defining an
1579 1590 # _ipy_key_completions_() method.
1580 1591 method = get_real_method(obj, '_ipython_key_completions_')
1581 1592 if method is not None:
1582 1593 return method()
1583 1594
1584 1595 # Special case some common in-memory dict-like types
1585 1596 if isinstance(obj, dict) or\
1586 1597 _safe_isinstance(obj, 'pandas', 'DataFrame'):
1587 1598 try:
1588 1599 return list(obj.keys())
1589 1600 except Exception:
1590 1601 return []
1591 1602 elif _safe_isinstance(obj, 'numpy', 'ndarray') or\
1592 1603 _safe_isinstance(obj, 'numpy', 'void'):
1593 1604 return obj.dtype.names or []
1594 1605 return []
1595 1606
1596 1607 try:
1597 1608 regexps = self.__dict_key_regexps
1598 1609 except AttributeError:
1599 1610 dict_key_re_fmt = r'''(?x)
1600 1611 ( # match dict-referring expression wrt greedy setting
1601 1612 %s
1602 1613 )
1603 1614 \[ # open bracket
1604 1615 \s* # and optional whitespace
1605 1616 ([uUbB]? # string prefix (r not handled)
1606 1617 (?: # unclosed string
1607 1618 '(?:[^']|(?<!\\)\\')*
1608 1619 |
1609 1620 "(?:[^"]|(?<!\\)\\")*
1610 1621 )
1611 1622 )?
1612 1623 $
1613 1624 '''
1614 1625 regexps = self.__dict_key_regexps = {
1615 1626 False: re.compile(dict_key_re_fmt % r'''
1616 1627 # identifiers separated by .
1617 1628 (?!\d)\w+
1618 1629 (?:\.(?!\d)\w+)*
1619 1630 '''),
1620 1631 True: re.compile(dict_key_re_fmt % '''
1621 1632 .+
1622 1633 ''')
1623 1634 }
1624 1635
1625 1636 match = regexps[self.greedy].search(self.text_until_cursor)
1626 1637 if match is None:
1627 1638 return []
1628 1639
1629 1640 expr, prefix = match.groups()
1630 1641 try:
1631 1642 obj = eval(expr, self.namespace)
1632 1643 except Exception:
1633 1644 try:
1634 1645 obj = eval(expr, self.global_namespace)
1635 1646 except Exception:
1636 1647 return []
1637 1648
1638 1649 keys = get_keys(obj)
1639 1650 if not keys:
1640 1651 return keys
1641 1652 closing_quote, token_offset, matches = match_dict_keys(keys, prefix, self.splitter.delims)
1642 1653 if not matches:
1643 1654 return matches
1644 1655
1645 1656 # get the cursor position of
1646 1657 # - the text being completed
1647 1658 # - the start of the key text
1648 1659 # - the start of the completion
1649 1660 text_start = len(self.text_until_cursor) - len(text)
1650 1661 if prefix:
1651 1662 key_start = match.start(2)
1652 1663 completion_start = key_start + token_offset
1653 1664 else:
1654 1665 key_start = completion_start = match.end()
1655 1666
1656 1667 # grab the leading prefix, to make sure all completions start with `text`
1657 1668 if text_start > key_start:
1658 1669 leading = ''
1659 1670 else:
1660 1671 leading = text[text_start:completion_start]
1661 1672
1662 1673 # the index of the `[` character
1663 1674 bracket_idx = match.end(1)
1664 1675
1665 1676 # append closing quote and bracket as appropriate
1666 1677 # this is *not* appropriate if the opening quote or bracket is outside
1667 1678 # the text given to this method
1668 1679 suf = ''
1669 1680 continuation = self.line_buffer[len(self.text_until_cursor):]
1670 1681 if key_start > text_start and closing_quote:
1671 1682 # quotes were opened inside text, maybe close them
1672 1683 if continuation.startswith(closing_quote):
1673 1684 continuation = continuation[len(closing_quote):]
1674 1685 else:
1675 1686 suf += closing_quote
1676 1687 if bracket_idx > text_start:
1677 1688 # brackets were opened inside text, maybe close them
1678 1689 if not continuation.startswith(']'):
1679 1690 suf += ']'
1680 1691
1681 1692 return [leading + k + suf for k in matches]
1682 1693
1683 1694 def unicode_name_matches(self, text):
1684 1695 u"""Match Latex-like syntax for unicode characters base
1685 1696 on the name of the character.
1686 1697
1687 1698 This does ``\\GREEK SMALL LETTER ETA`` -> ``Ξ·``
1688 1699
1689 1700 Works only on valid python 3 identifier, or on combining characters that
1690 1701 will combine to form a valid identifier.
1691 1702
1692 1703 Used on Python 3 only.
1693 1704 """
1694 1705 slashpos = text.rfind('\\')
1695 1706 if slashpos > -1:
1696 1707 s = text[slashpos+1:]
1697 1708 try :
1698 1709 unic = unicodedata.lookup(s)
1699 1710 # allow combining chars
1700 1711 if ('a'+unic).isidentifier():
1701 1712 return '\\'+s,[unic]
1702 1713 except KeyError:
1703 1714 pass
1704 1715 return u'', []
1705 1716
1706 1717
1707 1718 def latex_matches(self, text):
1708 1719 u"""Match Latex syntax for unicode characters.
1709 1720
1710 1721 This does both ``\\alp`` -> ``\\alpha`` and ``\\alpha`` -> ``Ξ±``
1711 1722 """
1712 1723 slashpos = text.rfind('\\')
1713 1724 if slashpos > -1:
1714 1725 s = text[slashpos:]
1715 1726 if s in latex_symbols:
1716 1727 # Try to complete a full latex symbol to unicode
1717 1728 # \\alpha -> Ξ±
1718 1729 return s, [latex_symbols[s]]
1719 1730 else:
1720 1731 # If a user has partially typed a latex symbol, give them
1721 1732 # a full list of options \al -> [\aleph, \alpha]
1722 1733 matches = [k for k in latex_symbols if k.startswith(s)]
1723 1734 if matches:
1724 1735 return s, matches
1725 1736 return u'', []
1726 1737
1727 1738 def dispatch_custom_completer(self, text):
1728 1739 if not self.custom_completers:
1729 1740 return
1730 1741
1731 1742 line = self.line_buffer
1732 1743 if not line.strip():
1733 1744 return None
1734 1745
1735 1746 # Create a little structure to pass all the relevant information about
1736 1747 # the current completion to any custom completer.
1737 1748 event = SimpleNamespace()
1738 1749 event.line = line
1739 1750 event.symbol = text
1740 1751 cmd = line.split(None,1)[0]
1741 1752 event.command = cmd
1742 1753 event.text_until_cursor = self.text_until_cursor
1743 1754
1744 1755 # for foo etc, try also to find completer for %foo
1745 1756 if not cmd.startswith(self.magic_escape):
1746 1757 try_magic = self.custom_completers.s_matches(
1747 1758 self.magic_escape + cmd)
1748 1759 else:
1749 1760 try_magic = []
1750 1761
1751 1762 for c in itertools.chain(self.custom_completers.s_matches(cmd),
1752 1763 try_magic,
1753 1764 self.custom_completers.flat_matches(self.text_until_cursor)):
1754 1765 try:
1755 1766 res = c(event)
1756 1767 if res:
1757 1768 # first, try case sensitive match
1758 1769 withcase = [r for r in res if r.startswith(text)]
1759 1770 if withcase:
1760 1771 return withcase
1761 1772 # if none, then case insensitive ones are ok too
1762 1773 text_low = text.lower()
1763 1774 return [r for r in res if r.lower().startswith(text_low)]
1764 1775 except TryNext:
1765 1776 pass
1766 1777 except KeyboardInterrupt:
1767 1778 """
1768 1779 If custom completer take too long,
1769 1780 let keyboard interrupt abort and return nothing.
1770 1781 """
1771 1782 break
1772 1783
1773 1784 return None
1774 1785
1775 1786 def completions(self, text: str, offset: int)->Iterator[Completion]:
1776 1787 """
1777 1788 Returns an iterator over the possible completions
1778 1789
1779 1790 .. warning:: Unstable
1780 1791
1781 1792 This function is unstable, API may change without warning.
1782 1793 It will also raise unless use in proper context manager.
1783 1794
1784 1795 Parameters
1785 1796 ----------
1786 1797
1787 1798 text:str
1788 1799 Full text of the current input, multi line string.
1789 1800 offset:int
1790 1801 Integer representing the position of the cursor in ``text``. Offset
1791 1802 is 0-based indexed.
1792 1803
1793 1804 Yields
1794 1805 ------
1795 1806 :any:`Completion` object
1796 1807
1797 1808
1798 1809 The cursor on a text can either be seen as being "in between"
1799 1810 characters or "On" a character depending on the interface visible to
1800 1811 the user. For consistency the cursor being on "in between" characters X
1801 1812 and Y is equivalent to the cursor being "on" character Y, that is to say
1802 1813 the character the cursor is on is considered as being after the cursor.
1803 1814
1804 1815 Combining characters may span more that one position in the
1805 1816 text.
1806 1817
1807 1818
1808 1819 .. note::
1809 1820
1810 1821 If ``IPCompleter.debug`` is :any:`True` will yield a ``--jedi/ipython--``
1811 1822 fake Completion token to distinguish completion returned by Jedi
1812 1823 and usual IPython completion.
1813 1824
1814 1825 .. note::
1815 1826
1816 1827 Completions are not completely deduplicated yet. If identical
1817 1828 completions are coming from different sources this function does not
1818 1829 ensure that each completion object will only be present once.
1819 1830 """
1820 1831 warnings.warn("_complete is a provisional API (as of IPython 6.0). "
1821 1832 "It may change without warnings. "
1822 1833 "Use in corresponding context manager.",
1823 1834 category=ProvisionalCompleterWarning, stacklevel=2)
1824 1835
1825 1836 seen = set()
1826 1837 try:
1838 if self.profile_completions:
1839 import cProfile
1840 profiler = cProfile.Profile()
1841 profiler.enable()
1842 else:
1843 profiler = None
1844
1827 1845 for c in self._completions(text, offset, _timeout=self.jedi_compute_type_timeout/1000):
1828 1846 if c and (c in seen):
1829 1847 continue
1830 1848 yield c
1831 1849 seen.add(c)
1832 1850 except KeyboardInterrupt:
1833 1851 """if completions take too long and users send keyboard interrupt,
1834 1852 do not crash and return ASAP. """
1835 1853 pass
1854 finally:
1855 if profiler is not None:
1856 profiler.disable()
1857 ensure_dir_exists(self.profiler_output_dir)
1858 output_path = os.path.join(self.profiler_output_dir, str(uuid.uuid4()))
1859 print("Writing profiler output to", output_path)
1860 profiler.dump_stats(output_path)
1836 1861
1837 1862 def _completions(self, full_text: str, offset: int, *, _timeout)->Iterator[Completion]:
1838 1863 """
1839 1864 Core completion module.Same signature as :any:`completions`, with the
1840 1865 extra `timeout` parameter (in seconds).
1841 1866
1842 1867
1843 1868 Computing jedi's completion ``.type`` can be quite expensive (it is a
1844 1869 lazy property) and can require some warm-up, more warm up than just
1845 1870 computing the ``name`` of a completion. The warm-up can be :
1846 1871
1847 1872 - Long warm-up the first time a module is encountered after
1848 1873 install/update: actually build parse/inference tree.
1849 1874
1850 1875 - first time the module is encountered in a session: load tree from
1851 1876 disk.
1852 1877
1853 1878 We don't want to block completions for tens of seconds so we give the
1854 1879 completer a "budget" of ``_timeout`` seconds per invocation to compute
1855 1880 completions types, the completions that have not yet been computed will
1856 1881 be marked as "unknown" an will have a chance to be computed next round
1857 1882 are things get cached.
1858 1883
1859 1884 Keep in mind that Jedi is not the only thing treating the completion so
1860 1885 keep the timeout short-ish as if we take more than 0.3 second we still
1861 1886 have lots of processing to do.
1862 1887
1863 1888 """
1864 1889 deadline = time.monotonic() + _timeout
1865 1890
1866 1891
1867 1892 before = full_text[:offset]
1868 1893 cursor_line, cursor_column = position_to_cursor(full_text, offset)
1869 1894
1870 1895 matched_text, matches, matches_origin, jedi_matches = self._complete(
1871 1896 full_text=full_text, cursor_line=cursor_line, cursor_pos=cursor_column)
1872 1897
1873 1898 iter_jm = iter(jedi_matches)
1874 1899 if _timeout:
1875 1900 for jm in iter_jm:
1876 1901 try:
1877 1902 type_ = jm.type
1878 1903 except Exception:
1879 1904 if self.debug:
1880 1905 print("Error in Jedi getting type of ", jm)
1881 1906 type_ = None
1882 1907 delta = len(jm.name_with_symbols) - len(jm.complete)
1883 1908 if type_ == 'function':
1884 1909 signature = _make_signature(jm)
1885 1910 else:
1886 1911 signature = ''
1887 1912 yield Completion(start=offset - delta,
1888 1913 end=offset,
1889 1914 text=jm.name_with_symbols,
1890 1915 type=type_,
1891 1916 signature=signature,
1892 1917 _origin='jedi')
1893 1918
1894 1919 if time.monotonic() > deadline:
1895 1920 break
1896 1921
1897 1922 for jm in iter_jm:
1898 1923 delta = len(jm.name_with_symbols) - len(jm.complete)
1899 1924 yield Completion(start=offset - delta,
1900 1925 end=offset,
1901 1926 text=jm.name_with_symbols,
1902 1927 type='<unknown>', # don't compute type for speed
1903 1928 _origin='jedi',
1904 1929 signature='')
1905 1930
1906 1931
1907 1932 start_offset = before.rfind(matched_text)
1908 1933
1909 1934 # TODO:
1910 1935 # Suppress this, right now just for debug.
1911 1936 if jedi_matches and matches and self.debug:
1912 1937 yield Completion(start=start_offset, end=offset, text='--jedi/ipython--',
1913 1938 _origin='debug', type='none', signature='')
1914 1939
1915 1940 # I'm unsure if this is always true, so let's assert and see if it
1916 1941 # crash
1917 1942 assert before.endswith(matched_text)
1918 1943 for m, t in zip(matches, matches_origin):
1919 1944 yield Completion(start=start_offset, end=offset, text=m, _origin=t, signature='', type='<unknown>')
1920 1945
1921 1946
1922 1947 def complete(self, text=None, line_buffer=None, cursor_pos=None):
1923 1948 """Find completions for the given text and line context.
1924 1949
1925 1950 Note that both the text and the line_buffer are optional, but at least
1926 1951 one of them must be given.
1927 1952
1928 1953 Parameters
1929 1954 ----------
1930 1955 text : string, optional
1931 1956 Text to perform the completion on. If not given, the line buffer
1932 1957 is split using the instance's CompletionSplitter object.
1933 1958
1934 1959 line_buffer : string, optional
1935 1960 If not given, the completer attempts to obtain the current line
1936 1961 buffer via readline. This keyword allows clients which are
1937 1962 requesting for text completions in non-readline contexts to inform
1938 1963 the completer of the entire text.
1939 1964
1940 1965 cursor_pos : int, optional
1941 1966 Index of the cursor in the full line buffer. Should be provided by
1942 1967 remote frontends where kernel has no access to frontend state.
1943 1968
1944 1969 Returns
1945 1970 -------
1946 1971 text : str
1947 1972 Text that was actually used in the completion.
1948 1973
1949 1974 matches : list
1950 1975 A list of completion matches.
1951 1976
1952 1977
1953 1978 .. note::
1954 1979
1955 1980 This API is likely to be deprecated and replaced by
1956 1981 :any:`IPCompleter.completions` in the future.
1957 1982
1958 1983
1959 1984 """
1960 1985 warnings.warn('`Completer.complete` is pending deprecation since '
1961 1986 'IPython 6.0 and will be replaced by `Completer.completions`.',
1962 1987 PendingDeprecationWarning)
1963 1988 # potential todo, FOLD the 3rd throw away argument of _complete
1964 1989 # into the first 2 one.
1965 1990 return self._complete(line_buffer=line_buffer, cursor_pos=cursor_pos, text=text, cursor_line=0)[:2]
1966 1991
1967 1992 def _complete(self, *, cursor_line, cursor_pos, line_buffer=None, text=None,
1968 1993 full_text=None) -> Tuple[str, List[str], List[str], Iterable[_FakeJediCompletion]]:
1969 1994 """
1970 1995
1971 1996 Like complete but can also returns raw jedi completions as well as the
1972 1997 origin of the completion text. This could (and should) be made much
1973 1998 cleaner but that will be simpler once we drop the old (and stateful)
1974 1999 :any:`complete` API.
1975 2000
1976 2001
1977 2002 With current provisional API, cursor_pos act both (depending on the
1978 2003 caller) as the offset in the ``text`` or ``line_buffer``, or as the
1979 2004 ``column`` when passing multiline strings this could/should be renamed
1980 2005 but would add extra noise.
1981 2006 """
1982 2007
1983 2008 # if the cursor position isn't given, the only sane assumption we can
1984 2009 # make is that it's at the end of the line (the common case)
1985 2010 if cursor_pos is None:
1986 2011 cursor_pos = len(line_buffer) if text is None else len(text)
1987 2012
1988 2013 if self.use_main_ns:
1989 2014 self.namespace = __main__.__dict__
1990 2015
1991 2016 # if text is either None or an empty string, rely on the line buffer
1992 2017 if (not line_buffer) and full_text:
1993 2018 line_buffer = full_text.split('\n')[cursor_line]
1994 2019 if not text:
1995 2020 text = self.splitter.split_line(line_buffer, cursor_pos)
1996 2021
1997 2022 if self.backslash_combining_completions:
1998 2023 # allow deactivation of these on windows.
1999 2024 base_text = text if not line_buffer else line_buffer[:cursor_pos]
2000 2025 latex_text, latex_matches = self.latex_matches(base_text)
2001 2026 if latex_matches:
2002 2027 return latex_text, latex_matches, ['latex_matches']*len(latex_matches), ()
2003 2028 name_text = ''
2004 2029 name_matches = []
2005 2030 # need to add self.fwd_unicode_match() function here when done
2006 2031 for meth in (self.unicode_name_matches, back_latex_name_matches, back_unicode_name_matches, self.fwd_unicode_match):
2007 2032 name_text, name_matches = meth(base_text)
2008 2033 if name_text:
2009 2034 return name_text, name_matches[:MATCHES_LIMIT], \
2010 2035 [meth.__qualname__]*min(len(name_matches), MATCHES_LIMIT), ()
2011 2036
2012 2037
2013 2038 # If no line buffer is given, assume the input text is all there was
2014 2039 if line_buffer is None:
2015 2040 line_buffer = text
2016 2041
2017 2042 self.line_buffer = line_buffer
2018 2043 self.text_until_cursor = self.line_buffer[:cursor_pos]
2019 2044
2020 2045 # Do magic arg matches
2021 2046 for matcher in self.magic_arg_matchers:
2022 2047 matches = list(matcher(line_buffer))[:MATCHES_LIMIT]
2023 2048 if matches:
2024 2049 origins = [matcher.__qualname__] * len(matches)
2025 2050 return text, matches, origins, ()
2026 2051
2027 2052 # Start with a clean slate of completions
2028 2053 matches = []
2029 2054
2030 2055 # FIXME: we should extend our api to return a dict with completions for
2031 2056 # different types of objects. The rlcomplete() method could then
2032 2057 # simply collapse the dict into a list for readline, but we'd have
2033 2058 # richer completion semantics in other environments.
2034 2059 completions = ()
2035 2060 if self.use_jedi:
2036 2061 if not full_text:
2037 2062 full_text = line_buffer
2038 2063 completions = self._jedi_matches(
2039 2064 cursor_pos, cursor_line, full_text)
2040 2065
2041 2066 if self.merge_completions:
2042 2067 matches = []
2043 2068 for matcher in self.matchers:
2044 2069 try:
2045 2070 matches.extend([(m, matcher.__qualname__)
2046 2071 for m in matcher(text)])
2047 2072 except:
2048 2073 # Show the ugly traceback if the matcher causes an
2049 2074 # exception, but do NOT crash the kernel!
2050 2075 sys.excepthook(*sys.exc_info())
2051 2076 else:
2052 2077 for matcher in self.matchers:
2053 2078 matches = [(m, matcher.__qualname__)
2054 2079 for m in matcher(text)]
2055 2080 if matches:
2056 2081 break
2057 2082
2058 2083 seen = set()
2059 2084 filtered_matches = set()
2060 2085 for m in matches:
2061 2086 t, c = m
2062 2087 if t not in seen:
2063 2088 filtered_matches.add(m)
2064 2089 seen.add(t)
2065 2090
2066 2091 _filtered_matches = sorted(filtered_matches, key=lambda x: completions_sorting_key(x[0]))
2067 2092
2068 2093 custom_res = [(m, 'custom') for m in self.dispatch_custom_completer(text) or []]
2069 2094
2070 2095 _filtered_matches = custom_res or _filtered_matches
2071 2096
2072 2097 _filtered_matches = _filtered_matches[:MATCHES_LIMIT]
2073 2098 _matches = [m[0] for m in _filtered_matches]
2074 2099 origins = [m[1] for m in _filtered_matches]
2075 2100
2076 2101 self.matches = _matches
2077 2102
2078 2103 return text, _matches, origins, completions
2079 2104
2080 2105 def fwd_unicode_match(self, text:str) -> Tuple[str, list]:
2081 2106 if self._names is None:
2082 2107 self._names = []
2083 2108 for c in range(0,0x10FFFF + 1):
2084 2109 try:
2085 2110 self._names.append(unicodedata.name(chr(c)))
2086 2111 except ValueError:
2087 2112 pass
2088 2113
2089 2114 slashpos = text.rfind('\\')
2090 2115 # if text starts with slash
2091 2116 if slashpos > -1:
2092 2117 s = text[slashpos+1:]
2093 2118 candidates = [x for x in self._names if x.startswith(s)]
2094 2119 if candidates:
2095 2120 return s, candidates
2096 2121 else:
2097 2122 return '', ()
2098 2123
2099 2124 # if text does not start with slash
2100 2125 else:
2101 2126 return u'', ()
General Comments 0
You need to be logged in to leave comments. Login now