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