Skip to content

Commit

Permalink
Do less resolves when showing the completion menu (#21286)
Browse files Browse the repository at this point in the history
Closes #21205

Zed does completion resolve on every menu item selection and when
applying the edit, so resolving all completion menu list is excessive
indeed.

In addition to that, removes the documentation-centric approach of menu
resolves, as we're actually resolving these for more than that, e.g.
additionalTextEdits and have to do that always, even if we do not show
the documentation.

Potentially, we can omit the second resolve too, but that seems
relatively dangerous, and many servers remove the `data` after the first
resolve, so a 2nd one is not that harmful given that we used to do much
more

Release Notes:

- Reduced the amount of `completionItem/resolve` calls done in the
completion menu
  • Loading branch information
SomeoneToIgnore authored Nov 28, 2024
1 parent 6cba467 commit f309445
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 173 deletions.
108 changes: 22 additions & 86 deletions crates/editor/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,6 @@ pub struct Editor {
auto_signature_help: Option<bool>,
find_all_references_task_sources: Vec<Anchor>,
next_completion_id: CompletionId,
completion_documentation_pre_resolve_debounce: DebouncedDelay,
available_code_actions: Option<(Location, Arc<[AvailableCodeAction]>)>,
code_actions_task: Option<Task<Result<()>>>,
document_highlights_task: Option<Task<()>>,
Expand Down Expand Up @@ -1006,7 +1005,7 @@ struct CompletionsMenu {
matches: Arc<[StringMatch]>,
selected_item: usize,
scroll_handle: UniformListScrollHandle,
selected_completion_documentation_resolve_debounce: Option<Arc<Mutex<DebouncedDelay>>>,
selected_completion_resolve_debounce: Option<Arc<Mutex<DebouncedDelay>>>,
}

impl CompletionsMenu {
Expand Down Expand Up @@ -1038,9 +1037,7 @@ impl CompletionsMenu {
matches: Vec::new().into(),
selected_item: 0,
scroll_handle: UniformListScrollHandle::new(),
selected_completion_documentation_resolve_debounce: Some(Arc::new(Mutex::new(
DebouncedDelay::new(),
))),
selected_completion_resolve_debounce: Some(Arc::new(Mutex::new(DebouncedDelay::new()))),
}
}

Expand Down Expand Up @@ -1093,15 +1090,12 @@ impl CompletionsMenu {
matches,
selected_item: 0,
scroll_handle: UniformListScrollHandle::new(),
selected_completion_documentation_resolve_debounce: Some(Arc::new(Mutex::new(
DebouncedDelay::new(),
))),
selected_completion_resolve_debounce: Some(Arc::new(Mutex::new(DebouncedDelay::new()))),
}
}

fn suppress_documentation_resolution(mut self) -> Self {
self.selected_completion_documentation_resolve_debounce
.take();
self.selected_completion_resolve_debounce.take();
self
}

Expand All @@ -1113,7 +1107,7 @@ impl CompletionsMenu {
self.selected_item = 0;
self.scroll_handle
.scroll_to_item(self.selected_item, ScrollStrategy::Top);
self.attempt_resolve_selected_completion_documentation(provider, cx);
self.resolve_selected_completion(provider, cx);
cx.notify();
}

Expand All @@ -1129,7 +1123,7 @@ impl CompletionsMenu {
}
self.scroll_handle
.scroll_to_item(self.selected_item, ScrollStrategy::Top);
self.attempt_resolve_selected_completion_documentation(provider, cx);
self.resolve_selected_completion(provider, cx);
cx.notify();
}

Expand All @@ -1145,7 +1139,7 @@ impl CompletionsMenu {
}
self.scroll_handle
.scroll_to_item(self.selected_item, ScrollStrategy::Top);
self.attempt_resolve_selected_completion_documentation(provider, cx);
self.resolve_selected_completion(provider, cx);
cx.notify();
}

Expand All @@ -1157,58 +1151,20 @@ impl CompletionsMenu {
self.selected_item = self.matches.len() - 1;
self.scroll_handle
.scroll_to_item(self.selected_item, ScrollStrategy::Top);
self.attempt_resolve_selected_completion_documentation(provider, cx);
self.resolve_selected_completion(provider, cx);
cx.notify();
}

