##// END OF EJS Templates
DOC: Use valid completion in docs for unicode completions....
Scott Sanderson -
Show More
@@ -1,2146 +1,2146 b''
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
129 from typing import Iterable, Iterator, List, Tuple
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[str], prefix: str, delims: str):
748 def match_dict_keys(keys: List[str], prefix: str, delims: 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 if not prefix:
769 if not prefix:
770 return None, 0, [repr(k) for k in keys
770 return None, 0, [repr(k) for k in keys
771 if isinstance(k, (str, bytes))]
771 if isinstance(k, (str, bytes))]
772 quote_match = re.search('["\']', prefix)
772 quote_match = re.search('["\']', prefix)
773 quote = quote_match.group()
773 quote = quote_match.group()
774 try:
774 try:
775 prefix_str = eval(prefix + quote, {})
775 prefix_str = eval(prefix + quote, {})
776 except Exception:
776 except Exception:
777 return None, 0, []
777 return None, 0, []
778
778
779 pattern = '[^' + ''.join('\\' + c for c in delims) + ']*$'
779 pattern = '[^' + ''.join('\\' + c for c in delims) + ']*$'
780 token_match = re.search(pattern, prefix, re.UNICODE)
780 token_match = re.search(pattern, prefix, re.UNICODE)
781 token_start = token_match.start()
781 token_start = token_match.start()
782 token_prefix = token_match.group()
782 token_prefix = token_match.group()
783
783
784 matched = []
784 matched = []
785 for key in keys:
785 for key in keys:
786 try:
786 try:
787 if not key.startswith(prefix_str):
787 if not key.startswith(prefix_str):
788 continue
788 continue
789 except (AttributeError, TypeError, UnicodeError):
789 except (AttributeError, TypeError, UnicodeError):
790 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
790 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
791 continue
791 continue
792
792
793 # reformat remainder of key to begin with prefix
793 # reformat remainder of key to begin with prefix
794 rem = key[len(prefix_str):]
794 rem = key[len(prefix_str):]
795 # force repr wrapped in '
795 # force repr wrapped in '
796 rem_repr = repr(rem + '"') if isinstance(rem, str) else repr(rem + b'"')
796 rem_repr = repr(rem + '"') if isinstance(rem, str) else repr(rem + b'"')
797 if rem_repr.startswith('u') and prefix[0] not in 'uU':
797 if rem_repr.startswith('u') and prefix[0] not in 'uU':
798 # Found key is unicode, but prefix is Py2 string.
798 # Found key is unicode, but prefix is Py2 string.
799 # Therefore attempt to interpret key as string.
799 # Therefore attempt to interpret key as string.
800 try:
800 try:
801 rem_repr = repr(rem.encode('ascii') + '"')
801 rem_repr = repr(rem.encode('ascii') + '"')
802 except UnicodeEncodeError:
802 except UnicodeEncodeError:
803 continue
803 continue
804
804
805 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
805 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
806 if quote == '"':
806 if quote == '"':
807 # The entered prefix is quoted with ",
807 # The entered prefix is quoted with ",
808 # but the match is quoted with '.
808 # but the match is quoted with '.
809 # A contained " hence needs escaping for comparison:
809 # A contained " hence needs escaping for comparison:
810 rem_repr = rem_repr.replace('"', '\\"')
810 rem_repr = rem_repr.replace('"', '\\"')
811
811
812 # then reinsert prefix from start of token
812 # then reinsert prefix from start of token
813 matched.append('%s%s' % (token_prefix, rem_repr))
813 matched.append('%s%s' % (token_prefix, rem_repr))
814 return quote, token_start, matched
814 return quote, token_start, matched
815
815
816
816
817 def cursor_to_position(text:str, line:int, column:int)->int:
817 def cursor_to_position(text:str, line:int, column:int)->int:
818 """
818 """
819
819
820 Convert the (line,column) position of the cursor in text to an offset in a
820 Convert the (line,column) position of the cursor in text to an offset in a
821 string.
821 string.
822
822
823 Parameters
823 Parameters
824 ----------
824 ----------
825
825
826 text : str
826 text : str
827 The text in which to calculate the cursor offset
827 The text in which to calculate the cursor offset
828 line : int
828 line : int
829 Line of the cursor; 0-indexed
829 Line of the cursor; 0-indexed
830 column : int
830 column : int
831 Column of the cursor 0-indexed
831 Column of the cursor 0-indexed
832
832
833 Return
833 Return
834 ------
834 ------
835 Position of the cursor in ``text``, 0-indexed.
835 Position of the cursor in ``text``, 0-indexed.
836
836
837 See Also
837 See Also
838 --------
838 --------
839 position_to_cursor: reciprocal of this function
839 position_to_cursor: reciprocal of this function
840
840
841 """
841 """
842 lines = text.split('\n')
842 lines = text.split('\n')
843 assert line <= len(lines), '{} <= {}'.format(str(line), str(len(lines)))
843 assert line <= len(lines), '{} <= {}'.format(str(line), str(len(lines)))
844
844
845 return sum(len(l) + 1 for l in lines[:line]) + column
845 return sum(len(l) + 1 for l in lines[:line]) + column
846
846
847 def position_to_cursor(text:str, offset:int)->Tuple[int, int]:
847 def position_to_cursor(text:str, offset:int)->Tuple[int, int]:
848 """
848 """
849 Convert the position of the cursor in text (0 indexed) to a line
849 Convert the position of the cursor in text (0 indexed) to a line
850 number(0-indexed) and a column number (0-indexed) pair
850 number(0-indexed) and a column number (0-indexed) pair
851
851
852 Position should be a valid position in ``text``.
852 Position should be a valid position in ``text``.
853
853
854 Parameters
854 Parameters
855 ----------
855 ----------
856
856
857 text : str
857 text : str
858 The text in which to calculate the cursor offset
858 The text in which to calculate the cursor offset
859 offset : int
859 offset : int
860 Position of the cursor in ``text``, 0-indexed.
860 Position of the cursor in ``text``, 0-indexed.
861
861
862 Return
862 Return
863 ------
863 ------
864 (line, column) : (int, int)
864 (line, column) : (int, int)
865 Line of the cursor; 0-indexed, column of the cursor 0-indexed
865 Line of the cursor; 0-indexed, column of the cursor 0-indexed
866
866
867
867
868 See Also
868 See Also
869 --------
869 --------
870 cursor_to_position : reciprocal of this function
870 cursor_to_position : reciprocal of this function
871
871
872
872
873 """
873 """
874
874
875 assert 0 <= offset <= len(text) , "0 <= %s <= %s" % (offset , len(text))
875 assert 0 <= offset <= len(text) , "0 <= %s <= %s" % (offset , len(text))
876
876
877 before = text[:offset]
877 before = text[:offset]
878 blines = before.split('\n') # ! splitnes trim trailing \n
878 blines = before.split('\n') # ! splitnes trim trailing \n
879 line = before.count('\n')
879 line = before.count('\n')
880 col = len(blines[-1])
880 col = len(blines[-1])
881 return line, col
881 return line, col
882
882
883
883
884 def _safe_isinstance(obj, module, class_name):
884 def _safe_isinstance(obj, module, class_name):
885 """Checks if obj is an instance of module.class_name if loaded
885 """Checks if obj is an instance of module.class_name if loaded
886 """
886 """
887 return (module in sys.modules and
887 return (module in sys.modules and
888 isinstance(obj, getattr(import_module(module), class_name)))
888 isinstance(obj, getattr(import_module(module), class_name)))
889
889
890
890
891 def back_unicode_name_matches(text):
891 def back_unicode_name_matches(text):
892 u"""Match unicode characters back to unicode name
892 u"""Match unicode characters back to unicode name
893
893
894 This does ``β˜ƒ`` -> ``\\snowman``
894 This does ``β˜ƒ`` -> ``\\snowman``
895
895
896 Note that snowman is not a valid python3 combining character but will be expanded.
896 Note that snowman is not a valid python3 combining character but will be expanded.
897 Though it will not recombine back to the snowman character by the completion machinery.
897 Though it will not recombine back to the snowman character by the completion machinery.
898
898
899 This will not either back-complete standard sequences like \\n, \\b ...
899 This will not either back-complete standard sequences like \\n, \\b ...
900
900
901 Used on Python 3 only.
901 Used on Python 3 only.
902 """
902 """
903 if len(text)<2:
903 if len(text)<2:
904 return u'', ()
904 return u'', ()
905 maybe_slash = text[-2]
905 maybe_slash = text[-2]
906 if maybe_slash != '\\':
906 if maybe_slash != '\\':
907 return u'', ()
907 return u'', ()
908
908
909 char = text[-1]
909 char = text[-1]
910 # no expand on quote for completion in strings.
910 # no expand on quote for completion in strings.
911 # nor backcomplete standard ascii keys
911 # nor backcomplete standard ascii keys
912 if char in string.ascii_letters or char in ['"',"'"]:
912 if char in string.ascii_letters or char in ['"',"'"]:
913 return u'', ()
913 return u'', ()
914 try :
914 try :
915 unic = unicodedata.name(char)
915 unic = unicodedata.name(char)
916 return '\\'+char,['\\'+unic]
916 return '\\'+char,['\\'+unic]
917 except KeyError:
917 except KeyError:
918 pass
918 pass
919 return u'', ()
919 return u'', ()
920
920
921 def back_latex_name_matches(text:str):
921 def back_latex_name_matches(text:str):
922 """Match latex characters back to unicode name
922 """Match latex characters back to unicode name
923
923
924 This does ``\\β„΅`` -> ``\\aleph``
924 This does ``\\β„΅`` -> ``\\aleph``
925
925
926 Used on Python 3 only.
926 Used on Python 3 only.
927 """
927 """
928 if len(text)<2:
928 if len(text)<2:
929 return u'', ()
929 return u'', ()
930 maybe_slash = text[-2]
930 maybe_slash = text[-2]
931 if maybe_slash != '\\':
931 if maybe_slash != '\\':
932 return u'', ()
932 return u'', ()
933
933
934
934
935 char = text[-1]
935 char = text[-1]
936 # no expand on quote for completion in strings.
936 # no expand on quote for completion in strings.
937 # nor backcomplete standard ascii keys
937 # nor backcomplete standard ascii keys
938 if char in string.ascii_letters or char in ['"',"'"]:
938 if char in string.ascii_letters or char in ['"',"'"]:
939 return u'', ()
939 return u'', ()
940 try :
940 try :
941 latex = reverse_latex_symbol[char]
941 latex = reverse_latex_symbol[char]
942 # '\\' replace the \ as well
942 # '\\' replace the \ as well
943 return '\\'+char,[latex]
943 return '\\'+char,[latex]
944 except KeyError:
944 except KeyError:
945 pass
945 pass
946 return u'', ()
946 return u'', ()
947
947
948
948
949 def _formatparamchildren(parameter) -> str:
949 def _formatparamchildren(parameter) -> str:
950 """
950 """
951 Get parameter name and value from Jedi Private API
951 Get parameter name and value from Jedi Private API
952
952
953 Jedi does not expose a simple way to get `param=value` from its API.
953 Jedi does not expose a simple way to get `param=value` from its API.
954
954
955 Parameter
955 Parameter
956 =========
956 =========
957
957
958 parameter:
958 parameter:
959 Jedi's function `Param`
959 Jedi's function `Param`
960
960
961 Returns
961 Returns
962 =======
962 =======
963
963
964 A string like 'a', 'b=1', '*args', '**kwargs'
964 A string like 'a', 'b=1', '*args', '**kwargs'
965
965
966
966
967 """
967 """
968 description = parameter.description
968 description = parameter.description
969 if not description.startswith('param '):
969 if not description.startswith('param '):
970 raise ValueError('Jedi function parameter description have change format.'
970 raise ValueError('Jedi function parameter description have change format.'
971 'Expected "param ...", found %r".' % description)
971 'Expected "param ...", found %r".' % description)
972 return description[6:]
972 return description[6:]
973
973
974 def _make_signature(completion)-> str:
974 def _make_signature(completion)-> str:
975 """
975 """
976 Make the signature from a jedi completion
976 Make the signature from a jedi completion
977
977
978 Parameter
978 Parameter
979 =========
979 =========
980
980
981 completion: jedi.Completion
981 completion: jedi.Completion
982 object does not complete a function type
982 object does not complete a function type
983
983
984 Returns
984 Returns
985 =======
985 =======
986
986
987 a string consisting of the function signature, with the parenthesis but
987 a string consisting of the function signature, with the parenthesis but
988 without the function name. example:
988 without the function name. example:
989 `(a, *args, b=1, **kwargs)`
989 `(a, *args, b=1, **kwargs)`
990
990
991 """
991 """
992
992
993 # it looks like this might work on jedi 0.17
993 # it looks like this might work on jedi 0.17
994 if hasattr(completion, 'get_signatures'):
994 if hasattr(completion, 'get_signatures'):
995 signatures = completion.get_signatures()
995 signatures = completion.get_signatures()
996 if not signatures:
996 if not signatures:
997 return '(?)'
997 return '(?)'
998
998
999 c0 = completion.get_signatures()[0]
999 c0 = completion.get_signatures()[0]
1000 return '('+c0.to_string().split('(', maxsplit=1)[1]
1000 return '('+c0.to_string().split('(', maxsplit=1)[1]
1001
1001
1002 return '(%s)'% ', '.join([f for f in (_formatparamchildren(p) for signature in completion.get_signatures()
1002 return '(%s)'% ', '.join([f for f in (_formatparamchildren(p) for signature in completion.get_signatures()
1003 for p in signature.defined_names()) if f])
1003 for p in signature.defined_names()) if f])
1004
1004
1005 class IPCompleter(Completer):
1005 class IPCompleter(Completer):
1006 """Extension of the completer class with IPython-specific features"""
1006 """Extension of the completer class with IPython-specific features"""
1007
1007
1008 @observe('greedy')
1008 @observe('greedy')
1009 def _greedy_changed(self, change):
1009 def _greedy_changed(self, change):
1010 """update the splitter and readline delims when greedy is changed"""
1010 """update the splitter and readline delims when greedy is changed"""
1011 if change['new']:
1011 if change['new']:
1012 self.splitter.delims = GREEDY_DELIMS
1012 self.splitter.delims = GREEDY_DELIMS
1013 else:
1013 else:
1014 self.splitter.delims = DELIMS
1014 self.splitter.delims = DELIMS
1015
1015
1016 dict_keys_only = Bool(False,
1016 dict_keys_only = Bool(False,
1017 help="""Whether to show dict key matches only""")
1017 help="""Whether to show dict key matches only""")
1018
1018
1019 merge_completions = Bool(True,
1019 merge_completions = Bool(True,
1020 help="""Whether to merge completion results into a single list
1020 help="""Whether to merge completion results into a single list
1021
1021
1022 If False, only the completion results from the first non-empty
1022 If False, only the completion results from the first non-empty
1023 completer will be returned.
1023 completer will be returned.
1024 """
1024 """
1025 ).tag(config=True)
1025 ).tag(config=True)
1026 omit__names = Enum((0,1,2), default_value=2,
1026 omit__names = Enum((0,1,2), default_value=2,
1027 help="""Instruct the completer to omit private method names
1027 help="""Instruct the completer to omit private method names
1028
1028
1029 Specifically, when completing on ``object.<tab>``.
1029 Specifically, when completing on ``object.<tab>``.
1030
1030
1031 When 2 [default]: all names that start with '_' will be excluded.
1031 When 2 [default]: all names that start with '_' will be excluded.
1032
1032
1033 When 1: all 'magic' names (``__foo__``) will be excluded.
1033 When 1: all 'magic' names (``__foo__``) will be excluded.
1034
1034
1035 When 0: nothing will be excluded.
1035 When 0: nothing will be excluded.
1036 """
1036 """
1037 ).tag(config=True)
1037 ).tag(config=True)
1038 limit_to__all__ = Bool(False,
1038 limit_to__all__ = Bool(False,
1039 help="""
1039 help="""
1040 DEPRECATED as of version 5.0.
1040 DEPRECATED as of version 5.0.
1041
1041
1042 Instruct the completer to use __all__ for the completion
1042 Instruct the completer to use __all__ for the completion
1043
1043
1044 Specifically, when completing on ``object.<tab>``.
1044 Specifically, when completing on ``object.<tab>``.
1045
1045
1046 When True: only those names in obj.__all__ will be included.
1046 When True: only those names in obj.__all__ will be included.
1047
1047
1048 When False [default]: the __all__ attribute is ignored
1048 When False [default]: the __all__ attribute is ignored
1049 """,
1049 """,
1050 ).tag(config=True)
1050 ).tag(config=True)
1051
1051
1052 profile_completions = Bool(
1052 profile_completions = Bool(
1053 default_value=False,
1053 default_value=False,
1054 help="If True, emit profiling data for completion subsystem using cProfile."
1054 help="If True, emit profiling data for completion subsystem using cProfile."
1055 ).tag(config=True)
1055 ).tag(config=True)
1056
1056
1057 profiler_output_dir = Unicode(
1057 profiler_output_dir = Unicode(
1058 default_value=".completion_profiles",
1058 default_value=".completion_profiles",
1059 help="Template for path at which to output profile data for completions."
1059 help="Template for path at which to output profile data for completions."
1060 ).tag(config=True)
1060 ).tag(config=True)
1061
1061
1062 @observe('limit_to__all__')
1062 @observe('limit_to__all__')
1063 def _limit_to_all_changed(self, change):
1063 def _limit_to_all_changed(self, change):
1064 warnings.warn('`IPython.core.IPCompleter.limit_to__all__` configuration '
1064 warnings.warn('`IPython.core.IPCompleter.limit_to__all__` configuration '
1065 'value has been deprecated since IPython 5.0, will be made to have '
1065 'value has been deprecated since IPython 5.0, will be made to have '
1066 'no effects and then removed in future version of IPython.',
1066 'no effects and then removed in future version of IPython.',
1067 UserWarning)
1067 UserWarning)
1068
1068
1069 def __init__(self, shell=None, namespace=None, global_namespace=None,
1069 def __init__(self, shell=None, namespace=None, global_namespace=None,
1070 use_readline=_deprecation_readline_sentinel, config=None, **kwargs):
1070 use_readline=_deprecation_readline_sentinel, config=None, **kwargs):
1071 """IPCompleter() -> completer
1071 """IPCompleter() -> completer
1072
1072
1073 Return a completer object.
1073 Return a completer object.
1074
1074
1075 Parameters
1075 Parameters
1076 ----------
1076 ----------
1077
1077
1078 shell
1078 shell
1079 a pointer to the ipython shell itself. This is needed
1079 a pointer to the ipython shell itself. This is needed
1080 because this completer knows about magic functions, and those can
1080 because this completer knows about magic functions, and those can
1081 only be accessed via the ipython instance.
1081 only be accessed via the ipython instance.
1082
1082
1083 namespace : dict, optional
1083 namespace : dict, optional
1084 an optional dict where completions are performed.
1084 an optional dict where completions are performed.
1085
1085
1086 global_namespace : dict, optional
1086 global_namespace : dict, optional
1087 secondary optional dict for completions, to
1087 secondary optional dict for completions, to
1088 handle cases (such as IPython embedded inside functions) where
1088 handle cases (such as IPython embedded inside functions) where
1089 both Python scopes are visible.
1089 both Python scopes are visible.
1090
1090
1091 use_readline : bool, optional
1091 use_readline : bool, optional
1092 DEPRECATED, ignored since IPython 6.0, will have no effects
1092 DEPRECATED, ignored since IPython 6.0, will have no effects
1093 """
1093 """
1094
1094
1095 self.magic_escape = ESC_MAGIC
1095 self.magic_escape = ESC_MAGIC
1096 self.splitter = CompletionSplitter()
1096 self.splitter = CompletionSplitter()
1097
1097
1098 if use_readline is not _deprecation_readline_sentinel:
1098 if use_readline is not _deprecation_readline_sentinel:
1099 warnings.warn('The `use_readline` parameter is deprecated and ignored since IPython 6.0.',
1099 warnings.warn('The `use_readline` parameter is deprecated and ignored since IPython 6.0.',
1100 DeprecationWarning, stacklevel=2)
1100 DeprecationWarning, stacklevel=2)
1101
1101
1102 # _greedy_changed() depends on splitter and readline being defined:
1102 # _greedy_changed() depends on splitter and readline being defined:
1103 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
1103 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
1104 config=config, **kwargs)
1104 config=config, **kwargs)
1105
1105
1106 # List where completion matches will be stored
1106 # List where completion matches will be stored
1107 self.matches = []
1107 self.matches = []
1108 self.shell = shell
1108 self.shell = shell
1109 # Regexp to split filenames with spaces in them
1109 # Regexp to split filenames with spaces in them
1110 self.space_name_re = re.compile(r'([^\\] )')
1110 self.space_name_re = re.compile(r'([^\\] )')
1111 # Hold a local ref. to glob.glob for speed
1111 # Hold a local ref. to glob.glob for speed
1112 self.glob = glob.glob
1112 self.glob = glob.glob
1113
1113
1114 # Determine if we are running on 'dumb' terminals, like (X)Emacs
1114 # Determine if we are running on 'dumb' terminals, like (X)Emacs
1115 # buffers, to avoid completion problems.
1115 # buffers, to avoid completion problems.
1116 term = os.environ.get('TERM','xterm')
1116 term = os.environ.get('TERM','xterm')
1117 self.dumb_terminal = term in ['dumb','emacs']
1117 self.dumb_terminal = term in ['dumb','emacs']
1118
1118
1119 # Special handling of backslashes needed in win32 platforms
1119 # Special handling of backslashes needed in win32 platforms
1120 if sys.platform == "win32":
1120 if sys.platform == "win32":
1121 self.clean_glob = self._clean_glob_win32
1121 self.clean_glob = self._clean_glob_win32
1122 else:
1122 else:
1123 self.clean_glob = self._clean_glob
1123 self.clean_glob = self._clean_glob
1124
1124
1125 #regexp to parse docstring for function signature
1125 #regexp to parse docstring for function signature
1126 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
1126 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
1127 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
1127 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
1128 #use this if positional argument name is also needed
1128 #use this if positional argument name is also needed
1129 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
1129 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
1130
1130
1131 self.magic_arg_matchers = [
1131 self.magic_arg_matchers = [
1132 self.magic_config_matches,
1132 self.magic_config_matches,
1133 self.magic_color_matches,
1133 self.magic_color_matches,
1134 ]
1134 ]
1135
1135
1136 # This is set externally by InteractiveShell
1136 # This is set externally by InteractiveShell
1137 self.custom_completers = None
1137 self.custom_completers = None
1138
1138
1139 # This is a list of names of unicode characters that can be completed
1139 # This is a list of names of unicode characters that can be completed
1140 # into their corresponding unicode value. The list is large, so we
1140 # into their corresponding unicode value. The list is large, so we
1141 # laziliy initialize it on first use. Consuming code should access this
1141 # laziliy initialize it on first use. Consuming code should access this
1142 # attribute through the `@unicode_names` property.
1142 # attribute through the `@unicode_names` property.
1143 self._unicode_names = None
1143 self._unicode_names = None
1144
1144
1145 @property
1145 @property
1146 def matchers(self):
1146 def matchers(self):
1147 """All active matcher routines for completion"""
1147 """All active matcher routines for completion"""
1148 if self.dict_keys_only:
1148 if self.dict_keys_only:
1149 return [self.dict_key_matches]
1149 return [self.dict_key_matches]
1150
1150
1151 if self.use_jedi:
1151 if self.use_jedi:
1152 return [
1152 return [
1153 *self.custom_matchers,
1153 *self.custom_matchers,
1154 self.file_matches,
1154 self.file_matches,
1155 self.magic_matches,
1155 self.magic_matches,
1156 self.dict_key_matches,
1156 self.dict_key_matches,
1157 ]
1157 ]
1158 else:
1158 else:
1159 return [
1159 return [
1160 *self.custom_matchers,
1160 *self.custom_matchers,
1161 self.python_matches,
1161 self.python_matches,
1162 self.file_matches,
1162 self.file_matches,
1163 self.magic_matches,
1163 self.magic_matches,
1164 self.python_func_kw_matches,
1164 self.python_func_kw_matches,
1165 self.dict_key_matches,
1165 self.dict_key_matches,
1166 ]
1166 ]
1167
1167
1168 def all_completions(self, text) -> List[str]:
1168 def all_completions(self, text) -> List[str]:
1169 """
1169 """
1170 Wrapper around the completion methods for the benefit of emacs.
1170 Wrapper around the completion methods for the benefit of emacs.
1171 """
1171 """
1172 prefix = text.rpartition('.')[0]
1172 prefix = text.rpartition('.')[0]
1173 with provisionalcompleter():
1173 with provisionalcompleter():
1174 return ['.'.join([prefix, c.text]) if prefix and self.use_jedi else c.text
1174 return ['.'.join([prefix, c.text]) if prefix and self.use_jedi else c.text
1175 for c in self.completions(text, len(text))]
1175 for c in self.completions(text, len(text))]
1176
1176
1177 return self.complete(text)[1]
1177 return self.complete(text)[1]
1178
1178
1179 def _clean_glob(self, text):
1179 def _clean_glob(self, text):
1180 return self.glob("%s*" % text)
1180 return self.glob("%s*" % text)
1181
1181
1182 def _clean_glob_win32(self,text):
1182 def _clean_glob_win32(self,text):
1183 return [f.replace("\\","/")
1183 return [f.replace("\\","/")
1184 for f in self.glob("%s*" % text)]
1184 for f in self.glob("%s*" % text)]
1185
1185
1186 def file_matches(self, text):
1186 def file_matches(self, text):
1187 """Match filenames, expanding ~USER type strings.
1187 """Match filenames, expanding ~USER type strings.
1188
1188
1189 Most of the seemingly convoluted logic in this completer is an
1189 Most of the seemingly convoluted logic in this completer is an
1190 attempt to handle filenames with spaces in them. And yet it's not
1190 attempt to handle filenames with spaces in them. And yet it's not
1191 quite perfect, because Python's readline doesn't expose all of the
1191 quite perfect, because Python's readline doesn't expose all of the
1192 GNU readline details needed for this to be done correctly.
1192 GNU readline details needed for this to be done correctly.
1193
1193
1194 For a filename with a space in it, the printed completions will be
1194 For a filename with a space in it, the printed completions will be
1195 only the parts after what's already been typed (instead of the
1195 only the parts after what's already been typed (instead of the
1196 full completions, as is normally done). I don't think with the
1196 full completions, as is normally done). I don't think with the
1197 current (as of Python 2.3) Python readline it's possible to do
1197 current (as of Python 2.3) Python readline it's possible to do
1198 better."""
1198 better."""
1199
1199
1200 # chars that require escaping with backslash - i.e. chars
1200 # chars that require escaping with backslash - i.e. chars
1201 # that readline treats incorrectly as delimiters, but we
1201 # that readline treats incorrectly as delimiters, but we
1202 # don't want to treat as delimiters in filename matching
1202 # don't want to treat as delimiters in filename matching
1203 # when escaped with backslash
1203 # when escaped with backslash
1204 if text.startswith('!'):
1204 if text.startswith('!'):
1205 text = text[1:]
1205 text = text[1:]
1206 text_prefix = u'!'
1206 text_prefix = u'!'
1207 else:
1207 else:
1208 text_prefix = u''
1208 text_prefix = u''
1209
1209
1210 text_until_cursor = self.text_until_cursor
1210 text_until_cursor = self.text_until_cursor
1211 # track strings with open quotes
1211 # track strings with open quotes
1212 open_quotes = has_open_quotes(text_until_cursor)
1212 open_quotes = has_open_quotes(text_until_cursor)
1213
1213
1214 if '(' in text_until_cursor or '[' in text_until_cursor:
1214 if '(' in text_until_cursor or '[' in text_until_cursor:
1215 lsplit = text
1215 lsplit = text
1216 else:
1216 else:
1217 try:
1217 try:
1218 # arg_split ~ shlex.split, but with unicode bugs fixed by us
1218 # arg_split ~ shlex.split, but with unicode bugs fixed by us
1219 lsplit = arg_split(text_until_cursor)[-1]
1219 lsplit = arg_split(text_until_cursor)[-1]
1220 except ValueError:
1220 except ValueError:
1221 # typically an unmatched ", or backslash without escaped char.
1221 # typically an unmatched ", or backslash without escaped char.
1222 if open_quotes:
1222 if open_quotes:
1223 lsplit = text_until_cursor.split(open_quotes)[-1]
1223 lsplit = text_until_cursor.split(open_quotes)[-1]
1224 else:
1224 else:
1225 return []
1225 return []
1226 except IndexError:
1226 except IndexError:
1227 # tab pressed on empty line
1227 # tab pressed on empty line
1228 lsplit = ""
1228 lsplit = ""
1229
1229
1230 if not open_quotes and lsplit != protect_filename(lsplit):
1230 if not open_quotes and lsplit != protect_filename(lsplit):
1231 # if protectables are found, do matching on the whole escaped name
1231 # if protectables are found, do matching on the whole escaped name
1232 has_protectables = True
1232 has_protectables = True
1233 text0,text = text,lsplit
1233 text0,text = text,lsplit
1234 else:
1234 else:
1235 has_protectables = False
1235 has_protectables = False
1236 text = os.path.expanduser(text)
1236 text = os.path.expanduser(text)
1237
1237
1238 if text == "":
1238 if text == "":
1239 return [text_prefix + protect_filename(f) for f in self.glob("*")]
1239 return [text_prefix + protect_filename(f) for f in self.glob("*")]
1240
1240
1241 # Compute the matches from the filesystem
1241 # Compute the matches from the filesystem
1242 if sys.platform == 'win32':
1242 if sys.platform == 'win32':
1243 m0 = self.clean_glob(text)
1243 m0 = self.clean_glob(text)
1244 else:
1244 else:
1245 m0 = self.clean_glob(text.replace('\\', ''))
1245 m0 = self.clean_glob(text.replace('\\', ''))
1246
1246
1247 if has_protectables:
1247 if has_protectables:
1248 # If we had protectables, we need to revert our changes to the
1248 # If we had protectables, we need to revert our changes to the
1249 # beginning of filename so that we don't double-write the part
1249 # beginning of filename so that we don't double-write the part
1250 # of the filename we have so far
1250 # of the filename we have so far
1251 len_lsplit = len(lsplit)
1251 len_lsplit = len(lsplit)
1252 matches = [text_prefix + text0 +
1252 matches = [text_prefix + text0 +
1253 protect_filename(f[len_lsplit:]) for f in m0]
1253 protect_filename(f[len_lsplit:]) for f in m0]
1254 else:
1254 else:
1255 if open_quotes:
1255 if open_quotes:
1256 # if we have a string with an open quote, we don't need to
1256 # if we have a string with an open quote, we don't need to
1257 # protect the names beyond the quote (and we _shouldn't_, as
1257 # protect the names beyond the quote (and we _shouldn't_, as
1258 # it would cause bugs when the filesystem call is made).
1258 # it would cause bugs when the filesystem call is made).
1259 matches = m0 if sys.platform == "win32" else\
1259 matches = m0 if sys.platform == "win32" else\
1260 [protect_filename(f, open_quotes) for f in m0]
1260 [protect_filename(f, open_quotes) for f in m0]
1261 else:
1261 else:
1262 matches = [text_prefix +
1262 matches = [text_prefix +
1263 protect_filename(f) for f in m0]
1263 protect_filename(f) for f in m0]
1264
1264
1265 # Mark directories in input list by appending '/' to their names.
1265 # Mark directories in input list by appending '/' to their names.
1266 return [x+'/' if os.path.isdir(x) else x for x in matches]
1266 return [x+'/' if os.path.isdir(x) else x for x in matches]
1267
1267
1268 def magic_matches(self, text):
1268 def magic_matches(self, text):
1269 """Match magics"""
1269 """Match magics"""
1270 # Get all shell magics now rather than statically, so magics loaded at
1270 # Get all shell magics now rather than statically, so magics loaded at
1271 # runtime show up too.
1271 # runtime show up too.
1272 lsm = self.shell.magics_manager.lsmagic()
1272 lsm = self.shell.magics_manager.lsmagic()
1273 line_magics = lsm['line']
1273 line_magics = lsm['line']
1274 cell_magics = lsm['cell']
1274 cell_magics = lsm['cell']
1275 pre = self.magic_escape
1275 pre = self.magic_escape
1276 pre2 = pre+pre
1276 pre2 = pre+pre
1277
1277
1278 explicit_magic = text.startswith(pre)
1278 explicit_magic = text.startswith(pre)
1279
1279
1280 # Completion logic:
1280 # Completion logic:
1281 # - user gives %%: only do cell magics
1281 # - user gives %%: only do cell magics
1282 # - user gives %: do both line and cell magics
1282 # - user gives %: do both line and cell magics
1283 # - no prefix: do both
1283 # - no prefix: do both
1284 # In other words, line magics are skipped if the user gives %% explicitly
1284 # In other words, line magics are skipped if the user gives %% explicitly
1285 #
1285 #
1286 # We also exclude magics that match any currently visible names:
1286 # We also exclude magics that match any currently visible names:
1287 # https://github.com/ipython/ipython/issues/4877, unless the user has
1287 # https://github.com/ipython/ipython/issues/4877, unless the user has
1288 # typed a %:
1288 # typed a %:
1289 # https://github.com/ipython/ipython/issues/10754
1289 # https://github.com/ipython/ipython/issues/10754
1290 bare_text = text.lstrip(pre)
1290 bare_text = text.lstrip(pre)
1291 global_matches = self.global_matches(bare_text)
1291 global_matches = self.global_matches(bare_text)
1292 if not explicit_magic:
1292 if not explicit_magic:
1293 def matches(magic):
1293 def matches(magic):
1294 """
1294 """
1295 Filter magics, in particular remove magics that match
1295 Filter magics, in particular remove magics that match
1296 a name present in global namespace.
1296 a name present in global namespace.
1297 """
1297 """
1298 return ( magic.startswith(bare_text) and
1298 return ( magic.startswith(bare_text) and
1299 magic not in global_matches )
1299 magic not in global_matches )
1300 else:
1300 else:
1301 def matches(magic):
1301 def matches(magic):
1302 return magic.startswith(bare_text)
1302 return magic.startswith(bare_text)
1303
1303
1304 comp = [ pre2+m for m in cell_magics if matches(m)]
1304 comp = [ pre2+m for m in cell_magics if matches(m)]
1305 if not text.startswith(pre2):
1305 if not text.startswith(pre2):
1306 comp += [ pre+m for m in line_magics if matches(m)]
1306 comp += [ pre+m for m in line_magics if matches(m)]
1307
1307
1308 return comp
1308 return comp
1309
1309
1310 def magic_config_matches(self, text:str) -> List[str]:
1310 def magic_config_matches(self, text:str) -> List[str]:
1311 """ Match class names and attributes for %config magic """
1311 """ Match class names and attributes for %config magic """
1312 texts = text.strip().split()
1312 texts = text.strip().split()
1313
1313
1314 if len(texts) > 0 and (texts[0] == 'config' or texts[0] == '%config'):
1314 if len(texts) > 0 and (texts[0] == 'config' or texts[0] == '%config'):
1315 # get all configuration classes
1315 # get all configuration classes
1316 classes = sorted(set([ c for c in self.shell.configurables
1316 classes = sorted(set([ c for c in self.shell.configurables
1317 if c.__class__.class_traits(config=True)
1317 if c.__class__.class_traits(config=True)
1318 ]), key=lambda x: x.__class__.__name__)
1318 ]), key=lambda x: x.__class__.__name__)
1319 classnames = [ c.__class__.__name__ for c in classes ]
1319 classnames = [ c.__class__.__name__ for c in classes ]
1320
1320
1321 # return all classnames if config or %config is given
1321 # return all classnames if config or %config is given
1322 if len(texts) == 1:
1322 if len(texts) == 1:
1323 return classnames
1323 return classnames
1324
1324
1325 # match classname
1325 # match classname
1326 classname_texts = texts[1].split('.')
1326 classname_texts = texts[1].split('.')
1327 classname = classname_texts[0]
1327 classname = classname_texts[0]
1328 classname_matches = [ c for c in classnames
1328 classname_matches = [ c for c in classnames
1329 if c.startswith(classname) ]
1329 if c.startswith(classname) ]
1330
1330
1331 # return matched classes or the matched class with attributes
1331 # return matched classes or the matched class with attributes
1332 if texts[1].find('.') < 0:
1332 if texts[1].find('.') < 0:
1333 return classname_matches
1333 return classname_matches
1334 elif len(classname_matches) == 1 and \
1334 elif len(classname_matches) == 1 and \
1335 classname_matches[0] == classname:
1335 classname_matches[0] == classname:
1336 cls = classes[classnames.index(classname)].__class__
1336 cls = classes[classnames.index(classname)].__class__
1337 help = cls.class_get_help()
1337 help = cls.class_get_help()
1338 # strip leading '--' from cl-args:
1338 # strip leading '--' from cl-args:
1339 help = re.sub(re.compile(r'^--', re.MULTILINE), '', help)
1339 help = re.sub(re.compile(r'^--', re.MULTILINE), '', help)
1340 return [ attr.split('=')[0]
1340 return [ attr.split('=')[0]
1341 for attr in help.strip().splitlines()
1341 for attr in help.strip().splitlines()
1342 if attr.startswith(texts[1]) ]
1342 if attr.startswith(texts[1]) ]
1343 return []
1343 return []
1344
1344
1345 def magic_color_matches(self, text:str) -> List[str] :
1345 def magic_color_matches(self, text:str) -> List[str] :
1346 """ Match color schemes for %colors magic"""
1346 """ Match color schemes for %colors magic"""
1347 texts = text.split()
1347 texts = text.split()
1348 if text.endswith(' '):
1348 if text.endswith(' '):
1349 # .split() strips off the trailing whitespace. Add '' back
1349 # .split() strips off the trailing whitespace. Add '' back
1350 # so that: '%colors ' -> ['%colors', '']
1350 # so that: '%colors ' -> ['%colors', '']
1351 texts.append('')
1351 texts.append('')
1352
1352
1353 if len(texts) == 2 and (texts[0] == 'colors' or texts[0] == '%colors'):
1353 if len(texts) == 2 and (texts[0] == 'colors' or texts[0] == '%colors'):
1354 prefix = texts[1]
1354 prefix = texts[1]
1355 return [ color for color in InspectColors.keys()
1355 return [ color for color in InspectColors.keys()
1356 if color.startswith(prefix) ]
1356 if color.startswith(prefix) ]
1357 return []
1357 return []
1358
1358
1359 def _jedi_matches(self, cursor_column:int, cursor_line:int, text:str):
1359 def _jedi_matches(self, cursor_column:int, cursor_line:int, text:str):
1360 """
1360 """
1361
1361
1362 Return a list of :any:`jedi.api.Completions` object from a ``text`` and
1362 Return a list of :any:`jedi.api.Completions` object from a ``text`` and
1363 cursor position.
1363 cursor position.
1364
1364
1365 Parameters
1365 Parameters
1366 ----------
1366 ----------
1367 cursor_column : int
1367 cursor_column : int
1368 column position of the cursor in ``text``, 0-indexed.
1368 column position of the cursor in ``text``, 0-indexed.
1369 cursor_line : int
1369 cursor_line : int
1370 line position of the cursor in ``text``, 0-indexed
1370 line position of the cursor in ``text``, 0-indexed
1371 text : str
1371 text : str
1372 text to complete
1372 text to complete
1373
1373
1374 Debugging
1374 Debugging
1375 ---------
1375 ---------
1376
1376
1377 If ``IPCompleter.debug`` is ``True`` may return a :any:`_FakeJediCompletion`
1377 If ``IPCompleter.debug`` is ``True`` may return a :any:`_FakeJediCompletion`
1378 object containing a string with the Jedi debug information attached.
1378 object containing a string with the Jedi debug information attached.
1379 """
1379 """
1380 namespaces = [self.namespace]
1380 namespaces = [self.namespace]
1381 if self.global_namespace is not None:
1381 if self.global_namespace is not None:
1382 namespaces.append(self.global_namespace)
1382 namespaces.append(self.global_namespace)
1383
1383
1384 completion_filter = lambda x:x
1384 completion_filter = lambda x:x
1385 offset = cursor_to_position(text, cursor_line, cursor_column)
1385 offset = cursor_to_position(text, cursor_line, cursor_column)
1386 # filter output if we are completing for object members
1386 # filter output if we are completing for object members
1387 if offset:
1387 if offset:
1388 pre = text[offset-1]
1388 pre = text[offset-1]
1389 if pre == '.':
1389 if pre == '.':
1390 if self.omit__names == 2:
1390 if self.omit__names == 2:
1391 completion_filter = lambda c:not c.name.startswith('_')
1391 completion_filter = lambda c:not c.name.startswith('_')
1392 elif self.omit__names == 1:
1392 elif self.omit__names == 1:
1393 completion_filter = lambda c:not (c.name.startswith('__') and c.name.endswith('__'))
1393 completion_filter = lambda c:not (c.name.startswith('__') and c.name.endswith('__'))
1394 elif self.omit__names == 0:
1394 elif self.omit__names == 0:
1395 completion_filter = lambda x:x
1395 completion_filter = lambda x:x
1396 else:
1396 else:
1397 raise ValueError("Don't understand self.omit__names == {}".format(self.omit__names))
1397 raise ValueError("Don't understand self.omit__names == {}".format(self.omit__names))
1398
1398
1399 interpreter = jedi.Interpreter(text[:offset], namespaces)
1399 interpreter = jedi.Interpreter(text[:offset], namespaces)
1400 try_jedi = True
1400 try_jedi = True
1401
1401
1402 try:
1402 try:
1403 # find the first token in the current tree -- if it is a ' or " then we are in a string
1403 # find the first token in the current tree -- if it is a ' or " then we are in a string
1404 completing_string = False
1404 completing_string = False
1405 try:
1405 try:
1406 first_child = next(c for c in interpreter._get_module().tree_node.children if hasattr(c, 'value'))
1406 first_child = next(c for c in interpreter._get_module().tree_node.children if hasattr(c, 'value'))
1407 except StopIteration:
1407 except StopIteration:
1408 pass
1408 pass
1409 else:
1409 else:
1410 # note the value may be ', ", or it may also be ''' or """, or
1410 # note the value may be ', ", or it may also be ''' or """, or
1411 # in some cases, """what/you/typed..., but all of these are
1411 # in some cases, """what/you/typed..., but all of these are
1412 # strings.
1412 # strings.
1413 completing_string = len(first_child.value) > 0 and first_child.value[0] in {"'", '"'}
1413 completing_string = len(first_child.value) > 0 and first_child.value[0] in {"'", '"'}
1414
1414
1415 # if we are in a string jedi is likely not the right candidate for
1415 # if we are in a string jedi is likely not the right candidate for
1416 # now. Skip it.
1416 # now. Skip it.
1417 try_jedi = not completing_string
1417 try_jedi = not completing_string
1418 except Exception as e:
1418 except Exception as e:
1419 # many of things can go wrong, we are using private API just don't crash.
1419 # many of things can go wrong, we are using private API just don't crash.
1420 if self.debug:
1420 if self.debug:
1421 print("Error detecting if completing a non-finished string :", e, '|')
1421 print("Error detecting if completing a non-finished string :", e, '|')
1422
1422
1423 if not try_jedi:
1423 if not try_jedi:
1424 return []
1424 return []
1425 try:
1425 try:
1426 return filter(completion_filter, interpreter.complete(column=cursor_column, line=cursor_line + 1))
1426 return filter(completion_filter, interpreter.complete(column=cursor_column, line=cursor_line + 1))
1427 except Exception as e:
1427 except Exception as e:
1428 if self.debug:
1428 if self.debug:
1429 return [_FakeJediCompletion('Oops Jedi has crashed, please report a bug with the following:\n"""\n%s\ns"""' % (e))]
1429 return [_FakeJediCompletion('Oops Jedi has crashed, please report a bug with the following:\n"""\n%s\ns"""' % (e))]
1430 else:
1430 else:
1431 return []
1431 return []
1432
1432
1433 def python_matches(self, text):
1433 def python_matches(self, text):
1434 """Match attributes or global python names"""
1434 """Match attributes or global python names"""
1435 if "." in text:
1435 if "." in text:
1436 try:
1436 try:
1437 matches = self.attr_matches(text)
1437 matches = self.attr_matches(text)
1438 if text.endswith('.') and self.omit__names:
1438 if text.endswith('.') and self.omit__names:
1439 if self.omit__names == 1:
1439 if self.omit__names == 1:
1440 # true if txt is _not_ a __ name, false otherwise:
1440 # true if txt is _not_ a __ name, false otherwise:
1441 no__name = (lambda txt:
1441 no__name = (lambda txt:
1442 re.match(r'.*\.__.*?__',txt) is None)
1442 re.match(r'.*\.__.*?__',txt) is None)
1443 else:
1443 else:
1444 # true if txt is _not_ a _ name, false otherwise:
1444 # true if txt is _not_ a _ name, false otherwise:
1445 no__name = (lambda txt:
1445 no__name = (lambda txt:
1446 re.match(r'\._.*?',txt[txt.rindex('.'):]) is None)
1446 re.match(r'\._.*?',txt[txt.rindex('.'):]) is None)
1447 matches = filter(no__name, matches)
1447 matches = filter(no__name, matches)
1448 except NameError:
1448 except NameError:
1449 # catches <undefined attributes>.<tab>
1449 # catches <undefined attributes>.<tab>
1450 matches = []
1450 matches = []
1451 else:
1451 else:
1452 matches = self.global_matches(text)
1452 matches = self.global_matches(text)
1453 return matches
1453 return matches
1454
1454
1455 def _default_arguments_from_docstring(self, doc):
1455 def _default_arguments_from_docstring(self, doc):
1456 """Parse the first line of docstring for call signature.
1456 """Parse the first line of docstring for call signature.
1457
1457
1458 Docstring should be of the form 'min(iterable[, key=func])\n'.
1458 Docstring should be of the form 'min(iterable[, key=func])\n'.
1459 It can also parse cython docstring of the form
1459 It can also parse cython docstring of the form
1460 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
1460 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
1461 """
1461 """
1462 if doc is None:
1462 if doc is None:
1463 return []
1463 return []
1464
1464
1465 #care only the firstline
1465 #care only the firstline
1466 line = doc.lstrip().splitlines()[0]
1466 line = doc.lstrip().splitlines()[0]
1467
1467
1468 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
1468 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
1469 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
1469 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
1470 sig = self.docstring_sig_re.search(line)
1470 sig = self.docstring_sig_re.search(line)
1471 if sig is None:
1471 if sig is None:
1472 return []
1472 return []
1473 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
1473 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
1474 sig = sig.groups()[0].split(',')
1474 sig = sig.groups()[0].split(',')
1475 ret = []
1475 ret = []
1476 for s in sig:
1476 for s in sig:
1477 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
1477 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
1478 ret += self.docstring_kwd_re.findall(s)
1478 ret += self.docstring_kwd_re.findall(s)
1479 return ret
1479 return ret
1480
1480
1481 def _default_arguments(self, obj):
1481 def _default_arguments(self, obj):
1482 """Return the list of default arguments of obj if it is callable,
1482 """Return the list of default arguments of obj if it is callable,
1483 or empty list otherwise."""
1483 or empty list otherwise."""
1484 call_obj = obj
1484 call_obj = obj
1485 ret = []
1485 ret = []
1486 if inspect.isbuiltin(obj):
1486 if inspect.isbuiltin(obj):
1487 pass
1487 pass
1488 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
1488 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
1489 if inspect.isclass(obj):
1489 if inspect.isclass(obj):
1490 #for cython embedsignature=True the constructor docstring
1490 #for cython embedsignature=True the constructor docstring
1491 #belongs to the object itself not __init__
1491 #belongs to the object itself not __init__
1492 ret += self._default_arguments_from_docstring(
1492 ret += self._default_arguments_from_docstring(
1493 getattr(obj, '__doc__', ''))
1493 getattr(obj, '__doc__', ''))
1494 # for classes, check for __init__,__new__
1494 # for classes, check for __init__,__new__
1495 call_obj = (getattr(obj, '__init__', None) or
1495 call_obj = (getattr(obj, '__init__', None) or
1496 getattr(obj, '__new__', None))
1496 getattr(obj, '__new__', None))
1497 # for all others, check if they are __call__able
1497 # for all others, check if they are __call__able
1498 elif hasattr(obj, '__call__'):
1498 elif hasattr(obj, '__call__'):
1499 call_obj = obj.__call__
1499 call_obj = obj.__call__
1500 ret += self._default_arguments_from_docstring(
1500 ret += self._default_arguments_from_docstring(
1501 getattr(call_obj, '__doc__', ''))
1501 getattr(call_obj, '__doc__', ''))
1502
1502
1503 _keeps = (inspect.Parameter.KEYWORD_ONLY,
1503 _keeps = (inspect.Parameter.KEYWORD_ONLY,
1504 inspect.Parameter.POSITIONAL_OR_KEYWORD)
1504 inspect.Parameter.POSITIONAL_OR_KEYWORD)
1505
1505
1506 try:
1506 try:
1507 sig = inspect.signature(call_obj)
1507 sig = inspect.signature(call_obj)
1508 ret.extend(k for k, v in sig.parameters.items() if
1508 ret.extend(k for k, v in sig.parameters.items() if
1509 v.kind in _keeps)
1509 v.kind in _keeps)
1510 except ValueError:
1510 except ValueError:
1511 pass
1511 pass
1512
1512
1513 return list(set(ret))
1513 return list(set(ret))
1514
1514
1515 def python_func_kw_matches(self,text):
1515 def python_func_kw_matches(self,text):
1516 """Match named parameters (kwargs) of the last open function"""
1516 """Match named parameters (kwargs) of the last open function"""
1517
1517
1518 if "." in text: # a parameter cannot be dotted
1518 if "." in text: # a parameter cannot be dotted
1519 return []
1519 return []
1520 try: regexp = self.__funcParamsRegex
1520 try: regexp = self.__funcParamsRegex
1521 except AttributeError:
1521 except AttributeError:
1522 regexp = self.__funcParamsRegex = re.compile(r'''
1522 regexp = self.__funcParamsRegex = re.compile(r'''
1523 '.*?(?<!\\)' | # single quoted strings or
1523 '.*?(?<!\\)' | # single quoted strings or
1524 ".*?(?<!\\)" | # double quoted strings or
1524 ".*?(?<!\\)" | # double quoted strings or
1525 \w+ | # identifier
1525 \w+ | # identifier
1526 \S # other characters
1526 \S # other characters
1527 ''', re.VERBOSE | re.DOTALL)
1527 ''', re.VERBOSE | re.DOTALL)
1528 # 1. find the nearest identifier that comes before an unclosed
1528 # 1. find the nearest identifier that comes before an unclosed
1529 # parenthesis before the cursor
1529 # parenthesis before the cursor
1530 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
1530 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
1531 tokens = regexp.findall(self.text_until_cursor)
1531 tokens = regexp.findall(self.text_until_cursor)
1532 iterTokens = reversed(tokens); openPar = 0
1532 iterTokens = reversed(tokens); openPar = 0
1533
1533
1534 for token in iterTokens:
1534 for token in iterTokens:
1535 if token == ')':
1535 if token == ')':
1536 openPar -= 1
1536 openPar -= 1
1537 elif token == '(':
1537 elif token == '(':
1538 openPar += 1
1538 openPar += 1
1539 if openPar > 0:
1539 if openPar > 0:
1540 # found the last unclosed parenthesis
1540 # found the last unclosed parenthesis
1541 break
1541 break
1542 else:
1542 else:
1543 return []
1543 return []
1544 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
1544 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
1545 ids = []
1545 ids = []
1546 isId = re.compile(r'\w+$').match
1546 isId = re.compile(r'\w+$').match
1547
1547
1548 while True:
1548 while True:
1549 try:
1549 try:
1550 ids.append(next(iterTokens))
1550 ids.append(next(iterTokens))
1551 if not isId(ids[-1]):
1551 if not isId(ids[-1]):
1552 ids.pop(); break
1552 ids.pop(); break
1553 if not next(iterTokens) == '.':
1553 if not next(iterTokens) == '.':
1554 break
1554 break
1555 except StopIteration:
1555 except StopIteration:
1556 break
1556 break
1557
1557
1558 # Find all named arguments already assigned to, as to avoid suggesting
1558 # Find all named arguments already assigned to, as to avoid suggesting
1559 # them again
1559 # them again
1560 usedNamedArgs = set()
1560 usedNamedArgs = set()
1561 par_level = -1
1561 par_level = -1
1562 for token, next_token in zip(tokens, tokens[1:]):
1562 for token, next_token in zip(tokens, tokens[1:]):
1563 if token == '(':
1563 if token == '(':
1564 par_level += 1
1564 par_level += 1
1565 elif token == ')':
1565 elif token == ')':
1566 par_level -= 1
1566 par_level -= 1
1567
1567
1568 if par_level != 0:
1568 if par_level != 0:
1569 continue
1569 continue
1570
1570
1571 if next_token != '=':
1571 if next_token != '=':
1572 continue
1572 continue
1573
1573
1574 usedNamedArgs.add(token)
1574 usedNamedArgs.add(token)
1575
1575
1576 argMatches = []
1576 argMatches = []
1577 try:
1577 try:
1578 callableObj = '.'.join(ids[::-1])
1578 callableObj = '.'.join(ids[::-1])
1579 namedArgs = self._default_arguments(eval(callableObj,
1579 namedArgs = self._default_arguments(eval(callableObj,
1580 self.namespace))
1580 self.namespace))
1581
1581
1582 # Remove used named arguments from the list, no need to show twice
1582 # Remove used named arguments from the list, no need to show twice
1583 for namedArg in set(namedArgs) - usedNamedArgs:
1583 for namedArg in set(namedArgs) - usedNamedArgs:
1584 if namedArg.startswith(text):
1584 if namedArg.startswith(text):
1585 argMatches.append(u"%s=" %namedArg)
1585 argMatches.append(u"%s=" %namedArg)
1586 except:
1586 except:
1587 pass
1587 pass
1588
1588
1589 return argMatches
1589 return argMatches
1590
1590
1591 def dict_key_matches(self, text):
1591 def dict_key_matches(self, text):
1592 "Match string keys in a dictionary, after e.g. 'foo[' "
1592 "Match string keys in a dictionary, after e.g. 'foo[' "
1593 def get_keys(obj):
1593 def get_keys(obj):
1594 # Objects can define their own completions by defining an
1594 # Objects can define their own completions by defining an
1595 # _ipy_key_completions_() method.
1595 # _ipy_key_completions_() method.
1596 method = get_real_method(obj, '_ipython_key_completions_')
1596 method = get_real_method(obj, '_ipython_key_completions_')
1597 if method is not None:
1597 if method is not None:
1598 return method()
1598 return method()
1599
1599
1600 # Special case some common in-memory dict-like types
1600 # Special case some common in-memory dict-like types
1601 if isinstance(obj, dict) or\
1601 if isinstance(obj, dict) or\
1602 _safe_isinstance(obj, 'pandas', 'DataFrame'):
1602 _safe_isinstance(obj, 'pandas', 'DataFrame'):
1603 try:
1603 try:
1604 return list(obj.keys())
1604 return list(obj.keys())
1605 except Exception:
1605 except Exception:
1606 return []
1606 return []
1607 elif _safe_isinstance(obj, 'numpy', 'ndarray') or\
1607 elif _safe_isinstance(obj, 'numpy', 'ndarray') or\
1608 _safe_isinstance(obj, 'numpy', 'void'):
1608 _safe_isinstance(obj, 'numpy', 'void'):
1609 return obj.dtype.names or []
1609 return obj.dtype.names or []
1610 return []
1610 return []
1611
1611
1612 try:
1612 try:
1613 regexps = self.__dict_key_regexps
1613 regexps = self.__dict_key_regexps
1614 except AttributeError:
1614 except AttributeError:
1615 dict_key_re_fmt = r'''(?x)
1615 dict_key_re_fmt = r'''(?x)
1616 ( # match dict-referring expression wrt greedy setting
1616 ( # match dict-referring expression wrt greedy setting
1617 %s
1617 %s
1618 )
1618 )
1619 \[ # open bracket
1619 \[ # open bracket
1620 \s* # and optional whitespace
1620 \s* # and optional whitespace
1621 ([uUbB]? # string prefix (r not handled)
1621 ([uUbB]? # string prefix (r not handled)
1622 (?: # unclosed string
1622 (?: # unclosed string
1623 '(?:[^']|(?<!\\)\\')*
1623 '(?:[^']|(?<!\\)\\')*
1624 |
1624 |
1625 "(?:[^"]|(?<!\\)\\")*
1625 "(?:[^"]|(?<!\\)\\")*
1626 )
1626 )
1627 )?
1627 )?
1628 $
1628 $
1629 '''
1629 '''
1630 regexps = self.__dict_key_regexps = {
1630 regexps = self.__dict_key_regexps = {
1631 False: re.compile(dict_key_re_fmt % r'''
1631 False: re.compile(dict_key_re_fmt % r'''
1632 # identifiers separated by .
1632 # identifiers separated by .
1633 (?!\d)\w+
1633 (?!\d)\w+
1634 (?:\.(?!\d)\w+)*
1634 (?:\.(?!\d)\w+)*
1635 '''),
1635 '''),
1636 True: re.compile(dict_key_re_fmt % '''
1636 True: re.compile(dict_key_re_fmt % '''
1637 .+
1637 .+
1638 ''')
1638 ''')
1639 }
1639 }
1640
1640
1641 match = regexps[self.greedy].search(self.text_until_cursor)
1641 match = regexps[self.greedy].search(self.text_until_cursor)
1642 if match is None:
1642 if match is None:
1643 return []
1643 return []
1644
1644
1645 expr, prefix = match.groups()
1645 expr, prefix = match.groups()
1646 try:
1646 try:
1647 obj = eval(expr, self.namespace)
1647 obj = eval(expr, self.namespace)
1648 except Exception:
1648 except Exception:
1649 try:
1649 try:
1650 obj = eval(expr, self.global_namespace)
1650 obj = eval(expr, self.global_namespace)
1651 except Exception:
1651 except Exception:
1652 return []
1652 return []
1653
1653
1654 keys = get_keys(obj)
1654 keys = get_keys(obj)
1655 if not keys:
1655 if not keys:
1656 return keys
1656 return keys
1657 closing_quote, token_offset, matches = match_dict_keys(keys, prefix, self.splitter.delims)
1657 closing_quote, token_offset, matches = match_dict_keys(keys, prefix, self.splitter.delims)
1658 if not matches:
1658 if not matches:
1659 return matches
1659 return matches
1660
1660
1661 # get the cursor position of
1661 # get the cursor position of
1662 # - the text being completed
1662 # - the text being completed
1663 # - the start of the key text
1663 # - the start of the key text
1664 # - the start of the completion
1664 # - the start of the completion
1665 text_start = len(self.text_until_cursor) - len(text)
1665 text_start = len(self.text_until_cursor) - len(text)
1666 if prefix:
1666 if prefix:
1667 key_start = match.start(2)
1667 key_start = match.start(2)
1668 completion_start = key_start + token_offset
1668 completion_start = key_start + token_offset
1669 else:
1669 else:
1670 key_start = completion_start = match.end()
1670 key_start = completion_start = match.end()
1671
1671
1672 # grab the leading prefix, to make sure all completions start with `text`
1672 # grab the leading prefix, to make sure all completions start with `text`
1673 if text_start > key_start:
1673 if text_start > key_start:
1674 leading = ''
1674 leading = ''
1675 else:
1675 else:
1676 leading = text[text_start:completion_start]
1676 leading = text[text_start:completion_start]
1677
1677
1678 # the index of the `[` character
1678 # the index of the `[` character
1679 bracket_idx = match.end(1)
1679 bracket_idx = match.end(1)
1680
1680
1681 # append closing quote and bracket as appropriate
1681 # append closing quote and bracket as appropriate
1682 # this is *not* appropriate if the opening quote or bracket is outside
1682 # this is *not* appropriate if the opening quote or bracket is outside
1683 # the text given to this method
1683 # the text given to this method
1684 suf = ''
1684 suf = ''
1685 continuation = self.line_buffer[len(self.text_until_cursor):]
1685 continuation = self.line_buffer[len(self.text_until_cursor):]
1686 if key_start > text_start and closing_quote:
1686 if key_start > text_start and closing_quote:
1687 # quotes were opened inside text, maybe close them
1687 # quotes were opened inside text, maybe close them
1688 if continuation.startswith(closing_quote):
1688 if continuation.startswith(closing_quote):
1689 continuation = continuation[len(closing_quote):]
1689 continuation = continuation[len(closing_quote):]
1690 else:
1690 else:
1691 suf += closing_quote
1691 suf += closing_quote
1692 if bracket_idx > text_start:
1692 if bracket_idx > text_start:
1693 # brackets were opened inside text, maybe close them
1693 # brackets were opened inside text, maybe close them
1694 if not continuation.startswith(']'):
1694 if not continuation.startswith(']'):
1695 suf += ']'
1695 suf += ']'
1696
1696
1697 return [leading + k + suf for k in matches]
1697 return [leading + k + suf for k in matches]
1698
1698
1699 def unicode_name_matches(self, text):
1699 def unicode_name_matches(self, text):
1700 u"""Match Latex-like syntax for unicode characters base
1700 u"""Match Latex-like syntax for unicode characters base
1701 on the name of the character.
1701 on the name of the character.
1702
1702
1703 This does ``\\GREEK SMALL LETTER ETA`` -> ``Ξ·``
1703 This does ``\\GREEK SMALL LETTER ETA`` -> ``Ξ·``
1704
1704
1705 Works only on valid python 3 identifier, or on combining characters that
1705 Works only on valid python 3 identifier, or on combining characters that
1706 will combine to form a valid identifier.
1706 will combine to form a valid identifier.
1707
1707
1708 Used on Python 3 only.
1708 Used on Python 3 only.
1709 """
1709 """
1710 slashpos = text.rfind('\\')
1710 slashpos = text.rfind('\\')
1711 if slashpos > -1:
1711 if slashpos > -1:
1712 s = text[slashpos+1:]
1712 s = text[slashpos+1:]
1713 try :
1713 try :
1714 unic = unicodedata.lookup(s)
1714 unic = unicodedata.lookup(s)
1715 # allow combining chars
1715 # allow combining chars
1716 if ('a'+unic).isidentifier():
1716 if ('a'+unic).isidentifier():
1717 return '\\'+s,[unic]
1717 return '\\'+s,[unic]
1718 except KeyError:
1718 except KeyError:
1719 pass
1719 pass
1720 return u'', []
1720 return u'', []
1721
1721
1722
1722
1723 def latex_matches(self, text):
1723 def latex_matches(self, text):
1724 u"""Match Latex syntax for unicode characters.
1724 u"""Match Latex syntax for unicode characters.
1725
1725
1726 This does both ``\\alp`` -> ``\\alpha`` and ``\\alpha`` -> ``Ξ±``
1726 This does both ``\\alp`` -> ``\\alpha`` and ``\\alpha`` -> ``Ξ±``
1727 """
1727 """
1728 slashpos = text.rfind('\\')
1728 slashpos = text.rfind('\\')
1729 if slashpos > -1:
1729 if slashpos > -1:
1730 s = text[slashpos:]
1730 s = text[slashpos:]
1731 if s in latex_symbols:
1731 if s in latex_symbols:
1732 # Try to complete a full latex symbol to unicode
1732 # Try to complete a full latex symbol to unicode
1733 # \\alpha -> Ξ±
1733 # \\alpha -> Ξ±
1734 return s, [latex_symbols[s]]
1734 return s, [latex_symbols[s]]
1735 else:
1735 else:
1736 # If a user has partially typed a latex symbol, give them
1736 # If a user has partially typed a latex symbol, give them
1737 # a full list of options \al -> [\aleph, \alpha]
1737 # a full list of options \al -> [\aleph, \alpha]
1738 matches = [k for k in latex_symbols if k.startswith(s)]
1738 matches = [k for k in latex_symbols if k.startswith(s)]
1739 if matches:
1739 if matches:
1740 return s, matches
1740 return s, matches
1741 return u'', []
1741 return u'', []
1742
1742
1743 def dispatch_custom_completer(self, text):
1743 def dispatch_custom_completer(self, text):
1744 if not self.custom_completers:
1744 if not self.custom_completers:
1745 return
1745 return
1746
1746
1747 line = self.line_buffer
1747 line = self.line_buffer
1748 if not line.strip():
1748 if not line.strip():
1749 return None
1749 return None
1750
1750
1751 # Create a little structure to pass all the relevant information about
1751 # Create a little structure to pass all the relevant information about
1752 # the current completion to any custom completer.
1752 # the current completion to any custom completer.
1753 event = SimpleNamespace()
1753 event = SimpleNamespace()
1754 event.line = line
1754 event.line = line
1755 event.symbol = text
1755 event.symbol = text
1756 cmd = line.split(None,1)[0]
1756 cmd = line.split(None,1)[0]
1757 event.command = cmd
1757 event.command = cmd
1758 event.text_until_cursor = self.text_until_cursor
1758 event.text_until_cursor = self.text_until_cursor
1759
1759
1760 # for foo etc, try also to find completer for %foo
1760 # for foo etc, try also to find completer for %foo
1761 if not cmd.startswith(self.magic_escape):
1761 if not cmd.startswith(self.magic_escape):
1762 try_magic = self.custom_completers.s_matches(
1762 try_magic = self.custom_completers.s_matches(
1763 self.magic_escape + cmd)
1763 self.magic_escape + cmd)
1764 else:
1764 else:
1765 try_magic = []
1765 try_magic = []
1766
1766
1767 for c in itertools.chain(self.custom_completers.s_matches(cmd),
1767 for c in itertools.chain(self.custom_completers.s_matches(cmd),
1768 try_magic,
1768 try_magic,
1769 self.custom_completers.flat_matches(self.text_until_cursor)):
1769 self.custom_completers.flat_matches(self.text_until_cursor)):
1770 try:
1770 try:
1771 res = c(event)
1771 res = c(event)
1772 if res:
1772 if res:
1773 # first, try case sensitive match
1773 # first, try case sensitive match
1774 withcase = [r for r in res if r.startswith(text)]
1774 withcase = [r for r in res if r.startswith(text)]
1775 if withcase:
1775 if withcase:
1776 return withcase
1776 return withcase
1777 # if none, then case insensitive ones are ok too
1777 # if none, then case insensitive ones are ok too
1778 text_low = text.lower()
1778 text_low = text.lower()
1779 return [r for r in res if r.lower().startswith(text_low)]
1779 return [r for r in res if r.lower().startswith(text_low)]
1780 except TryNext:
1780 except TryNext:
1781 pass
1781 pass
1782 except KeyboardInterrupt:
1782 except KeyboardInterrupt:
1783 """
1783 """
1784 If custom completer take too long,
1784 If custom completer take too long,
1785 let keyboard interrupt abort and return nothing.
1785 let keyboard interrupt abort and return nothing.
1786 """
1786 """
1787 break
1787 break
1788
1788
1789 return None
1789 return None
1790
1790
1791 def completions(self, text: str, offset: int)->Iterator[Completion]:
1791 def completions(self, text: str, offset: int)->Iterator[Completion]:
1792 """
1792 """
1793 Returns an iterator over the possible completions
1793 Returns an iterator over the possible completions
1794
1794
1795 .. warning:: Unstable
1795 .. warning:: Unstable
1796
1796
1797 This function is unstable, API may change without warning.
1797 This function is unstable, API may change without warning.
1798 It will also raise unless use in proper context manager.
1798 It will also raise unless use in proper context manager.
1799
1799
1800 Parameters
1800 Parameters
1801 ----------
1801 ----------
1802
1802
1803 text:str
1803 text:str
1804 Full text of the current input, multi line string.
1804 Full text of the current input, multi line string.
1805 offset:int
1805 offset:int
1806 Integer representing the position of the cursor in ``text``. Offset
1806 Integer representing the position of the cursor in ``text``. Offset
1807 is 0-based indexed.
1807 is 0-based indexed.
1808
1808
1809 Yields
1809 Yields
1810 ------
1810 ------
1811 :any:`Completion` object
1811 :any:`Completion` object
1812
1812
1813
1813
1814 The cursor on a text can either be seen as being "in between"
1814 The cursor on a text can either be seen as being "in between"
1815 characters or "On" a character depending on the interface visible to
1815 characters or "On" a character depending on the interface visible to
1816 the user. For consistency the cursor being on "in between" characters X
1816 the user. For consistency the cursor being on "in between" characters X
1817 and Y is equivalent to the cursor being "on" character Y, that is to say
1817 and Y is equivalent to the cursor being "on" character Y, that is to say
1818 the character the cursor is on is considered as being after the cursor.
1818 the character the cursor is on is considered as being after the cursor.
1819
1819
1820 Combining characters may span more that one position in the
1820 Combining characters may span more that one position in the
1821 text.
1821 text.
1822
1822
1823
1823
1824 .. note::
1824 .. note::
1825
1825
1826 If ``IPCompleter.debug`` is :any:`True` will yield a ``--jedi/ipython--``
1826 If ``IPCompleter.debug`` is :any:`True` will yield a ``--jedi/ipython--``
1827 fake Completion token to distinguish completion returned by Jedi
1827 fake Completion token to distinguish completion returned by Jedi
1828 and usual IPython completion.
1828 and usual IPython completion.
1829
1829
1830 .. note::
1830 .. note::
1831
1831
1832 Completions are not completely deduplicated yet. If identical
1832 Completions are not completely deduplicated yet. If identical
1833 completions are coming from different sources this function does not
1833 completions are coming from different sources this function does not
1834 ensure that each completion object will only be present once.
1834 ensure that each completion object will only be present once.
1835 """
1835 """
1836 warnings.warn("_complete is a provisional API (as of IPython 6.0). "
1836 warnings.warn("_complete is a provisional API (as of IPython 6.0). "
1837 "It may change without warnings. "
1837 "It may change without warnings. "
1838 "Use in corresponding context manager.",
1838 "Use in corresponding context manager.",
1839 category=ProvisionalCompleterWarning, stacklevel=2)
1839 category=ProvisionalCompleterWarning, stacklevel=2)
1840
1840
1841 seen = set()
1841 seen = set()
1842 try:
1842 try:
1843 if self.profile_completions:
1843 if self.profile_completions:
1844 import cProfile
1844 import cProfile
1845 profiler = cProfile.Profile()
1845 profiler = cProfile.Profile()
1846 profiler.enable()
1846 profiler.enable()
1847 else:
1847 else:
1848 profiler = None
1848 profiler = None
1849
1849
1850 for c in self._completions(text, offset, _timeout=self.jedi_compute_type_timeout/1000):
1850 for c in self._completions(text, offset, _timeout=self.jedi_compute_type_timeout/1000):
1851 if c and (c in seen):
1851 if c and (c in seen):
1852 continue
1852 continue
1853 yield c
1853 yield c
1854 seen.add(c)
1854 seen.add(c)
1855 except KeyboardInterrupt:
1855 except KeyboardInterrupt:
1856 """if completions take too long and users send keyboard interrupt,
1856 """if completions take too long and users send keyboard interrupt,
1857 do not crash and return ASAP. """
1857 do not crash and return ASAP. """
1858 pass
1858 pass
1859 finally:
1859 finally:
1860 if profiler is not None:
1860 if profiler is not None:
1861 profiler.disable()
1861 profiler.disable()
1862 ensure_dir_exists(self.profiler_output_dir)
1862 ensure_dir_exists(self.profiler_output_dir)
1863 output_path = os.path.join(self.profiler_output_dir, str(uuid.uuid4()))
1863 output_path = os.path.join(self.profiler_output_dir, str(uuid.uuid4()))
1864 print("Writing profiler output to", output_path)
1864 print("Writing profiler output to", output_path)
1865 profiler.dump_stats(output_path)
1865 profiler.dump_stats(output_path)
1866
1866
1867 def _completions(self, full_text: str, offset: int, *, _timeout)->Iterator[Completion]:
1867 def _completions(self, full_text: str, offset: int, *, _timeout)->Iterator[Completion]:
1868 """
1868 """
1869 Core completion module.Same signature as :any:`completions`, with the
1869 Core completion module.Same signature as :any:`completions`, with the
1870 extra `timeout` parameter (in seconds).
1870 extra `timeout` parameter (in seconds).
1871
1871
1872
1872
1873 Computing jedi's completion ``.type`` can be quite expensive (it is a
1873 Computing jedi's completion ``.type`` can be quite expensive (it is a
1874 lazy property) and can require some warm-up, more warm up than just
1874 lazy property) and can require some warm-up, more warm up than just
1875 computing the ``name`` of a completion. The warm-up can be :
1875 computing the ``name`` of a completion. The warm-up can be :
1876
1876
1877 - Long warm-up the first time a module is encountered after
1877 - Long warm-up the first time a module is encountered after
1878 install/update: actually build parse/inference tree.
1878 install/update: actually build parse/inference tree.
1879
1879
1880 - first time the module is encountered in a session: load tree from
1880 - first time the module is encountered in a session: load tree from
1881 disk.
1881 disk.
1882
1882
1883 We don't want to block completions for tens of seconds so we give the
1883 We don't want to block completions for tens of seconds so we give the
1884 completer a "budget" of ``_timeout`` seconds per invocation to compute
1884 completer a "budget" of ``_timeout`` seconds per invocation to compute
1885 completions types, the completions that have not yet been computed will
1885 completions types, the completions that have not yet been computed will
1886 be marked as "unknown" an will have a chance to be computed next round
1886 be marked as "unknown" an will have a chance to be computed next round
1887 are things get cached.
1887 are things get cached.
1888
1888
1889 Keep in mind that Jedi is not the only thing treating the completion so
1889 Keep in mind that Jedi is not the only thing treating the completion so
1890 keep the timeout short-ish as if we take more than 0.3 second we still
1890 keep the timeout short-ish as if we take more than 0.3 second we still
1891 have lots of processing to do.
1891 have lots of processing to do.
1892
1892
1893 """
1893 """
1894 deadline = time.monotonic() + _timeout
1894 deadline = time.monotonic() + _timeout
1895
1895
1896
1896
1897 before = full_text[:offset]
1897 before = full_text[:offset]
1898 cursor_line, cursor_column = position_to_cursor(full_text, offset)
1898 cursor_line, cursor_column = position_to_cursor(full_text, offset)
1899
1899
1900 matched_text, matches, matches_origin, jedi_matches = self._complete(
1900 matched_text, matches, matches_origin, jedi_matches = self._complete(
1901 full_text=full_text, cursor_line=cursor_line, cursor_pos=cursor_column)
1901 full_text=full_text, cursor_line=cursor_line, cursor_pos=cursor_column)
1902
1902
1903 iter_jm = iter(jedi_matches)
1903 iter_jm = iter(jedi_matches)
1904 if _timeout:
1904 if _timeout:
1905 for jm in iter_jm:
1905 for jm in iter_jm:
1906 try:
1906 try:
1907 type_ = jm.type
1907 type_ = jm.type
1908 except Exception:
1908 except Exception:
1909 if self.debug:
1909 if self.debug:
1910 print("Error in Jedi getting type of ", jm)
1910 print("Error in Jedi getting type of ", jm)
1911 type_ = None
1911 type_ = None
1912 delta = len(jm.name_with_symbols) - len(jm.complete)
1912 delta = len(jm.name_with_symbols) - len(jm.complete)
1913 if type_ == 'function':
1913 if type_ == 'function':
1914 signature = _make_signature(jm)
1914 signature = _make_signature(jm)
1915 else:
1915 else:
1916 signature = ''
1916 signature = ''
1917 yield Completion(start=offset - delta,
1917 yield Completion(start=offset - delta,
1918 end=offset,
1918 end=offset,
1919 text=jm.name_with_symbols,
1919 text=jm.name_with_symbols,
1920 type=type_,
1920 type=type_,
1921 signature=signature,
1921 signature=signature,
1922 _origin='jedi')
1922 _origin='jedi')
1923
1923
1924 if time.monotonic() > deadline:
1924 if time.monotonic() > deadline:
1925 break
1925 break
1926
1926
1927 for jm in iter_jm:
1927 for jm in iter_jm:
1928 delta = len(jm.name_with_symbols) - len(jm.complete)
1928 delta = len(jm.name_with_symbols) - len(jm.complete)
1929 yield Completion(start=offset - delta,
1929 yield Completion(start=offset - delta,
1930 end=offset,
1930 end=offset,
1931 text=jm.name_with_symbols,
1931 text=jm.name_with_symbols,
1932 type='<unknown>', # don't compute type for speed
1932 type='<unknown>', # don't compute type for speed
1933 _origin='jedi',
1933 _origin='jedi',
1934 signature='')
1934 signature='')
1935
1935
1936
1936
1937 start_offset = before.rfind(matched_text)
1937 start_offset = before.rfind(matched_text)
1938
1938
1939 # TODO:
1939 # TODO:
1940 # Suppress this, right now just for debug.
1940 # Suppress this, right now just for debug.
1941 if jedi_matches and matches and self.debug:
1941 if jedi_matches and matches and self.debug:
1942 yield Completion(start=start_offset, end=offset, text='--jedi/ipython--',
1942 yield Completion(start=start_offset, end=offset, text='--jedi/ipython--',
1943 _origin='debug', type='none', signature='')
1943 _origin='debug', type='none', signature='')
1944
1944
1945 # I'm unsure if this is always true, so let's assert and see if it
1945 # I'm unsure if this is always true, so let's assert and see if it
1946 # crash
1946 # crash
1947 assert before.endswith(matched_text)
1947 assert before.endswith(matched_text)
1948 for m, t in zip(matches, matches_origin):
1948 for m, t in zip(matches, matches_origin):
1949 yield Completion(start=start_offset, end=offset, text=m, _origin=t, signature='', type='<unknown>')
1949 yield Completion(start=start_offset, end=offset, text=m, _origin=t, signature='', type='<unknown>')
1950
1950
1951
1951
1952 def complete(self, text=None, line_buffer=None, cursor_pos=None):
1952 def complete(self, text=None, line_buffer=None, cursor_pos=None):
1953 """Find completions for the given text and line context.
1953 """Find completions for the given text and line context.
1954
1954
1955 Note that both the text and the line_buffer are optional, but at least
1955 Note that both the text and the line_buffer are optional, but at least
1956 one of them must be given.
1956 one of them must be given.
1957
1957
1958 Parameters
1958 Parameters
1959 ----------
1959 ----------
1960 text : string, optional
1960 text : string, optional
1961 Text to perform the completion on. If not given, the line buffer
1961 Text to perform the completion on. If not given, the line buffer
1962 is split using the instance's CompletionSplitter object.
1962 is split using the instance's CompletionSplitter object.
1963
1963
1964 line_buffer : string, optional
1964 line_buffer : string, optional
1965 If not given, the completer attempts to obtain the current line
1965 If not given, the completer attempts to obtain the current line
1966 buffer via readline. This keyword allows clients which are
1966 buffer via readline. This keyword allows clients which are
1967 requesting for text completions in non-readline contexts to inform
1967 requesting for text completions in non-readline contexts to inform
1968 the completer of the entire text.
1968 the completer of the entire text.
1969
1969
1970 cursor_pos : int, optional
1970 cursor_pos : int, optional
1971 Index of the cursor in the full line buffer. Should be provided by
1971 Index of the cursor in the full line buffer. Should be provided by
1972 remote frontends where kernel has no access to frontend state.
1972 remote frontends where kernel has no access to frontend state.
1973
1973
1974 Returns
1974 Returns
1975 -------
1975 -------
1976 text : str
1976 text : str
1977 Text that was actually used in the completion.
1977 Text that was actually used in the completion.
1978
1978
1979 matches : list
1979 matches : list
1980 A list of completion matches.
1980 A list of completion matches.
1981
1981
1982
1982
1983 .. note::
1983 .. note::
1984
1984
1985 This API is likely to be deprecated and replaced by
1985 This API is likely to be deprecated and replaced by
1986 :any:`IPCompleter.completions` in the future.
1986 :any:`IPCompleter.completions` in the future.
1987
1987
1988
1988
1989 """
1989 """
1990 warnings.warn('`Completer.complete` is pending deprecation since '
1990 warnings.warn('`Completer.complete` is pending deprecation since '
1991 'IPython 6.0 and will be replaced by `Completer.completions`.',
1991 'IPython 6.0 and will be replaced by `Completer.completions`.',
1992 PendingDeprecationWarning)
1992 PendingDeprecationWarning)
1993 # potential todo, FOLD the 3rd throw away argument of _complete
1993 # potential todo, FOLD the 3rd throw away argument of _complete
1994 # into the first 2 one.
1994 # into the first 2 one.
1995 return self._complete(line_buffer=line_buffer, cursor_pos=cursor_pos, text=text, cursor_line=0)[:2]
1995 return self._complete(line_buffer=line_buffer, cursor_pos=cursor_pos, text=text, cursor_line=0)[:2]
1996
1996
1997 def _complete(self, *, cursor_line, cursor_pos, line_buffer=None, text=None,
1997 def _complete(self, *, cursor_line, cursor_pos, line_buffer=None, text=None,
1998 full_text=None) -> Tuple[str, List[str], List[str], Iterable[_FakeJediCompletion]]:
1998 full_text=None) -> Tuple[str, List[str], List[str], Iterable[_FakeJediCompletion]]:
1999 """
1999 """
2000
2000
2001 Like complete but can also returns raw jedi completions as well as the
2001 Like complete but can also returns raw jedi completions as well as the
2002 origin of the completion text. This could (and should) be made much
2002 origin of the completion text. This could (and should) be made much
2003 cleaner but that will be simpler once we drop the old (and stateful)
2003 cleaner but that will be simpler once we drop the old (and stateful)
2004 :any:`complete` API.
2004 :any:`complete` API.
2005
2005
2006
2006
2007 With current provisional API, cursor_pos act both (depending on the
2007 With current provisional API, cursor_pos act both (depending on the
2008 caller) as the offset in the ``text`` or ``line_buffer``, or as the
2008 caller) as the offset in the ``text`` or ``line_buffer``, or as the
2009 ``column`` when passing multiline strings this could/should be renamed
2009 ``column`` when passing multiline strings this could/should be renamed
2010 but would add extra noise.
2010 but would add extra noise.
2011 """
2011 """
2012
2012
2013 # if the cursor position isn't given, the only sane assumption we can
2013 # if the cursor position isn't given, the only sane assumption we can
2014 # make is that it's at the end of the line (the common case)
2014 # make is that it's at the end of the line (the common case)
2015 if cursor_pos is None:
2015 if cursor_pos is None:
2016 cursor_pos = len(line_buffer) if text is None else len(text)
2016 cursor_pos = len(line_buffer) if text is None else len(text)
2017
2017
2018 if self.use_main_ns:
2018 if self.use_main_ns:
2019 self.namespace = __main__.__dict__
2019 self.namespace = __main__.__dict__
2020
2020
2021 # if text is either None or an empty string, rely on the line buffer
2021 # if text is either None or an empty string, rely on the line buffer
2022 if (not line_buffer) and full_text:
2022 if (not line_buffer) and full_text:
2023 line_buffer = full_text.split('\n')[cursor_line]
2023 line_buffer = full_text.split('\n')[cursor_line]
2024 if not text:
2024 if not text:
2025 text = self.splitter.split_line(line_buffer, cursor_pos)
2025 text = self.splitter.split_line(line_buffer, cursor_pos)
2026
2026
2027 if self.backslash_combining_completions:
2027 if self.backslash_combining_completions:
2028 # allow deactivation of these on windows.
2028 # allow deactivation of these on windows.
2029 base_text = text if not line_buffer else line_buffer[:cursor_pos]
2029 base_text = text if not line_buffer else line_buffer[:cursor_pos]
2030 latex_text, latex_matches = self.latex_matches(base_text)
2030 latex_text, latex_matches = self.latex_matches(base_text)
2031 if latex_matches:
2031 if latex_matches:
2032 return latex_text, latex_matches, ['latex_matches']*len(latex_matches), ()
2032 return latex_text, latex_matches, ['latex_matches']*len(latex_matches), ()
2033 name_text = ''
2033 name_text = ''
2034 name_matches = []
2034 name_matches = []
2035 # need to add self.fwd_unicode_match() function here when done
2035 # need to add self.fwd_unicode_match() function here when done
2036 for meth in (self.unicode_name_matches, back_latex_name_matches, back_unicode_name_matches, self.fwd_unicode_match):
2036 for meth in (self.unicode_name_matches, back_latex_name_matches, back_unicode_name_matches, self.fwd_unicode_match):
2037 name_text, name_matches = meth(base_text)
2037 name_text, name_matches = meth(base_text)
2038 if name_text:
2038 if name_text:
2039 return name_text, name_matches[:MATCHES_LIMIT], \
2039 return name_text, name_matches[:MATCHES_LIMIT], \
2040 [meth.__qualname__]*min(len(name_matches), MATCHES_LIMIT), ()
2040 [meth.__qualname__]*min(len(name_matches), MATCHES_LIMIT), ()
2041
2041
2042
2042
2043 # If no line buffer is given, assume the input text is all there was
2043 # If no line buffer is given, assume the input text is all there was
2044 if line_buffer is None:
2044 if line_buffer is None:
2045 line_buffer = text
2045 line_buffer = text
2046
2046
2047 self.line_buffer = line_buffer
2047 self.line_buffer = line_buffer
2048 self.text_until_cursor = self.line_buffer[:cursor_pos]
2048 self.text_until_cursor = self.line_buffer[:cursor_pos]
2049
2049
2050 # Do magic arg matches
2050 # Do magic arg matches
2051 for matcher in self.magic_arg_matchers:
2051 for matcher in self.magic_arg_matchers:
2052 matches = list(matcher(line_buffer))[:MATCHES_LIMIT]
2052 matches = list(matcher(line_buffer))[:MATCHES_LIMIT]
2053 if matches:
2053 if matches:
2054 origins = [matcher.__qualname__] * len(matches)
2054 origins = [matcher.__qualname__] * len(matches)
2055 return text, matches, origins, ()
2055 return text, matches, origins, ()
2056
2056
2057 # Start with a clean slate of completions
2057 # Start with a clean slate of completions
2058 matches = []
2058 matches = []
2059
2059
2060 # FIXME: we should extend our api to return a dict with completions for
2060 # FIXME: we should extend our api to return a dict with completions for
2061 # different types of objects. The rlcomplete() method could then
2061 # different types of objects. The rlcomplete() method could then
2062 # simply collapse the dict into a list for readline, but we'd have
2062 # simply collapse the dict into a list for readline, but we'd have
2063 # richer completion semantics in other environments.
2063 # richer completion semantics in other environments.
2064 completions = ()
2064 completions = ()
2065 if self.use_jedi:
2065 if self.use_jedi:
2066 if not full_text:
2066 if not full_text:
2067 full_text = line_buffer
2067 full_text = line_buffer
2068 completions = self._jedi_matches(
2068 completions = self._jedi_matches(
2069 cursor_pos, cursor_line, full_text)
2069 cursor_pos, cursor_line, full_text)
2070
2070
2071 if self.merge_completions:
2071 if self.merge_completions:
2072 matches = []
2072 matches = []
2073 for matcher in self.matchers:
2073 for matcher in self.matchers:
2074 try:
2074 try:
2075 matches.extend([(m, matcher.__qualname__)
2075 matches.extend([(m, matcher.__qualname__)
2076 for m in matcher(text)])
2076 for m in matcher(text)])
2077 except:
2077 except:
2078 # Show the ugly traceback if the matcher causes an
2078 # Show the ugly traceback if the matcher causes an
2079 # exception, but do NOT crash the kernel!
2079 # exception, but do NOT crash the kernel!
2080 sys.excepthook(*sys.exc_info())
2080 sys.excepthook(*sys.exc_info())
2081 else:
2081 else:
2082 for matcher in self.matchers:
2082 for matcher in self.matchers:
2083 matches = [(m, matcher.__qualname__)
2083 matches = [(m, matcher.__qualname__)
2084 for m in matcher(text)]
2084 for m in matcher(text)]
2085 if matches:
2085 if matches:
2086 break
2086 break
2087
2087
2088 seen = set()
2088 seen = set()
2089 filtered_matches = set()
2089 filtered_matches = set()
2090 for m in matches:
2090 for m in matches:
2091 t, c = m
2091 t, c = m
2092 if t not in seen:
2092 if t not in seen:
2093 filtered_matches.add(m)
2093 filtered_matches.add(m)
2094 seen.add(t)
2094 seen.add(t)
2095
2095
2096 _filtered_matches = sorted(filtered_matches, key=lambda x: completions_sorting_key(x[0]))
2096 _filtered_matches = sorted(filtered_matches, key=lambda x: completions_sorting_key(x[0]))
2097
2097
2098 custom_res = [(m, 'custom') for m in self.dispatch_custom_completer(text) or []]
2098 custom_res = [(m, 'custom') for m in self.dispatch_custom_completer(text) or []]
2099
2099
2100 _filtered_matches = custom_res or _filtered_matches
2100 _filtered_matches = custom_res or _filtered_matches
2101
2101
2102 _filtered_matches = _filtered_matches[:MATCHES_LIMIT]
2102 _filtered_matches = _filtered_matches[:MATCHES_LIMIT]
2103 _matches = [m[0] for m in _filtered_matches]
2103 _matches = [m[0] for m in _filtered_matches]
2104 origins = [m[1] for m in _filtered_matches]
2104 origins = [m[1] for m in _filtered_matches]
2105
2105
2106 self.matches = _matches
2106 self.matches = _matches
2107
2107
2108 return text, _matches, origins, completions
2108 return text, _matches, origins, completions
2109
2109
2110 def fwd_unicode_match(self, text:str) -> Tuple[str, list]:
2110 def fwd_unicode_match(self, text:str) -> Tuple[str, list]:
2111
2111
2112 slashpos = text.rfind('\\')
2112 slashpos = text.rfind('\\')
2113 # if text starts with slash
2113 # if text starts with slash
2114 if slashpos > -1:
2114 if slashpos > -1:
2115 # PERF: It's important that we don't access self._unicode_names
2115 # PERF: It's important that we don't access self._unicode_names
2116 # until we're inside this if-block. _unicode_names is lazily
2116 # until we're inside this if-block. _unicode_names is lazily
2117 # initialized, and it takes a user-noticeable amount of time to
2117 # initialized, and it takes a user-noticeable amount of time to
2118 # initialize it, so we don't want to initialize it unless we're
2118 # initialize it, so we don't want to initialize it unless we're
2119 # actually going to use it.
2119 # actually going to use it.
2120 s = text[slashpos+1:]
2120 s = text[slashpos+1:]
2121 candidates = [x for x in self.unicode_names if x.startswith(s)]
2121 candidates = [x for x in self.unicode_names if x.startswith(s)]
2122 if candidates:
2122 if candidates:
2123 return s, candidates
2123 return s, candidates
2124 else:
2124 else:
2125 return '', ()
2125 return '', ()
2126
2126
2127 # if text does not start with slash
2127 # if text does not start with slash
2128 else:
2128 else:
2129 return u'', ()
2129 return u'', ()
2130
2130
2131 @property
2131 @property
2132 def unicode_names(self) -> List[str]:
2132 def unicode_names(self) -> List[str]:
2133 """List of names of unicode code points that can be completed.
2133 """List of names of unicode code points that can be completed.
2134
2134
2135 The list is lazily initialized on first access.
2135 The list is lazily initialized on first access.
2136 """
2136 """
2137 if self._unicode_names is None:
2137 if self._unicode_names is None:
2138 names = []
2138 names = []
2139 for c in range(0,0x10FFFF + 1):
2139 for c in range(0,0x10FFFF + 1):
2140 try:
2140 try:
2141 names.append(unicodedata.name(chr(c)))
2141 names.append(unicodedata.name(chr(c)))
2142 except ValueError:
2142 except ValueError:
2143 pass
2143 pass
2144 self._unicode_names = names
2144 self._unicode_names = names
2145
2145
2146 return self._unicode_names
2146 return self._unicode_names
General Comments 0
You need to be logged in to leave comments. Login now