Skip to content

[RFC] Remap GoTo commands in Python completer #1200

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

micbou
Copy link
Collaborator

@micbou micbou commented Mar 5, 2019

The GoToDefinition, GoToDeclaration, and GoTo commands in the Python completer are currently mapped to Jedi methods as follows:

These mappings don't really make sense since there is no distinction between a definition and a declaration in Python. All these GoTo commands should be identical. Said that, we need to decide to which function these commands should be mapped: goto_definitions or goto_assignments? My understanding is that goto_definitions doesn't jump to the definition but the type definition while goto_assignments actually jumps to the definition with the caveat that it doesn't follow imports by default. This is confirmed by looking at some examples (these examples are used in the tests):

my_variable = 1
my_variable

With the cursor on the second my_variable:

  • goto_definitions returns the int builtin. This is clearly not the definition of my_variable but its type;
  • goto_assignments returns the first my_variable which is where my_variable is defined.
class MyClass():
  pass

my_instance = MyClass()
my_instance

With the cursor on the second my_instance:

  • goto_definitions returns the first MyClass. Again, not the definition of my_instance but its type;
  • goto_assignments returns the first my_instance.

This PR thus proposes to remap the three GoTo commands to goto_assignments (with some additional work to follow imports and to deal with aliases) and to introduce a new command GoToType which is mapped to goto_definitions.


This change is Reviewable

Map GoTo, GoToDefinition, and GoToDeclaration to Jedi goto_assignments.
Add GoToType command and map it to Jedi goto_definitions.
Copy link
Member

@puremourning puremourning left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 0 of 2 LGTMs obtained (waiting on @micbou)


ycmd/completers/python/python_completer.py, line 290 at r1 (raw file):

      # set to True. Unfortunately, we can't use that option because it also
      # jumps to the original name of aliases which is unexpected as an alias is
      # a kind of definition. So, we need to traverse definitions by repeatedly

Hmmmmmmm.

I have personally become quite used to the behaviour of jumping to the import statement.

In fact, I rely on it. Often I will be looking at some code with the goal of, let's say, "re-appropriating" it for something. I see a type or something that I need to use, and do my GoTo mapping on it to get the import statement that I also need.

If I happen to actually want the real def, I just hit the mapping 2x.

So changing this is tricky in the sense that there's a real use case for the current behaviour, and probably why it's an option in Jedi's API.

I realise it is perhaps somewhat arbitrary, but maybe GoToDefinition jumps through imports, but GoToDeclaration jumps to imports ? Not sure.

Thoughts?

@codecov
Copy link

codecov bot commented Mar 5, 2019

Codecov Report

Merging #1200 into master will decrease coverage by 0.18%.
The diff coverage is 100%.

@@            Coverage Diff             @@
##           master    #1200      +/-   ##
==========================================
- Coverage   97.28%   97.09%   -0.19%     
==========================================
  Files          95       95              
  Lines        7109     7128      +19     
==========================================
+ Hits         6916     6921       +5     
- Misses        193      207      +14

Copy link
Collaborator

@bstaletic bstaletic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 12 of 12 files at r1.
Reviewable status: 0 of 2 LGTMs obtained (waiting on @puremourning)


ycmd/completers/python/python_completer.py, line 290 at r1 (raw file):

Previously, puremourning (Ben Jackson) wrote…

Hmmmmmmm.

I have personally become quite used to the behaviour of jumping to the import statement.

In fact, I rely on it. Often I will be looking at some code with the goal of, let's say, "re-appropriating" it for something. I see a type or something that I need to use, and do my GoTo mapping on it to get the import statement that I also need.

If I happen to actually want the real def, I just hit the mapping 2x.

So changing this is tricky in the sense that there's a real use case for the current behaviour, and probably why it's an option in Jedi's API.

I realise it is perhaps somewhat arbitrary, but maybe GoToDefinition jumps through imports, but GoToDeclaration jumps to imports ? Not sure.

Thoughts?

Sorry for taking a month to respond to this one... I completely forgot about it after our brief talk in gitter.

I'm not sure what @puremourning is referring to as "re-appropriating", but I too have had a need to see from where was something imported. Though I mostly used * followed by gg in vim. Much more often, my intention for :YcmCompleter GoTo was to jump through the imports and to the actual definition.

Copy link
Collaborator Author

@micbou micbou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 12 of 12 files at r1.
Reviewable status: 0 of 2 LGTMs obtained (waiting on @puremourning)


ycmd/completers/python/python_completer.py, line 290 at r1 (raw file):

Previously, bstaletic (Boris Staletic) wrote…

Sorry for taking a month to respond to this one... I completely forgot about it after our brief talk in gitter.

I'm not sure what @puremourning is referring to as "re-appropriating", but I too have had a need to see from where was something imported. Though I mostly used * followed by gg in vim. Much more often, my intention for :YcmCompleter GoTo was to jump through the imports and to the actual definition.

Using GoTo to find how a symbol is imported doesn't seem right to me. What about displaying that information with the GetType command? Jedi returns the fully qualified name in the full_name field. For instance, instead of returning the following info on GetType for the ExpandVariablesInPath function imported in that file:

def ExpandVariablesInPath(path)

we could return

def ycmd.utils.ExpandVariablesInPath(path)

which is enough to know how to import this symbol.

Copy link
Collaborator

@bstaletic bstaletic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 0 of 2 LGTMs obtained (waiting on @puremourning)


ycmd/completers/python/python_completer.py, line 290 at r1 (raw file):

Previously, micbou wrote…

Using GoTo to find how a symbol is imported doesn't seem right to me. What about displaying that information with the GetType command? Jedi returns the fully qualified name in the full_name field. For instance, instead of returning the following info on GetType for the ExpandVariablesInPath function imported in that file:

def ExpandVariablesInPath(path)

we could return

def ycmd.utils.ExpandVariablesInPath(path)

which is enough to know how to import this symbol.

That sounds good to me.

@puremourning
Copy link
Member

Submitted #1275

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants