mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-06 14:04:26 +08:00
showing function params working now on both sides, but not joined
This commit is contained in:
@@ -378,6 +378,8 @@ def parse_function_doc(func):
|
|||||||
end = 0
|
end = 0
|
||||||
param_str = ''
|
param_str = ''
|
||||||
|
|
||||||
|
param_str = param_str.replace('-', '_') # see: isinstance.__doc__
|
||||||
|
|
||||||
if doc is not None:
|
if doc is not None:
|
||||||
r = re.search('-[>-]* ', doc[end:end + 7])
|
r = re.search('-[>-]* ', doc[end:end + 7])
|
||||||
if doc is None or r is None:
|
if doc is None or r is None:
|
||||||
|
|||||||
80
functions.py
80
functions.py
@@ -13,7 +13,7 @@ import keywords
|
|||||||
from _compatibility import next
|
from _compatibility import next
|
||||||
|
|
||||||
__all__ = ['complete', 'goto', 'get_definition', 'related_names',
|
__all__ = ['complete', 'goto', 'get_definition', 'related_names',
|
||||||
'NotFoundError', 'set_debug_function']
|
'NotFoundError', 'set_debug_function', 'get_in_function_call']
|
||||||
|
|
||||||
|
|
||||||
class NotFoundError(Exception):
|
class NotFoundError(Exception):
|
||||||
@@ -112,6 +112,29 @@ class Definition(dynamic.BaseOutput):
|
|||||||
return "%s:%s%s" % (self.module_name, self.description, position)
|
return "%s:%s%s" % (self.module_name, self.description, position)
|
||||||
|
|
||||||
|
|
||||||
|
class CallDef(object):
|
||||||
|
def __init__(self, executable, index):
|
||||||
|
self.executable = executable
|
||||||
|
self.index = index
|
||||||
|
|
||||||
|
@property
|
||||||
|
def params(self):
|
||||||
|
if isinstance(self.executable, evaluate.Function):
|
||||||
|
return self.executable.params
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
sub = self.executable.get_subscope_by_name('__init__')
|
||||||
|
return sub.params
|
||||||
|
except KeyError:
|
||||||
|
print self.executable.subscopes
|
||||||
|
print 'LALA'
|
||||||
|
return []
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return '<%s: %s index %s>' % (self.__class__.__name__, self.executable,
|
||||||
|
self.index)
|
||||||
|
|
||||||
|
|
||||||
def _get_completion_parts(path):
|
def _get_completion_parts(path):
|
||||||
"""
|
"""
|
||||||
Returns the parts for the completion
|
Returns the parts for the completion
|
||||||
@@ -173,8 +196,10 @@ def complete(source, line, column, source_path):
|
|||||||
needs_dot = not dot and path
|
needs_dot = not dot and path
|
||||||
c = [Completion(c, needs_dot, len(like), s) for c, s in set(completions)]
|
c = [Completion(c, needs_dot, len(like), s) for c, s in set(completions)]
|
||||||
|
|
||||||
|
call_def = _get_in_function_call(f, pos)
|
||||||
|
|
||||||
_clear_caches()
|
_clear_caches()
|
||||||
return c
|
return c, call_def
|
||||||
|
|
||||||
|
|
||||||
def _prepare_goto(position, source_path, module, goto_path,
|
def _prepare_goto(position, source_path, module, goto_path,
|
||||||
@@ -365,3 +390,54 @@ def set_debug_function(func_cb):
|
|||||||
|
|
||||||
def _clear_caches():
|
def _clear_caches():
|
||||||
evaluate.clear_caches()
|
evaluate.clear_caches()
|
||||||
|
|
||||||
|
def get_in_function_call(source, line, column, source_path):
|
||||||
|
pos = (line, column)
|
||||||
|
f = modules.ModuleWithCursor(source_path, source=source, position=pos)
|
||||||
|
|
||||||
|
return _get_in_function_call(f, pos)
|
||||||
|
|
||||||
|
def _get_in_function_call(module, pos):
|
||||||
|
def scan_array_for_pos(arr, pos):
|
||||||
|
""" Returns the function Call that match search_name in an Array. """
|
||||||
|
index = None
|
||||||
|
call = None
|
||||||
|
for index, sub in enumerate(arr):
|
||||||
|
call = None
|
||||||
|
for s in sub:
|
||||||
|
if isinstance(s, parsing.Array):
|
||||||
|
new = scan_array_for_pos(s, pos)
|
||||||
|
if new[0] is not None:
|
||||||
|
call, index = new
|
||||||
|
elif isinstance(s, parsing.Call):
|
||||||
|
while s is not None:
|
||||||
|
if s.start_pos >= pos:
|
||||||
|
return call, index
|
||||||
|
if s.execution is not None:
|
||||||
|
if s.execution.start_pos <= pos:
|
||||||
|
call = s
|
||||||
|
else:
|
||||||
|
return call, index
|
||||||
|
c, index = scan_array_for_pos(s.execution, pos)
|
||||||
|
if c is not None:
|
||||||
|
call = c
|
||||||
|
s = s.next
|
||||||
|
return call, index
|
||||||
|
|
||||||
|
user_stmt = module.parser.user_stmt
|
||||||
|
if user_stmt is None:
|
||||||
|
return None
|
||||||
|
ass = user_stmt.get_assignment_calls()
|
||||||
|
|
||||||
|
call, index = scan_array_for_pos(ass, pos)
|
||||||
|
if call is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
call.execution, temp = None, call.execution
|
||||||
|
origins = evaluate.follow_call(call)
|
||||||
|
call.execution = temp
|
||||||
|
|
||||||
|
if len(origins) == 0:
|
||||||
|
return None
|
||||||
|
executable = origins[0] # just take entry zero, because we need just one.
|
||||||
|
return CallDef(executable, index)
|
||||||
|
|||||||
@@ -298,6 +298,9 @@ class Module(Scope):
|
|||||||
self._name = Name(names, self.start_pos, self.end_pos, self)
|
self._name = Name(names, self.start_pos, self.end_pos, self)
|
||||||
return self._name
|
return self._name
|
||||||
|
|
||||||
|
def is_builtin(self):
|
||||||
|
return not self.path.endswith('.py')
|
||||||
|
|
||||||
|
|
||||||
class Class(Scope):
|
class Class(Scope):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ if 1:
|
|||||||
# here again, the hacks, because jedi has a different interface than vim
|
# here again, the hacks, because jedi has a different interface than vim
|
||||||
column += len(base)
|
column += len(base)
|
||||||
try:
|
try:
|
||||||
completions = functions.complete(source, row, column, buf_path)
|
completions, call_def = functions.complete(source, row, column, buf_path)
|
||||||
out = []
|
out = []
|
||||||
for c in completions:
|
for c in completions:
|
||||||
d = dict(word=c.word[:len(base)] + c.complete,
|
d = dict(word=c.word[:len(base)] + c.complete,
|
||||||
@@ -64,9 +64,10 @@ if 1:
|
|||||||
print(traceback.format_exc())
|
print(traceback.format_exc())
|
||||||
strout = ''
|
strout = ''
|
||||||
completions = []
|
completions = []
|
||||||
|
call_def = None
|
||||||
|
|
||||||
#print 'end', strout
|
#print 'end', strout
|
||||||
show_func_def(len(completions))
|
show_func_def(call_def, len(completions))
|
||||||
vim.command('return ' + strout)
|
vim.command('return ' + strout)
|
||||||
PYTHONEOF
|
PYTHONEOF
|
||||||
endfunction
|
endfunction
|
||||||
@@ -459,7 +460,8 @@ def _goto(is_definition=False, is_related_name=False, no_output=False):
|
|||||||
vim.command('call <sid>add_goto_window()')
|
vim.command('call <sid>add_goto_window()')
|
||||||
return definitions
|
return definitions
|
||||||
|
|
||||||
def show_func_def(completion_lines=0):
|
|
||||||
|
def show_func_def(call_def, completion_lines=0):
|
||||||
row, column = vim.current.window.cursor
|
row, column = vim.current.window.cursor
|
||||||
vim.eval('jedi#clear_func_def()')
|
vim.eval('jedi#clear_func_def()')
|
||||||
|
|
||||||
@@ -470,6 +472,8 @@ def show_func_def(completion_lines=0):
|
|||||||
line = vim.eval("getline(%s)" % row_to_replace)
|
line = vim.eval("getline(%s)" % row_to_replace)
|
||||||
|
|
||||||
insert_column = column - 2 # because it has stuff at the beginning
|
insert_column = column - 2 # because it has stuff at the beginning
|
||||||
|
|
||||||
|
print call_def, call_def.params
|
||||||
text = " (*asdf*, basdf) "
|
text = " (*asdf*, basdf) "
|
||||||
text = ' ' * (insert_column - len(line)) + text
|
text = ' ' * (insert_column - len(line)) + text
|
||||||
end_column = insert_column + len(text) - 2 # -2 because of bold symbols
|
end_column = insert_column + len(text) - 2 # -2 because of bold symbols
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ class TestRegression(unittest.TestCase):
|
|||||||
def complete(self, src, pos):
|
def complete(self, src, pos):
|
||||||
return functions.complete(src, pos[0], pos[1], '')
|
return functions.complete(src, pos[0], pos[1], '')
|
||||||
|
|
||||||
|
def get_in_function_call(self, src, pos=None):
|
||||||
|
if pos is None:
|
||||||
|
pos = 1, len(src)
|
||||||
|
return functions.get_in_function_call(src, pos[0], pos[1], '')
|
||||||
|
|
||||||
def test_get_definition_cursor(self):
|
def test_get_definition_cursor(self):
|
||||||
|
|
||||||
s = ("class A():\n"
|
s = ("class A():\n"
|
||||||
@@ -100,6 +105,16 @@ class TestRegression(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
functions.related_names(s, 2, 2, '/')
|
functions.related_names(s, 2, 2, '/')
|
||||||
|
|
||||||
|
def test_get_in_function_call(self):
|
||||||
|
s = "isinstance(a, abs("
|
||||||
|
s2 = "isinstance(), "
|
||||||
|
print
|
||||||
|
check = lambda call_def, index: call_def and call_def.index == index
|
||||||
|
assert check(self.get_in_function_call(s, (1,11)), 0)
|
||||||
|
assert check(self.get_in_function_call(s, (1,14)), 1)
|
||||||
|
assert check(self.get_in_function_call(s, (1,15)), 1)
|
||||||
|
assert check(self.get_in_function_call(s, (1,18)), 0)
|
||||||
|
assert self.get_in_function_call(s2) is None
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ def run_completion_test(correct, source, line_nr, index, line, path):
|
|||||||
# lines start with 1 and column is just the last (makes no
|
# lines start with 1 and column is just the last (makes no
|
||||||
# difference for testing)
|
# difference for testing)
|
||||||
try:
|
try:
|
||||||
completions = functions.complete(source, line_nr, index, path)
|
completions, call_def = functions.complete(source, line_nr, index,
|
||||||
|
path)
|
||||||
#import cProfile as profile
|
#import cProfile as profile
|
||||||
#profile.run('functions.complete("""%s""", %i, %i, "%s")'
|
#profile.run('functions.complete("""%s""", %i, %i, "%s")'
|
||||||
# % (source, line_nr, len(line), path))
|
# % (source, line_nr, len(line), path))
|
||||||
|
|||||||
Reference in New Issue
Block a user