mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-07 11:11:30 +00:00
Do not allow concurrent FindAllReferences requests for the same multibuffer anchors (#9242)
FindAllReferences LSP requests might take a long time to complete, and currently Zed allows multiple requests spawned concurrently for the same Anchor in the multi buffer. That results in multiple search results' multi buffers appearing, sometimes at once, which is not what we want. Part of https://github.com/zed-industries/zed/issues/5351 that helps to reduce the amount of search results after clicks that did not resolve instantly. Release Notes: - Improved FindAllReferences action by not allowing concurrent requests for the same multi buffer source
This commit is contained in:
parent
64219ba49f
commit
c09fe1ce8a
1 changed files with 47 additions and 5 deletions
|
@ -395,6 +395,7 @@ pub struct Editor {
|
||||||
context_menu: RwLock<Option<ContextMenu>>,
|
context_menu: RwLock<Option<ContextMenu>>,
|
||||||
mouse_context_menu: Option<MouseContextMenu>,
|
mouse_context_menu: Option<MouseContextMenu>,
|
||||||
completion_tasks: Vec<(CompletionId, Task<Option<()>>)>,
|
completion_tasks: Vec<(CompletionId, Task<Option<()>>)>,
|
||||||
|
find_all_references_task_sources: Vec<Anchor>,
|
||||||
next_completion_id: CompletionId,
|
next_completion_id: CompletionId,
|
||||||
completion_documentation_pre_resolve_debounce: DebouncedDelay,
|
completion_documentation_pre_resolve_debounce: DebouncedDelay,
|
||||||
available_code_actions: Option<(Model<Buffer>, Arc<[CodeAction]>)>,
|
available_code_actions: Option<(Model<Buffer>, Arc<[CodeAction]>)>,
|
||||||
|
@ -1534,6 +1535,7 @@ impl Editor {
|
||||||
context_menu: RwLock::new(None),
|
context_menu: RwLock::new(None),
|
||||||
mouse_context_menu: None,
|
mouse_context_menu: None,
|
||||||
completion_tasks: Default::default(),
|
completion_tasks: Default::default(),
|
||||||
|
find_all_references_task_sources: Vec::new(),
|
||||||
next_completion_id: 0,
|
next_completion_id: 0,
|
||||||
completion_documentation_pre_resolve_debounce: DebouncedDelay::new(),
|
completion_documentation_pre_resolve_debounce: DebouncedDelay::new(),
|
||||||
next_inlay_id: 0,
|
next_inlay_id: 0,
|
||||||
|
@ -7887,15 +7889,40 @@ impl Editor {
|
||||||
_: &FindAllReferences,
|
_: &FindAllReferences,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Option<Task<Result<()>>> {
|
) -> Option<Task<Result<()>>> {
|
||||||
let buffer = self.buffer.read(cx);
|
let multi_buffer = self.buffer.read(cx);
|
||||||
let head = self.selections.newest::<usize>(cx).head();
|
let selection = self.selections.newest::<usize>(cx);
|
||||||
let (buffer, head) = buffer.text_anchor_for_position(head, cx)?;
|
let head = selection.head();
|
||||||
let replica_id = self.replica_id(cx);
|
|
||||||
|
|
||||||
|
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 workspace = self.workspace()?;
|
||||||
let project = workspace.read(cx).project().clone();
|
let project = workspace.read(cx).project().clone();
|
||||||
let references = project.update(cx, |project, cx| project.references(&buffer, head, cx));
|
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 mut locations = references.await?;
|
||||||
let snapshot = buffer.update(&mut cx, |buffer, _| buffer.snapshot())?;
|
let snapshot = buffer.update(&mut cx, |buffer, _| buffer.snapshot())?;
|
||||||
let head_offset = text::ToOffset::to_offset(&head, &snapshot);
|
let head_offset = text::ToOffset::to_offset(&head, &snapshot);
|
||||||
|
@ -7977,6 +8004,21 @@ impl Editor {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(())
|
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(())
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue