is great in terms of reusing code to support different IDEs. However, there are some challenges as not everything you expected is included in LSP. For example, In VSCode Python, if you do `Ctrl+click` (or Cmd+Click), it will jump to the definition of the function/variable. If you do this again at the definition, it will then jump to the references instead.
Language server
is what happened:
Behind the scene, this 1. User does `Ctrl+Click` on a function/variable for first time.
2. VSCode client sends `textDocument/definition` request to the language server.
3. Language server responds with the location of the definition.
4. VSCode client react to the response, and jump to the definition.
+Click` on the definition, VSCode client sends `textDocument/references` request to the language server. However, the language server does not know that this request is triggered by the second `Ctrl+Click` on the definition, it does something different:
The second time user does `Ctrl1. User does `Ctrl+Click` on a function/variable for first time.
2. VSCode client sends `textDocument/definition` request to the language server.
3. Language server responds with the location of the definition, but the location is same as the current location.
4. VSCode client react to the response, and send a new `textDocument/references` request to the language server.
5. Language server responds with the locations of the references.
6. VSCode client react to the response, and show the references in a new panel or go to the reference if there is only one.
and it's not universal across different IDEs. This is one of the limitations of using LSP. This behavior is not always ideal as well, for example the C++ complains about this behavior a lot as it triggers too many requests and slows down the IDE.
So to support a somewhat expected UX, it actually requires client side logic
In VSCode, the behavior can be configured by `editor.gotoLocation.alternativeDeclarationCmommand`, depends on what setting you have, it may or may not trigger the `reference` action. In PyCharm, the behavior is different. If you provide any non empty response, the PyCharm native Python plugin will not do anything. So the language server has to be aware of the IDE and return different response (i.e. In VScode you may want to return to cursor, but in PyCharm you rather it return `None`)
Langauge Server Protocol(LSP) defines what a LSP expect, return. It’s similar to MCP (in fact, MCP was inspired by LSP), in a sense that it is an API without actual implementation. (like an abstract class).