Skip to content

Remove the need for reloading VS Code when changing language servers

Kim-Adeline Miguel edited this page Apr 18, 2022 · 11 revisions

This is a design document for the refactoring needed in order to not require a reload when updating the python.languageServer setting (issue: 18509, PR: #18884).

Previous design

Language server-specific code was registered on extension activation depending on the value of the python.languageServer setting: For example, if python.languageServer was set to Jedi, only the Jedi-specific classes would be available in the extension. This meant that whenever python.languageServer was updated, we needed to reload the extension (and VS Code) in order to register the classes needed by the new language server.

Language server checks (if the setting is set to the default value, if the interpreter is Python 2.7, if the workspace is untrusted) were also done during activation on language server start.

Jupyter support

Notebook support in the Language Server Protocol is still in a proposed state, meaning that it isn't included in LSP v3.16, only in the pre-release 3.17 version.

Until notebook support lands in the stable API, we have a custom-made middleware in the Python extension that will intercept LSP calls and send them to the Jupyter LSP package. Since this middleware isn't tied to how we launch language servers, it shouldn't be impacted by this work.

As part of the Python extension API for the Jupyter extension, we provide a way to get a reference to the language server, via the ILanguageServerCache interface, which will be refactored as part of this work.

Existing classes and interfaces

Pylance classes

  • NodeLanguageServerAnalysisOptions: Provides a LanguageClientOptions object that will then be used by NodeLanguageServerProxy to start the language server
  • NodeLanguageServerActivator: Creates and start the language server, make sure Pylance is installed, display an error message otherwise
  • NodeLanguageClientFactory: Creates a language client, used in NodeLanguageServerProxy.start()
  • NodeLanguageServerManager: Will dispose of everything, connect/disconnect to/from the middleware, register the command to restart the language server, and will call NodeLanguageServerProxy.start() to start it
  • NodeLanguageServerProxy: Communicates directly with the language server
  • NodeLanguageServerFolderService: MPLS (language server that predates Pylance) remnants, currently only provides a helper function to retrieve the Pylance extension directory, which was necessary back when the MPLS had to be downloaded by the Python extension, instead of being a standalone extension
  • LanguageServerChangeHandler: Registers a handler for when extensions change, and displays a prompt to reload VS Code if Pylance just finished installing.

Jedi classes

Activation classes

Proposed design

TODO

  • Remove DI, allow stopping and starting LS on the fly

Note: As of today (April 2022) mermaid graphs aren't supported in wikis yet, please enjoy screenshots instead.

General architecture

Activation flow

Language server change flow

Clone this wiki locally