Start out Copilot2;

Piotr Osiewicz and Antonio created

Add hidden_action_types to CommandPaletteFilter.
WindowContext.available_actions now returns global actions as well.

Co-authored-by: Antonio <antonio@zed.dev>

Change summary

crates/collections/src/collections.rs          |   4 
crates/command_palette/src/command_palette.rs  |   4 
crates/command_palette2/src/command_palette.rs |   7 
crates/copilot/src/copilot.rs                  |  12 
crates/copilot2/src/copilot2.rs                | 119 ++-
crates/copilot2/src/sign_in.rs                 | 587 ++++++++++---------
crates/gpui2/src/window.rs                     |  12 
crates/vim/src/vim.rs                          |   6 
8 files changed, 391 insertions(+), 360 deletions(-)

Detailed changes

crates/collections/src/collections.rs 🔗

@@ -23,11 +23,13 @@ pub type HashMap<K, V> = std::collections::HashMap<K, V>;
 #[cfg(not(feature = "test-support"))]
 pub type HashSet<T> = std::collections::HashSet<T>;
 
+use std::any::TypeId;
 pub use std::collections::*;
 
 // NEW TYPES
 
 #[derive(Default)]
 pub struct CommandPaletteFilter {
-    pub filtered_namespaces: HashSet<&'static str>,
+    pub hidden_namespaces: HashSet<&'static str>,
+    pub hidden_action_types: HashSet<TypeId>,
 }

crates/command_palette/src/command_palette.rs 🔗

@@ -109,7 +109,7 @@ impl PickerDelegate for CommandPaletteDelegate {
                     let filtered = cx.read(|cx| {
                         if cx.has_global::<CommandPaletteFilter>() {
                             let filter = cx.global::<CommandPaletteFilter>();
-                            filter.filtered_namespaces.contains(action.namespace())
+                            filter.hidden_namespaces.contains(action.namespace())
                         } else {
                             false
                         }
@@ -430,7 +430,7 @@ mod tests {
         // Add namespace filter, and redeploy the palette
         cx.update(|cx| {
             cx.update_default_global::<CommandPaletteFilter, _, _>(|filter, _| {
-                filter.filtered_namespaces.insert("editor");
+                filter.hidden_namespaces.insert("editor");
             })
         });
 

crates/command_palette2/src/command_palette.rs 🔗

@@ -49,7 +49,10 @@ impl CommandPalette {
             .filter_map(|action| {
                 let name = gpui::remove_the_2(action.name());
                 let namespace = name.split("::").next().unwrap_or("malformed action name");
-                if filter.is_some_and(|f| f.filtered_namespaces.contains(namespace)) {
+                if filter.is_some_and(|f| {
+                    f.hidden_namespaces.contains(namespace)
+                        || f.hidden_action_types.contains(&action.type_id())
+                }) {
                     return None;
                 }
 
@@ -429,7 +432,7 @@ mod tests {
         cx.update(|cx| {
             cx.set_global(CommandPaletteFilter::default());
             cx.update_global::<CommandPaletteFilter, _>(|filter, _| {
-                filter.filtered_namespaces.insert("editor");
+                filter.hidden_namespaces.insert("editor");
             })
         });
 

crates/copilot/src/copilot.rs 🔗

@@ -58,16 +58,16 @@ pub fn init(
         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);
+                    filter.hidden_namespaces.insert(COPILOT_NAMESPACE);
+                    filter.hidden_namespaces.insert(COPILOT_AUTH_NAMESPACE);
                 }
                 Status::Authorized => {
-                    filter.filtered_namespaces.remove(COPILOT_NAMESPACE);
-                    filter.filtered_namespaces.remove(COPILOT_AUTH_NAMESPACE);
+                    filter.hidden_namespaces.remove(COPILOT_NAMESPACE);
+                    filter.hidden_namespaces.remove(COPILOT_AUTH_NAMESPACE);
                 }
                 _ => {
-                    filter.filtered_namespaces.insert(COPILOT_NAMESPACE);
-                    filter.filtered_namespaces.remove(COPILOT_AUTH_NAMESPACE);
+                    filter.hidden_namespaces.insert(COPILOT_NAMESPACE);
+                    filter.hidden_namespaces.remove(COPILOT_AUTH_NAMESPACE);
                 }
             }
         });

crates/copilot2/src/copilot2.rs 🔗

@@ -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 {

crates/copilot2/src/sign_in.rs 🔗

@@ -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 = ();

crates/gpui2/src/window.rs 🔗

@@ -1486,10 +1486,18 @@ impl<'a> WindowContext<'a> {
 
     pub fn available_actions(&self) -> Vec<Box<dyn Action>> {
         if let Some(focus_id) = self.window.focus {
-            self.window
+            let mut actions = self
+                .window
                 .current_frame
                 .dispatch_tree
-                .available_actions(focus_id)
+                .available_actions(focus_id);
+            actions.extend(
+                self.app
+                    .global_action_listeners
+                    .keys()
+                    .filter_map(|type_id| self.app.actions.build_action_type(type_id).ok()),
+            );
+            actions
         } else {
             Vec::new()
         }

crates/vim/src/vim.rs 🔗

@@ -101,7 +101,7 @@ pub fn init(cx: &mut AppContext) {
     // will be initialized as disabled by default, so we filter its commands
     // out when starting up.
     cx.update_default_global::<CommandPaletteFilter, _, _>(|filter, _| {
-        filter.filtered_namespaces.insert("vim");
+        filter.hidden_namespaces.insert("vim");
     });
     cx.update_global(|vim: &mut Vim, cx: &mut AppContext| {
         vim.set_enabled(settings::get::<VimModeSetting>(cx).0, cx)
@@ -477,9 +477,9 @@ impl Vim {
 
             cx.update_default_global::<CommandPaletteFilter, _, _>(|filter, _| {
                 if self.enabled {
-                    filter.filtered_namespaces.remove("vim");
+                    filter.hidden_namespaces.remove("vim");
                 } else {
-                    filter.filtered_namespaces.insert("vim");
+                    filter.hidden_namespaces.insert("vim");
                 }
             });