diff --git a/crates/editor/src/inlays.rs b/crates/editor/src/inlays.rs index f07bf0b315161f0ce9cdf3ef7e2f6db6d60abfb5..d5e05181ea919f47279a87fde6f6d0ba0835a9fd 100644 --- a/crates/editor/src/inlays.rs +++ b/crates/editor/src/inlays.rs @@ -150,6 +150,16 @@ impl Editor { inlay_hints.added_hints.remove(id_to_remove); } } + let a = to_insert + .iter() + .map(|inlay| (inlay.id, inlay.text().to_string())) + .collect::>(); + dbg!(( + self.buffer.read(cx).is_singleton(), + "splice_inlays", + &to_remove, + a, + )); self.display_map.update(cx, |display_map, cx| { display_map.splice_inlays(to_remove, to_insert, cx) }); diff --git a/crates/editor/src/inlays/inlay_hints.rs b/crates/editor/src/inlays/inlay_hints.rs index 74fe9988763b976f315624b8e1ab36110e2137ee..bb81794d3bfde46b9e51ec678a4eeaee8e8ab333 100644 --- a/crates/editor/src/inlays/inlay_hints.rs +++ b/crates/editor/src/inlays/inlay_hints.rs @@ -370,6 +370,12 @@ impl Editor { let Some(buffer) = multi_buffer.read(cx).buffer(buffer_id) else { continue; }; + dbg!(( + self.buffer.read(cx).is_singleton(), + buffer.read(cx).file().map(|f| f.path()), + invalidate_cache, + ignore_previous_fetches, + )); let fetched_tasks = inlay_hints.hint_chunk_fetched.entry(buffer_id).or_default(); if visible_excerpts .buffer_version diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index a8be82d5d5a3fcb20b8ea964af19e3f60fea0573..c83407e75f5cb7ddbfe6f37f66332e4f83ab1701 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -2344,7 +2344,15 @@ pub fn perform_project_search( #[cfg(test)] pub mod tests { - use std::{ops::Deref as _, sync::Arc, time::Duration}; + use std::{ + ops::Deref as _, + path::PathBuf, + sync::{ + Arc, + atomic::{self, AtomicUsize}, + }, + time::Duration, + }; use super::*; use editor::{DisplayPoint, display_map::DisplayRow}; @@ -4245,6 +4253,8 @@ pub mod tests { ) .await; + let requests_count = Arc::new(AtomicUsize::new(0)); + let closure_requests_count = requests_count.clone(); let project = Project::test(fs.clone(), [path!("/dir").as_ref()], cx).await; let language_registry = project.read_with(cx, |project, _| project.languages().clone()); let language = rust_lang(); @@ -4256,21 +4266,26 @@ pub mod tests { inlay_hint_provider: Some(lsp::OneOf::Left(true)), ..lsp::ServerCapabilities::default() }, - initializer: Some(Box::new(|fake_server| { - fake_server.set_request_handler::( - move |_, _| async move { - Ok(Some(vec![lsp::InlayHint { - position: lsp::Position::new(0, 17), - label: lsp::InlayHintLabel::String(": i32".to_owned()), - kind: Some(lsp::InlayHintKind::TYPE), - text_edits: None, - tooltip: None, - padding_left: None, - padding_right: None, - data: None, - }])) - }, - ); + initializer: Some(Box::new(move |fake_server| { + let requests_count = closure_requests_count.clone(); + fake_server.set_request_handler::({ + move |_, _| { + let requests_count = requests_count.clone(); + async move { + requests_count.fetch_add(1, atomic::Ordering::Release); + Ok(Some(vec![lsp::InlayHint { + position: lsp::Position::new(0, 17), + label: lsp::InlayHintLabel::String(": i32".to_owned()), + kind: Some(lsp::InlayHintKind::TYPE), + text_edits: None, + tooltip: None, + padding_left: None, + padding_right: None, + data: None, + }])) + } + } + }); })), ..FakeLspAdapter::default() }, @@ -4297,6 +4312,11 @@ pub mod tests { ); }) .unwrap(); + assert_eq!( + requests_count.load(atomic::Ordering::Acquire), + 1, + "New hints should have been queried", + ); // Can do the 2nd search without any panics perform_search(search_view, "let ", cx); @@ -4312,6 +4332,106 @@ pub mod tests { ); }) .unwrap(); + assert_eq!( + requests_count.load(atomic::Ordering::Acquire), + 2, + "We did drop the previous buffer when cleared the old project search results, hence another query was made", + ); + + let singleton_editor = window + .update(cx, |workspace, window, cx| { + workspace.open_abs_path( + PathBuf::from(path!("/dir/main.rs")), + workspace::OpenOptions::default(), + window, + cx, + ) + }) + .unwrap() + .await + .unwrap() + .downcast::() + .unwrap(); + cx.executor().advance_clock(Duration::from_millis(100)); + cx.executor().run_until_parked(); + singleton_editor.update(cx, |editor, cx| { + assert_eq!( + editor.display_text(cx), + "fn main() { let a: i32 = 2; }\n", + "Newly opened editor should have the correct text with hints", + ); + }); + assert_eq!( + requests_count.load(atomic::Ordering::Acquire), + 2, + "Opening the same buffer again should reuse the cached hints", + ); + + window + .update(cx, |_, window, cx| { + singleton_editor.update(cx, |editor, cx| { + editor.handle_input("test", window, cx); + }); + }) + .unwrap(); + + cx.executor().advance_clock(Duration::from_secs(1)); + cx.executor().run_until_parked(); + singleton_editor.update(cx, |editor, cx| { + assert_eq!( + editor.display_text(cx), + "testfn main() { l: i32et a = 2; }\n", + "Newly opened editor should have the correct text with hints", + ); + }); + assert_eq!( + requests_count.load(atomic::Ordering::Acquire), + // TODO kb this is wrong, should be 3 + 4, + "We have edited the buffer and should send a new request", + ); + + window + .update(cx, |_, window, cx| { + singleton_editor.update(cx, |editor, cx| { + editor.undo(&editor::actions::Undo, window, cx); + }); + }) + .unwrap(); + cx.executor().advance_clock(Duration::from_secs(1)); + cx.executor().run_until_parked(); + assert_eq!( + requests_count.load(atomic::Ordering::Acquire), + // TODO kb this is wrong, should be 4 + 6, + "We have edited the buffer again and should send a new request again", + ); + singleton_editor.update(cx, |editor, cx| { + assert_eq!( + editor.display_text(cx), + "fn main() { let a: i32 = 2; }\n", + "Newly opened editor should have the correct text with hints", + ); + }); + + perform_search(search_view, "let ", cx); + cx.executor().advance_clock(Duration::from_secs(1)); + cx.executor().run_until_parked(); + assert_eq!( + requests_count.load(atomic::Ordering::Acquire), + 6, + "New project search should reuse the cached hints", + ); + search_view + .update(cx, |search_view, _, cx| { + assert_eq!( + search_view + .results_editor + .update(cx, |editor, cx| editor.display_text(cx)), + "\n\nfn main() { let a: i32 = 2; }\n" + ); + }) + .unwrap(); } fn init_test(cx: &mut TestAppContext) {