##// END OF EJS Templates
Merge pull request #9375 from liukelly/jedi_completion...
Matthias Bussonnier -
r22297:730393a7 merge
parent child Browse files
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.
@@ -279,7 +290,7 b' class Completer(Configurable):'
279 def __init__(self, namespace=None, global_namespace=None, **kwargs):
290 def __init__(self, namespace=None, global_namespace=None, **kwargs):
280 """Create a new completer for the command line.
291 """Create a new completer for the command line.
281
292
282 Completer(namespace=ns,global_namespace=ns2) -> completer instance.
293 Completer(namespace=ns, global_namespace=ns2) -> completer instance.
283
294
284 If unspecified, the default namespace where completions are performed
295 If unspecified, the default namespace where completions are performed
285 is __main__ (technically, __main__.__dict__). Namespaces should be
296 is __main__ (technically, __main__.__dict__). Namespaces should be
@@ -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 = [self.python_matches,
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,
@@ -654,7 +669,7 b' class IPCompleter(Completer):'
654 """
669 """
655 return self.complete(text)[1]
670 return self.complete(text)[1]
656
671
657 def _clean_glob(self,text):
672 def _clean_glob(self, text):
658 return self.glob("%s*" % text)
673 return self.glob("%s*" % text)
659
674
660 def _clean_glob_win32(self,text):
675 def _clean_glob_win32(self,text):
@@ -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"""
768
832 # Jedi completion
769 #io.rprint('Completer->python_matches, txt=%r' % text) # dbg
833
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 'fjqyJMQVWY' :
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 = [prefix+s for s in suffixes]
267 comp = set(prefix+s for s in suffixes)
268 nt.assert_equal(c, comp)
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('a[0].real' in c,
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