Add pyright workspace configuration (#14265)

FilipeBisinella created

Release Notes:

- Added support for pyright workspace configuration, as described in
https://microsoft.github.io/pyright/#/settings .

Change summary

crates/languages/src/python.rs | 30 +++++++++++++++++++++--
docs/src/languages/python.md   | 45 ++++++++++++++++++++++++++++++++++++
2 files changed, 72 insertions(+), 3 deletions(-)

Detailed changes

crates/languages/src/python.rs 🔗

@@ -1,9 +1,13 @@
 use anyhow::Result;
 use async_trait::async_trait;
 use gpui::AppContext;
+use gpui::AsyncAppContext;
 use language::{ContextProvider, LanguageServerName, LspAdapter, LspAdapterDelegate};
 use lsp::LanguageServerBinary;
 use node_runtime::NodeRuntime;
+use project::project_settings::ProjectSettings;
+use serde_json::Value;
+use settings::Settings;
 use std::{
     any::Any,
     borrow::Cow,
@@ -25,6 +29,8 @@ pub struct PythonLspAdapter {
 }
 
 impl PythonLspAdapter {
+    const SERVER_NAME: &'static str = "pyright";
+
     pub fn new(node: Arc<dyn NodeRuntime>) -> Self {
         PythonLspAdapter { node }
     }
@@ -33,14 +39,18 @@ impl PythonLspAdapter {
 #[async_trait(?Send)]
 impl LspAdapter for PythonLspAdapter {
     fn name(&self) -> LanguageServerName {
-        LanguageServerName("pyright".into())
+        LanguageServerName(Self::SERVER_NAME.into())
     }
 
     async fn fetch_latest_server_version(
         &self,
         _: &dyn LspAdapterDelegate,
     ) -> Result<Box<dyn 'static + Any + Send>> {
-        Ok(Box::new(self.node.npm_package_latest_version("pyright").await?) as Box<_>)
+        Ok(Box::new(
+            self.node
+                .npm_package_latest_version(Self::SERVER_NAME)
+                .await?,
+        ) as Box<_>)
     }
 
     async fn fetch_server_binary(
@@ -51,7 +61,7 @@ impl LspAdapter for PythonLspAdapter {
     ) -> Result<LanguageServerBinary> {
         let latest_version = latest_version.downcast::<String>().unwrap();
         let server_path = container_dir.join(SERVER_PATH);
-        let package_name = "pyright";
+        let package_name = Self::SERVER_NAME;
 
         let should_install_language_server = self
             .node
@@ -164,6 +174,20 @@ impl LspAdapter for PythonLspAdapter {
             filter_range,
         })
     }
+
+    async fn workspace_configuration(
+        self: Arc<Self>,
+        _: &Arc<dyn LspAdapterDelegate>,
+        cx: &mut AsyncAppContext,
+    ) -> Result<Value> {
+        cx.update(|cx| {
+            ProjectSettings::get_global(cx)
+                .lsp
+                .get(Self::SERVER_NAME)
+                .and_then(|s| s.settings.clone())
+                .unwrap_or_default()
+        })
+    }
 }
 
 async fn get_cached_server_binary(

docs/src/languages/python.md 🔗

@@ -11,6 +11,35 @@ The [pyright](https://github.com/microsoft/pyright) language server offers flexi
 
 For more information, see the Pyright [configuration documentation](https://microsoft.github.io/pyright/#/configuration).
 
+### Settings
+
+The [pyright](https://github.com/microsoft/pyright) language server also accepts specific LSP related settings, not necessarily connected to a project. These can be changed in the `lsp` section of your `settings.json`.
+
+For example, in order to:
+- use strict type-checking level
+- diagnose all files in the workspace instead of the only open files default
+- provide the path to a specific python interpreter
+
+```json
+{
+  "lsp": {
+    "pyright": {
+      "settings": {
+        "python.analysis": {
+          "diagnosticMode": "workspace",
+          "typeCheckingMode": "strict"
+        },
+        "python": {
+          "pythonPath": ".venv/bin/python"
+        }
+      }
+    }
+  }
+}
+```
+
+For more information, see the Pyright [settings documentation](https://microsoft.github.io/pyright/#/settings).
+
 ### Virtual environments
 
 A python [virtual environment](https://docs.python.org/3/tutorial/venv.html) allows you to store all of a project's dependencies, including the Python interpreter and package manager, in a single directory that's isolated from any other Python projects on your computer.
@@ -48,6 +77,22 @@ venvPath = "."
 venv = ".venv"
 ```
 
+You can also configure this option directly in your `settings.json` file ([pyrights settings](#settings)), as recommended in [Configuring Your Python Environment](https://microsoft.github.io/pyright/#/import-resolution?id=configuring-your-python-environment).
+
+```json
+{
+  "lsp": {
+    "pyright": {
+      "settings": {
+        "python": {
+          "pythonPath": ".venv/bin/python"
+        }
+      }
+    }
+  }
+}
+```
+
 ### Code formatting
 
 The Pyright language server does not provide code formatting. If you want to automatically reformat your Python code when saving, you'll need to specify an \_external_code formatter in your settings. See the [configuration](../configuring-zed.md) documentation for more information.