fn pre_resolve_completion_documentation(
buffer: Model<Buffer>,
completions: Arc<RwLock<Box<[Completion]>>>,
matches: Arc<[StringMatch]>,
editor: &Editor,
cx: &mut ViewContext<Editor>,
) -> Task<()> {
let settings = EditorSettings::get_global(cx);
if !settings.show_completion_documentation {
return Task::ready(());
}

let Some(provider) = editor.completion_provider.as_ref() else {
return Task::ready(());
};

let resolve_task = provider.resolve_completions(
buffer,
matches.iter().map(|m| m.candidate_id).collect(),
completions.clone(),
cx,
);

cx.spawn(move |this, mut cx| async move {
if let Some(true) = resolve_task.await.log_err() {
this.update(&mut cx, |_, cx| cx.notify()).ok();
}
})
}

fn attempt_resolve_selected_completion_documentation(
fn resolve_selected_completion(
&mut self,
provider: Option<&dyn CompletionProvider>,
cx: &mut ViewContext<Editor>,
) {
let settings = EditorSettings::get_global(cx);
if !settings.show_completion_documentation {
return;
}

let completion_index = self.matches[self.selected_item].candidate_id;
let Some(provider) = provider else {
return;
};
let Some(documentation_resolve) = self
.selected_completion_documentation_resolve_debounce
.as_ref()
else {
let Some(completion_resolve) = self.selected_completion_resolve_debounce.as_ref() else {
return;
};

Expand All @@ -1223,7 +1179,7 @@ impl CompletionsMenu {
EditorSettings::get_global(cx).completion_documentation_secondary_query_debounce;
let delay = Duration::from_millis(delay_ms);

documentation_resolve.lock().fire_new(delay, cx, |_, cx| {
completion_resolve.lock().fire_new(delay, cx, |_, cx| {
cx.spawn(move |this, mut cx| async move {
if let Some(true) = resolve_task.await.log_err() {
this.update(&mut cx, |_, cx| cx.notify()).ok();
Expand Down Expand Up @@ -2118,7 +2074,6 @@ impl Editor {
auto_signature_help: None,
find_all_references_task_sources: Vec::new(),
next_completion_id: 0,
completion_documentation_pre_resolve_debounce: DebouncedDelay::new(),
next_inlay_id: 0,
code_action_providers,
available_code_actions: Default::default(),
Expand Down Expand Up @@ -4523,9 +4478,9 @@ impl Editor {
let sort_completions = provider.sort_completions();

let id = post_inc(&mut self.next_completion_id);
let task = cx.spawn(|this, mut cx| {
let task = cx.spawn(|editor, mut cx| {
async move {
this.update(&mut cx, |this, _| {
editor.update(&mut cx, |this, _| {
this.completion_tasks.retain(|(task_id, _)| *task_id >= id);
})?;
let completions = completions.await.log_err();
Expand All @@ -4543,34 +4498,14 @@ impl Editor {
if menu.matches.is_empty() {
None
} else {
this.update(&mut cx, |editor, cx| {
let completions = menu.completions.clone();
let matches = menu.matches.clone();

let delay_ms = EditorSettings::get_global(cx)
.completion_documentation_secondary_query_debounce;
let delay = Duration::from_millis(delay_ms);
editor
.completion_documentation_pre_resolve_debounce
.fire_new(delay, cx, |editor, cx| {
CompletionsMenu::pre_resolve_completion_documentation(
buffer,
completions,
matches,
editor,
cx,
)
});
})
.ok();
Some(menu)
}
} else {
None
};

this.update(&mut cx, |this, cx| {
let mut context_menu = this.context_menu.write();
editor.update(&mut cx, |editor, cx| {
let mut context_menu = editor.context_menu.write();
match context_menu.as_ref() {
None => {}

Expand All @@ -4583,19 +4518,20 @@ impl Editor {
_ => return,
}

if this.focus_handle.is_focused(cx) && menu.is_some() {
let menu = menu.unwrap();
if editor.focus_handle.is_focused(cx) && menu.is_some() {
let mut menu = menu.unwrap();
menu.resolve_selected_completion(editor.completion_provider.as_deref(), cx);
*context_menu = Some(ContextMenu::Completions(menu));
drop(context_menu);
this.discard_inline_completion(false, cx);
editor.discard_inline_completion(false, cx);
cx.notify();
} else if this.completion_tasks.len() <= 1 {
} else if editor.completion_tasks.len() <= 1 {
// If there are no more completion tasks and the last menu was
// empty, we should hide it. If it was already hidden, we should
// also show the copilot completion when available.
drop(context_menu);
if this.hide_context_menu(cx).is_none() {
this.update_visible_inline_completion(cx);
if editor.hide_context_menu(cx).is_none() {
editor.update_visible_inline_completion(cx);
}
}
})?;
Expand Down
Loading

0 comments on commit f309445

Please sign in to comment.