Detailed changes
@@ -17,7 +17,7 @@ use futures::{
future::{BoxFuture, Shared},
FutureExt, TryFutureExt as _,
};
-use gpui::{executor::Background, AppContext, Task};
+use gpui::{executor::Background, AppContext, AsyncAppContext, Task};
use highlight_map::HighlightMap;
use lazy_static::lazy_static;
use lsp::CodeActionKind;
@@ -125,27 +125,30 @@ impl CachedLspAdapter {
pub async fn fetch_latest_server_version(
&self,
- http: Arc<dyn HttpClient>,
+ delegate: &dyn LspAdapterDelegate,
) -> Result<Box<dyn 'static + Send + Any>> {
- self.adapter.fetch_latest_server_version(http).await
+ self.adapter.fetch_latest_server_version(delegate).await
}
pub async fn fetch_server_binary(
&self,
version: Box<dyn 'static + Send + Any>,
- http: Arc<dyn HttpClient>,
container_dir: PathBuf,
+ delegate: &dyn LspAdapterDelegate,
) -> Result<LanguageServerBinary> {
self.adapter
- .fetch_server_binary(version, http, container_dir)
+ .fetch_server_binary(version, container_dir, delegate)
.await
}
pub async fn cached_server_binary(
&self,
container_dir: PathBuf,
+ delegate: &dyn LspAdapterDelegate,
) -> Option<LanguageServerBinary> {
- self.adapter.cached_server_binary(container_dir).await
+ self.adapter
+ .cached_server_binary(container_dir, delegate)
+ .await
}
pub fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
@@ -187,23 +190,32 @@ impl CachedLspAdapter {
}
}
+pub trait LspAdapterDelegate: Send + Sync {
+ fn show_notification(&self, message: &str, cx: &mut AppContext);
+ fn http_client(&self) -> Arc<dyn HttpClient>;
+}
+
#[async_trait]
pub trait LspAdapter: 'static + Send + Sync {
async fn name(&self) -> LanguageServerName;
async fn fetch_latest_server_version(
&self,
- http: Arc<dyn HttpClient>,
+ delegate: &dyn LspAdapterDelegate,
) -> Result<Box<dyn 'static + Send + Any>>;
async fn fetch_server_binary(
&self,
version: Box<dyn 'static + Send + Any>,
- http: Arc<dyn HttpClient>,
container_dir: PathBuf,
+ delegate: &dyn LspAdapterDelegate,
) -> Result<LanguageServerBinary>;
- async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<LanguageServerBinary>;
+ async fn cached_server_binary(
+ &self,
+ container_dir: PathBuf,
+ delegate: &dyn LspAdapterDelegate,
+ ) -> Option<LanguageServerBinary>;
async fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {}
@@ -513,10 +525,7 @@ pub struct LanguageRegistry {
login_shell_env_loaded: Shared<Task<()>>,
#[allow(clippy::type_complexity)]
lsp_binary_paths: Mutex<
- HashMap<
- LanguageServerName,
- Shared<BoxFuture<'static, Result<LanguageServerBinary, Arc<anyhow::Error>>>>,
- >,
+ HashMap<LanguageServerName, Shared<Task<Result<LanguageServerBinary, Arc<anyhow::Error>>>>>,
>,
executor: Option<Arc<Background>>,
}
@@ -812,7 +821,7 @@ impl LanguageRegistry {
language: Arc<Language>,
adapter: Arc<CachedLspAdapter>,
root_path: Arc<Path>,
- http_client: Arc<dyn HttpClient>,
+ delegate: Arc<dyn LspAdapterDelegate>,
cx: &mut AppContext,
) -> Option<PendingLanguageServer> {
let server_id = self.state.write().next_language_server_id();
@@ -860,7 +869,6 @@ impl LanguageRegistry {
.log_err()?;
let this = self.clone();
let language = language.clone();
- let http_client = http_client.clone();
let download_dir = download_dir.clone();
let root_path = root_path.clone();
let adapter = adapter.clone();
@@ -870,23 +878,25 @@ impl LanguageRegistry {
let task = cx.spawn(|cx| async move {
login_shell_env_loaded.await;
- let mut lock = this.lsp_binary_paths.lock();
- let entry = lock
+ let entry = this
+ .lsp_binary_paths
+ .lock()
.entry(adapter.name.clone())
.or_insert_with(|| {
- get_binary(
- adapter.clone(),
- language.clone(),
- http_client,
- download_dir,
- lsp_binary_statuses,
- )
- .map_err(Arc::new)
- .boxed()
+ cx.spawn(|cx| {
+ get_binary(
+ adapter.clone(),
+ language.clone(),
+ delegate,
+ download_dir,
+ lsp_binary_statuses,
+ cx,
+ )
+ .map_err(Arc::new)
+ })
.shared()
})
.clone();
- drop(lock);
let binary = entry.clone().map_err(|e| anyhow!(e)).await?;
let server = lsp::LanguageServer::new(
@@ -958,9 +968,10 @@ impl Default for LanguageRegistry {
async fn get_binary(
adapter: Arc<CachedLspAdapter>,
language: Arc<Language>,
- http_client: Arc<dyn HttpClient>,
+ delegate: Arc<dyn LspAdapterDelegate>,
download_dir: Arc<Path>,
statuses: async_broadcast::Sender<(Arc<Language>, LanguageServerBinaryStatus)>,
+ _cx: AsyncAppContext,
) -> Result<LanguageServerBinary> {
let container_dir = download_dir.join(adapter.name.0.as_ref());
if !container_dir.exists() {
@@ -972,14 +983,17 @@ async fn get_binary(
let binary = fetch_latest_binary(
adapter.clone(),
language.clone(),
- http_client,
+ delegate.as_ref(),
&container_dir,
statuses.clone(),
)
.await;
if let Err(error) = binary.as_ref() {
- if let Some(cached) = adapter.cached_server_binary(container_dir).await {
+ if let Some(cached) = adapter
+ .cached_server_binary(container_dir, delegate.as_ref())
+ .await
+ {
statuses
.broadcast((language.clone(), LanguageServerBinaryStatus::Cached))
.await?;
@@ -1001,7 +1015,7 @@ async fn get_binary(
async fn fetch_latest_binary(
adapter: Arc<CachedLspAdapter>,
language: Arc<Language>,
- http_client: Arc<dyn HttpClient>,
+ delegate: &dyn LspAdapterDelegate,
container_dir: &Path,
lsp_binary_statuses_tx: async_broadcast::Sender<(Arc<Language>, LanguageServerBinaryStatus)>,
) -> Result<LanguageServerBinary> {
@@ -1012,14 +1026,12 @@ async fn fetch_latest_binary(
LanguageServerBinaryStatus::CheckingForUpdate,
))
.await?;
- let version_info = adapter
- .fetch_latest_server_version(http_client.clone())
- .await?;
+ let version_info = adapter.fetch_latest_server_version(delegate).await?;
lsp_binary_statuses_tx
.broadcast((language.clone(), LanguageServerBinaryStatus::Downloading))
.await?;
let binary = adapter
- .fetch_server_binary(version_info, http_client, container_dir.to_path_buf())
+ .fetch_server_binary(version_info, container_dir.to_path_buf(), delegate)
.await?;
lsp_binary_statuses_tx
.broadcast((language.clone(), LanguageServerBinaryStatus::Downloaded))
@@ -1543,7 +1555,7 @@ impl LspAdapter for Arc<FakeLspAdapter> {
async fn fetch_latest_server_version(
&self,
- _: Arc<dyn HttpClient>,
+ _: &dyn LspAdapterDelegate,
) -> Result<Box<dyn 'static + Send + Any>> {
unreachable!();
}
@@ -1551,13 +1563,17 @@ impl LspAdapter for Arc<FakeLspAdapter> {
async fn fetch_server_binary(
&self,
_: Box<dyn 'static + Send + Any>,
- _: Arc<dyn HttpClient>,
_: PathBuf,
+ _: &dyn LspAdapterDelegate,
) -> Result<LanguageServerBinary> {
unreachable!();
}
- async fn cached_server_binary(&self, _: PathBuf) -> Option<LanguageServerBinary> {
+ async fn cached_server_binary(
+ &self,
+ _: PathBuf,
+ _: &dyn LspAdapterDelegate,
+ ) -> Option<LanguageServerBinary> {
unreachable!();
}
@@ -38,9 +38,9 @@ use language::{
},
range_from_lsp, range_to_lsp, Anchor, Bias, Buffer, CachedLspAdapter, CodeAction, CodeLabel,
Completion, Diagnostic, DiagnosticEntry, DiagnosticSet, Diff, Event as BufferEvent, File as _,
- Language, LanguageRegistry, LanguageServerName, LocalFile, OffsetRangeExt, Operation, Patch,
- PendingLanguageServer, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Transaction,
- Unclipped,
+ Language, LanguageRegistry, LanguageServerName, LocalFile, LspAdapterDelegate, OffsetRangeExt,
+ Operation, Patch, PendingLanguageServer, PointUtf16, TextBufferSnapshot, ToOffset,
+ ToPointUtf16, Transaction, Unclipped,
};
use log::error;
use lsp::{
@@ -75,8 +75,8 @@ use std::{
};
use terminals::Terminals;
use util::{
- debug_panic, defer, merge_json_value_into, paths::LOCAL_SETTINGS_RELATIVE_PATH, post_inc,
- ResultExt, TryFutureExt as _,
+ debug_panic, defer, http::HttpClient, merge_json_value_into,
+ paths::LOCAL_SETTINGS_RELATIVE_PATH, post_inc, ResultExt, TryFutureExt as _,
};
pub use fs::*;
@@ -252,6 +252,7 @@ pub enum Event {
LanguageServerAdded(LanguageServerId),
LanguageServerRemoved(LanguageServerId),
LanguageServerLog(LanguageServerId, String),
+ LanguageServerNotification(String),
ActiveEntryChanged(Option<ProjectEntryId>),
WorktreeAdded,
WorktreeRemoved(WorktreeId),
@@ -435,6 +436,11 @@ pub enum FormatTrigger {
Manual,
}
+struct ProjectLspAdapterDelegate {
+ project: ModelHandle<Project>,
+ http_client: Arc<dyn HttpClient>,
+}
+
impl FormatTrigger {
fn from_proto(value: i32) -> FormatTrigger {
match value {
@@ -2407,7 +2413,7 @@ impl Project {
language.clone(),
adapter.clone(),
worktree_path.clone(),
- self.client.http_client(),
+ ProjectLspAdapterDelegate::new(self, cx),
cx,
) {
Some(pending_server) => pending_server,
@@ -7188,6 +7194,27 @@ impl<P: AsRef<Path>> From<(WorktreeId, P)> for ProjectPath {
}
}
+impl ProjectLspAdapterDelegate {
+ fn new(project: &Project, cx: &ModelContext<Project>) -> Arc<Self> {
+ Arc::new(Self {
+ project: cx.handle(),
+ http_client: project.client.http_client(),
+ })
+ }
+}
+
+impl LspAdapterDelegate for ProjectLspAdapterDelegate {
+ fn show_notification(&self, message: &str, cx: &mut AppContext) {
+ self.project.update(cx, |_, cx| {
+ cx.emit(Event::LanguageServerNotification(message.to_owned()))
+ });
+ }
+
+ fn http_client(&self) -> Arc<dyn HttpClient> {
+ self.http_client.clone()
+ }
+}
+
fn split_operations(
mut operations: Vec<proto::Operation>,
) -> impl Iterator<Item = Vec<proto::Operation>> {
@@ -4,12 +4,11 @@ use futures::StreamExt;
pub use language::*;
use smol::fs::{self, File};
use std::{any::Any, path::PathBuf, sync::Arc};
-use util::fs::remove_matching;
-use util::github::latest_github_release;
-use util::http::HttpClient;
-use util::ResultExt;
-
-use util::github::GitHubLspBinaryVersion;
+use util::{
+ fs::remove_matching,
+ github::{latest_github_release, GitHubLspBinaryVersion},
+ ResultExt,
+};
pub struct CLspAdapter;
@@ -21,9 +20,9 @@ impl super::LspAdapter for CLspAdapter {
async fn fetch_latest_server_version(
&self,
- http: Arc<dyn HttpClient>,
+ delegate: &dyn LspAdapterDelegate,
) -> Result<Box<dyn 'static + Send + Any>> {
- let release = latest_github_release("clangd/clangd", false, http).await?;
+ let release = latest_github_release("clangd/clangd", false, delegate.http_client()).await?;
let asset_name = format!("clangd-mac-{}.zip", release.name);
let asset = release
.assets
@@ -40,8 +39,8 @@ impl super::LspAdapter for CLspAdapter {
async fn fetch_server_binary(
&self,
version: Box<dyn 'static + Send + Any>,
- http: Arc<dyn HttpClient>,
container_dir: PathBuf,
+ delegate: &dyn LspAdapterDelegate,
) -> Result<LanguageServerBinary> {
let version = version.downcast::<GitHubLspBinaryVersion>().unwrap();
let zip_path = container_dir.join(format!("clangd_{}.zip", version.name));
@@ -49,7 +48,8 @@ impl super::LspAdapter for CLspAdapter {
let binary_path = version_dir.join("bin/clangd");
if fs::metadata(&binary_path).await.is_err() {
- let mut response = http
+ let mut response = delegate
+ .http_client()
.get(&version.url, Default::default(), true)
.await
.context("error downloading release")?;
@@ -81,7 +81,11 @@ impl super::LspAdapter for CLspAdapter {
})
}
- async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<LanguageServerBinary> {
+ async fn cached_server_binary(
+ &self,
+ container_dir: PathBuf,
+ _: &dyn LspAdapterDelegate,
+ ) -> Option<LanguageServerBinary> {
(|| async move {
let mut last_clangd_dir = None;
let mut entries = fs::read_dir(&container_dir).await?;
@@ -5,12 +5,11 @@ pub use language::*;
use lsp::{CompletionItemKind, SymbolKind};
use smol::fs::{self, File};
use std::{any::Any, path::PathBuf, sync::Arc};
-use util::fs::remove_matching;
-use util::github::latest_github_release;
-use util::http::HttpClient;
-use util::ResultExt;
-
-use util::github::GitHubLspBinaryVersion;
+use util::{
+ fs::remove_matching,
+ github::{latest_github_release, GitHubLspBinaryVersion},
+ ResultExt,
+};
pub struct ElixirLspAdapter;
@@ -22,9 +21,10 @@ impl LspAdapter for ElixirLspAdapter {
async fn fetch_latest_server_version(
&self,
- http: Arc<dyn HttpClient>,
+ delegate: &dyn LspAdapterDelegate,
) -> Result<Box<dyn 'static + Send + Any>> {
- let release = latest_github_release("elixir-lsp/elixir-ls", false, http).await?;
+ let release =
+ latest_github_release("elixir-lsp/elixir-ls", false, delegate.http_client()).await?;
let asset_name = "elixir-ls.zip";
let asset = release
.assets
@@ -41,8 +41,8 @@ impl LspAdapter for ElixirLspAdapter {
async fn fetch_server_binary(
&self,
version: Box<dyn 'static + Send + Any>,
- http: Arc<dyn HttpClient>,
container_dir: PathBuf,
+ delegate: &dyn LspAdapterDelegate,
) -> Result<LanguageServerBinary> {
let version = version.downcast::<GitHubLspBinaryVersion>().unwrap();
let zip_path = container_dir.join(format!("elixir-ls_{}.zip", version.name));
@@ -50,7 +50,8 @@ impl LspAdapter for ElixirLspAdapter {
let binary_path = version_dir.join("language_server.sh");
if fs::metadata(&binary_path).await.is_err() {
- let mut response = http
+ let mut response = delegate
+ .http_client()
.get(&version.url, Default::default(), true)
.await
.context("error downloading release")?;
@@ -88,7 +89,11 @@ impl LspAdapter for ElixirLspAdapter {
})
}
- async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<LanguageServerBinary> {
+ async fn cached_server_binary(
+ &self,
+ container_dir: PathBuf,
+ _: &dyn LspAdapterDelegate,
+ ) -> Option<LanguageServerBinary> {
(|| async move {
let mut last = None;
let mut entries = fs::read_dir(&container_dir).await?;
@@ -5,12 +5,15 @@ pub use language::*;
use lazy_static::lazy_static;
use regex::Regex;
use smol::{fs, process};
-use std::ffi::{OsStr, OsString};
-use std::{any::Any, ops::Range, path::PathBuf, str, sync::Arc};
-use util::fs::remove_matching;
-use util::github::latest_github_release;
-use util::http::HttpClient;
-use util::ResultExt;
+use std::{
+ any::Any,
+ ffi::{OsStr, OsString},
+ ops::Range,
+ path::PathBuf,
+ str,
+ sync::Arc,
+};
+use util::{fs::remove_matching, github::latest_github_release, ResultExt};
fn server_binary_arguments() -> Vec<OsString> {
vec!["-mode=stdio".into()]
@@ -31,9 +34,9 @@ impl super::LspAdapter for GoLspAdapter {
async fn fetch_latest_server_version(
&self,
- http: Arc<dyn HttpClient>,
+ delegate: &dyn LspAdapterDelegate,
) -> Result<Box<dyn 'static + Send + Any>> {
- let release = latest_github_release("golang/tools", false, http).await?;
+ let release = latest_github_release("golang/tools", false, delegate.http_client()).await?;
let version: Option<String> = release.name.strip_prefix("gopls/v").map(str::to_string);
if version.is_none() {
log::warn!(
@@ -47,8 +50,8 @@ impl super::LspAdapter for GoLspAdapter {
async fn fetch_server_binary(
&self,
version: Box<dyn 'static + Send + Any>,
- _: Arc<dyn HttpClient>,
container_dir: PathBuf,
+ delegate: &dyn LspAdapterDelegate,
) -> Result<LanguageServerBinary> {
let version = version.downcast::<Option<String>>().unwrap();
let this = *self;
@@ -68,7 +71,10 @@ impl super::LspAdapter for GoLspAdapter {
});
}
}
- } else if let Some(path) = this.cached_server_binary(container_dir.clone()).await {
+ } else if let Some(path) = this
+ .cached_server_binary(container_dir.clone(), delegate)
+ .await
+ {
return Ok(path);
}
@@ -105,7 +111,11 @@ impl super::LspAdapter for GoLspAdapter {
})
}
- async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<LanguageServerBinary> {
+ async fn cached_server_binary(
+ &self,
+ container_dir: PathBuf,
+ _: &dyn LspAdapterDelegate,
+ ) -> Option<LanguageServerBinary> {
(|| async move {
let mut last_binary_path = None;
let mut entries = fs::read_dir(&container_dir).await?;
@@ -1,14 +1,16 @@
use anyhow::{anyhow, Result};
use async_trait::async_trait;
use futures::StreamExt;
-use language::{LanguageServerBinary, LanguageServerName, LspAdapter};
+use language::{LanguageServerBinary, LanguageServerName, LspAdapter, LspAdapterDelegate};
use node_runtime::NodeRuntime;
use serde_json::json;
use smol::fs;
-use std::ffi::OsString;
-use std::path::Path;
-use std::{any::Any, path::PathBuf, sync::Arc};
-use util::http::HttpClient;
+use std::{
+ any::Any,
+ ffi::OsString,
+ path::{Path, PathBuf},
+ sync::Arc,
+};
use util::ResultExt;
fn server_binary_arguments(server_path: &Path) -> Vec<OsString> {
@@ -36,7 +38,7 @@ impl LspAdapter for HtmlLspAdapter {
async fn fetch_latest_server_version(
&self,
- _: Arc<dyn HttpClient>,
+ _: &dyn LspAdapterDelegate,
) -> Result<Box<dyn 'static + Any + Send>> {
Ok(Box::new(
self.node
@@ -48,8 +50,8 @@ impl LspAdapter for HtmlLspAdapter {
async fn fetch_server_binary(
&self,
version: Box<dyn 'static + Send + Any>,
- _: Arc<dyn HttpClient>,
container_dir: PathBuf,
+ _: &dyn LspAdapterDelegate,
) -> Result<LanguageServerBinary> {
let version = version.downcast::<String>().unwrap();
let server_path = container_dir.join(Self::SERVER_PATH);
@@ -69,7 +71,11 @@ impl LspAdapter for HtmlLspAdapter {
})
}
- async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<LanguageServerBinary> {
+ async fn cached_server_binary(
+ &self,
+ container_dir: PathBuf,
+ _: &dyn LspAdapterDelegate,
+ ) -> Option<LanguageServerBinary> {
(|| async move {
let mut last_version_dir = None;
let mut entries = fs::read_dir(&container_dir).await?;
@@ -3,7 +3,9 @@ use async_trait::async_trait;
use collections::HashMap;
use futures::{future::BoxFuture, FutureExt, StreamExt};
use gpui::AppContext;
-use language::{LanguageRegistry, LanguageServerBinary, LanguageServerName, LspAdapter};
+use language::{
+ LanguageRegistry, LanguageServerBinary, LanguageServerName, LspAdapter, LspAdapterDelegate,
+};
use node_runtime::NodeRuntime;
use serde_json::json;
use settings::{KeymapFile, SettingsJsonSchemaParams, SettingsStore};
@@ -16,7 +18,6 @@ use std::{
path::{Path, PathBuf},
sync::Arc,
};
-use util::http::HttpClient;
use util::{paths, ResultExt};
const SERVER_PATH: &'static str =
@@ -45,7 +46,7 @@ impl LspAdapter for JsonLspAdapter {
async fn fetch_latest_server_version(
&self,
- _: Arc<dyn HttpClient>,
+ _: &dyn LspAdapterDelegate,
) -> Result<Box<dyn 'static + Send + Any>> {
Ok(Box::new(
self.node
@@ -57,8 +58,8 @@ impl LspAdapter for JsonLspAdapter {
async fn fetch_server_binary(
&self,
version: Box<dyn 'static + Send + Any>,
- _: Arc<dyn HttpClient>,
container_dir: PathBuf,
+ _: &dyn LspAdapterDelegate,
) -> Result<LanguageServerBinary> {
let version = version.downcast::<String>().unwrap();
let server_path = container_dir.join(SERVER_PATH);
@@ -78,7 +79,11 @@ impl LspAdapter for JsonLspAdapter {
})
}
- async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<LanguageServerBinary> {
+ async fn cached_server_binary(
+ &self,
+ container_dir: PathBuf,
+ _: &dyn LspAdapterDelegate,
+ ) -> Option<LanguageServerBinary> {
(|| async move {
let mut last_version_dir = None;
let mut entries = fs::read_dir(&container_dir).await?;
@@ -3,12 +3,14 @@ use async_compression::futures::bufread::GzipDecoder;
use async_tar::Archive;
use async_trait::async_trait;
use futures::{io::BufReader, StreamExt};
-use language::{LanguageServerBinary, LanguageServerName};
+use language::{LanguageServerBinary, LanguageServerName, LspAdapterDelegate};
use smol::fs;
-use std::{any::Any, env::consts, ffi::OsString, path::PathBuf, sync::Arc};
-use util::{async_iife, github::latest_github_release, http::HttpClient, ResultExt};
-
-use util::github::GitHubLspBinaryVersion;
+use std::{any::Any, env::consts, ffi::OsString, path::PathBuf};
+use util::{
+ async_iife,
+ github::{latest_github_release, GitHubLspBinaryVersion},
+ ResultExt,
+};
#[derive(Copy, Clone)]
pub struct LuaLspAdapter;
@@ -28,9 +30,11 @@ impl super::LspAdapter for LuaLspAdapter {
async fn fetch_latest_server_version(
&self,
- http: Arc<dyn HttpClient>,
+ delegate: &dyn LspAdapterDelegate,
) -> Result<Box<dyn 'static + Send + Any>> {
- let release = latest_github_release("LuaLS/lua-language-server", false, http).await?;
+ let release =
+ latest_github_release("LuaLS/lua-language-server", false, delegate.http_client())
+ .await?;
let version = release.name.clone();
let platform = match consts::ARCH {
"x86_64" => "x64",
@@ -53,15 +57,16 @@ impl super::LspAdapter for LuaLspAdapter {
async fn fetch_server_binary(
&self,
version: Box<dyn 'static + Send + Any>,
- http: Arc<dyn HttpClient>,
container_dir: PathBuf,
+ delegate: &dyn LspAdapterDelegate,
) -> Result<LanguageServerBinary> {
let version = version.downcast::<GitHubLspBinaryVersion>().unwrap();
let binary_path = container_dir.join("bin/lua-language-server");
if fs::metadata(&binary_path).await.is_err() {
- let mut response = http
+ let mut response = delegate
+ .http_client()
.get(&version.url, Default::default(), true)
.await
.map_err(|err| anyhow!("error downloading release: {}", err))?;
@@ -81,7 +86,11 @@ impl super::LspAdapter for LuaLspAdapter {
})
}
- async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<LanguageServerBinary> {
+ async fn cached_server_binary(
+ &self,
+ container_dir: PathBuf,
+ _: &dyn LspAdapterDelegate,
+ ) -> Option<LanguageServerBinary> {
async_iife!({
let mut last_binary_path = None;
let mut entries = fs::read_dir(&container_dir).await?;
@@ -1,7 +1,7 @@
use anyhow::{anyhow, Result};
use async_trait::async_trait;
use futures::StreamExt;
-use language::{LanguageServerBinary, LanguageServerName, LspAdapter};
+use language::{LanguageServerBinary, LanguageServerName, LspAdapter, LspAdapterDelegate};
use node_runtime::NodeRuntime;
use smol::fs;
use std::{
@@ -10,7 +10,6 @@ use std::{
path::{Path, PathBuf},
sync::Arc,
};
-use util::http::HttpClient;
use util::ResultExt;
fn server_binary_arguments(server_path: &Path) -> Vec<OsString> {
@@ -37,7 +36,7 @@ impl LspAdapter for PythonLspAdapter {
async fn fetch_latest_server_version(
&self,
- _: Arc<dyn HttpClient>,
+ _: &dyn LspAdapterDelegate,
) -> Result<Box<dyn 'static + Any + Send>> {
Ok(Box::new(self.node.npm_package_latest_version("pyright").await?) as Box<_>)
}
@@ -45,8 +44,8 @@ impl LspAdapter for PythonLspAdapter {
async fn fetch_server_binary(
&self,
version: Box<dyn 'static + Send + Any>,
- _: Arc<dyn HttpClient>,
container_dir: PathBuf,
+ _: &dyn LspAdapterDelegate,
) -> Result<LanguageServerBinary> {
let version = version.downcast::<String>().unwrap();
let server_path = container_dir.join(Self::SERVER_PATH);
@@ -63,7 +62,11 @@ impl LspAdapter for PythonLspAdapter {
})
}
- async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<LanguageServerBinary> {
+ async fn cached_server_binary(
+ &self,
+ container_dir: PathBuf,
+ _: &dyn LspAdapterDelegate,
+ ) -> Option<LanguageServerBinary> {
(|| async move {
let mut last_version_dir = None;
let mut entries = fs::read_dir(&container_dir).await?;
@@ -1,8 +1,7 @@
use anyhow::{anyhow, Result};
use async_trait::async_trait;
-use language::{LanguageServerBinary, LanguageServerName, LspAdapter};
+use language::{LanguageServerBinary, LanguageServerName, LspAdapter, LspAdapterDelegate};
use std::{any::Any, path::PathBuf, sync::Arc};
-use util::http::HttpClient;
pub struct RubyLanguageServer;
@@ -14,7 +13,7 @@ impl LspAdapter for RubyLanguageServer {
async fn fetch_latest_server_version(
&self,
- _: Arc<dyn HttpClient>,
+ _: &dyn LspAdapterDelegate,
) -> Result<Box<dyn 'static + Any + Send>> {
Ok(Box::new(()))
}
@@ -22,13 +21,17 @@ impl LspAdapter for RubyLanguageServer {
async fn fetch_server_binary(
&self,
_version: Box<dyn 'static + Send + Any>,
- _: Arc<dyn HttpClient>,
_container_dir: PathBuf,
+ _: &dyn LspAdapterDelegate,
) -> Result<LanguageServerBinary> {
Err(anyhow!("solargraph must be installed manually"))
}
- async fn cached_server_binary(&self, _container_dir: PathBuf) -> Option<LanguageServerBinary> {
+ async fn cached_server_binary(
+ &self,
+ _: PathBuf,
+ _: &dyn LspAdapterDelegate,
+ ) -> Option<LanguageServerBinary> {
Some(LanguageServerBinary {
path: "solargraph".into(),
arguments: vec!["stdio".into()],
@@ -7,10 +7,11 @@ use lazy_static::lazy_static;
use regex::Regex;
use smol::fs::{self, File};
use std::{any::Any, borrow::Cow, env::consts, path::PathBuf, str, sync::Arc};
-use util::fs::remove_matching;
-use util::github::{latest_github_release, GitHubLspBinaryVersion};
-use util::http::HttpClient;
-use util::ResultExt;
+use util::{
+ fs::remove_matching,
+ github::{latest_github_release, GitHubLspBinaryVersion},
+ ResultExt,
+};
pub struct RustLspAdapter;
@@ -22,9 +23,11 @@ impl LspAdapter for RustLspAdapter {
async fn fetch_latest_server_version(
&self,
- http: Arc<dyn HttpClient>,
+ delegate: &dyn LspAdapterDelegate,
) -> Result<Box<dyn 'static + Send + Any>> {
- let release = latest_github_release("rust-analyzer/rust-analyzer", false, http).await?;
+ let release =
+ latest_github_release("rust-analyzer/rust-analyzer", false, delegate.http_client())
+ .await?;
let asset_name = format!("rust-analyzer-{}-apple-darwin.gz", consts::ARCH);
let asset = release
.assets
@@ -40,14 +43,15 @@ impl LspAdapter for RustLspAdapter {
async fn fetch_server_binary(
&self,
version: Box<dyn 'static + Send + Any>,
- http: Arc<dyn HttpClient>,
container_dir: PathBuf,
+ delegate: &dyn LspAdapterDelegate,
) -> Result<LanguageServerBinary> {
let version = version.downcast::<GitHubLspBinaryVersion>().unwrap();
let destination_path = container_dir.join(format!("rust-analyzer-{}", version.name));
if fs::metadata(&destination_path).await.is_err() {
- let mut response = http
+ let mut response = delegate
+ .http_client()
.get(&version.url, Default::default(), true)
.await
.map_err(|err| anyhow!("error downloading release: {}", err))?;
@@ -69,7 +73,11 @@ impl LspAdapter for RustLspAdapter {
})
}
- async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<LanguageServerBinary> {
+ async fn cached_server_binary(
+ &self,
+ container_dir: PathBuf,
+ _: &dyn LspAdapterDelegate,
+ ) -> Option<LanguageServerBinary> {
(|| async move {
let mut last = None;
let mut entries = fs::read_dir(&container_dir).await?;
@@ -4,7 +4,7 @@ use async_tar::Archive;
use async_trait::async_trait;
use futures::{future::BoxFuture, FutureExt};
use gpui::AppContext;
-use language::{LanguageServerBinary, LanguageServerName, LspAdapter};
+use language::{LanguageServerBinary, LanguageServerName, LspAdapter, LspAdapterDelegate};
use lsp::CodeActionKind;
use node_runtime::NodeRuntime;
use serde_json::{json, Value};
@@ -16,7 +16,7 @@ use std::{
path::{Path, PathBuf},
sync::Arc,
};
-use util::{fs::remove_matching, github::latest_github_release, http::HttpClient};
+use util::{fs::remove_matching, github::latest_github_release};
use util::{github::GitHubLspBinaryVersion, ResultExt};
fn typescript_server_binary_arguments(server_path: &Path) -> Vec<OsString> {
@@ -58,7 +58,7 @@ impl LspAdapter for TypeScriptLspAdapter {
async fn fetch_latest_server_version(
&self,
- _: Arc<dyn HttpClient>,
+ _: &dyn LspAdapterDelegate,
) -> Result<Box<dyn 'static + Send + Any>> {
Ok(Box::new(TypeScriptVersions {
typescript_version: self.node.npm_package_latest_version("typescript").await?,
@@ -72,8 +72,8 @@ impl LspAdapter for TypeScriptLspAdapter {
async fn fetch_server_binary(
&self,
version: Box<dyn 'static + Send + Any>,
- _: Arc<dyn HttpClient>,
container_dir: PathBuf,
+ _: &dyn LspAdapterDelegate,
) -> Result<LanguageServerBinary> {
let version = version.downcast::<TypeScriptVersions>().unwrap();
let server_path = container_dir.join(Self::NEW_SERVER_PATH);
@@ -99,7 +99,11 @@ impl LspAdapter for TypeScriptLspAdapter {
})
}
- async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<LanguageServerBinary> {
+ async fn cached_server_binary(
+ &self,
+ container_dir: PathBuf,
+ _: &dyn LspAdapterDelegate,
+ ) -> Option<LanguageServerBinary> {
(|| async move {
let old_server_path = container_dir.join(Self::OLD_SERVER_PATH);
let new_server_path = container_dir.join(Self::NEW_SERVER_PATH);
@@ -204,12 +208,13 @@ impl LspAdapter for EsLintLspAdapter {
async fn fetch_latest_server_version(
&self,
- http: Arc<dyn HttpClient>,
+ delegate: &dyn LspAdapterDelegate,
) -> Result<Box<dyn 'static + Send + Any>> {
// At the time of writing the latest vscode-eslint release was released in 2020 and requires
// special custom LSP protocol extensions be handled to fully initialize. Download the latest
// prerelease instead to sidestep this issue
- let release = latest_github_release("microsoft/vscode-eslint", true, http).await?;
+ let release =
+ latest_github_release("microsoft/vscode-eslint", true, delegate.http_client()).await?;
Ok(Box::new(GitHubLspBinaryVersion {
name: release.name,
url: release.tarball_url,
@@ -219,8 +224,8 @@ impl LspAdapter for EsLintLspAdapter {
async fn fetch_server_binary(
&self,
version: Box<dyn 'static + Send + Any>,
- http: Arc<dyn HttpClient>,
container_dir: PathBuf,
+ delegate: &dyn LspAdapterDelegate,
) -> Result<LanguageServerBinary> {
let version = version.downcast::<GitHubLspBinaryVersion>().unwrap();
let destination_path = container_dir.join(format!("vscode-eslint-{}", version.name));
@@ -229,7 +234,8 @@ impl LspAdapter for EsLintLspAdapter {
if fs::metadata(&server_path).await.is_err() {
remove_matching(&container_dir, |entry| entry != destination_path).await;
- let mut response = http
+ let mut response = delegate
+ .http_client()
.get(&version.url, Default::default(), true)
.await
.map_err(|err| anyhow!("error downloading release: {}", err))?;
@@ -257,7 +263,11 @@ impl LspAdapter for EsLintLspAdapter {
})
}
- async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<LanguageServerBinary> {
+ async fn cached_server_binary(
+ &self,
+ container_dir: PathBuf,
+ _: &dyn LspAdapterDelegate,
+ ) -> Option<LanguageServerBinary> {
(|| async move {
// This is unfortunate but we don't know what the version is to build a path directly
let mut dir = fs::read_dir(&container_dir).await?;
@@ -4,6 +4,7 @@ use futures::{future::BoxFuture, FutureExt, StreamExt};
use gpui::AppContext;
use language::{
language_settings::all_language_settings, LanguageServerBinary, LanguageServerName, LspAdapter,
+ LspAdapterDelegate,
};
use node_runtime::NodeRuntime;
use serde_json::Value;
@@ -15,7 +16,6 @@ use std::{
path::{Path, PathBuf},
sync::Arc,
};
-use util::http::HttpClient;
use util::ResultExt;
fn server_binary_arguments(server_path: &Path) -> Vec<OsString> {
@@ -42,7 +42,7 @@ impl LspAdapter for YamlLspAdapter {
async fn fetch_latest_server_version(
&self,
- _: Arc<dyn HttpClient>,
+ _: &dyn LspAdapterDelegate,
) -> Result<Box<dyn 'static + Any + Send>> {
Ok(Box::new(
self.node
@@ -54,8 +54,8 @@ impl LspAdapter for YamlLspAdapter {
async fn fetch_server_binary(
&self,
version: Box<dyn 'static + Send + Any>,
- _: Arc<dyn HttpClient>,
container_dir: PathBuf,
+ _: &dyn LspAdapterDelegate,
) -> Result<LanguageServerBinary> {
let version = version.downcast::<String>().unwrap();
let server_path = container_dir.join(Self::SERVER_PATH);
@@ -72,7 +72,11 @@ impl LspAdapter for YamlLspAdapter {
})
}
- async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<LanguageServerBinary> {
+ async fn cached_server_binary(
+ &self,
+ container_dir: PathBuf,
+ _: &dyn LspAdapterDelegate,
+ ) -> Option<LanguageServerBinary> {
(|| async move {
let mut last_version_dir = None;
let mut entries = fs::read_dir(&container_dir).await?;