diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 3333513290..e10fde467a 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -395,6 +395,7 @@ pub struct Editor { context_menu: RwLock>, mouse_context_menu: Option, completion_tasks: Vec<(CompletionId, Task>)>, + find_all_references_task_sources: Vec, next_completion_id: CompletionId, completion_documentation_pre_resolve_debounce: DebouncedDelay, available_code_actions: Option<(Model, Arc<[CodeAction]>)>, @@ -1534,6 +1535,7 @@ impl Editor { context_menu: RwLock::new(None), mouse_context_menu: None, completion_tasks: Default::default(), + find_all_references_task_sources: Vec::new(), next_completion_id: 0, completion_documentation_pre_resolve_debounce: DebouncedDelay::new(), next_inlay_id: 0, @@ -7887,15 +7889,40 @@ impl Editor { _: &FindAllReferences, cx: &mut ViewContext, ) -> Option>> { - let buffer = self.buffer.read(cx); - let head = self.selections.newest::(cx).head(); - let (buffer, head) = buffer.text_anchor_for_position(head, cx)?; - let replica_id = self.replica_id(cx); + let multi_buffer = self.buffer.read(cx); + let selection = self.selections.newest::(cx); + let head = selection.head(); + let multi_buffer_snapshot = multi_buffer.snapshot(cx); + let head_anchor = multi_buffer_snapshot.anchor_at( + head, + if head < selection.tail() { + Bias::Right + } else { + Bias::Left + }, + ); + match self + .find_all_references_task_sources + .binary_search_by(|task_anchor| task_anchor.cmp(&head_anchor, &multi_buffer_snapshot)) + { + Ok(_) => { + log::info!( + "Ignoring repeated FindAllReferences invocation with the position of already running task" + ); + return None; + } + Err(i) => { + self.find_all_references_task_sources.insert(i, head_anchor); + } + } + + let (buffer, head) = multi_buffer.text_anchor_for_position(head, cx)?; + let replica_id = self.replica_id(cx); let workspace = self.workspace()?; let project = workspace.read(cx).project().clone(); let references = project.update(cx, |project, cx| project.references(&buffer, head, cx)); - Some(cx.spawn(|editor, mut cx| async move { + let open_task = cx.spawn(|editor, mut cx| async move { let mut locations = references.await?; let snapshot = buffer.update(&mut cx, |buffer, _| buffer.snapshot())?; let head_offset = text::ToOffset::to_offset(&head, &snapshot); @@ -7977,6 +8004,21 @@ impl Editor { })?; Ok(()) + }); + Some(cx.spawn(|editor, mut cx| async move { + open_task.await?; + editor.update(&mut cx, |editor, _| { + if let Ok(i) = + editor + .find_all_references_task_sources + .binary_search_by(|task_anchor| { + task_anchor.cmp(&head_anchor, &multi_buffer_snapshot) + }) + { + editor.find_all_references_task_sources.remove(i); + } + })?; + anyhow::Ok(()) })) }