1use zed_extension_api::{self as zed, Result, settings::LspSettings};
2
3const PROTOBUF_LANGUAGE_SERVER_NAME: &str = "protobuf-language-server";
4
5struct ProtobufLanguageServerBinary {
6 path: String,
7 args: Option<Vec<String>>,
8}
9
10struct ProtobufExtension;
11
12impl ProtobufExtension {
13 fn language_server_binary(
14 &self,
15 _language_server_id: &zed::LanguageServerId,
16 worktree: &zed::Worktree,
17 ) -> Result<ProtobufLanguageServerBinary> {
18 let binary_settings = LspSettings::for_worktree("protobuf-language-server", worktree)
19 .ok()
20 .and_then(|lsp_settings| lsp_settings.binary);
21 let binary_args = binary_settings
22 .as_ref()
23 .and_then(|binary_settings| binary_settings.arguments.clone());
24
25 if let Some(path) = binary_settings.and_then(|binary_settings| binary_settings.path) {
26 return Ok(ProtobufLanguageServerBinary {
27 path,
28 args: binary_args,
29 });
30 }
31
32 if let Some(path) = worktree.which(PROTOBUF_LANGUAGE_SERVER_NAME) {
33 return Ok(ProtobufLanguageServerBinary {
34 path,
35 args: binary_args,
36 });
37 }
38
39 Err(format!("{PROTOBUF_LANGUAGE_SERVER_NAME} not found in PATH",))
40 }
41}
42
43impl zed::Extension for ProtobufExtension {
44 fn new() -> Self {
45 Self
46 }
47
48 fn language_server_command(
49 &mut self,
50 language_server_id: &zed_extension_api::LanguageServerId,
51 worktree: &zed_extension_api::Worktree,
52 ) -> zed_extension_api::Result<zed_extension_api::Command> {
53 let binary = self.language_server_binary(language_server_id, worktree)?;
54 Ok(zed::Command {
55 command: binary.path,
56 args: binary
57 .args
58 .unwrap_or_else(|| vec!["-logs".into(), "".into()]),
59 env: Default::default(),
60 })
61 }
62}
63
64zed::register_extension!(ProtobufExtension);