WIP

Mikayla Maki created

Change summary

crates/copilot/src/copilot_button.rs | 298 ++++++++++++-----------------
crates/editor/src/editor.rs          |   4 
crates/zed/src/zed.rs                |   3 
3 files changed, 129 insertions(+), 176 deletions(-)

Detailed changes

crates/copilot/src/copilot_button.rs 🔗

@@ -1,172 +1,126 @@
-// use context_menu::{ContextMenu, ContextMenuItem};
-// use gpui::{
-//     elements::*, impl_internal_actions, CursorStyle, Element, ElementBox, Entity, MouseButton,
-//     MutableAppContext, RenderContext, View, ViewContext, ViewHandle, WeakModelHandle,
-//     WeakViewHandle,
-// };
-// use settings::Settings;
-// use std::any::TypeId;
-// use workspace::{dock::FocusDock, item::ItemHandle, NewTerminal, StatusItemView, Workspace};
-
-// #[derive(Clone, PartialEq)]
-// pub struct DeployTerminalMenu;
-
-// impl_internal_actions!(terminal, [DeployTerminalMenu]);
-
-// pub fn init(cx: &mut MutableAppContext) {
-//     cx.add_action(CopilotButton::deploy_terminal_menu);
-// }
-
-// pub struct CopilotButton {
-//     workspace: WeakViewHandle<Workspace>,
-//     popup_menu: ViewHandle<ContextMenu>,
-// }
-
-// impl Entity for CopilotButton {
-//     type Event = ();
-// }
-
-// impl View for CopilotButton {
-//     fn ui_name() -> &'static str {
-//         "TerminalButton"
-//     }
-
-//     fn render(&mut self, cx: &mut RenderContext<'_, Self>) -> ElementBox {
-//         let workspace = self.workspace.upgrade(cx);
-//         let project = match workspace {
-//             Some(workspace) => workspace.read(cx).project().read(cx),
-//             None => return Empty::new().boxed(),
-//         };
-
-//         let focused_view = cx.focused_view_id(cx.window_id());
-//         let active = focused_view
-//             .map(|view_id| {
-//                 cx.view_type_id(cx.window_id(), view_id) == Some(TypeId::of::<TerminalView>())
-//             })
-//             .unwrap_or(false);
-
-//         let has_terminals = !project.local_terminal_handles().is_empty();
-//         let terminal_count = project.local_terminal_handles().len() as i32;
-//         let theme = cx.global::<Settings>().theme.clone();
-
-//         Stack::new()
-//             .with_child(
-//                 MouseEventHandler::<Self>::new(0, cx, {
-//                     let theme = theme.clone();
-//                     move |state, _cx| {
-//                         let style = theme
-//                             .workspace
-//                             .status_bar
-//                             .sidebar_buttons
-//                             .item
-//                             .style_for(state, active);
-
-//                         Flex::row()
-//                             .with_child(
-//                                 Svg::new("icons/terminal_12.svg")
-//                                     .with_color(style.icon_color)
-//                                     .constrained()
-//                                     .with_width(style.icon_size)
-//                                     .aligned()
-//                                     .named("terminals-icon"),
-//                             )
-//                             .with_children(has_terminals.then(|| {
-//                                 Label::new(terminal_count.to_string(), style.label.text.clone())
-//                                     .contained()
-//                                     .with_style(style.label.container)
-//                                     .aligned()
-//                                     .boxed()
-//                             }))
-//                             .constrained()
-//                             .with_height(style.icon_size)
-//                             .contained()
-//                             .with_style(style.container)
-//                             .boxed()
-//                     }
-//                 })
-//                 .with_cursor_style(CursorStyle::PointingHand)
-//                 .on_click(MouseButton::Left, move |_, cx| {
-//                     if has_terminals {
-//                         cx.dispatch_action(DeployTerminalMenu);
-//                     } else {
-//                         if !active {
-//                             cx.dispatch_action(FocusDock);
-//                         }
-//                     };
-//                 })
-//                 .with_tooltip::<Self, _>(
-//                     0,
-//                     "Show Terminal".into(),
-//                     Some(Box::new(FocusDock)),
-//                     theme.tooltip.clone(),
-//                     cx,
-//                 )
-//                 .boxed(),
-//             )
-//             .with_child(
-//                 ChildView::new(&self.popup_menu, cx)
-//                     .aligned()
-//                     .top()
-//                     .right()
-//                     .boxed(),
-//             )
-//             .boxed()
-//     }
-// }
-
-// impl CopilotButton {
-//     pub fn new(workspace: ViewHandle<Workspace>, cx: &mut ViewContext<Self>) -> Self {
-//         cx.observe(&workspace, |_, _, cx| cx.notify()).detach();
-//         Self {
-//             workspace: workspace.downgrade(),
-//             popup_menu: cx.add_view(|cx| {
-//                 let mut menu = ContextMenu::new(cx);
-//                 menu.set_position_mode(OverlayPositionMode::Local);
-//                 menu
-//             }),
-//         }
-//     }
-
-//     pub fn deploy_terminal_menu(
-//         &mut self,
-//         _action: &DeployTerminalMenu,
-//         cx: &mut ViewContext<Self>,
-//     ) {
-//         let mut menu_options = vec![ContextMenuItem::item("New Terminal", NewTerminal)];
-
-//         if let Some(workspace) = self.workspace.upgrade(cx) {
-//             let project = workspace.read(cx).project().read(cx);
-//             let local_terminal_handles = project.local_terminal_handles();
-
-//             if !local_terminal_handles.is_empty() {
-//                 menu_options.push(ContextMenuItem::Separator)
-//             }
-
-//             for local_terminal_handle in local_terminal_handles {
-//                 if let Some(terminal) = local_terminal_handle.upgrade(cx) {
-//                     menu_options.push(ContextMenuItem::item(
-//                         terminal.read(cx).title(),
-//                         // FocusTerminal {
-//                         //     terminal_handle: local_terminal_handle.clone(),
-//                         // },
-//                     ))
-//                 }
-//             }
-//         }
-
-//         self.popup_menu.update(cx, |menu, cx| {
-//             menu.show(
-//                 Default::default(),
-//                 AnchorCorner::BottomRight,
-//                 menu_options,
-//                 cx,
-//             );
-//         });
-//     }
-// }
-
-// impl StatusItemView for CopilotButton {
-//     fn set_active_pane_item(&mut self, _: Option<&dyn ItemHandle>, cx: &mut ViewContext<Self>) {
-//         cx.notify();
-//     }
-// }
+use context_menu::{ContextMenu, ContextMenuItem};
+use gpui::{
+    elements::*, impl_internal_actions, CursorStyle, Element, ElementBox, Entity, MouseButton,
+    MutableAppContext, RenderContext, View, ViewContext, ViewHandle,
+};
+use settings::Settings;
+use workspace::{item::ItemHandle, NewTerminal, StatusItemView};
+
+const COPILOT_SETTINGS_URL: &str = "https://github.com/settings/copilot";
+
+#[derive(Clone, PartialEq)]
+pub struct DeployCopilotMenu;
+
+impl_internal_actions!(copilot, [DeployCopilotMenu]);
+
+pub fn init(cx: &mut MutableAppContext) {
+    cx.add_action(CopilotButton::deploy_copilot_menu);
+}
+
+pub struct CopilotButton {
+    popup_menu: ViewHandle<ContextMenu>,
+}
+
+impl Entity for CopilotButton {
+    type Event = ();
+}
+
+impl View for CopilotButton {
+    fn ui_name() -> &'static str {
+        "CopilotButton"
+    }
+
+    fn render(&mut self, cx: &mut RenderContext<'_, Self>) -> ElementBox {
+        let theme = cx.global::<Settings>().theme.clone();
+
+        let visible = self.popup_menu.read(cx).visible();
+
+        Stack::new()
+            .with_child(
+                MouseEventHandler::<Self>::new(0, cx, {
+                    let theme = theme.clone();
+                    move |state, _cx| {
+                        let style = theme
+                            .workspace
+                            .status_bar
+                            .sidebar_buttons
+                            .item
+                            .style_for(state, visible);
+
+                        Flex::row()
+                            .with_child(
+                                Svg::new("icons/maybe_copilot.svg")
+                                    .with_color(style.icon_color)
+                                    .constrained()
+                                    .with_width(style.icon_size)
+                                    .aligned()
+                                    .named("copilot-icon"),
+                            )
+                            .constrained()
+                            .with_height(style.icon_size)
+                            .contained()
+                            .with_style(style.container)
+                            .boxed()
+                    }
+                })
+                .with_cursor_style(CursorStyle::PointingHand)
+                .on_click(MouseButton::Left, move |_, _cx| {
+                    // TODO: Behavior of this
+                    // if has_terminals {
+                    //     cx.dispatch_action(DeployCopilotMenu);
+                    // } else {
+                    //     if !active {
+                    //         cx.dispatch_action(FocusDock);
+                    //     }
+                    // };
+                })
+                .with_tooltip::<Self, _>(
+                    0,
+                    "GitHub Copilot".into(),
+                    None,
+                    theme.tooltip.clone(),
+                    cx,
+                )
+                .boxed(),
+            )
+            .with_child(
+                ChildView::new(&self.popup_menu, cx)
+                    .aligned()
+                    .top()
+                    .right()
+                    .boxed(),
+            )
+            .boxed()
+    }
+}
+
+impl CopilotButton {
+    pub fn new(cx: &mut ViewContext<Self>) -> Self {
+        Self {
+            popup_menu: cx.add_view(|cx| {
+                let mut menu = ContextMenu::new(cx);
+                menu.set_position_mode(OverlayPositionMode::Local);
+                menu
+            }),
+        }
+    }
+
+    pub fn deploy_copilot_menu(&mut self, _: &DeployCopilotMenu, cx: &mut ViewContext<Self>) {
+        let mut menu_options = vec![ContextMenuItem::item("New Terminal", NewTerminal)];
+
+        self.popup_menu.update(cx, |menu, cx| {
+            menu.show(
+                Default::default(),
+                AnchorCorner::BottomRight,
+                menu_options,
+                cx,
+            );
+        });
+    }
+}
+
+impl StatusItemView for CopilotButton {
+    fn set_active_pane_item(&mut self, item: Option<&dyn ItemHandle>, cx: &mut ViewContext<Self>) {
+        cx.notify();
+    }
+}

