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