Introduce UI affordances to make enabling/disabling inline completions easier (#22894)

Antonio Scandurra and Thorsten created

Release Notes:

- N/A

---------

Co-authored-by: Thorsten <thorsten@zed.dev>

Change summary

crates/editor/src/editor.rs                                     | 11 
crates/inline_completion_button/src/inline_completion_button.rs | 43 +-
crates/zed/src/zed/quick_action_bar.rs                          | 23 +
3 files changed, 62 insertions(+), 15 deletions(-)

Detailed changes

crates/editor/src/editor.rs 🔗

@@ -1787,6 +1787,17 @@ impl Editor {
         self.refresh_inline_completion(false, true, cx);
     }
 
+    pub fn inline_completions_enabled(&self, cx: &AppContext) -> bool {
+        let cursor = self.selections.newest_anchor().head();
+        if let Some((buffer, buffer_position)) =
+            self.buffer.read(cx).text_anchor_for_position(cursor, cx)
+        {
+            self.should_show_inline_completions(&buffer, buffer_position, cx)
+        } else {
+            false
+        }
+    }
+
     fn should_show_inline_completions(
         &self,
         buffer: &Model<Buffer>,

crates/inline_completion_button/src/inline_completion_button.rs 🔗

@@ -204,23 +204,17 @@ impl Render for InlineCompletionButton {
                     return div();
                 }
 
+                let this = cx.view().clone();
                 div().child(
-                    IconButton::new("zeta", IconName::ZedPredict)
-                        .tooltip(|cx| {
-                            Tooltip::with_meta(
-                                "Zed Predict",
-                                Some(&RateCompletions),
-                                "Click to rate completions",
-                                cx,
-                            )
+                    PopoverMenu::new("zeta")
+                        .menu(move |cx| {
+                            Some(this.update(cx, |this, cx| this.build_zeta_context_menu(cx)))
                         })
-                        .on_click(cx.listener(|this, _, cx| {
-                            if let Some(workspace) = this.workspace.upgrade() {
-                                workspace.update(cx, |workspace, cx| {
-                                    RateCompletionModal::toggle(workspace, cx)
-                                });
-                            }
-                        })),
+                        .anchor(Corner::BottomRight)
+                        .trigger(
+                            IconButton::new("zeta", IconName::ZedPredict)
+                                .tooltip(|cx| Tooltip::text("Zed Predict", cx)),
+                        ),
                 )
             }
         }
@@ -360,6 +354,25 @@ impl InlineCompletionButton {
         })
     }
 
+    fn build_zeta_context_menu(&self, cx: &mut ViewContext<Self>) -> View<ContextMenu> {
+        let workspace = self.workspace.clone();
+        ContextMenu::build(cx, |menu, cx| {
+            self.build_language_settings_menu(menu, cx)
+                .separator()
+                .entry(
+                    "Rate Completions",
+                    Some(RateCompletions.boxed_clone()),
+                    move |cx| {
+                        workspace
+                            .update(cx, |workspace, cx| {
+                                RateCompletionModal::toggle(workspace, cx)
+                            })
+                            .ok();
+                    },
+                )
+        })
+    }
+
     pub fn update_enabled(&mut self, editor: View<Editor>, cx: &mut ViewContext<Self>) {
         let editor = editor.read(cx);
         let snapshot = editor.buffer().read(cx).snapshot(cx);

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

@@ -94,6 +94,7 @@ impl Render for QuickActionBar {
             git_blame_inline_enabled,
             show_git_blame_gutter,
             auto_signature_help_enabled,
+            inline_completions_enabled,
         ) = {
             let editor = editor.read(cx);
             let selection_menu_enabled = editor.selection_menu_enabled(cx);
@@ -102,6 +103,7 @@ impl Render for QuickActionBar {
             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 inline_completions_enabled = editor.inline_completions_enabled(cx);
 
             (
                 selection_menu_enabled,
@@ -110,6 +112,7 @@ impl Render for QuickActionBar {
                 git_blame_inline_enabled,
                 show_git_blame_gutter,
                 auto_signature_help_enabled,
+                inline_completions_enabled,
             )
         };
 
@@ -283,6 +286,26 @@ impl Render for QuickActionBar {
                             },
                         );
 
+                        menu = menu.toggleable_entry(
+                            "Inline Completions",
+                            inline_completions_enabled,
+                            IconPosition::Start,
+                            Some(editor::actions::ToggleInlineCompletions.boxed_clone()),
+                            {
+                                let editor = editor.clone();
+                                move |cx| {
+                                    editor
+                                        .update(cx, |editor, cx| {
+                                            editor.toggle_inline_completions(
+                                                &editor::actions::ToggleInlineCompletions,
+                                                cx,
+                                            );
+                                        })
+                                        .ok();
+                                }
+                            },
+                        );
+
                         menu = menu.separator();
 
                         menu = menu.toggleable_entry(