ycm-core / YouCompleteMe

A code-completion engine for Vim
http://ycm-core.github.io/YouCompleteMe/
GNU General Public License v3.0
25.44k stars 2.81k forks source link

Go to inconsistent for python filetype #1236

Closed AleksandarPopadic closed 9 years ago

AleksandarPopadic commented 9 years ago

The go to commands lack some consistency for python files. Jedi has two functions: goto_definitions and goto_assignments (documented here). Right now GoToDefinition command is mapped to goto_assignment and GoToDeclaration to goto_definition.

I'd argue that GoToDeclaration shouldn't do anything as there are no declarations in python and I'd map GoToDefinition to goto_definitions. Maybe introduce a new command GoToAssignment and map it to goto_assignments?

Another problem I see is the GoTo command. Right now GoTo command tries GoToDefinition first and then GoToDeclaration. This means it tries goto_assignments first and then goto_definitions. I don't see how a definition could exist without an assignment.

Valloric commented 9 years ago

I'd argue that GoToDeclaration shouldn't do anything as there are no declarations in python and I'd map GoToDefinition to goto_definitions.

The reason why we want to support both of those GoTo commands is because they exist in YCM's "higher-level" command set (available for multiple filetypes) and we want people's Vim mappings to continue working as they switch between languages. So we have to map GoToDeclaration to something.

Could you provide an example python file and a description on how the various GoTo commands work in that file and how you think they should work? This would help get a better picture of the pros & cons of the various approaches.

AleksandarPopadic commented 9 years ago

The reason why we want to support both of those GoTo commands is because they exist in YCM's "higher-level" command set (available for multiple filetypes) and we want people's Vim mappings to continue working as they switch between languages. So we have to map GoToDeclaration to something.

I don't think there's anything wrong with the GoToDeclaration command being disabled in filetypes in which there are no declarations (and maybe giving a warning stating that the concept of a declaration is not defined in the current filetype). Users of respective filetypes know what definitions (definition, declaration, assignment, etc.) make sense in those filetypes and wouldn't expect for example a search for a declaration in a python file to return anything. In addition to the specific GoTo commands we'd then have a "smart" GoTo command (the current GoTo), which works in all filetypes and tries several specific GoTo commands. Else I'd fix the documentation to state that GoToDeclaration does more than implied by the command name.

Could you provide an example python file and a description on how the various GoTo commands work in that file and how you think they should work? This would help get a better picture of the pros & cons of the various approaches.

Example 1:

def a():
    pass
b = a
b

Example 2 (from the vim-jedi manual):

# file1.py:
from file2 import foo
foo

# file2.py:
from file3 import bar as foo

# file3.py
def bar():
    pass

Example 3:

from math import sin
sin

This is what happens right now. Call GoToDefinition on "b" and it'll take you to the assignment "b = a". I'd expect it to take you to the definition "def a". Similarly, if you call GoToDefinition on "foo", it'll take you to "from file2 import foo". I'd expect it to take you to the definition in file3. If the GoToDeclaration command absolutely has to do something, I'd give it the current behaviour of GoToDefinition of going to assignments and fix the documentation.

And then there's the GoTo command. Right now it tries to take you to an assignment first and then to the definition. But if a definition exists, so does the assignment. An assignment, however, can exist without a definition (a definition living outside a python file). Calling GoTo on "foo" will take you to "from file import foo" and calling it on "sin" will take you to "from math import sin". In both instances it takes you to an assignment. I think it should try taking you to a definition first and if that is impossible, then take you to an assignment. So if calling GoTo on "foo", it'd take you to the definition "def bar" and calling it on "sin" would try taking it to a definition which it can't and thus take you to the assignment "from math import sin" instead.

Valloric commented 9 years ago

I swapped what these commands do for Python, as per your feedback. GoTo is also reversed as well (calls goto_definitions before trying goto_assignments).