language: Change signature of initialization_options_schema (#45937)
This makes this take the LSP adapter delegate instead of the binary itself. Despite us passing `LanguageServerBinaryOptions` with `allow_download: false`, extensions would still try to download the binary because it was never implemented for these to respect that. This would cause us to try to download all langauge servers provided by extensions when opening a settings file and/or requesting the JSON schema for that. This PR fixes this by passing the LSP adapter delegate instead, so the few language servers which actually want to have the binary for resolving the initialization options can decide on this by themselves. With that, we no longer download all language servers for the schema request Release Notes: - N/A
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -8653,7 +8653,6 @@ dependencies = [
|
|||||||
"extension",
|
"extension",
|
||||||
"gpui",
|
"gpui",
|
||||||
"language",
|
"language",
|
||||||
"lsp",
|
|
||||||
"paths",
|
"paths",
|
||||||
"project",
|
"project",
|
||||||
"schemars",
|
"schemars",
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ dap.workspace = true
|
|||||||
extension.workspace = true
|
extension.workspace = true
|
||||||
gpui.workspace = true
|
gpui.workspace = true
|
||||||
language.workspace = true
|
language.workspace = true
|
||||||
lsp.workspace = true
|
|
||||||
paths.workspace = true
|
paths.workspace = true
|
||||||
project.workspace = true
|
project.workspace = true
|
||||||
schemars.workspace = true
|
schemars.workspace = true
|
||||||
@@ -31,11 +30,3 @@ snippet_provider.workspace = true
|
|||||||
task.workspace = true
|
task.workspace = true
|
||||||
theme.workspace = true
|
theme.workspace = true
|
||||||
util.workspace = true
|
util.workspace = true
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Uncomment other workspace dependencies as needed
|
|
||||||
# assistant.workspace = true
|
|
||||||
# client.workspace = true
|
|
||||||
# project.workspace = true
|
|
||||||
# settings.workspace = true
|
|
||||||
|
|||||||
@@ -3,8 +3,7 @@ use std::{str::FromStr, sync::Arc};
|
|||||||
|
|
||||||
use anyhow::{Context as _, Result};
|
use anyhow::{Context as _, Result};
|
||||||
use gpui::{App, AsyncApp, BorrowAppContext as _, Entity, Task, WeakEntity};
|
use gpui::{App, AsyncApp, BorrowAppContext as _, Entity, Task, WeakEntity};
|
||||||
use language::{LanguageRegistry, language_settings::all_language_settings};
|
use language::{LanguageRegistry, LspAdapterDelegate, language_settings::all_language_settings};
|
||||||
use lsp::LanguageServerBinaryOptions;
|
|
||||||
use project::{LspStore, lsp_store::LocalLspAdapterDelegate};
|
use project::{LspStore, lsp_store::LocalLspAdapterDelegate};
|
||||||
use settings::LSP_SETTINGS_SCHEMA_URL_PREFIX;
|
use settings::LSP_SETTINGS_SCHEMA_URL_PREFIX;
|
||||||
use util::schemars::{AllowTrailingCommas, DefaultDenyUnknownFields};
|
use util::schemars::{AllowTrailingCommas, DefaultDenyUnknownFields};
|
||||||
@@ -123,18 +122,18 @@ pub async fn resolve_schema_request_inner(
|
|||||||
.find(|adapter| adapter.name().as_ref() as &str == lsp_name)
|
.find(|adapter| adapter.name().as_ref() as &str == lsp_name)
|
||||||
.with_context(|| format!("LSP adapter not found: {}", lsp_name))?;
|
.with_context(|| format!("LSP adapter not found: {}", lsp_name))?;
|
||||||
|
|
||||||
let delegate = cx
|
let delegate: Arc<dyn LspAdapterDelegate> = cx
|
||||||
.update(|inner_cx| {
|
.update(|inner_cx| {
|
||||||
lsp_store.update(inner_cx, |lsp_store, inner_cx| {
|
lsp_store.update(inner_cx, |lsp_store, cx| {
|
||||||
let Some(local) = lsp_store.as_local() else {
|
let Some(local) = lsp_store.as_local() else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let Some(worktree) = local.worktree_store.read(inner_cx).worktrees().next()
|
let Some(worktree) = local.worktree_store.read(cx).worktrees().next()
|
||||||
else {
|
else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
Some(LocalLspAdapterDelegate::from_local_lsp(
|
Some(LocalLspAdapterDelegate::from_local_lsp(
|
||||||
local, &worktree, inner_cx,
|
local, &worktree, cx,
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
})?
|
})?
|
||||||
@@ -143,36 +142,8 @@ pub async fn resolve_schema_request_inner(
|
|||||||
"either LSP store is not in local mode or no worktree is available"
|
"either LSP store is not in local mode or no worktree is available"
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
let adapter_for_schema = adapter.clone();
|
adapter
|
||||||
|
.initialization_options_schema(&delegate, cx)
|
||||||
let binary = adapter
|
|
||||||
.get_language_server_command(
|
|
||||||
delegate,
|
|
||||||
None,
|
|
||||||
LanguageServerBinaryOptions {
|
|
||||||
allow_path_lookup: true,
|
|
||||||
allow_binary_download: false,
|
|
||||||
pre_release: false,
|
|
||||||
},
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.await
|
|
||||||
.0
|
|
||||||
.with_context(|| {
|
|
||||||
format!(
|
|
||||||
concat!(
|
|
||||||
"Failed to find language server {} ",
|
|
||||||
"to generate initialization params schema"
|
|
||||||
),
|
|
||||||
lsp_name
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
adapter_for_schema
|
|
||||||
.adapter
|
|
||||||
.clone()
|
|
||||||
.initialization_options_schema(&binary)
|
|
||||||
.await
|
.await
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
serde_json::json!({
|
serde_json::json!({
|
||||||
|
|||||||
@@ -331,6 +331,21 @@ impl CachedLspAdapter {
|
|||||||
.unwrap_or_else(|| language_name.lsp_id())
|
.unwrap_or_else(|| language_name.lsp_id())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn initialization_options_schema(
|
||||||
|
&self,
|
||||||
|
delegate: &Arc<dyn LspAdapterDelegate>,
|
||||||
|
cx: &mut AsyncApp,
|
||||||
|
) -> Option<serde_json::Value> {
|
||||||
|
self.adapter
|
||||||
|
.clone()
|
||||||
|
.initialization_options_schema(
|
||||||
|
delegate,
|
||||||
|
self.cached_binary.clone().lock_owned().await,
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
pub fn process_prompt_response(&self, context: &PromptResponseContext, cx: &mut AsyncApp) {
|
pub fn process_prompt_response(&self, context: &PromptResponseContext, cx: &mut AsyncApp) {
|
||||||
self.adapter.process_prompt_response(context, cx)
|
self.adapter.process_prompt_response(context, cx)
|
||||||
}
|
}
|
||||||
@@ -464,7 +479,9 @@ pub trait LspAdapter: 'static + Send + Sync + DynLspInstaller {
|
|||||||
/// Returns the JSON schema of the initialization_options for the language server.
|
/// Returns the JSON schema of the initialization_options for the language server.
|
||||||
async fn initialization_options_schema(
|
async fn initialization_options_schema(
|
||||||
self: Arc<Self>,
|
self: Arc<Self>,
|
||||||
_language_server_binary: &LanguageServerBinary,
|
_delegate: &Arc<dyn LspAdapterDelegate>,
|
||||||
|
_cached_binary: OwnedMutexGuard<Option<(bool, LanguageServerBinary)>>,
|
||||||
|
_cx: &mut AsyncApp,
|
||||||
) -> Option<serde_json::Value> {
|
) -> Option<serde_json::Value> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -591,6 +608,7 @@ pub trait DynLspInstaller {
|
|||||||
pre_release: bool,
|
pre_release: bool,
|
||||||
cx: &mut AsyncApp,
|
cx: &mut AsyncApp,
|
||||||
) -> Result<LanguageServerBinary>;
|
) -> Result<LanguageServerBinary>;
|
||||||
|
|
||||||
fn get_language_server_command(
|
fn get_language_server_command(
|
||||||
self: Arc<Self>,
|
self: Arc<Self>,
|
||||||
delegate: Arc<dyn LspAdapterDelegate>,
|
delegate: Arc<dyn LspAdapterDelegate>,
|
||||||
@@ -686,6 +704,12 @@ where
|
|||||||
return (Ok(binary), None);
|
return (Ok(binary), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some((pre_release, cached_binary)) = cached_binary_deref
|
||||||
|
&& *pre_release == binary_options.pre_release
|
||||||
|
{
|
||||||
|
return (Ok(cached_binary.clone()), None);
|
||||||
|
}
|
||||||
|
|
||||||
if !binary_options.allow_binary_download {
|
if !binary_options.allow_binary_download {
|
||||||
return (
|
return (
|
||||||
Err(anyhow::anyhow!("downloading language servers disabled")),
|
Err(anyhow::anyhow!("downloading language servers disabled")),
|
||||||
@@ -693,12 +717,6 @@ where
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((pre_release, cached_binary)) = cached_binary_deref
|
|
||||||
&& *pre_release == binary_options.pre_release
|
|
||||||
{
|
|
||||||
return (Ok(cached_binary.clone()), None);
|
|
||||||
}
|
|
||||||
|
|
||||||
let Some(container_dir) = delegate.language_server_download_dir(&self.name()).await
|
let Some(container_dir) = delegate.language_server_download_dir(&self.name()).await
|
||||||
else {
|
else {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -2,16 +2,17 @@ use anyhow::{Context as _, ensure};
|
|||||||
use anyhow::{Result, anyhow};
|
use anyhow::{Result, anyhow};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
|
use futures::lock::OwnedMutexGuard;
|
||||||
use futures::{AsyncBufReadExt, StreamExt as _};
|
use futures::{AsyncBufReadExt, StreamExt as _};
|
||||||
use gpui::{App, AsyncApp, SharedString, Task};
|
use gpui::{App, AsyncApp, SharedString, Task};
|
||||||
use http_client::github::{AssetKind, GitHubLspBinaryVersion, latest_github_release};
|
use http_client::github::{AssetKind, GitHubLspBinaryVersion, latest_github_release};
|
||||||
use language::language_settings::language_settings;
|
use language::language_settings::language_settings;
|
||||||
use language::{ContextLocation, LanguageToolchainStore, LspInstaller};
|
use language::{ContextLocation, DynLspInstaller, LanguageToolchainStore, LspInstaller};
|
||||||
use language::{ContextProvider, LspAdapter, LspAdapterDelegate};
|
use language::{ContextProvider, LspAdapter, LspAdapterDelegate};
|
||||||
use language::{LanguageName, ManifestName, ManifestProvider, ManifestQuery};
|
use language::{LanguageName, ManifestName, ManifestProvider, ManifestQuery};
|
||||||
use language::{Toolchain, ToolchainList, ToolchainLister, ToolchainMetadata};
|
use language::{Toolchain, ToolchainList, ToolchainLister, ToolchainMetadata};
|
||||||
use lsp::LanguageServerName;
|
|
||||||
use lsp::{LanguageServerBinary, Uri};
|
use lsp::{LanguageServerBinary, Uri};
|
||||||
|
use lsp::{LanguageServerBinaryOptions, LanguageServerName};
|
||||||
use node_runtime::{NodeRuntime, VersionStrategy};
|
use node_runtime::{NodeRuntime, VersionStrategy};
|
||||||
use pet_core::Configuration;
|
use pet_core::Configuration;
|
||||||
use pet_core::os_environment::Environment;
|
use pet_core::os_environment::Environment;
|
||||||
@@ -2342,9 +2343,27 @@ impl LspAdapter for RuffLspAdapter {
|
|||||||
|
|
||||||
async fn initialization_options_schema(
|
async fn initialization_options_schema(
|
||||||
self: Arc<Self>,
|
self: Arc<Self>,
|
||||||
language_server_binary: &LanguageServerBinary,
|
delegate: &Arc<dyn LspAdapterDelegate>,
|
||||||
|
cached_binary: OwnedMutexGuard<Option<(bool, LanguageServerBinary)>>,
|
||||||
|
cx: &mut AsyncApp,
|
||||||
) -> Option<serde_json::Value> {
|
) -> Option<serde_json::Value> {
|
||||||
let mut command = util::command::new_smol_command(&language_server_binary.path);
|
let binary = self
|
||||||
|
.get_language_server_command(
|
||||||
|
delegate.clone(),
|
||||||
|
None,
|
||||||
|
LanguageServerBinaryOptions {
|
||||||
|
allow_path_lookup: true,
|
||||||
|
allow_binary_download: false,
|
||||||
|
pre_release: false,
|
||||||
|
},
|
||||||
|
cached_binary,
|
||||||
|
cx.clone(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.0
|
||||||
|
.ok()?;
|
||||||
|
|
||||||
|
let mut command = util::command::new_smol_command(&binary.path);
|
||||||
command
|
command
|
||||||
.args(&["config", "--output-format", "json"])
|
.args(&["config", "--output-format", "json"])
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
|
|||||||
@@ -2,12 +2,13 @@ use anyhow::{Context as _, Result};
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
|
use futures::lock::OwnedMutexGuard;
|
||||||
use gpui::{App, AppContext, AsyncApp, SharedString, Task};
|
use gpui::{App, AppContext, AsyncApp, SharedString, Task};
|
||||||
use http_client::github::AssetKind;
|
use http_client::github::AssetKind;
|
||||||
use http_client::github::{GitHubLspBinaryVersion, latest_github_release};
|
use http_client::github::{GitHubLspBinaryVersion, latest_github_release};
|
||||||
use http_client::github_download::{GithubBinaryMetadata, download_server_binary};
|
use http_client::github_download::{GithubBinaryMetadata, download_server_binary};
|
||||||
pub use language::*;
|
pub use language::*;
|
||||||
use lsp::{InitializeParams, LanguageServerBinary};
|
use lsp::{InitializeParams, LanguageServerBinary, LanguageServerBinaryOptions};
|
||||||
use project::lsp_store::rust_analyzer_ext::CARGO_DIAGNOSTICS_SOURCE_NAME;
|
use project::lsp_store::rust_analyzer_ext::CARGO_DIAGNOSTICS_SOURCE_NAME;
|
||||||
use project::project_settings::ProjectSettings;
|
use project::project_settings::ProjectSettings;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
@@ -513,9 +514,27 @@ impl LspAdapter for RustLspAdapter {
|
|||||||
|
|
||||||
async fn initialization_options_schema(
|
async fn initialization_options_schema(
|
||||||
self: Arc<Self>,
|
self: Arc<Self>,
|
||||||
language_server_binary: &LanguageServerBinary,
|
delegate: &Arc<dyn LspAdapterDelegate>,
|
||||||
|
cached_binary: OwnedMutexGuard<Option<(bool, LanguageServerBinary)>>,
|
||||||
|
cx: &mut AsyncApp,
|
||||||
) -> Option<serde_json::Value> {
|
) -> Option<serde_json::Value> {
|
||||||
let mut command = util::command::new_smol_command(&language_server_binary.path);
|
let binary = self
|
||||||
|
.get_language_server_command(
|
||||||
|
delegate.clone(),
|
||||||
|
None,
|
||||||
|
LanguageServerBinaryOptions {
|
||||||
|
allow_path_lookup: true,
|
||||||
|
allow_binary_download: false,
|
||||||
|
pre_release: false,
|
||||||
|
},
|
||||||
|
cached_binary,
|
||||||
|
cx.clone(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.0
|
||||||
|
.ok()?;
|
||||||
|
|
||||||
|
let mut command = util::command::new_smol_command(&binary.path);
|
||||||
command
|
command
|
||||||
.arg("--print-config-schema")
|
.arg("--print-config-schema")
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
|
|||||||
Reference in New Issue
Block a user