diff --git a/crates/diagnostics/src/diagnostics_tests.rs b/crates/diagnostics/src/diagnostics_tests.rs index af46b1b07c..550aea56a3 100644 --- a/crates/diagnostics/src/diagnostics_tests.rs +++ b/crates/diagnostics/src/diagnostics_tests.rs @@ -18,7 +18,7 @@ use std::{ path::{Path, PathBuf}, }; use unindent::Unindent as _; -use util::{post_inc, RandomCharIter}; +use util::{path, post_inc, RandomCharIter}; #[ctor::ctor] fn init_logger() { @@ -33,7 +33,7 @@ async fn test_diagnostics(cx: &mut TestAppContext) { let fs = FakeFs::new(cx.executor()); fs.insert_tree( - "/test", + path!("/test"), json!({ "consts.rs": " const a: i32 = 'a'; @@ -59,7 +59,7 @@ async fn test_diagnostics(cx: &mut TestAppContext) { .await; let language_server_id = LanguageServerId(0); - let project = Project::test(fs.clone(), ["/test".as_ref()], cx).await; + let project = Project::test(fs.clone(), [path!("/test").as_ref()], cx).await; let lsp_store = project.read_with(cx, |project, _| project.lsp_store()); let window = cx.add_window(|window, cx| Workspace::test_new(project.clone(), window, cx)); let cx = &mut VisualTestContext::from_window(*window, cx); @@ -70,7 +70,7 @@ async fn test_diagnostics(cx: &mut TestAppContext) { lsp_store .update_diagnostic_entries( language_server_id, - PathBuf::from("/test/main.rs"), + PathBuf::from(path!("/test/main.rs")), None, vec![ DiagnosticEntry { @@ -234,7 +234,7 @@ async fn test_diagnostics(cx: &mut TestAppContext) { lsp_store .update_diagnostic_entries( language_server_id, - PathBuf::from("/test/consts.rs"), + PathBuf::from(path!("/test/consts.rs")), None, vec![DiagnosticEntry { range: Unclipped(PointUtf16::new(0, 15))..Unclipped(PointUtf16::new(0, 15)), @@ -341,7 +341,7 @@ async fn test_diagnostics(cx: &mut TestAppContext) { lsp_store .update_diagnostic_entries( language_server_id, - PathBuf::from("/test/consts.rs"), + PathBuf::from(path!("/test/consts.rs")), None, vec![ DiagnosticEntry { @@ -464,7 +464,7 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) { let fs = FakeFs::new(cx.executor()); fs.insert_tree( - "/test", + path!("/test"), json!({ "main.js": " a(); @@ -479,7 +479,7 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) { let server_id_1 = LanguageServerId(100); let server_id_2 = LanguageServerId(101); - let project = Project::test(fs.clone(), ["/test".as_ref()], cx).await; + let project = Project::test(fs.clone(), [path!("/test").as_ref()], cx).await; let lsp_store = project.read_with(cx, |project, _| project.lsp_store()); let window = cx.add_window(|window, cx| Workspace::test_new(project.clone(), window, cx)); let cx = &mut VisualTestContext::from_window(*window, cx); @@ -504,7 +504,7 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) { lsp_store .update_diagnostic_entries( server_id_1, - PathBuf::from("/test/main.js"), + PathBuf::from(path!("/test/main.js")), None, vec![DiagnosticEntry { range: Unclipped(PointUtf16::new(0, 0))..Unclipped(PointUtf16::new(0, 1)), @@ -557,7 +557,7 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) { lsp_store .update_diagnostic_entries( server_id_2, - PathBuf::from("/test/main.js"), + PathBuf::from(path!("/test/main.js")), None, vec![DiagnosticEntry { range: Unclipped(PointUtf16::new(1, 0))..Unclipped(PointUtf16::new(1, 1)), @@ -619,7 +619,7 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) { lsp_store .update_diagnostic_entries( server_id_1, - PathBuf::from("/test/main.js"), + PathBuf::from(path!("/test/main.js")), None, vec![DiagnosticEntry { range: Unclipped(PointUtf16::new(2, 0))..Unclipped(PointUtf16::new(2, 1)), @@ -638,7 +638,7 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) { lsp_store .update_diagnostic_entries( server_id_2, - PathBuf::from("/test/main.rs"), + PathBuf::from(path!("/test/main.rs")), None, vec![], cx, @@ -689,7 +689,7 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) { lsp_store .update_diagnostic_entries( server_id_2, - PathBuf::from("/test/main.js"), + PathBuf::from(path!("/test/main.js")), None, vec![DiagnosticEntry { range: Unclipped(PointUtf16::new(3, 0))..Unclipped(PointUtf16::new(3, 1)), @@ -755,9 +755,9 @@ async fn test_random_diagnostics(cx: &mut TestAppContext, mut rng: StdRng) { .unwrap_or(10); let fs = FakeFs::new(cx.executor()); - fs.insert_tree("/test", json!({})).await; + fs.insert_tree(path!("/test"), json!({})).await; - let project = Project::test(fs.clone(), ["/test".as_ref()], cx).await; + let project = Project::test(fs.clone(), [path!("/test").as_ref()], cx).await; let lsp_store = project.read_with(cx, |project, _| project.lsp_store()); let window = cx.add_window(|window, cx| Workspace::test_new(project.clone(), window, cx)); let cx = &mut VisualTestContext::from_window(*window, cx); @@ -817,7 +817,7 @@ async fn test_random_diagnostics(cx: &mut TestAppContext, mut rng: StdRng) { // insert a set of diagnostics for a new path _ => { let path: PathBuf = - format!("/test/{}.rs", post_inc(&mut next_filename)).into(); + format!(path!("/test/{}.rs"), post_inc(&mut next_filename)).into(); let len = rng.gen_range(128..256); let content = RandomCharIter::new(&mut rng).take(len).collect::(); @@ -891,7 +891,7 @@ async fn test_random_diagnostics(cx: &mut TestAppContext, mut rng: StdRng) { for diagnostic in diagnostics { let found_excerpt = reference_excerpts.iter().any(|info| { let row_range = info.range.context.start.row..info.range.context.end.row; - info.path == path.strip_prefix("/test").unwrap() + info.path == path.strip_prefix(path!("/test")).unwrap() && info.language_server == language_server_id && row_range.contains(&diagnostic.range.start.0.row) }); diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 29b266d970..680171413d 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -1793,7 +1793,7 @@ impl Editor { self.collapse_matches = collapse_matches; } - pub fn register_buffers_with_language_servers(&mut self, cx: &mut Context) { + fn register_buffers_with_language_servers(&mut self, cx: &mut Context) { let buffers = self.buffer.read(cx).all_buffers(); let Some(lsp_store) = self.lsp_store(cx) else { return; @@ -2020,6 +2020,21 @@ impl Editor { None } }; + if let Some(buffer_id) = new_cursor_position.buffer_id { + if !self.registered_buffers.contains_key(&buffer_id) { + if let Some(lsp_store) = self.lsp_store(cx) { + lsp_store.update(cx, |lsp_store, cx| { + let Some(buffer) = self.buffer.read(cx).buffer(buffer_id) else { + return; + }; + self.registered_buffers.insert( + buffer_id, + lsp_store.register_buffer_with_language_servers(&buffer, cx), + ); + }) + } + } + } if let Some(completion_menu) = completion_menu { let cursor_position = new_cursor_position.to_offset(buffer); diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index 1c4839f4f9..8fa37aaf7b 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -14875,7 +14875,7 @@ async fn test_multi_buffer_folding(cx: &mut gpui::TestAppContext) { let fs = FakeFs::new(cx.executor()); fs.insert_tree( - "/a", + path!("/a"), json!({ "first.rs": sample_text_1, "second.rs": sample_text_2, @@ -14883,7 +14883,7 @@ async fn test_multi_buffer_folding(cx: &mut gpui::TestAppContext) { }), ) .await; - let project = Project::test(fs, ["/a".as_ref()], cx).await; + let project = Project::test(fs, [path!("/a").as_ref()], cx).await; let workspace = cx.add_window(|window, cx| Workspace::test_new(project.clone(), window, cx)); let cx = &mut VisualTestContext::from_window(*workspace.deref(), cx); let worktree = project.update(cx, |project, cx| { @@ -15059,7 +15059,7 @@ async fn test_multi_buffer_single_excerpts_folding(cx: &mut gpui::TestAppContext let fs = FakeFs::new(cx.executor()); fs.insert_tree( - "/a", + path!("/a"), json!({ "first.rs": sample_text_1, "second.rs": sample_text_2, @@ -15067,7 +15067,7 @@ async fn test_multi_buffer_single_excerpts_folding(cx: &mut gpui::TestAppContext }), ) .await; - let project = Project::test(fs, ["/a".as_ref()], cx).await; + let project = Project::test(fs, [path!("/a").as_ref()], cx).await; let workspace = cx.add_window(|window, cx| Workspace::test_new(project.clone(), window, cx)); let cx = &mut VisualTestContext::from_window(*workspace.deref(), cx); let worktree = project.update(cx, |project, cx| { @@ -15206,13 +15206,13 @@ async fn test_multi_buffer_with_single_excerpt_folding(cx: &mut gpui::TestAppCon let fs = FakeFs::new(cx.executor()); fs.insert_tree( - "/a", + path!("/a"), json!({ "main.rs": sample_text, }), ) .await; - let project = Project::test(fs, ["/a".as_ref()], cx).await; + let project = Project::test(fs, [path!("/a").as_ref()], cx).await; let workspace = cx.add_window(|window, cx| Workspace::test_new(project.clone(), window, cx)); let cx = &mut VisualTestContext::from_window(*workspace.deref(), cx); let worktree = project.update(cx, |project, cx| { diff --git a/crates/project/src/lsp_store.rs b/crates/project/src/lsp_store.rs index f85ba369f7..df0c833ab0 100644 --- a/crates/project/src/lsp_store.rs +++ b/crates/project/src/lsp_store.rs @@ -1977,7 +1977,12 @@ impl LocalLspStore { Some(local) => local.abs_path(cx), None => return, }; - let file_url = lsp::Url::from_file_path(old_path).unwrap(); + let file_url = lsp::Url::from_file_path(old_path.as_path()).unwrap_or_else(|_| { + panic!( + "`{}` is not parseable as an URI", + old_path.to_string_lossy() + ) + }); self.unregister_buffer_from_language_servers(buffer, file_url, cx); } diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 3fe85f13f2..71887c067d 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -2197,7 +2197,7 @@ pub mod tests { let fs = FakeFs::new(cx.background_executor.clone()); fs.insert_tree( - "/dir", + path!("/dir"), json!({ "one.rs": "const ONE: usize = 1;", "two.rs": "const TWO: usize = one::ONE + one::ONE;", @@ -2206,7 +2206,7 @@ pub mod tests { }), ) .await; - let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await; + let project = Project::test(fs.clone(), [path!("/dir").as_ref()], cx).await; let window = cx.add_window(|window, cx| Workspace::test_new(project.clone(), window, cx)); let workspace = window.root(cx).unwrap(); let search = cx.new(|cx| ProjectSearch::new(project.clone(), cx)); @@ -2564,7 +2564,7 @@ pub mod tests { let fs = FakeFs::new(cx.background_executor.clone()); fs.insert_tree( - "/dir", + path!("/dir"), json!({ "one.rs": "const ONE: usize = 1;", "two.rs": "const TWO: usize = one::ONE + one::ONE;", @@ -2573,7 +2573,7 @@ pub mod tests { }), ) .await; - let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await; + let project = Project::test(fs.clone(), [path!("/dir").as_ref()], cx).await; let window = cx.add_window(|window, cx| Workspace::test_new(project, window, cx)); let workspace = window; let search_bar = window.build_entity(cx, |_, _| ProjectSearchBar::new()); @@ -2859,7 +2859,7 @@ pub mod tests { let fs = FakeFs::new(cx.background_executor.clone()); fs.insert_tree( - "/dir", + path!("/dir"), json!({ "a": { "one.rs": "const ONE: usize = 1;", @@ -2984,7 +2984,7 @@ pub mod tests { let fs = FakeFs::new(cx.background_executor.clone()); fs.insert_tree( - "/dir", + path!("/dir"), json!({ "one.rs": "const ONE: usize = 1;", "two.rs": "const TWO: usize = one::ONE + one::ONE;", @@ -2993,7 +2993,7 @@ pub mod tests { }), ) .await; - let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await; + let project = Project::test(fs.clone(), [path!("/dir").as_ref()], cx).await; let window = cx.add_window(|window, cx| Workspace::test_new(project, window, cx)); let workspace = window.root(cx).unwrap(); let search_bar = window.build_entity(cx, |_, _| ProjectSearchBar::new()); @@ -3693,7 +3693,7 @@ pub mod tests { // We need many lines in the search results to be able to scroll the window let fs = FakeFs::new(cx.background_executor.clone()); fs.insert_tree( - "/dir", + path!("/dir"), json!({ "1.txt": "\n\n\n\n\n A \n\n\n\n\n", "2.txt": "\n\n\n\n\n A \n\n\n\n\n", @@ -3718,7 +3718,7 @@ pub mod tests { }), ) .await; - let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await; + let project = Project::test(fs.clone(), [path!("/dir").as_ref()], cx).await; let window = cx.add_window(|window, cx| Workspace::test_new(project.clone(), window, cx)); let workspace = window.root(cx).unwrap(); let search = cx.new(|cx| ProjectSearch::new(project, cx));