diff --git a/Cargo.lock b/Cargo.lock index 9945b2df9a..120f51ec93 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14863,6 +14863,13 @@ dependencies = [ "zed_extension_api 0.1.0", ] +[[package]] +name = "zed_proto" +version = "0.1.0" +dependencies = [ + "zed_extension_api 0.1.0", +] + [[package]] name = "zed_purescript" version = "0.0.1" diff --git a/Cargo.toml b/Cargo.toml index d6f4279449..6fc22029e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -154,6 +154,7 @@ members = [ "extensions/php", "extensions/perplexity", "extensions/prisma", + "extensions/proto", "extensions/purescript", "extensions/ruff", "extensions/ruby", diff --git a/extensions/proto/Cargo.toml b/extensions/proto/Cargo.toml new file mode 100644 index 0000000000..496099c526 --- /dev/null +++ b/extensions/proto/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "zed_proto" +version = "0.1.0" +edition = "2021" +publish = false +license = "Apache-2.0" + +[lints] +workspace = true + +[lib] +path = "src/proto.rs" +crate-type = ["cdylib"] + +[dependencies] +zed_extension_api = "0.1.0" diff --git a/extensions/proto/LICENSE-APACHE b/extensions/proto/LICENSE-APACHE new file mode 120000 index 0000000000..1cd601d0a3 --- /dev/null +++ b/extensions/proto/LICENSE-APACHE @@ -0,0 +1 @@ +../../LICENSE-APACHE \ No newline at end of file diff --git a/extensions/proto/extension.toml b/extensions/proto/extension.toml index a49ba7a4c4..6ecf9bf33f 100644 --- a/extensions/proto/extension.toml +++ b/extensions/proto/extension.toml @@ -9,3 +9,7 @@ repository = "https://github.com/zed-industries/zed" [grammars.proto] repository = "https://github.com/zed-industries/tree-sitter-proto" commit = "0848bd30a64be48772e15fbb9d5ba8c0cc5772ad" + +[language_servers.protobuf-language-server] +name = "Protobuf Language Server" +languages = ["Proto"] diff --git a/extensions/proto/src/proto.rs b/extensions/proto/src/proto.rs new file mode 100644 index 0000000000..c692a09327 --- /dev/null +++ b/extensions/proto/src/proto.rs @@ -0,0 +1,64 @@ +use zed_extension_api::{self as zed, settings::LspSettings, Result}; + +const PROTOBUF_LANGUAGE_SERVER_NAME: &str = "protobuf-language-server"; + +struct ProtobufLanguageServerBinary { + path: String, + args: Option>, +} + +struct ProtobufExtension; + +impl ProtobufExtension { + fn language_server_binary( + &self, + _language_server_id: &zed::LanguageServerId, + worktree: &zed::Worktree, + ) -> Result { + let binary_settings = LspSettings::for_worktree("protobuf-language-server", 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(ProtobufLanguageServerBinary { + path, + args: binary_args, + }); + } + + if let Some(path) = worktree.which(PROTOBUF_LANGUAGE_SERVER_NAME) { + return Ok(ProtobufLanguageServerBinary { + path, + args: binary_args, + }); + } + + Err(format!("{PROTOBUF_LANGUAGE_SERVER_NAME} not found in PATH",)) + } +} + +impl zed::Extension for ProtobufExtension { + fn new() -> Self { + Self + } + + fn language_server_command( + &mut self, + language_server_id: &zed_extension_api::LanguageServerId, + worktree: &zed_extension_api::Worktree, + ) -> zed_extension_api::Result { + let binary = self.language_server_binary(language_server_id, worktree)?; + Ok(zed::Command { + command: binary.path, + args: binary + .args + .unwrap_or_else(|| vec!["-logs".into(), "".into()]), + env: Default::default(), + }) + } +} + +zed::register_extension!(ProtobufExtension);