diff --git a/crates/project/src/lsp_store.rs b/crates/project/src/lsp_store.rs index 72f04f8c3814834d86a7a12877b67c9178410954..9410697d03dd10ca0ce4f9e459a20c1a8975f370 100644 --- a/crates/project/src/lsp_store.rs +++ b/crates/project/src/lsp_store.rs @@ -36,7 +36,7 @@ use crate::{ ManifestTree, }, prettier_store::{self, PrettierStore, PrettierStoreEvent}, - project_settings::{LspSettings, ProjectSettings}, + project_settings::{BinarySettings, LspSettings, ProjectSettings}, toolchain_store::{LocalToolchainStore, ToolchainStoreEvent}, trusted_worktrees::{PathTrust, TrustedWorktrees, TrustedWorktreesEvent}, worktree_store::{WorktreeStore, WorktreeStoreEvent}, @@ -226,12 +226,22 @@ struct UnifiedLanguageServer { project_roots: HashSet>, } +/// Settings that affect language server identity. +/// +/// Dynamic settings (`LspSettings::settings`) are excluded because they can be +/// updated via `workspace/didChangeConfiguration` without restarting the server. +#[derive(Clone, Debug, Hash, PartialEq, Eq)] +struct LanguageServerSeedSettings { + binary: Option, + initialization_options: Option, +} + #[derive(Clone, Debug, Hash, PartialEq, Eq)] struct LanguageServerSeed { worktree_id: WorktreeId, name: LanguageServerName, toolchain: Option, - settings: Arc, + settings: LanguageServerSeedSettings, } #[derive(Debug)] @@ -332,7 +342,10 @@ impl LocalLspStore { let key = LanguageServerSeed { worktree_id: worktree_handle.read(cx).id(), name: disposition.server_name.clone(), - settings: disposition.settings.clone(), + settings: LanguageServerSeedSettings { + binary: disposition.settings.binary.clone(), + initialization_options: disposition.settings.initialization_options.clone(), + }, toolchain: disposition.toolchain.clone(), }; if let Some(state) = self.language_server_ids.get_mut(&key) { @@ -5052,7 +5065,13 @@ impl LspStore { let key = LanguageServerSeed { worktree_id, name: disposition.server_name.clone(), - settings: disposition.settings.clone(), + settings: LanguageServerSeedSettings { + binary: disposition.settings.binary.clone(), + initialization_options: disposition + .settings + .initialization_options + .clone(), + }, toolchain: local.toolchain_store.read(cx).active_toolchain( path.worktree_id, &path.path, diff --git a/crates/project/src/manifest_tree/server_tree.rs b/crates/project/src/manifest_tree/server_tree.rs index b6828fdb281d51600096bbcad411f94a91c69e54..4756f541d01d4ff33ca5c1a185164ae73e5d918e 100644 --- a/crates/project/src/manifest_tree/server_tree.rs +++ b/crates/project/src/manifest_tree/server_tree.rs @@ -421,11 +421,13 @@ impl ServerTreeRebase { .and_then(|worktree_nodes| worktree_nodes.roots.get(&disposition.path.path)) .and_then(|roots| roots.get(&disposition.server_name)) .filter(|(old_node, _)| { - (&disposition.toolchain, &disposition.settings) - == ( - &old_node.disposition.toolchain, - &old_node.disposition.settings, - ) + // Only compare settings that require server restart. + // Dynamic settings (settings.settings) can be updated via DidChangeConfiguration + // without restarting the server. + disposition.toolchain == old_node.disposition.toolchain + && disposition.settings.binary == old_node.disposition.settings.binary + && disposition.settings.initialization_options + == old_node.disposition.settings.initialization_options }) else { return Some(node); diff --git a/crates/project/src/project_settings.rs b/crates/project/src/project_settings.rs index af730c6e86290dc6bf7a6dd6a2c430e4c95224c7..4e0b176b7d5da949422fb130f1e3317c12dddfd0 100644 --- a/crates/project/src/project_settings.rs +++ b/crates/project/src/project_settings.rs @@ -17,6 +17,7 @@ use rpc::{ }; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; +pub use settings::BinarySettings; pub use settings::DirenvSettings; pub use settings::LspSettings; use settings::{