diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index bdf1ae16474c647abd7ecb0593fb272b37ef9c54..999e66efdcf7a39774cb29a6dba28473cd84fa81 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -5488,6 +5488,18 @@ impl Editor { drop(multibuffer_snapshot); + // Hide the current completions menu when query is empty. Without this, cached + // completions from before the trigger char may be reused (#32774). + if query.is_none() { + let menu_is_open = matches!( + self.context_menu.borrow().as_ref(), + Some(CodeContextMenu::Completions(_)) + ); + if menu_is_open { + self.hide_context_menu(window, cx); + } + } + let mut ignore_word_threshold = false; let provider = match requested_source { Some(CompletionsMenuSource::Normal) | None => self.completion_provider.clone(), @@ -5509,37 +5521,6 @@ impl Editor { .as_ref() .is_none_or(|provider| provider.filter_completions()); - let trigger_kind = match trigger { - Some(trigger) if buffer.read(cx).completion_triggers().contains(trigger) => { - CompletionTriggerKind::TRIGGER_CHARACTER - } - _ => CompletionTriggerKind::INVOKED, - }; - let completion_context = CompletionContext { - trigger_character: trigger.and_then(|trigger| { - if trigger_kind == CompletionTriggerKind::TRIGGER_CHARACTER { - Some(String::from(trigger)) - } else { - None - } - }), - trigger_kind, - }; - - // Hide the current completions menu when a trigger char is typed. Without this, cached - // completions from before the trigger char may be reused (#32774). Snippet choices could - // involve trigger chars, so this is skipped in that case. - if trigger_kind == CompletionTriggerKind::TRIGGER_CHARACTER && self.snippet_stack.is_empty() - { - let menu_is_open = matches!( - self.context_menu.borrow().as_ref(), - Some(CodeContextMenu::Completions(_)) - ); - if menu_is_open { - self.hide_context_menu(window, cx); - } - } - if let Some(CodeContextMenu::Completions(menu)) = self.context_menu.borrow_mut().as_mut() { if filter_completions { menu.filter(query.clone(), provider.clone(), window, cx); @@ -5570,11 +5551,29 @@ impl Editor { } }; + let trigger_kind = match trigger { + Some(trigger) if buffer.read(cx).completion_triggers().contains(trigger) => { + CompletionTriggerKind::TRIGGER_CHARACTER + } + _ => CompletionTriggerKind::INVOKED, + }; + let completion_context = CompletionContext { + trigger_character: trigger.and_then(|trigger| { + if trigger_kind == CompletionTriggerKind::TRIGGER_CHARACTER { + Some(String::from(trigger)) + } else { + None + } + }), + trigger_kind, + }; + let Anchor { excerpt_id: buffer_excerpt_id, text_anchor: buffer_position, .. } = buffer_position; + let (word_replace_range, word_to_exclude) = if let (word_range, Some(CharKind::Word)) = buffer_snapshot.surrounding_word(buffer_position, false) {