@@ -22,6 +22,7 @@ use request::StatusNotification;
use settings::SettingsStore;
use smol::{fs, io::BufReader, stream::StreamExt};
use std::{
+ any::TypeId,
ffi::OsString,
mem,
ops::Range,
@@ -32,13 +33,14 @@ use util::{
fs::remove_matching, github::latest_github_release, http::HttpClient, paths, ResultExt,
};
-// todo!()
-// const COPILOT_AUTH_NAMESPACE: &'static str = "copilot_auth";
-actions!(SignIn, SignOut);
-
-// todo!()
-// const COPILOT_NAMESPACE: &'static str = "copilot";
-actions!(Suggest, NextSuggestion, PreviousSuggestion, Reinstall);
+actions!(
+ Suggest,
+ NextSuggestion,
+ PreviousSuggestion,
+ Reinstall,
+ SignIn,
+ SignOut
+);
pub fn init(
new_server_id: LanguageServerId,
@@ -51,52 +53,63 @@ pub fn init(
move |cx| Copilot::start(new_server_id, http, node_runtime, cx)
});
cx.set_global(copilot.clone());
-
- // TODO
- // cx.observe(&copilot, |handle, cx| {
- // let status = handle.read(cx).status();
- // cx.update_default_global::<collections::CommandPaletteFilter, _, _>(move |filter, _cx| {
- // match status {
- // Status::Disabled => {
- // filter.filtered_namespaces.insert(COPILOT_NAMESPACE);
- // filter.filtered_namespaces.insert(COPILOT_AUTH_NAMESPACE);
- // }
- // Status::Authorized => {
- // filter.filtered_namespaces.remove(COPILOT_NAMESPACE);
- // filter.filtered_namespaces.remove(COPILOT_AUTH_NAMESPACE);
- // }
- // _ => {
- // filter.filtered_namespaces.insert(COPILOT_NAMESPACE);
- // filter.filtered_namespaces.remove(COPILOT_AUTH_NAMESPACE);
- // }
- // }
- // });
- // })
- // .detach();
-
- // sign_in::init(cx);
- // cx.add_global_action(|_: &SignIn, cx| {
- // if let Some(copilot) = Copilot::global(cx) {
- // copilot
- // .update(cx, |copilot, cx| copilot.sign_in(cx))
- // .detach_and_log_err(cx);
- // }
- // });
- // cx.add_global_action(|_: &SignOut, cx| {
- // if let Some(copilot) = Copilot::global(cx) {
- // copilot
- // .update(cx, |copilot, cx| copilot.sign_out(cx))
- // .detach_and_log_err(cx);
- // }
- // });
-
- // cx.add_global_action(|_: &Reinstall, cx| {
- // if let Some(copilot) = Copilot::global(cx) {
- // copilot
- // .update(cx, |copilot, cx| copilot.reinstall(cx))
- // .detach();
- // }
- // });
+ cx.observe(&copilot, |handle, cx| {
+ let copilot_action_types = [
+ TypeId::of::<Suggest>(),
+ TypeId::of::<NextSuggestion>(),
+ TypeId::of::<PreviousSuggestion>(),
+ TypeId::of::<Reinstall>(),
+ ];
+ let copilot_auth_action_types = [TypeId::of::<SignIn>(), TypeId::of::<SignOut>()];
+
+ let status = handle.read(cx).status();
+ let filter = cx.default_global::<collections::CommandPaletteFilter>();
+
+ match status {
+ Status::Disabled => {
+ filter.hidden_action_types.extend(copilot_action_types);
+ filter.hidden_action_types.extend(copilot_auth_action_types);
+ }
+ Status::Authorized => {
+ for type_id in copilot_action_types
+ .iter()
+ .chain(&copilot_auth_action_types)
+ {
+ filter.hidden_action_types.remove(type_id);
+ }
+ }
+ _ => {
+ filter.hidden_action_types.extend(copilot_action_types);
+ for type_id in &copilot_auth_action_types {
+ filter.hidden_action_types.remove(type_id);
+ }
+ }
+ }
+ })
+ .detach();
+
+ sign_in::init(cx);
+ cx.on_action(|_: &SignIn, cx| {
+ if let Some(copilot) = Copilot::global(cx) {
+ copilot
+ .update(cx, |copilot, cx| copilot.sign_in(cx))
+ .detach_and_log_err(cx);
+ }
+ });
+ cx.on_action(|_: &SignOut, cx| {
+ if let Some(copilot) = Copilot::global(cx) {
+ copilot
+ .update(cx, |copilot, cx| copilot.sign_out(cx))
+ .detach_and_log_err(cx);
+ }
+ });
+ cx.on_action(|_: &Reinstall, cx| {
+ if let Some(copilot) = Copilot::global(cx) {
+ copilot
+ .update(cx, |copilot, cx| copilot.reinstall(cx))
+ .detach();
+ }
+ });
}
enum CopilotServer {
@@ -9,314 +9,319 @@
// };
// use theme::ui::modal;
-// #[derive(PartialEq, Eq, Debug, Clone)]
-// struct CopyUserCode;
+const COPILOT_SIGN_UP_URL: &'static str = "https://github.com/features/copilot";
-// #[derive(PartialEq, Eq, Debug, Clone)]
-// struct OpenGithub;
+use crate::{Copilot, Status};
+use gpui::{
+ px, size, AppContext, Bounds, Div, GlobalPixels, Point, Render, ViewContext, VisualContext,
+ WindowBounds, WindowHandle, WindowKind, WindowOptions,
+};
-// const COPILOT_SIGN_UP_URL: &'static str = "https://github.com/features/copilot";
+pub fn init(cx: &mut AppContext) {
+ if let Some(copilot) = Copilot::global(cx) {
+ let mut verification_window: Option<WindowHandle<CopilotCodeVerification>> = None;
+ cx.observe(&copilot, move |copilot, cx| {
+ let status = copilot.read(cx).status();
-// pub fn init(cx: &mut AppContext) {
-// if let Some(copilot) = Copilot::global(cx) {
-// let mut verification_window: Option<WindowHandle<CopilotCodeVerification>> = None;
-// cx.observe(&copilot, move |copilot, cx| {
-// let status = copilot.read(cx).status();
+ match &status {
+ crate::Status::SigningIn { prompt } => {
+ if let Some(window) = verification_window.as_mut() {
+ let updated = window
+ .update(cx, |verification, cx| {
+ verification.set_status(status.clone(), cx);
+ cx.activate_window();
+ })
+ .is_ok();
+ if !updated {
+ verification_window = Some(create_copilot_auth_window(cx, &status));
+ }
+ } else if let Some(_prompt) = prompt {
+ verification_window = Some(create_copilot_auth_window(cx, &status));
+ }
+ }
+ Status::Authorized | Status::Unauthorized => {
+ if let Some(window) = verification_window.as_ref() {
+ window
+ .update(cx, |verification, cx| {
+ verification.set_status(status, cx);
+ cx.activate(true);
+ cx.activate_window();
+ })
+ .ok();
+ }
+ }
+ _ => {
+ if let Some(code_verification) = verification_window.take() {
+ code_verification.update(cx, |_, cx| cx.remove_window());
+ }
+ }
+ }
+ })
+ .detach();
+ }
+}
-// match &status {
-// crate::Status::SigningIn { prompt } => {
-// if let Some(window) = verification_window.as_mut() {
-// let updated = window
-// .root(cx)
-// .map(|root| {
-// root.update(cx, |verification, cx| {
-// verification.set_status(status.clone(), cx);
-// cx.activate_window();
-// })
-// })
-// .is_some();
-// if !updated {
-// verification_window = Some(create_copilot_auth_window(cx, &status));
-// }
-// } else if let Some(_prompt) = prompt {
-// verification_window = Some(create_copilot_auth_window(cx, &status));
-// }
-// }
-// Status::Authorized | Status::Unauthorized => {
-// if let Some(window) = verification_window.as_ref() {
-// if let Some(verification) = window.root(cx) {
-// verification.update(cx, |verification, cx| {
-// verification.set_status(status, cx);
-// cx.platform().activate(true);
-// cx.activate_window();
-// });
-// }
-// }
-// }
-// _ => {
-// if let Some(code_verification) = verification_window.take() {
-// code_verification.update(cx, |cx| cx.remove_window());
-// }
-// }
-// }
-// })
-// .detach();
-// }
-// }
+fn create_copilot_auth_window(
+ cx: &mut AppContext,
+ status: &Status,
+) -> WindowHandle<CopilotCodeVerification> {
+ let window_size = size(GlobalPixels::from(280.), GlobalPixels::from(280.));
+ let window_options = WindowOptions {
+ bounds: WindowBounds::Fixed(Bounds::new(Point::default(), window_size)),
+ titlebar: None,
+ center: true,
+ focus: true,
+ show: true,
+ kind: WindowKind::Normal,
+ is_movable: true,
+ display_id: None,
+ };
+ cx.open_window(window_options, |cx| {
+ cx.build_view(|_| CopilotCodeVerification::new(status.clone()))
+ })
+}
-// fn create_copilot_auth_window(
-// cx: &mut AppContext,
-// status: &Status,
-// ) -> WindowHandle<CopilotCodeVerification> {
-// let window_size = theme::current(cx).copilot.modal.dimensions();
-// let window_options = WindowOptions {
-// bounds: WindowBounds::Fixed(RectF::new(Default::default(), window_size)),
-// titlebar: None,
-// center: true,
-// focus: true,
-// show: true,
-// kind: WindowKind::Normal,
-// is_movable: true,
-// screen: None,
-// };
-// cx.add_window(window_options, |_cx| {
-// CopilotCodeVerification::new(status.clone())
-// })
-// }
+pub struct CopilotCodeVerification {
+ status: Status,
+ connect_clicked: bool,
+}
-// pub struct CopilotCodeVerification {
-// status: Status,
-// connect_clicked: bool,
-// }
+impl CopilotCodeVerification {
+ pub fn new(status: Status) -> Self {
+ Self {
+ status,
+ connect_clicked: false,
+ }
+ }
-// impl CopilotCodeVerification {
-// pub fn new(status: Status) -> Self {
-// Self {
-// status,
-// connect_clicked: false,
-// }
-// }
+ pub fn set_status(&mut self, status: Status, cx: &mut ViewContext<Self>) {
+ self.status = status;
+ cx.notify();
+ }
-// pub fn set_status(&mut self, status: Status, cx: &mut ViewContext<Self>) {
-// self.status = status;
-// cx.notify();
-// }
+ // fn render_device_code(
+ // data: &PromptUserDeviceFlow,
+ // style: &theme::Copilot,
+ // cx: &mut ViewContext<Self>,
+ // ) -> impl IntoAnyElement<Self> {
+ // let copied = cx
+ // .read_from_clipboard()
+ // .map(|item| item.text() == &data.user_code)
+ // .unwrap_or(false);
-// fn render_device_code(
-// data: &PromptUserDeviceFlow,
-// style: &theme::Copilot,
-// cx: &mut ViewContext<Self>,
-// ) -> impl IntoAnyElement<Self> {
-// let copied = cx
-// .read_from_clipboard()
-// .map(|item| item.text() == &data.user_code)
-// .unwrap_or(false);
+ // let device_code_style = &style.auth.prompting.device_code;
-// let device_code_style = &style.auth.prompting.device_code;
+ // MouseEventHandler::new::<Self, _>(0, cx, |state, _cx| {
+ // Flex::row()
+ // .with_child(
+ // Label::new(data.user_code.clone(), device_code_style.text.clone())
+ // .aligned()
+ // .contained()
+ // .with_style(device_code_style.left_container)
+ // .constrained()
+ // .with_width(device_code_style.left),
+ // )
+ // .with_child(
+ // Label::new(
+ // if copied { "Copied!" } else { "Copy" },
+ // device_code_style.cta.style_for(state).text.clone(),
+ // )
+ // .aligned()
+ // .contained()
+ // .with_style(*device_code_style.right_container.style_for(state))
+ // .constrained()
+ // .with_width(device_code_style.right),
+ // )
+ // .contained()
+ // .with_style(device_code_style.cta.style_for(state).container)
+ // })
+ // .on_click(gpui::platform::MouseButton::Left, {
+ // let user_code = data.user_code.clone();
+ // move |_, _, cx| {
+ // cx.platform()
+ // .write_to_clipboard(ClipboardItem::new(user_code.clone()));
+ // cx.notify();
+ // }
+ // })
+ // .with_cursor_style(gpui::platform::CursorStyle::PointingHand)
+ // }
-// MouseEventHandler::new::<Self, _>(0, cx, |state, _cx| {
-// Flex::row()
-// .with_child(
-// Label::new(data.user_code.clone(), device_code_style.text.clone())
-// .aligned()
-// .contained()
-// .with_style(device_code_style.left_container)
-// .constrained()
-// .with_width(device_code_style.left),
-// )
-// .with_child(
-// Label::new(
-// if copied { "Copied!" } else { "Copy" },
-// device_code_style.cta.style_for(state).text.clone(),
-// )
-// .aligned()
-// .contained()
-// .with_style(*device_code_style.right_container.style_for(state))
-// .constrained()
-// .with_width(device_code_style.right),
-// )
-// .contained()
-// .with_style(device_code_style.cta.style_for(state).container)
-// })
-// .on_click(gpui::platform::MouseButton::Left, {
-// let user_code = data.user_code.clone();
-// move |_, _, cx| {
-// cx.platform()
-// .write_to_clipboard(ClipboardItem::new(user_code.clone()));
-// cx.notify();
-// }
-// })
-// .with_cursor_style(gpui::platform::CursorStyle::PointingHand)
-// }
+ // fn render_prompting_modal(
+ // connect_clicked: bool,
+ // data: &PromptUserDeviceFlow,
+ // style: &theme::Copilot,
+ // cx: &mut ViewContext<Self>,
+ // ) -> AnyElement<Self> {
+ // enum ConnectButton {}
-// fn render_prompting_modal(
-// connect_clicked: bool,
-// data: &PromptUserDeviceFlow,
-// style: &theme::Copilot,
-// cx: &mut ViewContext<Self>,
-// ) -> AnyElement<Self> {
-// enum ConnectButton {}
+ // Flex::column()
+ // .with_child(
+ // Flex::column()
+ // .with_children([
+ // Label::new(
+ // "Enable Copilot by connecting",
+ // style.auth.prompting.subheading.text.clone(),
+ // )
+ // .aligned(),
+ // Label::new(
+ // "your existing license.",
+ // style.auth.prompting.subheading.text.clone(),
+ // )
+ // .aligned(),
+ // ])
+ // .align_children_center()
+ // .contained()
+ // .with_style(style.auth.prompting.subheading.container),
+ // )
+ // .with_child(Self::render_device_code(data, &style, cx))
+ // .with_child(
+ // Flex::column()
+ // .with_children([
+ // Label::new(
+ // "Paste this code into GitHub after",
+ // style.auth.prompting.hint.text.clone(),
+ // )
+ // .aligned(),
+ // Label::new(
+ // "clicking the button below.",
+ // style.auth.prompting.hint.text.clone(),
+ // )
+ // .aligned(),
+ // ])
+ // .align_children_center()
+ // .contained()
+ // .with_style(style.auth.prompting.hint.container.clone()),
+ // )
+ // .with_child(theme::ui::cta_button::<ConnectButton, _, _, _>(
+ // if connect_clicked {
+ // "Waiting for connection..."
+ // } else {
+ // "Connect to GitHub"
+ // },
+ // style.auth.content_width,
+ // &style.auth.cta_button,
+ // cx,
+ // {
+ // let verification_uri = data.verification_uri.clone();
+ // move |_, verification, cx| {
+ // cx.platform().open_url(&verification_uri);
+ // verification.connect_clicked = true;
+ // }
+ // },
+ // ))
+ // .align_children_center()
+ // .into_any()
+ // }
-// Flex::column()
-// .with_child(
-// Flex::column()
-// .with_children([
-// Label::new(
-// "Enable Copilot by connecting",
-// style.auth.prompting.subheading.text.clone(),
-// )
-// .aligned(),
-// Label::new(
-// "your existing license.",
-// style.auth.prompting.subheading.text.clone(),
-// )
-// .aligned(),
-// ])
-// .align_children_center()
-// .contained()
-// .with_style(style.auth.prompting.subheading.container),
-// )
-// .with_child(Self::render_device_code(data, &style, cx))
-// .with_child(
-// Flex::column()
-// .with_children([
-// Label::new(
-// "Paste this code into GitHub after",
-// style.auth.prompting.hint.text.clone(),
-// )
-// .aligned(),
-// Label::new(
-// "clicking the button below.",
-// style.auth.prompting.hint.text.clone(),
-// )
-// .aligned(),
-// ])
-// .align_children_center()
-// .contained()
-// .with_style(style.auth.prompting.hint.container.clone()),
-// )
-// .with_child(theme::ui::cta_button::<ConnectButton, _, _, _>(
-// if connect_clicked {
-// "Waiting for connection..."
-// } else {
-// "Connect to GitHub"
-// },
-// style.auth.content_width,
-// &style.auth.cta_button,
-// cx,
-// {
-// let verification_uri = data.verification_uri.clone();
-// move |_, verification, cx| {
-// cx.platform().open_url(&verification_uri);
-// verification.connect_clicked = true;
-// }
-// },
-// ))
-// .align_children_center()
-// .into_any()
-// }
+ // fn render_enabled_modal(
+ // style: &theme::Copilot,
+ // cx: &mut ViewContext<Self>,
+ // ) -> AnyElement<Self> {
+ // enum DoneButton {}
-// fn render_enabled_modal(
-// style: &theme::Copilot,
-// cx: &mut ViewContext<Self>,
-// ) -> AnyElement<Self> {
-// enum DoneButton {}
+ // let enabled_style = &style.auth.authorized;
+ // Flex::column()
+ // .with_child(
+ // Label::new("Copilot Enabled!", enabled_style.subheading.text.clone())
+ // .contained()
+ // .with_style(enabled_style.subheading.container)
+ // .aligned(),
+ // )
+ // .with_child(
+ // Flex::column()
+ // .with_children([
+ // Label::new(
+ // "You can update your settings or",
+ // enabled_style.hint.text.clone(),
+ // )
+ // .aligned(),
+ // Label::new(
+ // "sign out from the Copilot menu in",
+ // enabled_style.hint.text.clone(),
+ // )
+ // .aligned(),
+ // Label::new("the status bar.", enabled_style.hint.text.clone()).aligned(),
+ // ])
+ // .align_children_center()
+ // .contained()
+ // .with_style(enabled_style.hint.container),
+ // )
+ // .with_child(theme::ui::cta_button::<DoneButton, _, _, _>(
+ // "Done",
+ // style.auth.content_width,
+ // &style.auth.cta_button,
+ // cx,
+ // |_, _, cx| cx.remove_window(),
+ // ))
+ // .align_children_center()
+ // .into_any()
+ // }
-// let enabled_style = &style.auth.authorized;
-// Flex::column()
-// .with_child(
-// Label::new("Copilot Enabled!", enabled_style.subheading.text.clone())
-// .contained()
-// .with_style(enabled_style.subheading.container)
-// .aligned(),
-// )
-// .with_child(
-// Flex::column()
-// .with_children([
-// Label::new(
-// "You can update your settings or",
-// enabled_style.hint.text.clone(),
-// )
-// .aligned(),
-// Label::new(
-// "sign out from the Copilot menu in",
-// enabled_style.hint.text.clone(),
-// )
-// .aligned(),
-// Label::new("the status bar.", enabled_style.hint.text.clone()).aligned(),
-// ])
-// .align_children_center()
-// .contained()
-// .with_style(enabled_style.hint.container),
-// )
-// .with_child(theme::ui::cta_button::<DoneButton, _, _, _>(
-// "Done",
-// style.auth.content_width,
-// &style.auth.cta_button,
-// cx,
-// |_, _, cx| cx.remove_window(),
-// ))
-// .align_children_center()
-// .into_any()
-// }
+ // fn render_unauthorized_modal(
+ // style: &theme::Copilot,
+ // cx: &mut ViewContext<Self>,
+ // ) -> AnyElement<Self> {
+ // let unauthorized_style = &style.auth.not_authorized;
-// fn render_unauthorized_modal(
-// style: &theme::Copilot,
-// cx: &mut ViewContext<Self>,
-// ) -> AnyElement<Self> {
-// let unauthorized_style = &style.auth.not_authorized;
+ // Flex::column()
+ // .with_child(
+ // Flex::column()
+ // .with_children([
+ // Label::new(
+ // "Enable Copilot by connecting",
+ // unauthorized_style.subheading.text.clone(),
+ // )
+ // .aligned(),
+ // Label::new(
+ // "your existing license.",
+ // unauthorized_style.subheading.text.clone(),
+ // )
+ // .aligned(),
+ // ])
+ // .align_children_center()
+ // .contained()
+ // .with_style(unauthorized_style.subheading.container),
+ // )
+ // .with_child(
+ // Flex::column()
+ // .with_children([
+ // Label::new(
+ // "You must have an active copilot",
+ // unauthorized_style.warning.text.clone(),
+ // )
+ // .aligned(),
+ // Label::new(
+ // "license to use it in Zed.",
+ // unauthorized_style.warning.text.clone(),
+ // )
+ // .aligned(),
+ // ])
+ // .align_children_center()
+ // .contained()
+ // .with_style(unauthorized_style.warning.container),
+ // )
+ // .with_child(theme::ui::cta_button::<Self, _, _, _>(
+ // "Subscribe on GitHub",
+ // style.auth.content_width,
+ // &style.auth.cta_button,
+ // cx,
+ // |_, _, cx| {
+ // cx.remove_window();
+ // cx.platform().open_url(COPILOT_SIGN_UP_URL)
+ // },
+ // ))
+ // .align_children_center()
+ // .into_any()
+ // }
+}
-// Flex::column()
-// .with_child(
-// Flex::column()
-// .with_children([
-// Label::new(
-// "Enable Copilot by connecting",
-// unauthorized_style.subheading.text.clone(),
-// )
-// .aligned(),
-// Label::new(
-// "your existing license.",
-// unauthorized_style.subheading.text.clone(),
-// )
-// .aligned(),
-// ])
-// .align_children_center()
-// .contained()
-// .with_style(unauthorized_style.subheading.container),
-// )
-// .with_child(
-// Flex::column()
-// .with_children([
-// Label::new(
-// "You must have an active copilot",
-// unauthorized_style.warning.text.clone(),
-// )
-// .aligned(),
-// Label::new(
-// "license to use it in Zed.",
-// unauthorized_style.warning.text.clone(),
-// )
-// .aligned(),
-// ])
-// .align_children_center()
-// .contained()
-// .with_style(unauthorized_style.warning.container),
-// )
-// .with_child(theme::ui::cta_button::<Self, _, _, _>(
-// "Subscribe on GitHub",
-// style.auth.content_width,
-// &style.auth.cta_button,
-// cx,
-// |_, _, cx| {
-// cx.remove_window();
-// cx.platform().open_url(COPILOT_SIGN_UP_URL)
-// },
-// ))
-// .align_children_center()
-// .into_any()
-// }
-// }
+impl Render for CopilotCodeVerification {
+ type Element = Div;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+ todo!()
+ }
+}
// impl Entity for CopilotCodeVerification {
// type Event = ();