toml: Respect language server `binary` settings (#25276)

Marshall Bowers created

This PR updates the TOML extension to respect the `binary` settings for
the language server.

Related to https://github.com/zed-industries/zed/issues/22775.

Release Notes:

- N/A

Change summary

extensions/toml/src/toml.rs | 51 +++++++++++++++++++++++++++++++++-----
1 file changed, 44 insertions(+), 7 deletions(-)

Detailed changes

extensions/toml/src/toml.rs 🔗

@@ -1,19 +1,50 @@
 use std::fs;
 use zed::LanguageServerId;
+use zed_extension_api::settings::LspSettings;
 use zed_extension_api::{self as zed, Result};
 
+struct TaploBinary {
+    path: String,
+    args: Option<Vec<String>>,
+}
+
 struct TomlExtension {
     cached_binary_path: Option<String>,
 }
 
 impl TomlExtension {
-    fn language_server_binary_path(
+    fn language_server_binary(
         &mut self,
         language_server_id: &LanguageServerId,
-    ) -> Result<String> {
+        worktree: &zed::Worktree,
+    ) -> Result<TaploBinary> {
+        let binary_settings = LspSettings::for_worktree("taplo", worktree)
+            .ok()
+            .and_then(|lsp_settings| lsp_settings.binary);
+        let binary_args = binary_settings
+            .as_ref()
+            .and_then(|binary_settings| binary_settings.arguments.clone());
+
+        if let Some(path) = binary_settings.and_then(|binary_settings| binary_settings.path) {
+            return Ok(TaploBinary {
+                path,
+                args: binary_args,
+            });
+        }
+
+        if let Some(path) = worktree.which("taplo") {
+            return Ok(TaploBinary {
+                path,
+                args: binary_args,
+            });
+        }
+
         if let Some(path) = &self.cached_binary_path {
             if fs::metadata(path).map_or(false, |stat| stat.is_file()) {
-                return Ok(path.clone());
+                return Ok(TaploBinary {
+                    path: path.clone(),
+                    args: binary_args,
+                });
             }
         }
 
@@ -88,7 +119,10 @@ impl TomlExtension {
         }
 
         self.cached_binary_path = Some(binary_path.clone());
-        Ok(binary_path)
+        Ok(TaploBinary {
+            path: binary_path,
+            args: binary_args,
+        })
     }
 }
 
@@ -102,11 +136,14 @@ impl zed::Extension for TomlExtension {
     fn language_server_command(
         &mut self,
         language_server_id: &LanguageServerId,
-        _worktree: &zed::Worktree,
+        worktree: &zed::Worktree,
     ) -> Result<zed::Command> {
+        let taplo_binary = self.language_server_binary(language_server_id, worktree)?;
         Ok(zed::Command {
-            command: self.language_server_binary_path(language_server_id)?,
-            args: vec!["lsp".to_string(), "stdio".to_string()],
+            command: taplo_binary.path,
+            args: taplo_binary
+                .args
+                .unwrap_or_else(|| vec!["lsp".to_string(), "stdio".to_string()]),
             env: Default::default(),
         })
     }