showing function params working now on both sides, but not joined

This commit is contained in:
David Halter
2012-09-15 03:57:22 +02:00
parent 4a23a1d533
commit 9b7d82a251
6 changed files with 107 additions and 6 deletions

View File

@@ -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:

View File

@@ -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)

View File

@@ -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):
""" """

View File

@@ -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

View File

@@ -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()

View File

@@ -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))