Show More
@@ -53,6 +53,8 b' Notes:' | |||||
53 | # Some of this code originated from rlcompleter in the Python standard library |
|
53 | # Some of this code originated from rlcompleter in the Python standard library | |
54 | # Copyright (C) 2001 Python Software Foundation, www.python.org |
|
54 | # Copyright (C) 2001 Python Software Foundation, www.python.org | |
55 |
|
55 | |||
|
56 | from __future__ import print_function | |||
|
57 | ||||
56 | import __main__ |
|
58 | import __main__ | |
57 | import glob |
|
59 | import glob | |
58 | import inspect |
|
60 | import inspect | |
@@ -75,6 +77,14 b' from IPython.utils.process import arg_split' | |||||
75 | from IPython.utils.py3compat import builtin_mod, string_types, PY3, cast_unicode_py2 |
|
77 | from IPython.utils.py3compat import builtin_mod, string_types, PY3, cast_unicode_py2 | |
76 | from traitlets import CBool, Enum |
|
78 | from traitlets import CBool, Enum | |
77 |
|
79 | |||
|
80 | try: | |||
|
81 | import jedi | |||
|
82 | import jedi.api.helpers | |||
|
83 | import jedi.parser.user_context | |||
|
84 | JEDI_INSTALLED = True | |||
|
85 | except ImportError: | |||
|
86 | JEDI_INSTALLED = False | |||
|
87 | ||||
78 | #----------------------------------------------------------------------------- |
|
88 | #----------------------------------------------------------------------------- | |
79 | # Globals |
|
89 | # Globals | |
80 | #----------------------------------------------------------------------------- |
|
90 | #----------------------------------------------------------------------------- | |
@@ -269,6 +279,7 b' class Completer(Configurable):' | |||||
269 |
|
279 | |||
270 | greedy = CBool(False, config=True, |
|
280 | greedy = CBool(False, config=True, | |
271 | help="""Activate greedy completion |
|
281 | help="""Activate greedy completion | |
|
282 | PENDING DEPRECTION. this is now mostly taken care of with Jedi. | |||
272 |
|
283 | |||
273 | This will enable completion on elements of lists, results of function calls, etc., |
|
284 | This will enable completion on elements of lists, results of function calls, etc., | |
274 | but can be unsafe because the code is actually evaluated on TAB. |
|
285 | but can be unsafe because the code is actually evaluated on TAB. | |
@@ -339,7 +350,6 b' class Completer(Configurable):' | |||||
339 | defined in self.namespace or self.global_namespace that match. |
|
350 | defined in self.namespace or self.global_namespace that match. | |
340 |
|
351 | |||
341 | """ |
|
352 | """ | |
342 | #print 'Completer->global_matches, txt=%r' % text # dbg |
|
|||
343 | matches = [] |
|
353 | matches = [] | |
344 | match_append = matches.append |
|
354 | match_append = matches.append | |
345 | n = len(text) |
|
355 | n = len(text) | |
@@ -366,7 +376,6 b' class Completer(Configurable):' | |||||
366 |
|
376 | |||
367 | """ |
|
377 | """ | |
368 |
|
378 | |||
369 | #io.rprint('Completer->attr_matches, txt=%r' % text) # dbg |
|
|||
370 | # Another option, seems to work great. Catches things like ''.<tab> |
|
379 | # Another option, seems to work great. Catches things like ''.<tab> | |
371 | m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text) |
|
380 | m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text) | |
372 |
|
381 | |||
@@ -565,7 +574,10 b' class IPCompleter(Completer):' | |||||
565 | """ |
|
574 | """ | |
566 | ) |
|
575 | ) | |
567 | limit_to__all__ = CBool(default_value=False, config=True, |
|
576 | limit_to__all__ = CBool(default_value=False, config=True, | |
568 | help="""Instruct the completer to use __all__ for the completion |
|
577 | help=""" | |
|
578 | DEPRECATED as of version 5.0. | |||
|
579 | ||||
|
580 | Instruct the completer to use __all__ for the completion | |||
569 |
|
581 | |||
570 | Specifically, when completing on ``object.<tab>``. |
|
582 | Specifically, when completing on ``object.<tab>``. | |
571 |
|
583 | |||
@@ -574,6 +586,9 b' class IPCompleter(Completer):' | |||||
574 | When False [default]: the __all__ attribute is ignored |
|
586 | When False [default]: the __all__ attribute is ignored | |
575 | """ |
|
587 | """ | |
576 | ) |
|
588 | ) | |
|
589 | use_jedi_completions = CBool(default_value=JEDI_INSTALLED, config=True, | |||
|
590 | help="""Use Jedi to generate autocompletions. | |||
|
591 | """) | |||
577 |
|
592 | |||
578 | def __init__(self, shell=None, namespace=None, global_namespace=None, |
|
593 | def __init__(self, shell=None, namespace=None, global_namespace=None, | |
579 | use_readline=True, config=None, **kwargs): |
|
594 | use_readline=True, config=None, **kwargs): | |
@@ -640,7 +655,7 b' class IPCompleter(Completer):' | |||||
640 | #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)') |
|
655 | #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)') | |
641 |
|
656 | |||
642 | # All active matcher routines for completion |
|
657 | # All active matcher routines for completion | |
643 |
self.matchers = [ |
|
658 | self.matchers = [ | |
644 | self.file_matches, |
|
659 | self.file_matches, | |
645 | self.magic_matches, |
|
660 | self.magic_matches, | |
646 | self.python_func_kw_matches, |
|
661 | self.python_func_kw_matches, | |
@@ -675,8 +690,6 b' class IPCompleter(Completer):' | |||||
675 | current (as of Python 2.3) Python readline it's possible to do |
|
690 | current (as of Python 2.3) Python readline it's possible to do | |
676 | better.""" |
|
691 | better.""" | |
677 |
|
692 | |||
678 | #io.rprint('Completer->file_matches: <%r>' % text) # dbg |
|
|||
679 |
|
||||
680 | # chars that require escaping with backslash - i.e. chars |
|
693 | # chars that require escaping with backslash - i.e. chars | |
681 | # that readline treats incorrectly as delimiters, but we |
|
694 | # that readline treats incorrectly as delimiters, but we | |
682 | # don't want to treat as delimiters in filename matching |
|
695 | # don't want to treat as delimiters in filename matching | |
@@ -743,7 +756,6 b' class IPCompleter(Completer):' | |||||
743 |
|
756 | |||
744 | def magic_matches(self, text): |
|
757 | def magic_matches(self, text): | |
745 | """Match magics""" |
|
758 | """Match magics""" | |
746 | #print 'Completer->magic_matches:',text,'lb',self.text_until_cursor # dbg |
|
|||
747 | # Get all shell magics now rather than statically, so magics loaded at |
|
759 | # Get all shell magics now rather than statically, so magics loaded at | |
748 | # runtime show up too. |
|
760 | # runtime show up too. | |
749 | lsm = self.shell.magics_manager.lsmagic() |
|
761 | lsm = self.shell.magics_manager.lsmagic() | |
@@ -763,10 +775,62 b' class IPCompleter(Completer):' | |||||
763 | comp += [ pre+m for m in line_magics if m.startswith(bare_text)] |
|
775 | comp += [ pre+m for m in line_magics if m.startswith(bare_text)] | |
764 | return [cast_unicode_py2(c) for c in comp] |
|
776 | return [cast_unicode_py2(c) for c in comp] | |
765 |
|
777 | |||
|
778 | def python_jedi_matches(self, text, line_buffer, cursor_pos): | |||
|
779 | """Match attributes or global Python names using Jedi.""" | |||
|
780 | if line_buffer.startswith('aimport ') or line_buffer.startswith('%aimport '): | |||
|
781 | return () | |||
|
782 | namespaces = [] | |||
|
783 | if self.namespace is None: | |||
|
784 | import __main__ | |||
|
785 | namespaces.append(__main__.__dict__) | |||
|
786 | else: | |||
|
787 | namespaces.append(self.namespace) | |||
|
788 | if self.global_namespace is not None: | |||
|
789 | namespaces.append(self.global_namespace) | |||
|
790 | ||||
|
791 | # cursor_pos is an it, jedi wants line and column | |||
|
792 | ||||
|
793 | interpreter = jedi.Interpreter(line_buffer, namespaces, column=cursor_pos) | |||
|
794 | path = jedi.parser.user_context.UserContext(line_buffer, \ | |||
|
795 | (1, len(line_buffer))).get_path_until_cursor() | |||
|
796 | path, dot, like = jedi.api.helpers.completion_parts(path) | |||
|
797 | if text.startswith('.'): | |||
|
798 | # text will be `.` on completions like `a[0].<tab>` | |||
|
799 | before = dot | |||
|
800 | else: | |||
|
801 | before = line_buffer[:len(line_buffer) - len(like)] | |||
|
802 | ||||
|
803 | ||||
|
804 | def trim_start(completion): | |||
|
805 | """completions need to start with `text`, trim the beginning until it does""" | |||
|
806 | if text in completion and not (completion.startswith(text)): | |||
|
807 | start_index = completion.index(text) | |||
|
808 | if cursor_pos: | |||
|
809 | assert start_index < cursor_pos | |||
|
810 | return completion[start_index:] | |||
|
811 | return completion | |||
|
812 | ||||
|
813 | completions = interpreter.completions() | |||
|
814 | ||||
|
815 | completion_text = [c.name_with_symbols for c in completions] | |||
|
816 | ||||
|
817 | if self.omit__names: | |||
|
818 | if self.omit__names == 1: | |||
|
819 | # true if txt is _not_ a __ name, false otherwise: | |||
|
820 | no__name = lambda txt: not txt.startswith('__') | |||
|
821 | else: | |||
|
822 | # true if txt is _not_ a _ name, false otherwise: | |||
|
823 | no__name = lambda txt: not txt.startswith('_') | |||
|
824 | completion_text = filter(no__name, completion_text) | |||
|
825 | ||||
|
826 | ||||
|
827 | return [trim_start(before + c_text) for c_text in completion_text] | |||
|
828 | ||||
|
829 | ||||
766 | def python_matches(self, text): |
|
830 | def python_matches(self, text): | |
767 | """Match attributes or global python names""" |
|
831 | """Match attributes or global python names""" | |
|
832 | # Jedi completion | |||
768 |
|
833 | |||
769 | #io.rprint('Completer->python_matches, txt=%r' % text) # dbg |
|
|||
770 | if "." in text: |
|
834 | if "." in text: | |
771 | try: |
|
835 | try: | |
772 | matches = self.attr_matches(text) |
|
836 | matches = self.attr_matches(text) | |
@@ -1085,8 +1149,6 b' class IPCompleter(Completer):' | |||||
1085 | event.command = cmd |
|
1149 | event.command = cmd | |
1086 | event.text_until_cursor = self.text_until_cursor |
|
1150 | event.text_until_cursor = self.text_until_cursor | |
1087 |
|
1151 | |||
1088 | #print "\ncustom:{%s]\n" % event # dbg |
|
|||
1089 |
|
||||
1090 | # for foo etc, try also to find completer for %foo |
|
1152 | # for foo etc, try also to find completer for %foo | |
1091 | if not cmd.startswith(self.magic_escape): |
|
1153 | if not cmd.startswith(self.magic_escape): | |
1092 | try_magic = self.custom_completers.s_matches( |
|
1154 | try_magic = self.custom_completers.s_matches( | |
@@ -1142,8 +1204,6 b' class IPCompleter(Completer):' | |||||
1142 | matches : list |
|
1204 | matches : list | |
1143 | A list of completion matches. |
|
1205 | A list of completion matches. | |
1144 | """ |
|
1206 | """ | |
1145 | # io.rprint('\nCOMP1 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg |
|
|||
1146 |
|
||||
1147 | # if the cursor position isn't given, the only sane assumption we can |
|
1207 | # if the cursor position isn't given, the only sane assumption we can | |
1148 | # make is that it's at the end of the line (the common case) |
|
1208 | # make is that it's at the end of the line (the common case) | |
1149 | if cursor_pos is None: |
|
1209 | if cursor_pos is None: | |
@@ -1172,7 +1232,6 b' class IPCompleter(Completer):' | |||||
1172 |
|
1232 | |||
1173 | self.line_buffer = line_buffer |
|
1233 | self.line_buffer = line_buffer | |
1174 | self.text_until_cursor = self.line_buffer[:cursor_pos] |
|
1234 | self.text_until_cursor = self.line_buffer[:cursor_pos] | |
1175 | # io.rprint('COMP2 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg |
|
|||
1176 |
|
1235 | |||
1177 | # Start with a clean slate of completions |
|
1236 | # Start with a clean slate of completions | |
1178 | self.matches[:] = [] |
|
1237 | self.matches[:] = [] | |
@@ -1202,10 +1261,11 b' class IPCompleter(Completer):' | |||||
1202 | # different types of objects. The rlcomplete() method could then |
|
1261 | # different types of objects. The rlcomplete() method could then | |
1203 | # simply collapse the dict into a list for readline, but we'd have |
|
1262 | # simply collapse the dict into a list for readline, but we'd have | |
1204 | # richer completion semantics in other evironments. |
|
1263 | # richer completion semantics in other evironments. | |
|
1264 | if self.use_jedi_completions: | |||
|
1265 | self.matches.extend(self.python_jedi_matches(text, line_buffer, cursor_pos)) | |||
1205 |
|
1266 | |||
1206 | self.matches = sorted(set(self.matches), key=completions_sorting_key) |
|
1267 | self.matches = sorted(set(self.matches), key=completions_sorting_key) | |
1207 |
|
1268 | |||
1208 | #io.rprint('COMP TEXT, MATCHES: %r, %r' % (text, self.matches)) # dbg |
|
|||
1209 | return text, self.matches |
|
1269 | return text, self.matches | |
1210 |
|
1270 | |||
1211 | def rlcomplete(self, text, state): |
|
1271 | def rlcomplete(self, text, state): |
@@ -181,7 +181,7 b' def test_no_ascii_back_completion():' | |||||
181 | ip = get_ipython() |
|
181 | ip = get_ipython() | |
182 | with TemporaryWorkingDirectory(): # Avoid any filename completions |
|
182 | with TemporaryWorkingDirectory(): # Avoid any filename completions | |
183 | # single ascii letter that don't have yet completions |
|
183 | # single ascii letter that don't have yet completions | |
184 |
for letter in ' |
|
184 | for letter in 'jJ' : | |
185 | name, matches = ip.complete('\\'+letter) |
|
185 | name, matches = ip.complete('\\'+letter) | |
186 | nt.assert_equal(matches, []) |
|
186 | nt.assert_equal(matches, []) | |
187 |
|
187 | |||
@@ -264,19 +264,36 b' def test_local_file_completions():' | |||||
264 | # Now check with a function call |
|
264 | # Now check with a function call | |
265 | cmd = 'a = f("%s' % prefix |
|
265 | cmd = 'a = f("%s' % prefix | |
266 | c = ip.complete(prefix, cmd)[1] |
|
266 | c = ip.complete(prefix, cmd)[1] | |
267 |
comp = |
|
267 | comp = set(prefix+s for s in suffixes) | |
268 |
nt.assert_ |
|
268 | nt.assert_true(comp.issubset(set(c))) | |
269 |
|
269 | |||
270 |
|
270 | |||
271 | def test_greedy_completions(): |
|
271 | def test_greedy_completions(): | |
272 | ip = get_ipython() |
|
272 | ip = get_ipython() | |
273 | ip.ex('a=list(range(5))') |
|
273 | ip.ex('a=list(range(5))') | |
274 | _,c = ip.complete('.',line='a[0].') |
|
274 | _,c = ip.complete('.',line='a[0].') | |
275 |
nt.assert_false(' |
|
275 | nt.assert_false('.real' in c, | |
276 | "Shouldn't have completed on a[0]: %s"%c) |
|
276 | "Shouldn't have completed on a[0]: %s"%c) | |
277 | with greedy_completion(): |
|
277 | with greedy_completion(): | |
278 | _,c = ip.complete('.',line='a[0].') |
|
278 | def _(line, cursor_pos, expect, message): | |
279 | nt.assert_true('a[0].real' in c, "Should have completed on a[0]: %s"%c) |
|
279 | _,c = ip.complete('.', line=line, cursor_pos=cursor_pos) | |
|
280 | nt.assert_in(expect, c, message%c) | |||
|
281 | ||||
|
282 | yield _, 'a[0].', 5, '.real', "Should have completed on a[0].: %s" | |||
|
283 | yield _, 'a[0].r', 6, '.real', "Should have completed on a[0].r: %s" | |||
|
284 | ||||
|
285 | if sys.version_info > (3,4): | |||
|
286 | yield _, 'a[0].from_', 10, '.from_bytes', "Should have completed on a[0].from_: %s" | |||
|
287 | ||||
|
288 | ||||
|
289 | def _2(): | |||
|
290 | # jedi bug, this will be empty, makeitfail for now, | |||
|
291 | # once jedi is fixed, switch to assert_in | |||
|
292 | # https://github.com/davidhalter/jedi/issues/718 | |||
|
293 | _,c = ip.complete('.',line='a[0].from', cursor_pos=9) | |||
|
294 | nt.assert_not_in('.from_bytes', c, "Should not have completed on a[0].from (jedi bug), if fails, update test to assert_in: %s"%c) | |||
|
295 | yield _2 | |||
|
296 | ||||
280 |
|
297 | |||
281 |
|
298 | |||
282 | def test_omit__names(): |
|
299 | def test_omit__names(): | |
@@ -321,20 +338,6 b' def test_limit_to__all__False_ok():' | |||||
321 | nt.assert_in('d.x', matches) |
|
338 | nt.assert_in('d.x', matches) | |
322 |
|
339 | |||
323 |
|
340 | |||
324 | def test_limit_to__all__True_ok(): |
|
|||
325 | ip = get_ipython() |
|
|||
326 | c = ip.Completer |
|
|||
327 | ip.ex('class D: x=24') |
|
|||
328 | ip.ex('d=D()') |
|
|||
329 | ip.ex("d.__all__=['z']") |
|
|||
330 | cfg = Config() |
|
|||
331 | cfg.IPCompleter.limit_to__all__ = True |
|
|||
332 | c.update_config(cfg) |
|
|||
333 | s, matches = c.complete('d.') |
|
|||
334 | nt.assert_in('d.z', matches) |
|
|||
335 | nt.assert_not_in('d.x', matches) |
|
|||
336 |
|
||||
337 |
|
||||
338 | def test_get__all__entries_ok(): |
|
341 | def test_get__all__entries_ok(): | |
339 | class A(object): |
|
342 | class A(object): | |
340 | __all__ = ['x', 1] |
|
343 | __all__ = ['x', 1] | |
@@ -366,7 +369,6 b' def test_func_kw_completions():' | |||||
366 |
|
369 | |||
367 |
|
370 | |||
368 | def test_default_arguments_from_docstring(): |
|
371 | def test_default_arguments_from_docstring(): | |
369 | doc = min.__doc__ |
|
|||
370 | ip = get_ipython() |
|
372 | ip = get_ipython() | |
371 | c = ip.Completer |
|
373 | c = ip.Completer | |
372 | kwd = c._default_arguments_from_docstring( |
|
374 | kwd = c._default_arguments_from_docstring( |
@@ -68,9 +68,13 b' class IPythonPTCompleter(Completer):' | |||||
68 | yield Completion(m, start_position=start_pos - 1) |
|
68 | yield Completion(m, start_position=start_pos - 1) | |
69 | continue |
|
69 | continue | |
70 |
|
70 | |||
|
71 | # TODO: Use Jedi to determine meta_text | |||
|
72 | # (Jedi currently has a bug that results in incorrect information.) | |||
|
73 | # meta_text = '' | |||
|
74 | # yield Completion(m, start_position=start_pos, | |||
|
75 | # display_meta=meta_text) | |||
71 | yield Completion(m, start_position=start_pos) |
|
76 | yield Completion(m, start_position=start_pos) | |
72 |
|
77 | |||
73 |
|
||||
74 | class IPythonPTLexer(Lexer): |
|
78 | class IPythonPTLexer(Lexer): | |
75 | """ |
|
79 | """ | |
76 | Wrapper around PythonLexer and BashLexer. |
|
80 | Wrapper around PythonLexer and BashLexer. |
@@ -182,7 +182,7 b' extras_require = dict(' | |||||
182 | parallel = ['ipyparallel'], |
|
182 | parallel = ['ipyparallel'], | |
183 | qtconsole = ['qtconsole'], |
|
183 | qtconsole = ['qtconsole'], | |
184 | doc = ['Sphinx>=1.3'], |
|
184 | doc = ['Sphinx>=1.3'], | |
185 | test = ['nose>=0.10.1', 'requests', 'testpath', 'pygments'], |
|
185 | test = ['nose>=0.10.1', 'requests', 'testpath', 'pygments', 'path.py'], | |
186 | terminal = [], |
|
186 | terminal = [], | |
187 | kernel = ['ipykernel'], |
|
187 | kernel = ['ipykernel'], | |
188 | nbformat = ['nbformat'], |
|
188 | nbformat = ['nbformat'], | |
@@ -191,6 +191,7 b' extras_require = dict(' | |||||
191 | ) |
|
191 | ) | |
192 | install_requires = [ |
|
192 | install_requires = [ | |
193 | 'setuptools>=18.5', |
|
193 | 'setuptools>=18.5', | |
|
194 | 'jedi', | |||
194 | 'decorator', |
|
195 | 'decorator', | |
195 | 'pickleshare', |
|
196 | 'pickleshare', | |
196 | 'simplegeneric>0.8', |
|
197 | 'simplegeneric>0.8', |
General Comments 0
You need to be logged in to leave comments.
Login now