From 5aae3bdc695356a9d1119e4590e51d84b3be1afc Mon Sep 17 00:00:00 2001 From: Smit Barmase Date: Sun, 9 Mar 2025 16:09:14 +0000 Subject: [PATCH] copilot: Fix missing sign-out button when Zed is the edit prediction provider (#26340) Closes #25884 Added a sign-out button for Copilot in Assistant settings, allowing sign-out even when copilot is disabled. image Release Notes: - Added a sign-out button for Copilot in Assistant settings. --- crates/copilot/src/copilot.rs | 27 ++++++++++++------- crates/copilot/src/copilot_chat.rs | 2 +- .../src/provider/copilot_chat.rs | 21 +++++++++++---- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/crates/copilot/src/copilot.rs b/crates/copilot/src/copilot.rs index 1bc2de21f8..11c1ee83d8 100644 --- a/crates/copilot/src/copilot.rs +++ b/crates/copilot/src/copilot.rs @@ -623,16 +623,21 @@ impl Copilot { pub fn sign_out(&mut self, cx: &mut Context) -> Task> { self.update_sign_in_status(request::SignInStatus::NotSignedIn, cx); - if let CopilotServer::Running(RunningCopilotServer { lsp: server, .. }) = &self.server { - let server = server.clone(); - cx.background_spawn(async move { - server - .request::(request::SignOutParams {}) - .await?; + match &self.server { + CopilotServer::Running(RunningCopilotServer { lsp: server, .. }) => { + let server = server.clone(); + cx.background_spawn(async move { + server + .request::(request::SignOutParams {}) + .await?; + anyhow::Ok(()) + }) + } + CopilotServer::Disabled => cx.background_spawn(async move { + clear_copilot_config_dir().await; anyhow::Ok(()) - }) - } else { - Task::ready(Err(anyhow!("copilot hasn't started yet"))) + }), + _ => Task::ready(Err(anyhow!("copilot hasn't started yet"))), } } @@ -1016,6 +1021,10 @@ async fn clear_copilot_dir() { remove_matching(paths::copilot_dir(), |_| true).await } +async fn clear_copilot_config_dir() { + remove_matching(copilot_chat::copilot_chat_config_dir(), |_| true).await +} + async fn get_copilot_lsp(http: Arc) -> anyhow::Result { const SERVER_PATH: &str = "dist/language-server.js"; diff --git a/crates/copilot/src/copilot_chat.rs b/crates/copilot/src/copilot_chat.rs index 90e164e38b..bccdfd9cc9 100644 --- a/crates/copilot/src/copilot_chat.rs +++ b/crates/copilot/src/copilot_chat.rs @@ -213,7 +213,7 @@ pub fn init(fs: Arc, client: Arc, cx: &mut App) { cx.set_global(GlobalCopilotChat(copilot_chat)); } -fn copilot_chat_config_dir() -> &'static PathBuf { +pub fn copilot_chat_config_dir() -> &'static PathBuf { static COPILOT_CHAT_CONFIG_DIR: OnceLock = OnceLock::new(); COPILOT_CHAT_CONFIG_DIR.get_or_init(|| { diff --git a/crates/language_models/src/provider/copilot_chat.rs b/crates/language_models/src/provider/copilot_chat.rs index 631427cd11..c680cf78e7 100644 --- a/crates/language_models/src/provider/copilot_chat.rs +++ b/crates/language_models/src/provider/copilot_chat.rs @@ -11,8 +11,8 @@ use futures::future::BoxFuture; use futures::stream::BoxStream; use futures::{FutureExt, StreamExt}; use gpui::{ - percentage, svg, Animation, AnimationExt, AnyView, App, AsyncApp, Entity, Render, Subscription, - Task, Transformation, + percentage, svg, Action, Animation, AnimationExt, AnyView, App, AsyncApp, Entity, Render, + Subscription, Task, Transformation, }; use language_model::{ AuthenticateError, LanguageModel, LanguageModelCompletionEvent, LanguageModelId, @@ -337,9 +337,20 @@ impl Render for ConfigurationView { if self.state.read(cx).is_authenticated(cx) { const LABEL: &str = "Authorized."; h_flex() - .gap_1() - .child(Icon::new(IconName::Check).color(Color::Success)) - .child(Label::new(LABEL)) + .justify_between() + .child( + h_flex() + .gap_1() + .child(Icon::new(IconName::Check).color(Color::Success)) + .child(Label::new(LABEL)), + ) + .child( + Button::new("sign_out", "Sign Out") + .style(ui::ButtonStyle::Filled) + .on_click(|_, window, cx| { + window.dispatch_action(copilot::SignOut.boxed_clone(), cx); + }), + ) } else { let loading_icon = svg() .size_8()