crates/editor/src/editor.rs 🔗

@@ -2756,8 +2756,6 @@ impl Editor {
 
         let settings = cx.global::<Settings>();
 
-        dbg!(self.copilot_state.user_enabled);
-
         if !self
             .copilot_state
             .user_enabled
@@ -2776,8 +2774,6 @@ impl Editor {
 
             let copilot_enabled = settings.copilot_on(language_name.as_deref());
 
-            dbg!(language_name, copilot_enabled);
-
             if !copilot_enabled {
                 return None;
             }

crates/zed/src/zed.rs 🔗

@@ -8,6 +8,7 @@ use breadcrumbs::Breadcrumbs;
 pub use client;
 use collab_ui::{CollabTitlebarItem, ToggleContactsMenu};
 use collections::VecDeque;
+use copilot::copilot_button::CopilotButton;
 pub use editor;
 use editor::{Editor, MultiBuffer};
 
@@ -311,6 +312,7 @@ pub fn initialize_workspace(
     });
 
     let toggle_terminal = cx.add_view(|cx| TerminalButton::new(workspace_handle.clone(), cx));
+    let copilot = cx.add_view(|cx| CopilotButton::new(cx));
     let diagnostic_summary =
         cx.add_view(|cx| diagnostics::items::DiagnosticIndicator::new(workspace.project(), cx));
     let activity_indicator =
@@ -324,6 +326,7 @@ pub fn initialize_workspace(
         status_bar.add_left_item(activity_indicator, cx);
         status_bar.add_right_item(toggle_terminal, cx);
         status_bar.add_right_item(feedback_button, cx);
+        status_bar.add_right_item(copilot, cx);
         status_bar.add_right_item(active_buffer_language, cx);
         status_bar.add_right_item(cursor_position, cx);
     });