From 4bc324ccdce1d71a41104718ee5737c93937bc5a Mon Sep 17 00:00:00 2001 From: Tim Vermeulen Date: Tue, 17 Mar 2026 10:59:17 +0100 Subject: [PATCH] copilot: Clear completions upon discard (#40185) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #37836 This behavior was already fixed for Supermaven in #37047, but is still present in Copilot. What's actually happening: - Receive a multi-line edit prediction - Dismiss it with escape - Clicking anywhere in the editor below the cursor calls `Editor::select` which starts out by calling `Editor::hide_context_menu` -> `Editor::update_visible_edit_prediction`, bringing back the prediction that was just dismissed and updating the editor's display map - The subsequent selection logic in `Editor::select` now operates using a display map that is inconsistent with what the user saw when clicking - If the click was anywhere where the prediction inlay used to be, `Editor::select` thinks the user clicked on the inlay and does nothing, and the inlay reappears - If the click was below where the prediction inlay used to be, the inlay is immediately removed again but the cursor is moved to the wrong position because the inlay temporarily added a vertical offset to all lines after it in the buffer Ultimately, `Editor::select` should be handling the user input using the same display map that the user saw when making the input. This can obviously be solved in multiple ways, I chose to clear the current completions in `CopilotCompletionProvider::discard` such that any subsequent calls to `Editor::update_visible_edit_prediction` doesn't immediately nullify the dismissal of the edit prediction by the user. Note that this also changes the behavior that occurs after dismissing an edit prediction, moving to a different position in the buffer, and then returning: currently, this resurfaces the dismissed edit prediction (which the `test_copilot` test exercises), and after this change it doesn’t. This current behavior didn't seem desirable to me because it doesn't happen when using Zeta or Supermaven, but if we want to keep it, then we could fix the incorrect selection behavior some other way. Release Notes: - Fixed bug that resurfaced dismissed Copilot edit predictions when moving the cursor around Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Co-authored-by: Ben Brandt --- .../copilot/src/copilot_edit_prediction_delegate.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/crates/copilot/src/copilot_edit_prediction_delegate.rs b/crates/copilot/src/copilot_edit_prediction_delegate.rs index cfb5eef7e08caab8fec624a1cf364eecac16ec9b..2d5b387479f380f66519a07468a88929d1c5cc55 100644 --- a/crates/copilot/src/copilot_edit_prediction_delegate.rs +++ b/crates/copilot/src/copilot_edit_prediction_delegate.rs @@ -129,7 +129,9 @@ impl EditPredictionDelegate for CopilotEditPredictionDelegate { } } - fn discard(&mut self, _reason: EditPredictionDiscardReason, _: &mut Context) {} + fn discard(&mut self, _reason: EditPredictionDiscardReason, _: &mut Context) { + self.completion.take(); + } fn suggest( &mut self, @@ -410,8 +412,14 @@ mod tests { assert_eq!(editor.display_text(cx), "one.c \ntwo\nthree\n"); assert_eq!(editor.text(cx), "one.c \ntwo\nthree\n"); - // When undoing the previously active suggestion is shown again. + // When undoing the previously active suggestion isn't shown again. editor.undo(&Default::default(), window, cx); + assert!(!editor.has_active_edit_prediction()); + assert_eq!(editor.display_text(cx), "one.c\ntwo\nthree\n"); + assert_eq!(editor.text(cx), "one.c\ntwo\nthree\n"); + }); + executor.advance_clock(COPILOT_DEBOUNCE_TIMEOUT); + cx.editor(|editor, _, cx| { assert!(editor.has_active_edit_prediction()); assert_eq!(editor.display_text(cx), "one.copilot2\ntwo\nthree\n"); assert_eq!(editor.text(cx), "one.c\ntwo\nthree\n");