1
0
forked from VimPlug/jedi

use builtin repl completion after all, but written by us not the std lib module, which doesn't seem to work really, #280

This commit is contained in:
David Halter
2013-08-15 12:47:10 +04:30
parent 306dbf12e4
commit 9a3ea38b1c
4 changed files with 47 additions and 12 deletions

View File

@@ -173,3 +173,8 @@ def u(string):
elif not isinstance(string, unicode): elif not isinstance(string, unicode):
return unicode(str(string), 'UTF-8') return unicode(str(string), 'UTF-8')
return string return string
try:
import builtins # module name in python 3
except ImportError:
import __builtin__ as builtins

View File

@@ -91,7 +91,7 @@ class Script(object):
path = self._module.get_path_until_cursor() path = self._module.get_path_until_cursor()
if re.search('^\.|\.\.$', path): if re.search('^\.|\.\.$', path):
return [] return []
path, dot, like = self._get_completion_parts(path) path, dot, like = self._get_completion_parts()
completion_line = self._module.get_line(self.pos[0])[:self.pos[1]] completion_line = self._module.get_line(self.pos[0])[:self.pos[1]]
try: try:
@@ -506,11 +506,12 @@ class Script(object):
kill_count=kill_count, direct_resolve=True) kill_count=kill_count, direct_resolve=True)
return i, cur_name_part return i, cur_name_part
def _get_completion_parts(self, path): def _get_completion_parts(self):
""" """
Returns the parts for the completion Returns the parts for the completion
:return: tuple - (path, dot, like) :return: tuple - (path, dot, like)
""" """
path = self._module.get_path_until_cursor()
match = re.match(r'^(.*?)(\.|)(\w?[\w\d]*)$', path, flags=re.S) match = re.match(r'^(.*?)(\.|)(\w?[\w\d]*)$', path, flags=re.S)
return match.groups() return match.groups()

View File

@@ -95,13 +95,13 @@ class ModuleWithCursor(Module):
def __init__(self, path, source, position): def __init__(self, path, source, position):
super(ModuleWithCursor, self).__init__(path, source) super(ModuleWithCursor, self).__init__(path, source)
self.position = position self.position = position
self.source = source
self._path_until_cursor = None
# this two are only used, because there is no nonlocal in Python 2 # this two are only used, because there is no nonlocal in Python 2
self._line_temp = None self._line_temp = None
self._relevant_temp = None self._relevant_temp = None
self.source = source
@property @property
def parser(self): def parser(self):
""" get the parser lazy """ """ get the parser lazy """
@@ -121,9 +121,10 @@ class ModuleWithCursor(Module):
def get_path_until_cursor(self): def get_path_until_cursor(self):
""" Get the path under the cursor. """ """ Get the path under the cursor. """
result = self._get_path_until_cursor() if self._path_until_cursor is None: # small caching
self._start_cursor_pos = self._start_cursor_pos_temp self._path_until_cursor = self._get_path_until_cursor()
return result self._start_cursor_pos = self._start_cursor_pos_temp
return self._path_until_cursor
def _get_path_until_cursor(self, start_pos=None): def _get_path_until_cursor(self, start_pos=None):
def fetch_line(): def fetch_line():

View File

@@ -4,7 +4,9 @@ Utilities for end-users.
from __future__ import absolute_import from __future__ import absolute_import
import __main__ import __main__
import re
from jedi._compatibility import builtins
from jedi import Interpreter from jedi import Interpreter
@@ -61,20 +63,46 @@ def setup_readline():
a lot more sense, but probably due to backwards compatibility a lot more sense, but probably due to backwards compatibility
this is still the way how it works. this is still the way how it works.
The only important part is the ``Interpreter`` call, everything The only important part is stuff in the ``state == 0`` flow,
else hsa been copied from the ``rlcompleter`` std. library everything else has been copied from the ``rlcompleter`` std.
module. library module.
""" """
if state == 0: if state == 0:
namespace = __main__.__dict__ namespace = __main__.__dict__
completions = Interpreter(text, [namespace]).completions() interpreter = Interpreter(text, [namespace])
self.matches = [text + c.complete for c in completions]
# The following part is a bit hackish, because it tries to
# directly access some jedi internals. The goal is to just
# use the "default" completion with ``getattr`` if
# possible.
path, dot, like = interpreter._get_completion_parts()
if re.match('^[\w][\w\d.]*$', path):
paths = path.split('.') if path else []
namespaces = (namespace, builtins)
for p in paths:
old, namespaces = namespaces, []
for n in old:
try:
namespaces.append(getattr(n, p))
except AttributeError:
pass
self.matches = []
for n in namespaces:
for name in dir(n):
if name.lower().startswith(like.lower()):
self.matches.append(path + dot + name)
else:
completions = interpreter.completions()
self.matches = [text + c.complete for c in completions]
try: try:
return self.matches[state] return self.matches[state]
except IndexError: except IndexError:
return None return None
readline.set_completer(JediRL().complete) readline.set_completer(JediRL().complete)
j = JediRL()
j.complete('r', 0)
readline.parse_and_bind("tab: complete") readline.parse_and_bind("tab: complete")
# No delimiters, Jedi handles that. # No delimiters, Jedi handles that.