Add menu item to switch Supermaven and Copilot (#15443)

Kevin Wang created

Adds a "Use Supermaven" and "Use Copilot" menu item to the signed out
menus for each of the autocomplete providers to make it easier to switch
between them without having to update your local settings json.

<img width="222" alt="image"
src="https://github.com/user-attachments/assets/6f760f4e-5527-4971-bdaf-383bc99649bd">

Release Notes:

- Added menu items to quickly switch between Supermaven and Copilot
inline completions when the provider is not configured

Change summary

crates/inline_completion_button/src/inline_completion_button.rs | 49 ++
1 file changed, 43 insertions(+), 6 deletions(-)

Detailed changes

crates/inline_completion_button/src/inline_completion_button.rs 🔗

@@ -15,7 +15,7 @@ use language::{
 use settings::{update_settings_file, Settings, SettingsStore};
 use std::{path::Path, sync::Arc};
 use supermaven::{AccountStatus, Supermaven};
-use util::ResultExt;
+use util::{with_clone, ResultExt};
 use workspace::{
     create_and_open_local_file,
     item::ItemHandle,
@@ -159,16 +159,29 @@ impl Render for InlineCompletionButton {
                 let icon = status.to_icon();
                 let tooltip_text = status.to_tooltip();
                 let this = cx.view().clone();
+                let fs = self.fs.clone();
 
                 return div().child(
                     PopoverMenu::new("supermaven")
                         .menu(move |cx| match &status {
                             SupermavenButtonStatus::NeedsActivation(activate_url) => {
                                 Some(ContextMenu::build(cx, |menu, _| {
+                                    let fs = fs.clone();
                                     let activate_url = activate_url.clone();
                                     menu.entry("Sign In", None, move |cx| {
                                         cx.open_url(activate_url.as_str())
                                     })
+                                    .entry(
+                                        "Use Copilot",
+                                        None,
+                                        move |cx| {
+                                            set_completion_provider(
+                                                fs.clone(),
+                                                cx,
+                                                InlineCompletionProvider::Copilot,
+                                            )
+                                        },
+                                    )
                                 }))
                             }
                             SupermavenButtonStatus::Ready => Some(
@@ -208,11 +221,23 @@ impl InlineCompletionButton {
     pub fn build_copilot_start_menu(&mut self, cx: &mut ViewContext<Self>) -> View<ContextMenu> {
         let fs = self.fs.clone();
         ContextMenu::build(cx, |menu, _| {
-            menu.entry("Sign In", None, initiate_sign_in).entry(
-                "Disable Copilot",
-                None,
-                move |cx| hide_copilot(fs.clone(), cx),
-            )
+            menu.entry("Sign In", None, initiate_sign_in)
+                .entry(
+                    "Disable Copilot",
+                    None,
+                    with_clone!(fs, move |cx| hide_copilot(fs.clone(), cx)),
+                )
+                .entry(
+                    "Use Supermaven",
+                    None,
+                    with_clone!(fs, move |cx| {
+                        set_completion_provider(
+                            fs.clone(),
+                            cx,
+                            InlineCompletionProvider::Supermaven,
+                        )
+                    }),
+                )
         })
     }
 
@@ -425,6 +450,18 @@ fn toggle_inline_completions_globally(fs: Arc<dyn Fs>, cx: &mut AppContext) {
     });
 }
 
+fn set_completion_provider(
+    fs: Arc<dyn Fs>,
+    cx: &mut AppContext,
+    provider: InlineCompletionProvider,
+) {
+    update_settings_file::<AllLanguageSettings>(fs, cx, move |file, _| {
+        file.features
+            .get_or_insert(Default::default())
+            .inline_completion_provider = Some(provider);
+    });
+}
+
 fn toggle_inline_completions_for_language(
     language: Arc<Language>,
     fs: Arc<dyn Fs>,