language_model: Remove dependency on `inline_completion_button` (#20930)

Marshall Bowers created

This PR removes a dependency on the `inline_completion_button` crate
from the `language_model` crate.

We were taking on this dependency solely to call `initiate_sign_in`,
which can easily be moved to the `copilot` crate.

This allows `language_model` to move up in the crate dependency graph.

Release Notes:

- N/A

Change summary

Cargo.lock                                                      |  4 
crates/copilot/src/copilot.rs                                   |  4 
crates/copilot/src/sign_in.rs                                   | 71 ++
crates/inline_completion_button/Cargo.toml                      |  1 
crates/inline_completion_button/src/inline_completion_button.rs | 72 --
crates/language_model/Cargo.toml                                |  1 
crates/language_model/src/provider/copilot_chat.rs              |  4 
crates/welcome/Cargo.toml                                       |  2 
crates/welcome/src/welcome.rs                                   |  2 
9 files changed, 78 insertions(+), 83 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -6076,7 +6076,6 @@ dependencies = [
  "supermaven",
  "theme",
  "ui",
- "util",
  "workspace",
  "zed_actions",
 ]
@@ -6521,7 +6520,6 @@ dependencies = [
  "gpui",
  "http_client",
  "image",
- "inline_completion_button",
  "language",
  "log",
  "menu",
@@ -14356,11 +14354,11 @@ version = "0.1.0"
 dependencies = [
  "anyhow",
  "client",
+ "copilot",
  "db",
  "editor",
  "fuzzy",
  "gpui",
- "inline_completion_button",
  "install_cli",
  "picker",
  "project",

crates/copilot/src/copilot.rs 🔗

@@ -38,8 +38,8 @@ use std::{
 };
 use util::{fs::remove_matching, maybe, ResultExt};
 
-pub use copilot_completion_provider::CopilotCompletionProvider;
-pub use sign_in::CopilotCodeVerification;
+pub use crate::copilot_completion_provider::CopilotCompletionProvider;
+pub use crate::sign_in::{initiate_sign_in, CopilotCodeVerification};
 
 actions!(
     copilot,

crates/copilot/src/sign_in.rs 🔗

@@ -5,10 +5,79 @@ use gpui::{
     Styled, Subscription, ViewContext,
 };
 use ui::{prelude::*, Button, Label, Vector, VectorName};
-use workspace::ModalView;
+use util::ResultExt as _;
+use workspace::notifications::NotificationId;
+use workspace::{ModalView, Toast, Workspace};
 
 const COPILOT_SIGN_UP_URL: &str = "https://github.com/features/copilot";
 
+struct CopilotStartingToast;
+
+pub fn initiate_sign_in(cx: &mut WindowContext) {
+    let Some(copilot) = Copilot::global(cx) else {
+        return;
+    };
+    let status = copilot.read(cx).status();
+    let Some(workspace) = cx.window_handle().downcast::<Workspace>() else {
+        return;
+    };
+    match status {
+        Status::Starting { task } => {
+            let Some(workspace) = cx.window_handle().downcast::<Workspace>() else {
+                return;
+            };
+
+            let Ok(workspace) = workspace.update(cx, |workspace, cx| {
+                workspace.show_toast(
+                    Toast::new(
+                        NotificationId::unique::<CopilotStartingToast>(),
+                        "Copilot is starting...",
+                    ),
+                    cx,
+                );
+                workspace.weak_handle()
+            }) else {
+                return;
+            };
+
+            cx.spawn(|mut cx| async move {
+                task.await;
+                if let Some(copilot) = cx.update(|cx| Copilot::global(cx)).ok().flatten() {
+                    workspace
+                        .update(&mut cx, |workspace, cx| match copilot.read(cx).status() {
+                            Status::Authorized => workspace.show_toast(
+                                Toast::new(
+                                    NotificationId::unique::<CopilotStartingToast>(),
+                                    "Copilot has started!",
+                                ),
+                                cx,
+                            ),
+                            _ => {
+                                workspace.dismiss_toast(
+                                    &NotificationId::unique::<CopilotStartingToast>(),
+                                    cx,
+                                );
+                                copilot
+                                    .update(cx, |copilot, cx| copilot.sign_in(cx))
+                                    .detach_and_log_err(cx);
+                            }
+                        })
+                        .log_err();
+                }
+            })
+            .detach();
+        }
+        _ => {
+            copilot.update(cx, |this, cx| this.sign_in(cx)).detach();
+            workspace
+                .update(cx, |this, cx| {
+                    this.toggle_modal(cx, |cx| CopilotCodeVerification::new(&copilot, cx));
+                })
+                .ok();
+        }
+    }
+}
+
 pub struct CopilotCodeVerification {
     status: Status,
     connect_clicked: bool,

crates/inline_completion_button/Cargo.toml 🔗

@@ -23,7 +23,6 @@ paths.workspace = true
 settings.workspace = true
 supermaven.workspace = true
 ui.workspace = true
-util.workspace = true
 workspace.workspace = true
 zed_actions.workspace = true
 

crates/inline_completion_button/src/inline_completion_button.rs 🔗

@@ -1,5 +1,5 @@
 use anyhow::Result;
-use copilot::{Copilot, CopilotCodeVerification, Status};
+use copilot::{Copilot, Status};
 use editor::{scroll::Autoscroll, Editor};
 use fs::Fs;
 use gpui::{
@@ -15,7 +15,6 @@ use language::{
 use settings::{update_settings_file, Settings, SettingsStore};
 use std::{path::Path, sync::Arc};
 use supermaven::{AccountStatus, Supermaven};
-use util::ResultExt;
 use workspace::{
     create_and_open_local_file,
     item::ItemHandle,
@@ -29,8 +28,6 @@ use zed_actions::OpenBrowser;
 
 const COPILOT_SETTINGS_URL: &str = "https://github.com/settings/copilot";
 
-struct CopilotStartingToast;
-
 struct CopilotErrorToast;
 
 pub struct InlineCompletionButton {
@@ -221,7 +218,7 @@ 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)
+            menu.entry("Sign In", None, copilot::initiate_sign_in)
                 .entry("Disable Copilot", None, {
                     let fs = fs.clone();
                     move |cx| hide_copilot(fs.clone(), cx)
@@ -484,68 +481,3 @@ fn hide_copilot(fs: Arc<dyn Fs>, cx: &mut AppContext) {
             .inline_completion_provider = Some(InlineCompletionProvider::None);
     });
 }
-
-pub fn initiate_sign_in(cx: &mut WindowContext) {
-    let Some(copilot) = Copilot::global(cx) else {
-        return;
-    };
-    let status = copilot.read(cx).status();
-    let Some(workspace) = cx.window_handle().downcast::<Workspace>() else {
-        return;
-    };
-    match status {
-        Status::Starting { task } => {
-            let Some(workspace) = cx.window_handle().downcast::<Workspace>() else {
-                return;
-            };
-
-            let Ok(workspace) = workspace.update(cx, |workspace, cx| {
-                workspace.show_toast(
-                    Toast::new(
-                        NotificationId::unique::<CopilotStartingToast>(),
-                        "Copilot is starting...",
-                    ),
-                    cx,
-                );
-                workspace.weak_handle()
-            }) else {
-                return;
-            };
-
-            cx.spawn(|mut cx| async move {
-                task.await;
-                if let Some(copilot) = cx.update(|cx| Copilot::global(cx)).ok().flatten() {
-                    workspace
-                        .update(&mut cx, |workspace, cx| match copilot.read(cx).status() {
-                            Status::Authorized => workspace.show_toast(
-                                Toast::new(
-                                    NotificationId::unique::<CopilotStartingToast>(),
-                                    "Copilot has started!",
-                                ),
-                                cx,
-                            ),
-                            _ => {
-                                workspace.dismiss_toast(
-                                    &NotificationId::unique::<CopilotStartingToast>(),
-                                    cx,
-                                );
-                                copilot
-                                    .update(cx, |copilot, cx| copilot.sign_in(cx))
-                                    .detach_and_log_err(cx);
-                            }
-                        })
-                        .log_err();
-                }
-            })
-            .detach();
-        }
-        _ => {
-            copilot.update(cx, |this, cx| this.sign_in(cx)).detach();
-            workspace
-                .update(cx, |this, cx| {
-                    this.toggle_modal(cx, |cx| CopilotCodeVerification::new(&copilot, cx));
-                })
-                .ok();
-        }
-    }
-}

crates/language_model/Cargo.toml 🔗

@@ -32,7 +32,6 @@ futures.workspace = true
 google_ai = { workspace = true, features = ["schemars"] }
 gpui.workspace = true
 http_client.workspace = true
-inline_completion_button.workspace = true
 log.workspace = true
 menu.workspace = true
 ollama = { workspace = true, features = ["schemars"] }

crates/language_model/src/provider/copilot_chat.rs 🔗

@@ -383,9 +383,7 @@ impl Render for ConfigurationView {
                                         .icon_size(IconSize::Medium)
                                         .style(ui::ButtonStyle::Filled)
                                         .full_width()
-                                        .on_click(|_, cx| {
-                                            inline_completion_button::initiate_sign_in(cx)
-                                        }),
+                                        .on_click(|_, cx| copilot::initiate_sign_in(cx)),
                                 )
                                 .child(
                                     div().flex().w_full().items_center().child(

crates/welcome/Cargo.toml 🔗

@@ -17,10 +17,10 @@ test-support = []
 [dependencies]
 anyhow.workspace = true
 client.workspace = true
+copilot.workspace = true
 db.workspace = true
 fuzzy.workspace = true
 gpui.workspace = true
-inline_completion_button.workspace = true
 install_cli.workspace = true
 picker.workspace = true
 project.workspace = true

crates/welcome/src/welcome.rs 🔗

@@ -177,7 +177,7 @@ impl Render for WelcomePage {
                                                 this.telemetry.report_app_event(
                                                     "welcome page: sign in to copilot".to_string(),
                                                 );
-                                                inline_completion_button::initiate_sign_in(cx);
+                                                copilot::initiate_sign_in(cx);
                                             }),
                                         ),
                                     )