diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index 7979850899..e1316e2dc9 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -72,8 +72,9 @@ pub trait LspExt: 'static + Send + Sync { &self, version: LspBinaryVersion, http: Arc, + download_dir: Arc, ) -> BoxFuture<'static, Result>; - fn cached_server_binary(&self) -> BoxFuture<'static, Option>; + fn cached_server_binary(&self, download_dir: Arc) -> BoxFuture<'static, Option>; fn process_diagnostics(&self, diagnostics: &mut lsp::PublishDiagnosticsParams); fn label_for_completion( &self, @@ -152,6 +153,7 @@ pub enum LanguageServerBinaryStatus { pub struct LanguageRegistry { languages: Vec>, + language_server_download_dir: Option>, lsp_binary_statuses_tx: async_broadcast::Sender<(Arc, LanguageServerBinaryStatus)>, lsp_binary_statuses_rx: async_broadcast::Receiver<(Arc, LanguageServerBinaryStatus)>, } @@ -160,6 +162,7 @@ impl LanguageRegistry { pub fn new() -> Self { let (lsp_binary_statuses_tx, lsp_binary_statuses_rx) = async_broadcast::broadcast(16); Self { + language_server_download_dir: None, languages: Default::default(), lsp_binary_statuses_tx, lsp_binary_statuses_rx, @@ -176,6 +179,10 @@ impl LanguageRegistry { } } + pub fn set_language_server_download_dir(&mut self, path: impl Into>) { + self.language_server_download_dir = Some(path.into()); + } + pub fn get_language(&self, name: &str) -> Option<&Arc> { self.languages .iter() @@ -230,6 +237,11 @@ impl LanguageRegistry { } } + let download_dir = self + .language_server_download_dir + .clone() + .expect("language server download directory has not been assigned"); + let lsp_ext = language.lsp_ext.clone()?; let background = cx.background().clone(); let server_binary_path = { @@ -242,6 +254,7 @@ impl LanguageRegistry { lsp_ext, language.clone(), http_client, + download_dir, self.lsp_binary_statuses_tx.clone(), ) .map_err(Arc::new) @@ -270,17 +283,19 @@ async fn get_server_binary_path( lsp_ext: Arc, language: Arc, http_client: Arc, + download_dir: Arc, statuses: async_broadcast::Sender<(Arc, LanguageServerBinaryStatus)>, ) -> Result { let path = fetch_latest_server_binary_path( lsp_ext.clone(), language.clone(), http_client, + download_dir.clone(), statuses.clone(), ) .await; if path.is_err() { - if let Some(cached_path) = lsp_ext.cached_server_binary().await { + if let Some(cached_path) = lsp_ext.cached_server_binary(download_dir).await { statuses .broadcast((language.clone(), LanguageServerBinaryStatus::Cached)) .await?; @@ -298,6 +313,7 @@ async fn fetch_latest_server_binary_path( lsp_ext: Arc, language: Arc, http_client: Arc, + download_dir: Arc, lsp_binary_statuses_tx: async_broadcast::Sender<(Arc, LanguageServerBinaryStatus)>, ) -> Result { lsp_binary_statuses_tx @@ -313,7 +329,7 @@ async fn fetch_latest_server_binary_path( .broadcast((language.clone(), LanguageServerBinaryStatus::Downloading)) .await?; let path = lsp_ext - .fetch_server_binary(version_info, http_client) + .fetch_server_binary(version_info, http_client, download_dir) .await?; lsp_binary_statuses_tx .broadcast((language.clone(), LanguageServerBinaryStatus::Downloaded)) diff --git a/crates/zed/src/language.rs b/crates/zed/src/language.rs index 9c8810b7ff..748e82ffe8 100644 --- a/crates/zed/src/language.rs +++ b/crates/zed/src/language.rs @@ -8,7 +8,13 @@ use regex::Regex; use rust_embed::RustEmbed; use serde::Deserialize; use smol::fs::{self, File}; -use std::{borrow::Cow, env::consts, path::PathBuf, str, sync::Arc}; +use std::{ + borrow::Cow, + env::consts, + path::{Path, PathBuf}, + str, + sync::Arc, +}; use util::{ResultExt, TryFutureExt}; #[derive(RustEmbed)] @@ -70,11 +76,10 @@ impl LspExt for RustLsp { &self, version: LspBinaryVersion, http: Arc, + download_dir: Arc, ) -> BoxFuture<'static, Result> { async move { - let destination_dir_path = dirs::home_dir() - .ok_or_else(|| anyhow!("can't determine home directory"))? - .join(".zed/rust-analyzer"); + let destination_dir_path = download_dir.join("rust-analyzer"); fs::create_dir_all(&destination_dir_path).await?; let destination_path = destination_dir_path.join(format!("rust-analyzer-{}", version.name)); @@ -114,11 +119,9 @@ impl LspExt for RustLsp { .boxed() } - fn cached_server_binary(&self) -> BoxFuture<'static, Option> { + fn cached_server_binary(&self, download_dir: Arc) -> BoxFuture<'static, Option> { async move { - let destination_dir_path = dirs::home_dir() - .ok_or_else(|| anyhow!("can't determine home directory"))? - .join(".zed/rust-analyzer"); + let destination_dir_path = download_dir.join("rust-analyzer"); fs::create_dir_all(&destination_dir_path).await?; let mut last = None; @@ -234,6 +237,11 @@ impl LspExt for RustLsp { pub fn build_language_registry() -> LanguageRegistry { let mut languages = LanguageRegistry::new(); + languages.set_language_server_download_dir( + dirs::home_dir() + .expect("failed to determine home directory") + .join(".zed"), + ); languages.add(Arc::new(rust())); languages.add(Arc::new(markdown())); languages