typescript: Make it possible to use local vtsls (#15775)

Konstantin Matsiushonak created

Related things:
https://github.com/zed-industries/zed/issues/7902
https://github.com/zed-industries/zed/issues/4978

Release Notes:
- Added: positibily to use locally installed vtsls

Change summary

crates/languages/src/vtsls.rs | 44 ++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+), 1 deletion(-)

Detailed changes

crates/languages/src/vtsls.rs 🔗

@@ -5,7 +5,7 @@ use gpui::AsyncAppContext;
 use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
 use lsp::{CodeActionKind, LanguageServerBinary};
 use node_runtime::NodeRuntime;
-use project::project_settings::ProjectSettings;
+use project::project_settings::{BinarySettings, ProjectSettings};
 use serde_json::{json, Value};
 use settings::Settings;
 use std::{
@@ -69,6 +69,48 @@ impl LspAdapter for VtslsLspAdapter {
         }) as Box<_>)
     }
 
+    async fn check_if_user_installed(
+        &self,
+        delegate: &dyn LspAdapterDelegate,
+        cx: &AsyncAppContext,
+    ) -> Option<LanguageServerBinary> {
+        let configured_binary = cx.update(|cx| {
+            ProjectSettings::get_global(cx)
+                .lsp
+                .get(SERVER_NAME)
+                .and_then(|s| s.binary.clone())
+        });
+
+        match configured_binary {
+            Ok(Some(BinarySettings {
+                path: Some(path),
+                arguments,
+                ..
+            })) => Some(LanguageServerBinary {
+                path: path.into(),
+                arguments: arguments
+                    .unwrap_or_default()
+                    .iter()
+                    .map(|arg| arg.into())
+                    .collect(),
+                env: None,
+            }),
+            Ok(Some(BinarySettings {
+                path_lookup: Some(false),
+                ..
+            })) => None,
+            _ => {
+                let env = delegate.shell_env().await;
+                let path = delegate.which(SERVER_NAME.as_ref()).await?;
+                Some(LanguageServerBinary {
+                    path: path.clone(),
+                    arguments: typescript_server_binary_arguments(&path),
+                    env: Some(env),
+                })
+            }
+        }
+    }
+
     async fn fetch_server_binary(
         &self,
         latest_version: Box<dyn 'static + Send + Any>,