edit predictions: Invalidate cached settings and unset provider when set to none (#25505)

Fixes a few state mismatches when changing providers and other settings

Release Notes:

- edit predictions: Fix mismatch between status bar settings and editor
control settings
- edit predictions: Turn off as soon as `edit_prediction_provider` is
set to `none`

---------

Co-authored-by: Danilo <danilo@zed.dev>
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
This commit is contained in:
Agus Zubiaga 2025-02-24 22:56:28 -03:00 committed by GitHub
parent 20440f83e9
commit 3f168e85c2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 70 additions and 72 deletions

View file

@ -1824,6 +1824,7 @@ impl Editor {
}), }),
provider: Arc::new(provider), provider: Arc::new(provider),
}); });
self.update_edit_prediction_settings(cx);
self.refresh_inline_completion(false, false, window, cx); self.refresh_inline_completion(false, false, window, cx);
} }
@ -1943,7 +1944,7 @@ impl Editor {
self.auto_replace_emoji_shortcode = auto_replace; self.auto_replace_emoji_shortcode = auto_replace;
} }
pub fn toggle_inline_completions( pub fn toggle_edit_predictions(
&mut self, &mut self,
_: &ToggleEditPrediction, _: &ToggleEditPrediction,
window: &mut Window, window: &mut Window,
@ -1964,6 +1965,7 @@ impl Editor {
cx: &mut Context<Self>, cx: &mut Context<Self>,
) { ) {
self.show_inline_completions_override = show_edit_predictions; self.show_inline_completions_override = show_edit_predictions;
self.update_edit_prediction_settings(cx);
if let Some(false) = show_edit_predictions { if let Some(false) = show_edit_predictions {
self.discard_inline_completion(false, cx); self.discard_inline_completion(false, cx);
@ -4822,7 +4824,7 @@ impl Editor {
let (buffer, cursor_buffer_position) = let (buffer, cursor_buffer_position) =
self.buffer.read(cx).text_anchor_for_position(cursor, cx)?; self.buffer.read(cx).text_anchor_for_position(cursor, cx)?;
if !self.inline_completions_enabled_in_buffer(&buffer, cursor_buffer_position, cx) { if !self.edit_predictions_enabled_in_buffer(&buffer, cursor_buffer_position, cx) {
self.discard_inline_completion(false, cx); self.discard_inline_completion(false, cx);
return None; return None;
} }
@ -4871,6 +4873,22 @@ impl Editor {
} }
} }
pub fn update_edit_prediction_settings(&mut self, cx: &mut Context<Self>) {
if self.edit_prediction_provider.is_none() {
self.edit_prediction_settings = EditPredictionSettings::Disabled;
} else {
let selection = self.selections.newest_anchor();
let cursor = selection.head();
if let Some((buffer, cursor_buffer_position)) =
self.buffer.read(cx).text_anchor_for_position(cursor, cx)
{
self.edit_prediction_settings =
self.edit_prediction_settings_at_position(&buffer, cursor_buffer_position, cx);
}
}
}
fn edit_prediction_settings_at_position( fn edit_prediction_settings_at_position(
&self, &self,
buffer: &Entity<Buffer>, buffer: &Entity<Buffer>,
@ -4925,18 +4943,18 @@ impl Editor {
) )
} }
pub fn inline_completions_enabled(&self, cx: &App) -> bool { pub fn edit_predictions_enabled_at_cursor(&self, cx: &App) -> bool {
let cursor = self.selections.newest_anchor().head(); let cursor = self.selections.newest_anchor().head();
if let Some((buffer, cursor_position)) = if let Some((buffer, cursor_position)) =
self.buffer.read(cx).text_anchor_for_position(cursor, cx) self.buffer.read(cx).text_anchor_for_position(cursor, cx)
{ {
self.inline_completions_enabled_in_buffer(&buffer, cursor_position, cx) self.edit_predictions_enabled_in_buffer(&buffer, cursor_position, cx)
} else { } else {
false false
} }
} }
fn inline_completions_enabled_in_buffer( fn edit_predictions_enabled_in_buffer(
&self, &self,
buffer: &Entity<Buffer>, buffer: &Entity<Buffer>,
buffer_position: language::Anchor, buffer_position: language::Anchor,
@ -15154,6 +15172,7 @@ impl Editor {
fn settings_changed(&mut self, window: &mut Window, cx: &mut Context<Self>) { fn settings_changed(&mut self, window: &mut Window, cx: &mut Context<Self>) {
self.tasks_update_task = Some(self.refresh_runnables(window, cx)); self.tasks_update_task = Some(self.refresh_runnables(window, cx));
self.update_edit_prediction_settings(cx);
self.refresh_inline_completion(true, false, window, cx); self.refresh_inline_completion(true, false, window, cx);
self.refresh_inlay_hints( self.refresh_inlay_hints(
InlayHintRefreshReason::SettingsChange(inlay_hint_settings( InlayHintRefreshReason::SettingsChange(inlay_hint_settings(

View file

@ -406,7 +406,7 @@ impl EditorElement {
register_action(editor, window, Editor::toggle_relative_line_numbers); register_action(editor, window, Editor::toggle_relative_line_numbers);
register_action(editor, window, Editor::toggle_indent_guides); register_action(editor, window, Editor::toggle_indent_guides);
register_action(editor, window, Editor::toggle_inlay_hints); register_action(editor, window, Editor::toggle_inlay_hints);
register_action(editor, window, Editor::toggle_inline_completions); register_action(editor, window, Editor::toggle_edit_predictions);
register_action(editor, window, Editor::toggle_inline_diagnostics); register_action(editor, window, Editor::toggle_inline_diagnostics);
register_action(editor, window, hover_popover::hover); register_action(editor, window, hover_popover::hover);
register_action(editor, window, Editor::reveal_in_finder); register_action(editor, window, Editor::reveal_in_finder);

View file

@ -9,7 +9,7 @@ use settings::SettingsStore;
use std::{cell::RefCell, rc::Rc, sync::Arc}; use std::{cell::RefCell, rc::Rc, sync::Arc};
use supermaven::{Supermaven, SupermavenCompletionProvider}; use supermaven::{Supermaven, SupermavenCompletionProvider};
use ui::Window; use ui::Window;
use zeta::ProviderDataCollection; use zeta::{ProviderDataCollection, ZetaInlineCompletionProvider};
pub fn init(client: Arc<Client>, user_store: Entity<UserStore>, cx: &mut App) { pub fn init(client: Arc<Client>, user_store: Entity<UserStore>, cx: &mut App) {
let editors: Rc<RefCell<HashMap<WeakEntity<Editor>, AnyWindowHandle>>> = Rc::default(); let editors: Rc<RefCell<HashMap<WeakEntity<Editor>, AnyWindowHandle>>> = Rc::default();
@ -225,7 +225,9 @@ fn assign_edit_prediction_provider(
let singleton_buffer = editor.buffer().read(cx).as_singleton(); let singleton_buffer = editor.buffer().read(cx).as_singleton();
match provider { match provider {
EditPredictionProvider::None => {} EditPredictionProvider::None => {
editor.set_edit_prediction_provider::<ZetaInlineCompletionProvider>(None, window, cx);
}
EditPredictionProvider::Copilot => { EditPredictionProvider::Copilot => {
if let Some(copilot) = Copilot::global(cx) { if let Some(copilot) = Copilot::global(cx) {
if let Some(buffer) = singleton_buffer { if let Some(buffer) = singleton_buffer {

View file

@ -87,46 +87,21 @@ impl Render for QuickActionBar {
return div().id("empty quick action bar"); return div().id("empty quick action bar");
}; };
let ( let supports_inlay_hints = editor.update(cx, |editor, cx| editor.supports_inlay_hints(cx));
selection_menu_enabled, let editor_value = editor.read(cx);
inlay_hints_enabled, let selection_menu_enabled = editor_value.selection_menu_enabled(cx);
supports_inlay_hints, let inlay_hints_enabled = editor_value.inlay_hints_enabled();
inline_diagnostics_enabled, let inline_diagnostics_enabled = editor_value.show_inline_diagnostics();
supports_inline_diagnostics, let supports_inline_diagnostics = editor_value.inline_diagnostics_enabled();
git_blame_inline_enabled, let git_blame_inline_enabled = editor_value.git_blame_inline_enabled();
show_git_blame_gutter, let show_git_blame_gutter = editor_value.show_git_blame_gutter();
auto_signature_help_enabled, let auto_signature_help_enabled = editor_value.auto_signature_help_enabled(cx);
show_inline_completions, let has_edit_prediction_provider = editor_value.edit_prediction_provider().is_some();
inline_completion_enabled, let show_edit_predictions = editor_value.edit_predictions_enabled();
) = { let edit_predictions_enabled_at_cursor =
let supports_inlay_hints = editor_value.edit_predictions_enabled_at_cursor(cx);
editor.update(cx, |editor, cx| editor.supports_inlay_hints(cx));
let editor = editor.read(cx);
let selection_menu_enabled = editor.selection_menu_enabled(cx);
let inlay_hints_enabled = editor.inlay_hints_enabled();
let show_inline_diagnostics = editor.show_inline_diagnostics();
let supports_inline_diagnostics = editor.inline_diagnostics_enabled();
let git_blame_inline_enabled = editor.git_blame_inline_enabled();
let show_git_blame_gutter = editor.show_git_blame_gutter();
let auto_signature_help_enabled = editor.auto_signature_help_enabled(cx);
let show_edit_predictions = editor.edit_predictions_enabled();
let inline_completion_enabled = editor.inline_completions_enabled(cx);
( let focus_handle = editor_value.focus_handle(cx);
selection_menu_enabled,
inlay_hints_enabled,
supports_inlay_hints,
show_inline_diagnostics,
supports_inline_diagnostics,
git_blame_inline_enabled,
show_git_blame_gutter,
auto_signature_help_enabled,
show_edit_predictions,
inline_completion_enabled,
)
};
let focus_handle = editor.read(cx).focus_handle(cx);
let search_button = editor.is_singleton(cx).then(|| { let search_button = editor.is_singleton(cx).then(|| {
QuickActionBarButton::new( QuickActionBarButton::new(
@ -328,32 +303,34 @@ impl Render for QuickActionBar {
}, },
); );
let mut inline_completion_entry = ContextMenuEntry::new("Edit Predictions") if has_edit_prediction_provider {
.toggleable(IconPosition::Start, inline_completion_enabled && show_inline_completions) let mut inline_completion_entry = ContextMenuEntry::new("Edit Predictions")
.disabled(!inline_completion_enabled) .toggleable(IconPosition::Start, edit_predictions_enabled_at_cursor && show_edit_predictions)
.action(Some( .disabled(!edit_predictions_enabled_at_cursor)
editor::actions::ToggleEditPrediction.boxed_clone(), .action(Some(
)).handler({ editor::actions::ToggleEditPrediction.boxed_clone(),
let editor = editor.clone(); )).handler({
move |window, cx| { let editor = editor.clone();
editor move |window, cx| {
.update(cx, |editor, cx| { editor
editor.toggle_inline_completions( .update(cx, |editor, cx| {
&editor::actions::ToggleEditPrediction, editor.toggle_edit_predictions(
window, &editor::actions::ToggleEditPrediction,
cx, window,
); cx,
}) );
.ok(); })
} .ok();
}); }
if !inline_completion_enabled { });
inline_completion_entry = inline_completion_entry.documentation_aside(|_| { if !edit_predictions_enabled_at_cursor {
Label::new("You can't toggle edit predictions for this file as it is within the excluded files list.").into_any_element() inline_completion_entry = inline_completion_entry.documentation_aside(|_| {
}); Label::new("You can't toggle edit predictions for this file as it is within the excluded files list.").into_any_element()
} });
}
menu = menu.item(inline_completion_entry); menu = menu.item(inline_completion_entry);
}
menu = menu.separator(); menu = menu.separator();