From a6811524a74963775149d59e7a8a5b31ee563dff Mon Sep 17 00:00:00 2001 From: "gcp-cherry-pick-bot[bot]" <98988430+gcp-cherry-pick-bot[bot]@users.noreply.github.com> Date: Wed, 18 Jun 2025 03:04:28 -0600 Subject: [PATCH] Fix bug where prior LSP completions can be displayed after trigger char (cherry-pick #32927) (#32931) Cherry-picked Fix bug where prior LSP completions can be displayed after trigger char (#32927) Bug in #31872 Closes #32774 Release Notes: - Fixed a bug in LSP completions caching where prior completions may be used when they should not, after typing a trigger char like `.` Co-authored-by: Michael Sloan --- crates/editor/src/editor.rs | 48 ++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index dbdca99dd8ebeb3904e60ec8d11d3e5787384154..d3ff9aa91cea51afdfeca172a4c18d719f01f020 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -5139,6 +5139,37 @@ impl Editor { .as_ref() .map_or(true, |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); @@ -5169,23 +5200,6 @@ 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 (word_replace_range, word_to_exclude) = if let (word_range, Some(CharKind::Word)) = buffer_snapshot.surrounding_word(buffer_position) {