diff --git a/functions.py b/functions.py index 82a95310..61ec0cc4 100644 --- a/functions.py +++ b/functions.py @@ -9,6 +9,7 @@ import modules import debug import imports import settings +import keywords from _compatibility import next @@ -105,6 +106,8 @@ class Definition(object): elif isinstance(d, evaluate.parsing.Module): # only show module name d = 'module %s' % self.module_name + elif isinstance(d, keywords.Keyword): + d = 'keyword %s' % d.name else: d = d.get_code().replace('\n', '') return d @@ -243,10 +246,18 @@ def get_definition(source, line, column, source_path): context = f.get_context() if next(context) in ('class', 'def'): - scopes = [f.parser.user_scope] + scopes = set([f.parser.user_scope]) + elif not goto_path: + op = f.get_operator_under_cursor() + scopes = set([keywords.get_operator(op)]) else: scopes = _prepare_goto(source, pos, source_path, f, goto_path) - d = [Definition(s) for s in set(scopes)] + + # add keywords + scopes |= keywords.get_keywords(string=goto_path) + + + d = set([Definition(s) for s in scopes]) _clear_caches() return d diff --git a/modules.py b/modules.py index 49b38dfc..5cb3d16b 100644 --- a/modules.py +++ b/modules.py @@ -132,17 +132,30 @@ class ModuleWithCursor(Module): after = re.search("[\w\d]*", line[self.position[1]:]).group(0) return self.get_path_until_cursor() + after + def get_operator_under_cursor(self): + line = self.get_line(self.position[0]) + after = re.match("[^\w\s]+", line[self.position[1]:]) + before = re.match("[^\w\s]+", line[:self.position[1]][::-1]) + return (before.group(0) if before is not None else '') \ + + (after.group(0) if after is not None else '') + def get_context(self): pos = self._start_cursor_pos - while pos > (0, 0): + while pos > (1, 0): # remove non important white space line = self.get_line(pos[0]) while pos > 0 and line[pos[1] - 1].isspace(): pos = pos[0], pos[1] - 1 - yield self._get_path_until_cursor(start_pos=pos) + try: + yield self._get_path_until_cursor(start_pos=pos) + except StopIteration: + yield '' pos = self._line_temp, self._column_temp + while True: + yield '' + def get_line(self, line_nr): if not self._line_cache: self._line_cache = self.source.split('\n') diff --git a/plugin/jedi.vim b/plugin/jedi.vim index e51be90d..425bd43c 100644 --- a/plugin/jedi.vim +++ b/plugin/jedi.vim @@ -132,8 +132,8 @@ PYTHONEOF setlocal nomodified setlocal filetype=rst - if l:doc_lines > 20 " max 20 lines for plugin - let l:doc_lines = 20 + if l:doc_lines > 30 " max lines for plugin + let l:doc_lines = 30 endif execute "resize ".l:doc_lines @@ -315,7 +315,7 @@ def _goto(is_definition=False): # has a better idea, let me know. vim.command('normal! m`') - d = definitions[0] + d = list(definitions)[0] if d.in_builtin_module(): echo_highlight("Builtin modules cannot be displayed.") else: diff --git a/test/regression.py b/test/regression.py index 9069f62e..54344e49 100755 --- a/test/regression.py +++ b/test/regression.py @@ -50,6 +50,24 @@ class TestRegression(unittest.TestCase): self.assertRaises(functions.NotFoundError, get_def, cls) + def test_keyword_doc(self): + r = list(self.get_def("or", (1,1))) + assert len(r) == 1 + assert len(r[0].doc) > 100 + + r = list(self.get_def("asfdasfd", (1,1))) + assert len(r) == 0 + + def test_operator_doc(self): + r = list(self.get_def("a == b", (1,3))) + assert len(r) == 1 + assert len(r[0].doc) > 100 + + def test_get_definition_at_zero(self): + assert self.get_def("a", (1,1)) == set() + ##assert self.get_def("", (1,0)) == set() + + if __name__ == '__main__': unittest.main()