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