Show inline completions when completion menu is visible (#21858)

This changes the behavior of how we display inline completions and
non-inline completions (i.e. completion menu).

Previously we would never show inline completions if a completion menu
was visible, meaning that we'd never show Copilot/Supermaven/...
suggestions if the language server had a suggestion.

With this change, we now display the inline completions even if there is
a completion menu visible.

In that case `<tab>` then accepts the inline completion and `<enter>`
accepts the selected entry in the completion menu.

Release Notes:

- Changed how inline completions (Copilot, Supermaven, ...) and normal
completions (from language servers) interact. Zed will now also show
inline completions when the completion menu is visible. The user can
accept the inline completion with `<tab>` and the active entry in the
completion menu with `<enter>`. Previously, `<tab>` would also select
the active entry in the completion menu.

---------

Co-authored-by: Antonio <antonio@zed.dev>
This commit is contained in:
Thorsten Ball 2024-12-11 17:13:22 +01:00 committed by GitHub
parent dd66a20d78
commit 124e63d07c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 32 additions and 68 deletions

View file

@ -3687,16 +3687,13 @@ impl Editor {
menu.resolve_visible_completions(editor.completion_provider.as_deref(), cx);
*context_menu = Some(CodeContextMenu::Completions(menu));
drop(context_menu);
editor.discard_inline_completion(false, cx);
cx.notify();
} 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 editor.hide_context_menu(cx).is_none() {
editor.update_visible_inline_completion(cx);
}
editor.hide_context_menu(cx);
}
})?;
@ -3732,6 +3729,7 @@ impl Editor {
) -> Option<Task<std::result::Result<(), anyhow::Error>>> {
use language::ToOffset as _;
self.discard_inline_completion(true, cx);
let completions_menu =
if let CodeContextMenu::Completions(menu) = self.hide_context_menu(cx)? {
menu
@ -4475,6 +4473,8 @@ impl Editor {
_: &AcceptInlineCompletion,
cx: &mut ViewContext<Self>,
) {
self.hide_context_menu(cx);
let Some(active_inline_completion) = self.active_inline_completion.as_ref() else {
return;
};
@ -4629,9 +4629,7 @@ impl Editor {
let offset_selection = selection.map(|endpoint| endpoint.to_offset(&multibuffer));
let excerpt_id = cursor.excerpt_id;
if self.context_menu.read().is_some()
|| (!self.completion_tasks.is_empty() && !self.has_active_inline_completion())
|| !offset_selection.is_empty()
if !offset_selection.is_empty()
|| self
.active_inline_completion
.as_ref()
@ -4978,11 +4976,7 @@ impl Editor {
fn hide_context_menu(&mut self, cx: &mut ViewContext<Self>) -> Option<CodeContextMenu> {
cx.notify();
self.completion_tasks.clear();
let context_menu = self.context_menu.write().take();
if context_menu.is_some() {
self.update_visible_inline_completion(cx);
}
context_menu
self.context_menu.write().take()
}
fn show_snippet_choices(