How to make `cmd` + `click` switch between `Go to definition` and `Go to reference`? (VSCode only)
Opened this issue · 3 comments
Context:
microsoft/vscode#73081 (comment)
In the Python extension, Cmd + Click trigger Go to Definition
or Go to reference
depending if the click is on a declaration or reference.
I have this pseudocode and it doesn't seem to trigger the action correctly. p.s. the language server is working properly, the example is simplified.
@LSP_SERVER.feature(TEXT_DOCUMENT_DEFINITION)
def definition(
ls, params: TextDocumentPositionParams
):
uri = params.text_document.uri
pos = params.position
curr_pos = Position(line= pos.line, character=pos.character)
return Location(uri = uri, range = Location (Range(start=curr_pos, end=curr_pos))
alternatively, I have tried:
@LSP_SERVER.feature(TEXT_DOCUMENT_DEFINITION)
def definition(ls, params):
return params
p.s. I am not so sure What's the difference between TextDocumentPositionParams
and a Location
I am not so sure What's the difference between
TextDocumentPositionParams
and aLocation
The main difference is that TextDocumentPositionParams
contains a Position
and therefore describes a single location within the document e.g. where the cursor is. Whereas Location
contains a Range
which describes a region of text within the document e.g. the text you highlight just before you copy it.
I have this pseudocode and it doesn't seem to trigger the action correctly.
I think you are close, though you have an extra Location
in your return statement, something like the following should work
return Location(uri=uri, range=Range(start=curr_pos, end=curr_pos))
Though I'm not sure how VSCode handles a zero-length range, it might not be obvious that it did anything, you may also want to try something like this
return Location(
uri=uri,
range=Range(
start=Position(line=pos.line, character=0),
end=Position(line=pos.line + 1, character=0)
)
)
Now when you trigger Goto Definition, VSCode should highlight the whole line
In the Python extension, Cmd + Click trigger Go to Definition or Go to reference depending if the click is on a declaration or reference.
Unfortunately, I don't know for sure how to make this work - the LSP spec tries hard not to dictate how the UI for each method should work. The server provides the data and it's up to the client to decide how to show it.
However, I would start by also implementing TEXT_DOCUMENT_REFERENCES
to return two Locations
, one being the definition itself, the other being some other location in the document and see how VSCode handles it.
Hope that helps!
return Location(uri=uri, range=Range(start=curr_pos, end=curr_pos))
, I think my previous implementation has a bug as you have noticed. Once I return the current cursor it seems to behave as I expected.
Thanks a lot for the help! This issue can be closed
Unfortunately, I don't know for sure how to make this work - the LSP spec tries hard not to dictate how the UI for each method should work. The server provides the data and it's up to the client to decide how to show it.
You are correct that this is up to the client. I asked because
fyi - I have pushed a commit that adds settings like editor.gotoLocation.alternativeDefinitionCommand etc. They allow to define what happens when the corresponding go-to-command navigates to the current location microsoft/vscode#73081 (comment)
It's not clear to me whether "current location" is Location
or if I can return an exact position like TextDocumentPositionParams
. Is it possible if my LSP return TextDocumentPositionParams
instead of Location
? I assume ultimately they all get converted to a standard format (JSON like I assume)
I assume ultimately they all get converted to a standard format (JSON like I assume)
Everything in LSP is JSON under the hood, types like Location
are just names given to a well defined JSON object with a specific structure
or if I can return an exact position like
TextDocumentPositionParams
.
As a general rule anything with Params
in the name can't be sent as a response to a request.
The LSP specification itself is probably the best place to look for answers to questions like "what can I return here?"
Admittedly, it's not the easiest document to navigate, but the information is there. Taking your
Goto Definition request as an example, if you scroll down to just before the Goto Type Definition Request heading, you should see a Response section.
Under it the spec lists the valid responses to the request separated by |
characters
result: Location | Location[] | LocationLink[] | null