From 6585daccf93f8844be5e3909eecc8b2bb21b970d Mon Sep 17 00:00:00 2001 From: Isaac Clayton Date: Wed, 6 Jul 2022 14:24:42 +0200 Subject: [PATCH] Further unpropogate async --- crates/collab/src/integration_tests.rs | 16 +-- crates/editor/src/editor.rs | 14 +-- crates/editor/src/test.rs | 8 +- crates/lsp/src/lsp.rs | 3 + crates/project/src/project.rs | 129 ++++++++------------ crates/zed/src/languages/c.rs | 2 +- crates/zed/src/languages/go.rs | 2 +- crates/zed/src/languages/json.rs | 4 +- crates/zed/src/languages/language_plugin.rs | 4 +- crates/zed/src/languages/python.rs | 4 +- crates/zed/src/languages/rust.rs | 2 +- crates/zed/src/languages/typescript.rs | 4 +- 12 files changed, 86 insertions(+), 106 deletions(-) diff --git a/crates/collab/src/integration_tests.rs b/crates/collab/src/integration_tests.rs index 7767b361c1..0d96dcc8ca 100644 --- a/crates/collab/src/integration_tests.rs +++ b/crates/collab/src/integration_tests.rs @@ -1675,7 +1675,7 @@ async fn test_collaborating_with_completion(cx_a: &mut TestAppContext, cx_b: &mu }, Some(tree_sitter_rust::language()), ); - let mut fake_language_servers = language.set_fake_lsp_adapter(FakeLspAdapter { + let mut fake_language_servers = language.set_fake_lsp_adapter(Arc::new(FakeLspAdapterInner { capabilities: lsp::ServerCapabilities { completion_provider: Some(lsp::CompletionOptions { trigger_characters: Some(vec![".".to_string()]), @@ -1684,7 +1684,7 @@ async fn test_collaborating_with_completion(cx_a: &mut TestAppContext, cx_b: &mu ..Default::default() }, ..Default::default() - }); + })); client_a.language_registry.add(Arc::new(language)); client_a @@ -2867,7 +2867,7 @@ async fn test_collaborating_with_renames(cx_a: &mut TestAppContext, cx_b: &mut T }, Some(tree_sitter_rust::language()), ); - let mut fake_language_servers = language.set_fake_lsp_adapter(FakeLspAdapter { + let mut fake_language_servers = language.set_fake_lsp_adapter(Arc::new(FakeLspAdapterInner { capabilities: lsp::ServerCapabilities { rename_provider: Some(lsp::OneOf::Right(lsp::RenameOptions { prepare_provider: Some(true), @@ -2876,7 +2876,7 @@ async fn test_collaborating_with_renames(cx_a: &mut TestAppContext, cx_b: &mut T ..Default::default() }, ..Default::default() - }); + })); client_a.language_registry.add(Arc::new(language)); client_a @@ -3051,10 +3051,10 @@ async fn test_language_server_statuses( }, Some(tree_sitter_rust::language()), ); - let mut fake_language_servers = language.set_fake_lsp_adapter(FakeLspAdapter { + let mut fake_language_servers = language.set_fake_lsp_adapter(Arc::new(FakeLspAdapterInner { name: "the-language-server", ..Default::default() - }); + })); client_a.language_registry.add(Arc::new(language)); client_a @@ -4577,7 +4577,7 @@ async fn test_random_collaboration( }, None, ); - let _fake_servers = language.set_fake_lsp_adapter(FakeLspAdapter { + let _fake_servers = language.set_fake_lsp_adapter(Arc::new(FakeLspAdapterInner { name: "the-fake-language-server", capabilities: lsp::LanguageServer::full_capabilities(), initializer: Some(Box::new({ @@ -4689,7 +4689,7 @@ async fn test_random_collaboration( } })), ..Default::default() - }); + })); host_language_registry.add(Arc::new(language)); let op_start_signal = futures::channel::mpsc::unbounded(); diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index c1e2557555..6d0427ad61 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -6233,7 +6233,7 @@ mod tests { platform::{WindowBounds, WindowOptions}, }; use indoc::indoc; - use language::{FakeLspAdapter, LanguageConfig}; + use language::{FakeLspAdapter, LanguageConfig, FakeLspAdapterInner}; use lsp::FakeLanguageServer; use project::FakeFs; use settings::LanguageSettings; @@ -9302,13 +9302,13 @@ mod tests { }, Some(tree_sitter_rust::language()), ); - let mut fake_servers = language.set_fake_lsp_adapter(FakeLspAdapter { + let mut fake_servers = language.set_fake_lsp_adapter(Arc::new(FakeLspAdapterInner { capabilities: lsp::ServerCapabilities { document_formatting_provider: Some(lsp::OneOf::Left(true)), ..Default::default() }, ..Default::default() - }); + })); let fs = FakeFs::new(cx.background().clone()); fs.insert_file("/file.rs", Default::default()).await; @@ -9414,13 +9414,13 @@ mod tests { }, Some(tree_sitter_rust::language()), ); - let mut fake_servers = language.set_fake_lsp_adapter(FakeLspAdapter { + let mut fake_servers = language.set_fake_lsp_adapter(Arc::new(FakeLspAdapterInner { capabilities: lsp::ServerCapabilities { document_range_formatting_provider: Some(lsp::OneOf::Left(true)), ..Default::default() }, ..Default::default() - }); + })); let fs = FakeFs::new(cx.background().clone()); fs.insert_file("/file.rs", Default::default()).await; @@ -9526,7 +9526,7 @@ mod tests { }, Some(tree_sitter_rust::language()), ); - let mut fake_servers = language.set_fake_lsp_adapter(FakeLspAdapter { + let mut fake_servers = language.set_fake_lsp_adapter(Arc::new(FakeLspAdapterInner { capabilities: lsp::ServerCapabilities { completion_provider: Some(lsp::CompletionOptions { trigger_characters: Some(vec![".".to_string(), ":".to_string()]), @@ -9535,7 +9535,7 @@ mod tests { ..Default::default() }, ..Default::default() - }); + })); let text = " one diff --git a/crates/editor/src/test.rs b/crates/editor/src/test.rs index d1316a85a0..a2efc87249 100644 --- a/crates/editor/src/test.rs +++ b/crates/editor/src/test.rs @@ -9,7 +9,9 @@ use indoc::indoc; use collections::BTreeMap; use gpui::{json, keymap::Keystroke, AppContext, ModelHandle, ViewContext, ViewHandle}; -use language::{point_to_lsp, FakeLspAdapter, Language, LanguageConfig, Selection}; +use language::{ + point_to_lsp, FakeLspAdapter, FakeLspAdapterInner, Language, LanguageConfig, Selection, +}; use project::Project; use settings::Settings; use util::{ @@ -457,10 +459,10 @@ impl<'a> EditorLspTestContext<'a> { .unwrap_or(&"txt".to_string()) ); - let mut fake_servers = language.set_fake_lsp_adapter(FakeLspAdapter { + let mut fake_servers = language.set_fake_lsp_adapter(Arc::new(FakeLspAdapterInner { capabilities, ..Default::default() - }); + })); let project = Project::test(params.fs.clone(), [], cx).await; project.update(cx, |project, _| project.languages().add(Arc::new(language))); diff --git a/crates/lsp/src/lsp.rs b/crates/lsp/src/lsp.rs index bb6562629f..8c689808ae 100644 --- a/crates/lsp/src/lsp.rs +++ b/crates/lsp/src/lsp.rs @@ -258,6 +258,9 @@ impl LanguageServer { } } + /// Initializes a language server. + /// Note that `options` is used directly to construct [`InitializeParams`], + /// which is why it is owned. pub async fn initialize(mut self, options: Option) -> Result> { let root_uri = Url::from_file_path(&self.root_path).unwrap(); #[allow(deprecated)] diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index b1d45ac9a2..7d75da4443 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -113,7 +113,6 @@ pub struct Project { collaborators: HashMap, client_subscriptions: Vec, _subscriptions: Vec, - lsp_settings_changed: Option>, opened_buffer: (Rc>>, watch::Receiver<()>), shared_buffers: HashMap>, loading_buffers: HashMap< @@ -489,7 +488,6 @@ impl Project { next_language_server_id: 0, nonce: StdRng::from_entropy().gen(), initialized_persistent_state: false, - lsp_settings_changed: None, } }) } @@ -604,7 +602,6 @@ impl Project { buffer_snapshots: Default::default(), nonce: StdRng::from_entropy().gen(), initialized_persistent_state: false, - lsp_settings_changed: None, }; for worktree in worktrees { this.add_worktree(&worktree, cx); @@ -713,63 +710,51 @@ impl Project { fn on_settings_changed(&mut self, cx: &mut ModelContext<'_, Self>) { let settings = cx.global::(); - self.lsp_settings_changed = Some(cx.spawn(|project, cx| async { - let language_servers_to_start = project.update(&mut cx, |project, cx| { - let mut language_servers_to_start = Vec::new(); - for buffer in self.opened_buffers.values() { - if let Some(buffer) = buffer.upgrade(cx) { - let buffer = buffer.read(cx); - if let Some((file, language)) = - File::from_dyn(buffer.file()).zip(buffer.language()) - { - if settings.enable_language_server(Some(&language.name())) { - let worktree = file.worktree.read(cx); - language_servers_to_start.push(( - worktree.id(), - worktree.as_local().unwrap().abs_path().clone(), - language.clone(), - )); - } - } + + let mut language_servers_to_start = Vec::new(); + for buffer in self.opened_buffers.values() { + if let Some(buffer) = buffer.upgrade(cx) { + let buffer = buffer.read(cx); + if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) + { + if settings.enable_language_server(Some(&language.name())) { + let worktree = file.worktree.read(cx); + language_servers_to_start.push(( + worktree.id(), + worktree.as_local().unwrap().abs_path().clone(), + language.clone(), + )); } } - language_servers_to_start - }); + } + } - let mut language_servers_to_stop = Vec::new(); - for language in self.languages.to_vec() { - if let Some(lsp_adapter) = language.lsp_adapter() { - if !settings.enable_language_server(Some(&language.name())) { - let lsp_name = lsp_adapter.name; - for (worktree_id, started_lsp_name) in self.started_language_servers.keys() - { - if lsp_name == *started_lsp_name { - language_servers_to_stop - .push((*worktree_id, started_lsp_name.clone())); - } + let mut language_servers_to_stop = Vec::new(); + for language in self.languages.to_vec() { + if let Some(lsp_adapter) = language.lsp_adapter() { + if !settings.enable_language_server(Some(&language.name())) { + let lsp_name = &lsp_adapter.name; + for (worktree_id, started_lsp_name) in self.language_servers.keys() { + if lsp_name == started_lsp_name { + language_servers_to_stop.push((*worktree_id, started_lsp_name.clone())); } } } } + } - project.update(&mut cx, |project, cx| { - // Stop all newly-disabled language servers. - for (worktree_id, adapter_name) in language_servers_to_stop { - self.stop_language_server(worktree_id, adapter_name, cx) - .detach(); - } + // Stop all newly-disabled language servers. + for (worktree_id, adapter_name) in language_servers_to_stop { + self.stop_language_server(worktree_id, adapter_name, cx) + .detach(); + } - // Start all the newly-enabled language servers. - for (worktree_id, worktree_path, language) in language_servers_to_start { - self.start_language_server(worktree_id, worktree_path, language, cx); - } + // Start all the newly-enabled language servers. + for (worktree_id, worktree_path, language) in language_servers_to_start { + self.start_language_server(worktree_id, worktree_path, language, cx); + } - cx.notify(); - }); - })) - - // // TODO(isaac): uncomment the above - // todo!() + cx.notify(); } pub fn buffer_for_id(&self, remote_id: u64, cx: &AppContext) -> Option> { @@ -1663,7 +1648,7 @@ impl Project { this.create_local_worktree(&abs_path, false, cx) }) .await?; - let name = lsp_adapter.name; + let name = lsp_adapter.name.clone(); this.update(&mut cx, |this, cx| { this.language_servers .insert((worktree.read(cx).id(), name), (lsp_adapter, lsp_server)); @@ -1733,8 +1718,7 @@ impl Project { this.update(&mut cx, |this, cx| { this.assign_language_to_buffer(&buffer, cx); this.register_buffer_with_language_server(&buffer, cx) - }) - .await; + }); Ok(()) }) } @@ -1788,13 +1772,13 @@ impl Project { } cx.subscribe(buffer, |this, buffer, event, cx| { // TODO(isaac): should this be done in the background? - this.on_buffer_event(buffer, event, cx).await; + this.on_buffer_event(buffer, event, cx); }) .detach(); self.assign_language_to_buffer(buffer, cx); // TODO(isaac): should this be done in the background - self.register_buffer_with_language_server(buffer, cx).await; + self.register_buffer_with_language_server(buffer, cx); cx.observe_release(buffer, |this, buffer, cx| { if let Some(file) = File::from_dyn(buffer.file()) { if file.is_local() { @@ -1910,7 +1894,7 @@ impl Project { }); } - async fn on_buffer_event( + fn on_buffer_event( &mut self, buffer: ModelHandle, event: &BufferEvent, @@ -2050,13 +2034,12 @@ impl Project { let worktree = file.worktree.read(cx).as_local()?; let worktree_id = worktree.id(); let worktree_abs_path = worktree.abs_path().clone(); - self.start_language_server(worktree_id, worktree_abs_path, language, cx) - .await; + self.start_language_server(worktree_id, worktree_abs_path, language, cx); None } - async fn start_language_server( + fn start_language_server( &mut self, worktree_id: WorktreeId, worktree_path: Arc, @@ -2324,8 +2307,6 @@ impl Project { }) })), ); - - server_id }); } @@ -2403,14 +2384,13 @@ impl Project { .collect(); for (worktree_id, worktree_abs_path, full_path) in language_server_lookup_info { let language = self.languages.select_language(&full_path)?; - self.restart_language_server(worktree_id, worktree_abs_path, language, cx) - .await; + self.restart_language_server(worktree_id, worktree_abs_path, language, cx); } None } - async fn restart_language_server( + fn restart_language_server( &mut self, worktree_id: WorktreeId, fallback_path: Arc, @@ -2423,7 +2403,7 @@ impl Project { return; }; - let stop = self.stop_language_server(worktree_id, adapter.name, cx); + let stop = self.stop_language_server(worktree_id, adapter.name.clone(), cx); cx.spawn_weak(|this, mut cx| async move { let (original_root_path, orphaned_worktrees) = stop.await; if let Some(this) = this.upgrade(&cx) { @@ -2476,7 +2456,7 @@ impl Project { &mut self, progress: lsp::ProgressParams, server_id: usize, - disk_based_diagnostics_progress_token: Option, + disk_based_diagnostics_progress_token: Option<&str>, cx: &mut ModelContext, ) { let token = match progress.token { @@ -2500,8 +2480,7 @@ impl Project { return; } - let same_token = - Some(token.as_ref()) == disk_based_diagnostics_progress_token.as_ref().map(|x| &**x); + let same_token = Some(token.as_ref()) == disk_based_diagnostics_progress_token; match progress { lsp::WorkDoneProgress::Begin(report) => { @@ -3309,7 +3288,7 @@ impl Project { struct PartialSymbol { source_worktree_id: WorktreeId, worktree_id: WorktreeId, - adapter: Arc, + language_server_name: LanguageServerName, path: PathBuf, language: Option>, name: String, @@ -3343,8 +3322,7 @@ impl Project { partial_symbols.push(PartialSymbol { source_worktree_id, worktree_id, - // TODO: just pass out single adapter? - adapter: adapter.clone(), + language_server_name: adapter.name.clone(), name: lsp_symbol.name, kind: lsp_symbol.kind, language, @@ -3367,12 +3345,10 @@ impl Project { } .unwrap_or_else(|| CodeLabel::plain(ps.name.clone(), None)); - let language_server_name = ps.adapter.name; - Symbol { source_worktree_id: ps.source_worktree_id, worktree_id: ps.worktree_id, - language_server_name, + language_server_name: ps.language_server_name, name: ps.name, kind: ps.kind, label, @@ -3535,7 +3511,6 @@ impl Project { Default::default() }; - // TODO(isaac): use futures::future::join_all struct PartialCompletion { pub old_range: Range, pub new_text: String, @@ -4645,7 +4620,7 @@ impl Project { for (buffer, old_path) in renamed_buffers { self.unregister_buffer_from_language_server(&buffer, old_path, cx); self.assign_language_to_buffer(&buffer, cx); - self.register_buffer_with_language_server(&buffer, cx).await; + self.register_buffer_with_language_server(&buffer, cx); } } @@ -6026,7 +6001,7 @@ impl Project { cx: &AppContext, ) -> Option<&(Arc, Arc)> { if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) { - let name = language.lsp_adapter()?.name; + let name = language.lsp_adapter()?.name.clone(); let worktree_id = file.worktree_id(cx); let key = (worktree_id, language.lsp_adapter()?.name()); diff --git a/crates/zed/src/languages/c.rs b/crates/zed/src/languages/c.rs index 54554beaf6..9f2d64748b 100644 --- a/crates/zed/src/languages/c.rs +++ b/crates/zed/src/languages/c.rs @@ -11,7 +11,7 @@ use util::ResultExt; pub struct CLspAdapter; #[async_trait] -impl super::LspAdapter for CLspAdapter { +impl super::LspAdapterTrait for CLspAdapter { async fn name(&self) -> LanguageServerName { LanguageServerName("clangd".into()) } diff --git a/crates/zed/src/languages/go.rs b/crates/zed/src/languages/go.rs index 314055e5ff..a8fe908867 100644 --- a/crates/zed/src/languages/go.rs +++ b/crates/zed/src/languages/go.rs @@ -18,7 +18,7 @@ lazy_static! { } #[async_trait] -impl super::LspAdapter for GoLspAdapter { +impl super::LspAdapterTrait for GoLspAdapter { async fn name(&self) -> LanguageServerName { LanguageServerName("gopls".into()) } diff --git a/crates/zed/src/languages/json.rs b/crates/zed/src/languages/json.rs index 29e8e7da02..28294d26e1 100644 --- a/crates/zed/src/languages/json.rs +++ b/crates/zed/src/languages/json.rs @@ -3,7 +3,7 @@ use anyhow::{anyhow, Context, Result}; use async_trait::async_trait; use client::http::HttpClient; use futures::StreamExt; -use language::{LanguageServerName, LspAdapter}; +use language::{LanguageServerName, LspAdapter, LspAdapterTrait}; use serde_json::json; use smol::fs; use std::{any::Any, path::PathBuf, sync::Arc}; @@ -17,7 +17,7 @@ impl JsonLspAdapter { } #[async_trait] -impl LspAdapter for JsonLspAdapter { +impl LspAdapterTrait for JsonLspAdapter { async fn name(&self) -> LanguageServerName { LanguageServerName("vscode-json-languageserver".into()) } diff --git a/crates/zed/src/languages/language_plugin.rs b/crates/zed/src/languages/language_plugin.rs index 9494705c27..4dfe7478ab 100644 --- a/crates/zed/src/languages/language_plugin.rs +++ b/crates/zed/src/languages/language_plugin.rs @@ -4,7 +4,7 @@ use client::http::HttpClient; use futures::lock::Mutex; use futures::Future; use gpui::executor::Background; -use language::{LanguageServerName, LspAdapter}; +use language::{LanguageServerName, LspAdapter, LspAdapterTrait}; use plugin_runtime::{Plugin, PluginBuilder, WasiFn}; use std::{any::Any, path::PathBuf, sync::Arc}; use util::ResultExt; @@ -72,7 +72,7 @@ struct Versions { // - it's totally a deadlock, the proof is in the pudding #[async_trait] -impl LspAdapter for PluginLspAdapter { +impl LspAdapterTrait for PluginLspAdapter { async fn name(&self) -> LanguageServerName { let name: String = self .runtime diff --git a/crates/zed/src/languages/python.rs b/crates/zed/src/languages/python.rs index ca0b24bda7..c5508ac337 100644 --- a/crates/zed/src/languages/python.rs +++ b/crates/zed/src/languages/python.rs @@ -3,7 +3,7 @@ use anyhow::{anyhow, Context, Result}; use async_trait::async_trait; use client::http::HttpClient; use futures::StreamExt; -use language::{LanguageServerName, LspAdapter}; +use language::{LanguageServerName, LspAdapter, LspAdapterTrait}; use smol::fs; use std::{any::Any, path::PathBuf, sync::Arc}; use util::ResultExt; @@ -15,7 +15,7 @@ impl PythonLspAdapter { } #[async_trait] -impl LspAdapter for PythonLspAdapter { +impl LspAdapterTrait for PythonLspAdapter { async fn name(&self) -> LanguageServerName { LanguageServerName("pyright".into()) } diff --git a/crates/zed/src/languages/rust.rs b/crates/zed/src/languages/rust.rs index 7d7c60dea4..03999b15ff 100644 --- a/crates/zed/src/languages/rust.rs +++ b/crates/zed/src/languages/rust.rs @@ -14,7 +14,7 @@ use util::ResultExt; pub struct RustLspAdapter; #[async_trait] -impl LspAdapter for RustLspAdapter { +impl LspAdapterTrait for RustLspAdapter { async fn name(&self) -> LanguageServerName { LanguageServerName("rust-analyzer".into()) } diff --git a/crates/zed/src/languages/typescript.rs b/crates/zed/src/languages/typescript.rs index 199a7f22ae..8f262d4e70 100644 --- a/crates/zed/src/languages/typescript.rs +++ b/crates/zed/src/languages/typescript.rs @@ -3,7 +3,7 @@ use anyhow::{anyhow, Context, Result}; use async_trait::async_trait; use client::http::HttpClient; use futures::StreamExt; -use language::{LanguageServerName, LspAdapter}; +use language::{LanguageServerName, LspAdapter, LspAdapterTrait}; use serde_json::json; use smol::fs; use std::{any::Any, path::PathBuf, sync::Arc}; @@ -21,7 +21,7 @@ struct Versions { } #[async_trait] -impl LspAdapter for TypeScriptLspAdapter { +impl LspAdapterTrait for TypeScriptLspAdapter { async fn name(&self) -> LanguageServerName { LanguageServerName("typescript-language-server".into()) }