1use zed_extension_api::{self as zed, Result};
2
3struct GleamExtension {
4 cached_binary_path: Option<String>,
5}
6
7impl zed::Extension for GleamExtension {
8 fn new() -> Self {
9 Self {
10 cached_binary_path: None,
11 }
12 }
13
14 fn language_server_command(
15 &mut self,
16 config: zed::LanguageServerConfig,
17 _worktree: &zed::Worktree,
18 ) -> Result<zed::Command> {
19 let binary_path = if let Some(path) = &self.cached_binary_path {
20 zed::set_language_server_installation_status(
21 &config.name,
22 &zed::LanguageServerInstallationStatus::Cached,
23 );
24
25 path.clone()
26 } else {
27 zed::set_language_server_installation_status(
28 &config.name,
29 &zed::LanguageServerInstallationStatus::CheckingForUpdate,
30 );
31 let release = zed::latest_github_release(
32 "gleam-lang/gleam",
33 zed::GithubReleaseOptions {
34 require_assets: true,
35 pre_release: false,
36 },
37 )?;
38
39 let (platform, arch) = zed::current_platform();
40 let asset_name = format!(
41 "gleam-{version}-{arch}-{os}.tar.gz",
42 version = release.version,
43 arch = match arch {
44 zed::Architecture::Aarch64 => "aarch64",
45 zed::Architecture::X86 => "x86",
46 zed::Architecture::X8664 => "x86_64",
47 },
48 os = match platform {
49 zed::Os::Mac => "apple-darwin",
50 zed::Os::Linux => "unknown-linux-musl",
51 zed::Os::Windows => "pc-windows-msvc",
52 },
53 );
54
55 let asset = release
56 .assets
57 .iter()
58 .find(|asset| asset.name == asset_name)
59 .ok_or_else(|| format!("no asset found matching {:?}", asset_name))?;
60
61 zed::set_language_server_installation_status(
62 &config.name,
63 &zed::LanguageServerInstallationStatus::Downloading,
64 );
65 let version_dir = format!("gleam-{}", release.version);
66 zed::download_file(
67 &asset.download_url,
68 &version_dir,
69 zed::DownloadedFileType::GzipTar,
70 )
71 .map_err(|e| format!("failed to download file: {e}"))?;
72
73 zed::set_language_server_installation_status(
74 &config.name,
75 &zed::LanguageServerInstallationStatus::Downloaded,
76 );
77
78 let binary_path = format!("{version_dir}/gleam");
79 self.cached_binary_path = Some(binary_path.clone());
80 binary_path
81 };
82
83 Ok(zed::Command {
84 command: binary_path,
85 args: vec!["lsp".to_string()],
86 env: Default::default(),
87 })
88 }
89}
90
91zed::register_extension!(GleamExtension);