mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-08 23:04:48 +08:00
goto function added
This commit is contained in:
@@ -39,6 +39,7 @@ nice in Python 2. To keep things simple, some things have been held back:
|
||||
|
||||
- Classes: Always Python 3, therefore all classes inherit from `object`.
|
||||
- Generators: No `next` method. The `__next__` method is there instead.
|
||||
- Exceptions are only looked at in the form of `Exception as e`, no comma!
|
||||
|
||||
Syntax Errors and other strange stuff, that is defined differently in the
|
||||
Python language, may lead to undefined behaviour of the completion. If you
|
||||
|
||||
23
evaluate.py
23
evaluate.py
@@ -286,11 +286,24 @@ class Instance(Executable):
|
||||
|
||||
return names
|
||||
|
||||
@property
|
||||
def parent(self):
|
||||
return self.base.parent
|
||||
|
||||
@property
|
||||
def line_nr(self):
|
||||
return self.base.line_nr
|
||||
|
||||
@property
|
||||
def indent(self):
|
||||
return self.base.indent
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self.base.name
|
||||
|
||||
def __repr__(self):
|
||||
return "<p%s of %s (var_args: %s)>" % \
|
||||
return "<e%s of %s (var_args: %s)>" % \
|
||||
(self.__class__.__name__, self.base, len(self.var_args or []))
|
||||
|
||||
|
||||
@@ -345,11 +358,15 @@ class Class(object):
|
||||
names.append(i)
|
||||
return names
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self.base.name
|
||||
|
||||
def __getattr__(self, name):
|
||||
return getattr(self.base, name)
|
||||
|
||||
def __repr__(self):
|
||||
return "<p%s of %s>" % (self.__class__.__name__, self.base)
|
||||
return "<e%s of %s>" % (self.__class__.__name__, self.base)
|
||||
|
||||
|
||||
class Execution(Executable):
|
||||
@@ -537,7 +554,7 @@ class Array(object):
|
||||
return self._array
|
||||
|
||||
def __repr__(self):
|
||||
return "<p%s of %s>" % (self.__class__.__name__, self._array)
|
||||
return "<e%s of %s>" % (self.__class__.__name__, self._array)
|
||||
|
||||
|
||||
class ArrayElement(object):
|
||||
|
||||
2
ftest.py
2
ftest.py
@@ -15,7 +15,7 @@ path = os.path.join(os.getcwd(), f_name)
|
||||
f = open(path)
|
||||
code = f.read()
|
||||
for i in range(1):
|
||||
completions = functions.complete(code, 180, 200, path)
|
||||
completions = functions.get_definitions(code, 180, 200, path)
|
||||
#completions = functions.complete(code, 42, 200, path)
|
||||
|
||||
print '\n', ', '.join(sorted(str(c) for c in completions))
|
||||
|
||||
101
functions.py
101
functions.py
@@ -1,4 +1,5 @@
|
||||
import re
|
||||
import sys
|
||||
|
||||
import parsing
|
||||
import evaluate
|
||||
@@ -10,7 +11,10 @@ __all__ = ['complete', 'goto', 'get_completion_parts', 'set_debug_function']
|
||||
|
||||
class NotFoundError(Exception):
|
||||
""" A custom error to avoid catching the wrong errors """
|
||||
pass
|
||||
def __init__(self, scope, path_tuple, message=None):
|
||||
super(NotFoundError, self).__init__(message)
|
||||
self.scope = scope
|
||||
self.path_tuple = path_tuple
|
||||
|
||||
|
||||
class Completion(object):
|
||||
@@ -32,7 +36,7 @@ class Completion(object):
|
||||
def help(self):
|
||||
try:
|
||||
return str(self.name.parent.docstr)
|
||||
except:
|
||||
except AttributeError:
|
||||
return ''
|
||||
|
||||
def get_type(self):
|
||||
@@ -63,6 +67,42 @@ class Completion(object):
|
||||
return self.name.names[-1]
|
||||
|
||||
|
||||
class Definition(object):
|
||||
def __init__(self, scope):
|
||||
""" The definition of a function """
|
||||
self.scope = scope
|
||||
|
||||
def get_name(self):
|
||||
return self.scope.name
|
||||
|
||||
def get_module(self):
|
||||
par = self.scope
|
||||
while True:
|
||||
if par.parent is not None:
|
||||
par = par.parent
|
||||
else:
|
||||
break
|
||||
return par.path
|
||||
|
||||
def get_line(self):
|
||||
return self.scope.line_nr
|
||||
|
||||
def get_indent(self):
|
||||
return self.scope.indent
|
||||
|
||||
def __str__(self):
|
||||
module = self.get_module()
|
||||
if module[0] == '/':
|
||||
position = '@%s' % (self.get_line())
|
||||
else:
|
||||
# no path - is a builtin
|
||||
position = ''
|
||||
|
||||
return "%s.%s%s" % (module, self.get_name(), position)
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s %s>" % (self.__class__.__name__, self)
|
||||
|
||||
def get_completion_parts(path):
|
||||
"""
|
||||
Returns the parts for the completion
|
||||
@@ -88,18 +128,14 @@ def complete(source, row, column, source_path):
|
||||
:return: list of completion objects
|
||||
:rtype: list
|
||||
"""
|
||||
f = modules.ModuleWithCursor(source_path, source=source, row=row)
|
||||
scope = f.parser.user_scope
|
||||
path = f.get_path_until_cursor(column)
|
||||
debug.dbg('completion_start: %s in %s' % (path, scope))
|
||||
|
||||
# just parse one statement, take it and evaluate it
|
||||
path, dot, like = get_completion_parts(path)
|
||||
r = parsing.PyFuzzyParser(path, source_path)
|
||||
try:
|
||||
stmt = r.top.statements[0]
|
||||
except IndexError:
|
||||
scope_generator = evaluate.get_names_for_scope(scope)
|
||||
scopes, path, dot, like = prepare_goto(source, row, column, source_path, True)
|
||||
except NotFoundError:
|
||||
# normally this would be used like this: `NotFoundError as exc`, but
|
||||
# this guarantues backwards compatibility with Python2.5.
|
||||
exc = sys.exc_info()[1]
|
||||
path, dot, like = exc.path_tuple
|
||||
scope_generator = evaluate.get_names_for_scope(exc.scope)
|
||||
completions = []
|
||||
for dummy, name_list in scope_generator:
|
||||
completions += name_list
|
||||
@@ -107,11 +143,6 @@ def complete(source, row, column, source_path):
|
||||
# if isinstance(, parsing.Function):
|
||||
# print c.parent
|
||||
else:
|
||||
stmt.line_nr = row
|
||||
stmt.indent = column
|
||||
stmt.parent = scope
|
||||
scopes = evaluate.follow_statement(stmt, scope=scope)
|
||||
|
||||
completions = []
|
||||
debug.dbg('possible scopes', scopes)
|
||||
for s in scopes:
|
||||
@@ -146,21 +177,41 @@ def prepare_goto(source, row, column, source_path, is_like_search):
|
||||
try:
|
||||
stmt = r.top.statements[0]
|
||||
except IndexError:
|
||||
raise NotFoundError()
|
||||
path_tuple = path, dot, like
|
||||
raise NotFoundError(scope, path_tuple)
|
||||
else:
|
||||
stmt.line_nr = row
|
||||
stmt.indent = column
|
||||
stmt.parent = scope
|
||||
scopes = evaluate.follow_statement(stmt, scope=scope)
|
||||
return scope, scopes
|
||||
|
||||
|
||||
def goto(source, row, column, source_path):
|
||||
dummy, scopes = prepare_goto(source, row, column, source_path, False)
|
||||
|
||||
_clear_caches()
|
||||
if is_like_search:
|
||||
return scopes, path, dot, like
|
||||
else:
|
||||
return scopes
|
||||
|
||||
def get_definitions(source, row, column, source_path):
|
||||
"""
|
||||
Returns the definitions of a the path under the cursor.
|
||||
This is not a goto function! This follows complicated paths and returns the
|
||||
end, not the first definition.
|
||||
|
||||
:param source: The source code of the current file
|
||||
:type source: string
|
||||
:param row: The row to complete in.
|
||||
:type row: int
|
||||
:param col: The column to complete in.
|
||||
:type col: int
|
||||
:param source_path: The path in the os, the current module is in.
|
||||
:type source_path: int
|
||||
|
||||
:return: list of Definition objects, which are basically scopes.
|
||||
:rtype: list
|
||||
"""
|
||||
scopes = prepare_goto(source, row, column, source_path, False)
|
||||
_clear_caches()
|
||||
return [Definition(s) for s in set(scopes)]
|
||||
|
||||
|
||||
def set_debug_function(func_cb):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user