edit predictions: Disable "This Buffer" option when disabled for language (#25566)

Agus Zubiaga created

![image](https://github.com/user-attachments/assets/7b888c7d-a1e9-4d0b-ba6d-9a41916acf79)


Release Notes:

- edit prediction: Disable "This Buffer" option when predictions are
disabled for its language

Change summary

crates/inline_completion_button/src/inline_completion_button.rs | 45 +-
crates/ui/src/components/context_menu.rs                        |  4 
crates/workspace/src/pane.rs                                    | 12 
crates/zed/src/zed/quick_action_bar.rs                          |  4 
4 files changed, 39 insertions(+), 26 deletions(-)

Detailed changes

crates/inline_completion_button/src/inline_completion_button.rs 🔗

@@ -410,26 +410,39 @@ impl InlineCompletionButton {
 
         menu = menu.header("Show Edit Predictions For");
 
+        let language_state = self.language.as_ref().map(|language| {
+            (
+                language.clone(),
+                language_settings::language_settings(Some(language.name()), None, cx)
+                    .show_edit_predictions,
+            )
+        });
+
         if let Some(editor_focus_handle) = self.editor_focus_handle.clone() {
-            menu = menu.toggleable_entry(
-                "This Buffer",
-                self.editor_show_predictions,
-                IconPosition::Start,
-                Some(Box::new(ToggleEditPrediction)),
-                {
-                    let editor_focus_handle = editor_focus_handle.clone();
-                    move |window, cx| {
-                        editor_focus_handle.dispatch_action(&ToggleEditPrediction, window, cx);
-                    }
-                },
-            );
+            let entry = ContextMenuEntry::new("This Buffer")
+                .toggleable(IconPosition::Start, self.editor_show_predictions)
+                .action(Box::new(ToggleEditPrediction))
+                .handler(move |window, cx| {
+                    editor_focus_handle.dispatch_action(&ToggleEditPrediction, window, cx);
+                });
+
+            match language_state.clone() {
+                Some((language, false)) => {
+                    menu = menu.item(
+                        entry
+                            .disabled(true)
+                            .documentation_aside(move |_cx| {
+                                Label::new(format!("Edit predictions cannot be toggled for this buffer because they are disabled for {}", language.name()))
+                                    .into_any_element()
+                            })
+                    );
+                }
+                Some(_) | None => menu = menu.item(entry),
+            }
         }
 
-        if let Some(language) = self.language.clone() {
+        if let Some((language, language_enabled)) = language_state {
             let fs = fs.clone();
-            let language_enabled =
-                language_settings::language_settings(Some(language.name()), None, cx)
-                    .show_edit_predictions;
 
             menu = menu.toggleable_entry(
                 language.name(),

crates/ui/src/components/context_menu.rs 🔗

@@ -95,8 +95,8 @@ impl ContextMenuEntry {
         self
     }
 
-    pub fn action(mut self, action: Option<Box<dyn Action>>) -> Self {
-        self.action = action;
+    pub fn action(mut self, action: Box<dyn Action>) -> Self {
+        self.action = Some(action);
         self
     }
 

crates/workspace/src/pane.rs 🔗

@@ -2425,10 +2425,10 @@ impl Pane {
                         )
                         .item(ContextMenuItem::Entry(
                             ContextMenuEntry::new("Close Others")
-                                .action(Some(Box::new(CloseInactiveItems {
+                                .action(Box::new(CloseInactiveItems {
                                     save_intent: None,
                                     close_pinned: false,
-                                })))
+                                }))
                                 .disabled(total_items == 1)
                                 .handler(window.handler_for(&pane, move |pane, window, cx| {
                                     pane.close_items(window, cx, SaveIntent::Close, |id| {
@@ -2440,9 +2440,9 @@ impl Pane {
                         .separator()
                         .item(ContextMenuItem::Entry(
                             ContextMenuEntry::new("Close Left")
-                                .action(Some(Box::new(CloseItemsToTheLeft {
+                                .action(Box::new(CloseItemsToTheLeft {
                                     close_pinned: false,
-                                })))
+                                }))
                                 .disabled(!has_items_to_left)
                                 .handler(window.handler_for(&pane, move |pane, window, cx| {
                                     pane.close_items_to_the_left_by_id(
@@ -2459,9 +2459,9 @@ impl Pane {
                         ))
                         .item(ContextMenuItem::Entry(
                             ContextMenuEntry::new("Close Right")
-                                .action(Some(Box::new(CloseItemsToTheRight {
+                                .action(Box::new(CloseItemsToTheRight {
                                     close_pinned: false,
-                                })))
+                                }))
                                 .disabled(!has_items_to_right)
                                 .handler(window.handler_for(&pane, move |pane, window, cx| {
                                     pane.close_items_to_the_right_by_id(

crates/zed/src/zed/quick_action_bar.rs 🔗

@@ -307,9 +307,9 @@ impl Render for QuickActionBar {
                                 let mut inline_completion_entry = ContextMenuEntry::new("Edit Predictions")
                                     .toggleable(IconPosition::Start, edit_predictions_enabled_at_cursor && show_edit_predictions)
                                     .disabled(!edit_predictions_enabled_at_cursor)
-                                    .action(Some(
+                                    .action(
                                         editor::actions::ToggleEditPrediction.boxed_clone(),
-                                    )).handler({
+                                    ).handler({
                                         let editor = editor.clone();
                                         move |window, cx| {
                                             editor