@@ -395,6 +395,7 @@ pub struct Editor {
context_menu: RwLock<Option<ContextMenu>>,
mouse_context_menu: Option<MouseContextMenu>,
completion_tasks: Vec<(CompletionId, Task<Option<()>>)>,
+ find_all_references_task_sources: Vec<Anchor>,
next_completion_id: CompletionId,
completion_documentation_pre_resolve_debounce: DebouncedDelay,
available_code_actions: Option<(Model<Buffer>, 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<Self>,
) -> Option<Task<Result<()>>> {
- let buffer = self.buffer.read(cx);
- let head = self.selections.newest::<usize>(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::<usize>(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(())
}))
}