Split Lsp installation methods from LspAdapter

This commit is contained in:
Lukas Wirth 2025-08-06 11:48:05 +02:00
parent 85865fc950
commit aae59a2842
13 changed files with 719 additions and 717 deletions

View file

@ -9,7 +9,7 @@ use gpui::{App, AsyncApp, Task};
use http_client::github::{GitHubLspBinaryVersion, latest_github_release};
use language::{
ContextProvider, LanguageName, LanguageRegistry, LocalFile as _, LspAdapter,
LspAdapterDelegate, Toolchain,
LspAdapterDelegate, LspInstaller, Toolchain,
};
use lsp::{LanguageServerBinary, LanguageServerName};
use node_runtime::{NodeRuntime, VersionStrategy};
@ -22,7 +22,6 @@ use smol::{
lock::RwLock,
};
use std::{
any::Any,
env::consts,
ffi::OsString,
path::{Path, PathBuf},
@ -294,10 +293,13 @@ fn generate_inspector_style_schema() -> serde_json_lenient::Value {
serde_json_lenient::to_value(schema).unwrap()
}
#[async_trait(?Send)]
impl LspAdapter for JsonLspAdapter {
fn name(&self) -> LanguageServerName {
LanguageServerName("json-language-server".into())
impl LspInstaller for JsonLspAdapter {
type BinaryVersion = String;
async fn fetch_latest_server_version(&self, _: &dyn LspAdapterDelegate) -> Result<String> {
self.node
.npm_package_latest_version(Self::PACKAGE_NAME)
.await
}
async fn check_if_user_installed(
@ -318,24 +320,12 @@ impl LspAdapter for JsonLspAdapter {
})
}
async fn fetch_latest_server_version(
&self,
_: &dyn LspAdapterDelegate,
) -> Result<Box<dyn 'static + Send + Any>> {
Ok(Box::new(
self.node
.npm_package_latest_version(Self::PACKAGE_NAME)
.await?,
) as Box<_>)
}
async fn check_if_version_installed(
&self,
version: &(dyn 'static + Send + Any),
version: &String,
container_dir: &PathBuf,
_: &dyn LspAdapterDelegate,
) -> Option<LanguageServerBinary> {
let version = version.downcast_ref::<String>().unwrap();
let server_path = container_dir.join(SERVER_PATH);
let should_install_language_server = self
@ -361,11 +351,10 @@ impl LspAdapter for JsonLspAdapter {
async fn fetch_server_binary(
&self,
latest_version: Box<dyn 'static + Send + Any>,
latest_version: String,
container_dir: PathBuf,
_: &dyn LspAdapterDelegate,
) -> Result<LanguageServerBinary> {
let latest_version = latest_version.downcast::<String>().unwrap();
let server_path = container_dir.join(SERVER_PATH);
self.node
@ -389,6 +378,13 @@ impl LspAdapter for JsonLspAdapter {
) -> Option<LanguageServerBinary> {
get_cached_server_binary(container_dir, &self.node).await
}
}
#[async_trait(?Send)]
impl LspAdapter for JsonLspAdapter {
fn name(&self) -> LanguageServerName {
LanguageServerName("json-language-server".into())
}
async fn initialization_options(
self: Arc<Self>,
@ -485,16 +481,13 @@ impl NodeVersionAdapter {
LanguageServerName::new_static("package-version-server");
}
#[async_trait(?Send)]
impl LspAdapter for NodeVersionAdapter {
fn name(&self) -> LanguageServerName {
Self::SERVER_NAME
}
impl LspInstaller for NodeVersionAdapter {
type BinaryVersion = GitHubLspBinaryVersion;
async fn fetch_latest_server_version(
&self,
delegate: &dyn LspAdapterDelegate,
) -> Result<Box<dyn 'static + Send + Any>> {
) -> Result<GitHubLspBinaryVersion> {
let release = latest_github_release(
"zed-industries/package-version-server",
true,
@ -519,11 +512,11 @@ impl LspAdapter for NodeVersionAdapter {
.iter()
.find(|asset| asset.name == asset_name)
.with_context(|| format!("no asset found matching `{asset_name:?}`"))?;
Ok(Box::new(GitHubLspBinaryVersion {
Ok(GitHubLspBinaryVersion {
name: release.tag_name,
url: asset.browser_download_url.clone(),
digest: asset.digest.clone(),
}))
})
}
async fn check_if_user_installed(
@ -542,11 +535,11 @@ impl LspAdapter for NodeVersionAdapter {
async fn fetch_server_binary(
&self,
latest_version: Box<dyn 'static + Send + Any>,
latest_version: GitHubLspBinaryVersion,
container_dir: PathBuf,
delegate: &dyn LspAdapterDelegate,
) -> Result<LanguageServerBinary> {
let version = latest_version.downcast::<GitHubLspBinaryVersion>().unwrap();
let version = &latest_version;
let destination_path = container_dir.join(format!(
"{}-{}{}",
Self::SERVER_NAME,
@ -596,6 +589,13 @@ impl LspAdapter for NodeVersionAdapter {
}
}
#[async_trait(?Send)]
impl LspAdapter for NodeVersionAdapter {
fn name(&self) -> LanguageServerName {
Self::SERVER_NAME
}
}
async fn get_cached_version_server_binary(container_dir: PathBuf) -> Option<LanguageServerBinary> {
maybe!(async {
let mut last = None;