Remove 2 suffix from gpui_macros, fix compile errors in tests

Max Brunsfeld and Mikayla created

Co-authored-by: Mikayla <mikayla@zed.dev>

Change summary

.cargo/config.toml                            |   3 
Cargo.lock                                    |  56 --
Cargo.toml                                    |   6 
crates/collab_ui/src/face_pile.rs             |   2 
crates/component_test/Cargo.toml              |  18 
crates/component_test/src/component_test.rs   | 121 ----
crates/context_menu/Cargo.toml                |  16 
crates/context_menu/src/context_menu.rs       | 528 ---------------------
crates/drag_and_drop/Cargo.toml               |  16 
crates/drag_and_drop/src/drag_and_drop.rs     | 378 ---------------
crates/gpui/Cargo.toml                        |   2 
crates/gpui/src/gpui.rs                       |   2 
crates/gpui/src/styled.rs                     |   2 
crates/gpui/tests/action_macros.rs            |   6 
crates/gpui2_macros/Cargo.toml                |  14 
crates/gpui2_macros/src/gpui2_macros.rs       |  32 -
crates/gpui_macros/Cargo.toml                 |   8 
crates/gpui_macros/src/derive_into_element.rs |   2 
crates/gpui_macros/src/derive_render.rs       |   2 
crates/gpui_macros/src/gpui_macros.rs         | 393 --------------
crates/gpui_macros/src/register_action.rs     |   0 
crates/gpui_macros/src/style_helpers.rs       |   0 
crates/gpui_macros/src/test.rs                |   0 
crates/rpc/src/peer.rs                        |  55 +-
crates/storybook/Cargo.toml                   |   1 
crates/ui/src/components/popover.rs           |   3 
crates/xtask/Cargo.toml                       |  13 
crates/xtask/src/cli.rs                       |  23 
crates/xtask/src/main.rs                      |  29 -
29 files changed, 66 insertions(+), 1,665 deletions(-)

Detailed changes

.cargo/config.toml 🔗

@@ -1,6 +1,3 @@
-[alias]
-xtask = "run --package xtask --"
-
 [build]
 # v0 mangling scheme provides more detailed backtraces around closures
 rustflags = ["-C", "symbol-mangling-version=v0"]

Cargo.lock 🔗

@@ -1618,19 +1618,6 @@ dependencies = [
  "zed_actions",
 ]
 
-[[package]]
-name = "component_test"
-version = "0.1.0"
-dependencies = [
- "anyhow",
- "gpui",
- "project",
- "settings",
- "theme",
- "util",
- "workspace",
-]
-
 [[package]]
 name = "concurrent-queue"
 version = "2.2.0"
@@ -1665,17 +1652,6 @@ version = "0.9.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f"
 
-[[package]]
-name = "context_menu"
-version = "0.1.0"
-dependencies = [
- "gpui",
- "menu",
- "settings",
- "smallvec",
- "theme",
-]
-
 [[package]]
 name = "convert_case"
 version = "0.4.0"
@@ -2354,14 +2330,6 @@ version = "0.15.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
 
-[[package]]
-name = "drag_and_drop"
-version = "0.1.0"
-dependencies = [
- "collections",
- "gpui",
-]
-
 [[package]]
 name = "dwrote"
 version = "0.11.0"
@@ -3185,7 +3153,7 @@ dependencies = [
  "font-kit",
  "foreign-types",
  "futures 0.3.28",
- "gpui2_macros",
+ "gpui_macros",
  "image",
  "itertools 0.10.5",
  "lazy_static",
@@ -3225,20 +3193,10 @@ dependencies = [
  "waker-fn",
 ]
 
-[[package]]
-name = "gpui2_macros"
-version = "0.1.0"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 1.0.109",
-]
-
 [[package]]
 name = "gpui_macros"
 version = "0.1.0"
 dependencies = [
- "lazy_static",
  "proc-macro2",
  "quote",
  "syn 1.0.109",
@@ -7677,6 +7635,7 @@ dependencies = [
  "story",
  "strum",
  "theme",
+ "ui",
  "util",
 ]
 
@@ -9936,17 +9895,6 @@ version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9"
 
-[[package]]
-name = "xtask"
-version = "0.1.0"
-dependencies = [
- "anyhow",
- "clap 4.4.4",
- "schemars",
- "serde_json",
- "theme",
-]
-
 [[package]]
 name = "yaml-rust"
 version = "0.4.5"

Cargo.toml 🔗

@@ -15,15 +15,12 @@ members = [
     "crates/collab_ui",
     "crates/collections",
     "crates/command_palette",
-    "crates/component_test",
-    "crates/context_menu",
     "crates/copilot",
     "crates/copilot_button",
     "crates/db",
     "crates/refineable",
     "crates/refineable/derive_refineable",
     "crates/diagnostics",
-    "crates/drag_and_drop",
     "crates/editor",
     "crates/feature_flags",
     "crates/feedback",
@@ -36,7 +33,7 @@ members = [
     "crates/gpui",
     "crates/gpui_macros",
     "crates/gpui",
-    "crates/gpui2_macros",
+    "crates/gpui_macros",
     "crates/install_cli",
     "crates/journal",
     "crates/journal",
@@ -85,7 +82,6 @@ members = [
     "crates/vcs_menu",
     "crates/workspace",
     "crates/welcome",
-    "crates/xtask",
     "crates/zed",
     "crates/zed_actions",
 ]

crates/collab_ui/src/face_pile.rs 🔗

@@ -1,5 +1,5 @@
 use gpui::{
-    div, AnyElement, ElementId, IntoElement, ParentElement, RenderOnce, Styled, WindowContext,
+    div, AnyElement, IntoElement, ParentElement, RenderOnce, Styled, WindowContext,
 };
 use smallvec::SmallVec;
 

crates/component_test/Cargo.toml 🔗

@@ -1,18 +0,0 @@
-[package]
-name = "component_test"
-version = "0.1.0"
-edition = "2021"
-publish = false
-
-[lib]
-path = "src/component_test.rs"
-doctest = false
-
-[dependencies]
-anyhow.workspace = true
-gpui = { path = "../gpui" }
-settings = { path = "../settings" }
-util = { path = "../util" }
-theme = { path = "../theme" }
-workspace = { path = "../workspace" }
-project = { path = "../project" }

crates/component_test/src/component_test.rs 🔗

@@ -1,121 +0,0 @@
-use gpui::{
-    actions,
-    elements::{Component, Flex, ParentElement, SafeStylable},
-    AppContext, Element, Entity, ModelHandle, Task, View, ViewContext, ViewHandle, WeakViewHandle,
-};
-use project::Project;
-use theme::components::{action_button::Button, label::Label, ComponentExt};
-use workspace::{
-    item::Item, register_deserializable_item, ItemId, Pane, PaneBackdrop, Workspace, WorkspaceId,
-};
-
-pub fn init(cx: &mut AppContext) {
-    cx.add_action(ComponentTest::toggle_disclosure);
-    cx.add_action(ComponentTest::toggle_toggle);
-    cx.add_action(ComponentTest::deploy);
-    register_deserializable_item::<ComponentTest>(cx);
-}
-
-actions!(
-    test,
-    [NoAction, ToggleDisclosure, ToggleToggle, NewComponentTest]
-);
-
-struct ComponentTest {
-    disclosed: bool,
-    toggled: bool,
-}
-
-impl ComponentTest {
-    fn new() -> Self {
-        Self {
-            disclosed: false,
-            toggled: false,
-        }
-    }
-
-    fn deploy(workspace: &mut Workspace, _: &NewComponentTest, cx: &mut ViewContext<Workspace>) {
-        workspace.add_item(Box::new(cx.add_view(|_| ComponentTest::new())), cx);
-    }
-
-    fn toggle_disclosure(&mut self, _: &ToggleDisclosure, cx: &mut ViewContext<Self>) {
-        self.disclosed = !self.disclosed;
-        cx.notify();
-    }
-
-    fn toggle_toggle(&mut self, _: &ToggleToggle, cx: &mut ViewContext<Self>) {
-        self.toggled = !self.toggled;
-        cx.notify();
-    }
-}
-
-impl Entity for ComponentTest {
-    type Event = ();
-}
-
-impl View for ComponentTest {
-    fn ui_name() -> &'static str {
-        "Component Test"
-    }
-
-    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> gpui::AnyElement<Self> {
-        let theme = theme::current(cx);
-
-        PaneBackdrop::new(
-            cx.view_id(),
-            Flex::column()
-                .with_spacing(10.)
-                .with_child(
-                    Button::action(NoAction)
-                        .with_tooltip("Here's what a tooltip looks like", theme.tooltip.clone())
-                        .with_contents(Label::new("Click me!"))
-                        .with_style(theme.component_test.button.clone())
-                        .element(),
-                )
-                .with_child(
-                    Button::action(ToggleToggle)
-                        .with_tooltip("Here's what a tooltip looks like", theme.tooltip.clone())
-                        .with_contents(Label::new("Toggle me!"))
-                        .toggleable(self.toggled)
-                        .with_style(theme.component_test.toggle.clone())
-                        .element(),
-                )
-                .with_child(
-                    Label::new("A disclosure")
-                        .disclosable(Some(self.disclosed), Box::new(ToggleDisclosure))
-                        .with_style(theme.component_test.disclosure.clone())
-                        .element(),
-                )
-                .constrained()
-                .with_width(200.)
-                .aligned()
-                .into_any(),
-        )
-        .into_any()
-    }
-}
-
-impl Item for ComponentTest {
-    fn tab_content<V: 'static>(
-        &self,
-        _: Option<usize>,
-        style: &theme::Tab,
-        _: &AppContext,
-    ) -> gpui::AnyElement<V> {
-        gpui::elements::Label::new("Component test", style.label.clone()).into_any()
-    }
-
-    fn serialized_item_kind() -> Option<&'static str> {
-        Some("ComponentTest")
-    }
-
-    fn deserialize(
-        _project: ModelHandle<Project>,
-        _workspace: WeakViewHandle<Workspace>,
-        _workspace_id: WorkspaceId,
-        _item_id: ItemId,
-        cx: &mut ViewContext<Pane>,
-    ) -> Task<anyhow::Result<ViewHandle<Self>>> {
-        Task::ready(Ok(cx.add_view(|_| Self::new())))
-    }
-}

crates/context_menu/Cargo.toml 🔗

@@ -1,16 +0,0 @@
-[package]
-name = "context_menu"
-version = "0.1.0"
-edition = "2021"
-publish = false
-
-[lib]
-path = "src/context_menu.rs"
-doctest = false
-
-[dependencies]
-gpui = { path = "../gpui" }
-menu = { path = "../menu" }
-settings = { path = "../settings" }
-theme = { path = "../theme" }
-smallvec.workspace = true

crates/context_menu/src/context_menu.rs 🔗

@@ -1,528 +0,0 @@
-use gpui::{
-    anyhow::{self, anyhow},
-    elements::*,
-    geometry::vector::Vector2F,
-    keymap_matcher::KeymapContext,
-    platform::{CursorStyle, MouseButton},
-    Action, AnyViewHandle, AppContext, Axis, Entity, MouseState, SizeConstraint, Subscription,
-    View, ViewContext,
-};
-use menu::*;
-use std::{any::TypeId, borrow::Cow, sync::Arc, time::Duration};
-
-pub fn init(cx: &mut AppContext) {
-    cx.add_action(ContextMenu::select_first);
-    cx.add_action(ContextMenu::select_last);
-    cx.add_action(ContextMenu::select_next);
-    cx.add_action(ContextMenu::select_prev);
-    cx.add_action(ContextMenu::confirm);
-    cx.add_action(ContextMenu::cancel);
-}
-
-pub type StaticItem = Box<dyn Fn(&mut AppContext) -> AnyElement<ContextMenu>>;
-
-type ContextMenuItemBuilder =
-    Box<dyn Fn(&mut MouseState, &theme::ContextMenuItem) -> AnyElement<ContextMenu>>;
-
-pub enum ContextMenuItemLabel {
-    String(Cow<'static, str>),
-    Element(ContextMenuItemBuilder),
-}
-
-impl From<Cow<'static, str>> for ContextMenuItemLabel {
-    fn from(s: Cow<'static, str>) -> Self {
-        Self::String(s)
-    }
-}
-
-impl From<&'static str> for ContextMenuItemLabel {
-    fn from(s: &'static str) -> Self {
-        Self::String(s.into())
-    }
-}
-
-impl From<String> for ContextMenuItemLabel {
-    fn from(s: String) -> Self {
-        Self::String(s.into())
-    }
-}
-
-impl<T> From<T> for ContextMenuItemLabel
-where
-    T: 'static + Fn(&mut MouseState, &theme::ContextMenuItem) -> AnyElement<ContextMenu>,
-{
-    fn from(f: T) -> Self {
-        Self::Element(Box::new(f))
-    }
-}
-
-pub enum ContextMenuItemAction {
-    Action(Box<dyn Action>),
-    Handler(Arc<dyn Fn(&mut ViewContext<ContextMenu>)>),
-}
-
-impl Clone for ContextMenuItemAction {
-    fn clone(&self) -> Self {
-        match self {
-            Self::Action(action) => Self::Action(action.boxed_clone()),
-            Self::Handler(handler) => Self::Handler(handler.clone()),
-        }
-    }
-}
-
-pub enum ContextMenuItem {
-    Item {
-        label: ContextMenuItemLabel,
-        action: ContextMenuItemAction,
-    },
-    Static(StaticItem),
-    Separator,
-}
-
-impl ContextMenuItem {
-    pub fn action(label: impl Into<ContextMenuItemLabel>, action: impl 'static + Action) -> Self {
-        Self::Item {
-            label: label.into(),
-            action: ContextMenuItemAction::Action(Box::new(action)),
-        }
-    }
-
-    pub fn handler(
-        label: impl Into<ContextMenuItemLabel>,
-        handler: impl 'static + Fn(&mut ViewContext<ContextMenu>),
-    ) -> Self {
-        Self::Item {
-            label: label.into(),
-            action: ContextMenuItemAction::Handler(Arc::new(handler)),
-        }
-    }
-
-    pub fn separator() -> Self {
-        Self::Separator
-    }
-
-    fn is_action(&self) -> bool {
-        matches!(self, Self::Item { .. })
-    }
-
-    fn action_id(&self) -> Option<TypeId> {
-        match self {
-            ContextMenuItem::Item { action, .. } => match action {
-                ContextMenuItemAction::Action(action) => Some(action.id()),
-                ContextMenuItemAction::Handler(_) => None,
-            },
-            ContextMenuItem::Static(..) | ContextMenuItem::Separator => None,
-        }
-    }
-}
-
-pub struct ContextMenu {
-    show_count: usize,
-    anchor_position: Vector2F,
-    anchor_corner: AnchorCorner,
-    position_mode: OverlayPositionMode,
-    items: Vec<ContextMenuItem>,
-    selected_index: Option<usize>,
-    visible: bool,
-    delay_cancel: bool,
-    previously_focused_view_id: Option<usize>,
-    parent_view_id: usize,
-    _actions_observation: Subscription,
-}
-
-impl Entity for ContextMenu {
-    type Event = ();
-}
-
-impl View for ContextMenu {
-    fn ui_name() -> &'static str {
-        "ContextMenu"
-    }
-
-    fn update_keymap_context(&self, keymap: &mut KeymapContext, _: &AppContext) {
-        Self::reset_to_default_keymap_context(keymap);
-        keymap.add_identifier("menu");
-    }
-
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
-        if !self.visible {
-            return Empty::new().into_any();
-        }
-
-        // Render the menu once at minimum width.
-        let mut collapsed_menu = self.render_menu_for_measurement(cx);
-        let expanded_menu =
-            self.render_menu(cx)
-                .constrained()
-                .dynamically(move |constraint, view, cx| {
-                    SizeConstraint::strict_along(
-                        Axis::Horizontal,
-                        collapsed_menu.layout(constraint, view, cx).0.x(),
-                    )
-                });
-
-        Overlay::new(expanded_menu)
-            .with_hoverable(true)
-            .with_fit_mode(OverlayFitMode::SnapToWindow)
-            .with_anchor_position(self.anchor_position)
-            .with_anchor_corner(self.anchor_corner)
-            .with_position_mode(self.position_mode)
-            .into_any()
-    }
-
-    fn focus_out(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
-        self.reset(cx);
-    }
-}
-
-impl ContextMenu {
-    pub fn new(parent_view_id: usize, cx: &mut ViewContext<Self>) -> Self {
-        Self {
-            show_count: 0,
-            delay_cancel: false,
-            anchor_position: Default::default(),
-            anchor_corner: AnchorCorner::TopLeft,
-            position_mode: OverlayPositionMode::Window,
-            items: Default::default(),
-            selected_index: Default::default(),
-            visible: Default::default(),
-            previously_focused_view_id: Default::default(),
-            parent_view_id,
-            _actions_observation: cx.observe_actions(Self::action_dispatched),
-        }
-    }
-
-    pub fn visible(&self) -> bool {
-        self.visible
-    }
-
-    fn action_dispatched(&mut self, action_id: TypeId, cx: &mut ViewContext<Self>) {
-        if let Some(ix) = self
-            .items
-            .iter()
-            .position(|item| item.action_id() == Some(action_id))
-        {
-            self.selected_index = Some(ix);
-            cx.notify();
-            cx.spawn(|this, mut cx| async move {
-                cx.background().timer(Duration::from_millis(50)).await;
-                this.update(&mut cx, |this, cx| this.cancel(&Default::default(), cx))?;
-                anyhow::Ok(())
-            })
-            .detach_and_log_err(cx);
-        }
-    }
-
-    fn confirm(&mut self, _: &Confirm, cx: &mut ViewContext<Self>) {
-        if let Some(ix) = self.selected_index {
-            if let Some(ContextMenuItem::Item { action, .. }) = self.items.get(ix) {
-                match action {
-                    ContextMenuItemAction::Action(action) => {
-                        let window = cx.window();
-                        let view_id = self.parent_view_id;
-                        let action = action.boxed_clone();
-                        cx.app_context()
-                            .spawn(|mut cx| async move {
-                                window
-                                    .dispatch_action(view_id, action.as_ref(), &mut cx)
-                                    .ok_or_else(|| anyhow!("window was closed"))
-                            })
-                            .detach_and_log_err(cx);
-                    }
-                    ContextMenuItemAction::Handler(handler) => handler(cx),
-                }
-                self.reset(cx);
-            }
-        }
-    }
-
-    pub fn delay_cancel(&mut self) {
-        self.delay_cancel = true;
-    }
-
-    fn cancel(&mut self, _: &Cancel, cx: &mut ViewContext<Self>) {
-        if !self.delay_cancel {
-            self.reset(cx);
-            let show_count = self.show_count;
-            cx.defer(move |this, cx| {
-                if cx.handle().is_focused(cx) && this.show_count == show_count {
-                    (**cx).focus(this.previously_focused_view_id.take());
-                }
-            });
-        } else {
-            self.delay_cancel = false;
-        }
-    }
-
-    fn reset(&mut self, cx: &mut ViewContext<Self>) {
-        self.items.clear();
-        self.visible = false;
-        self.selected_index.take();
-        cx.notify();
-    }
-
-    fn select_first(&mut self, _: &SelectFirst, cx: &mut ViewContext<Self>) {
-        self.selected_index = self.items.iter().position(|item| item.is_action());
-        cx.notify();
-    }
-
-    fn select_last(&mut self, _: &SelectLast, cx: &mut ViewContext<Self>) {
-        for (ix, item) in self.items.iter().enumerate().rev() {
-            if item.is_action() {
-                self.selected_index = Some(ix);
-                cx.notify();
-                break;
-            }
-        }
-    }
-
-    fn select_next(&mut self, _: &SelectNext, cx: &mut ViewContext<Self>) {
-        if let Some(ix) = self.selected_index {
-            for (ix, item) in self.items.iter().enumerate().skip(ix + 1) {
-                if item.is_action() {
-                    self.selected_index = Some(ix);
-                    cx.notify();
-                    break;
-                }
-            }
-        } else {
-            self.select_first(&Default::default(), cx);
-        }
-    }
-
-    fn select_prev(&mut self, _: &SelectPrev, cx: &mut ViewContext<Self>) {
-        if let Some(ix) = self.selected_index {
-            for (ix, item) in self.items.iter().enumerate().take(ix).rev() {
-                if item.is_action() {
-                    self.selected_index = Some(ix);
-                    cx.notify();
-                    break;
-                }
-            }
-        } else {
-            self.select_last(&Default::default(), cx);
-        }
-    }
-
-    pub fn toggle(
-        &mut self,
-        anchor_position: Vector2F,
-        anchor_corner: AnchorCorner,
-        items: Vec<ContextMenuItem>,
-        cx: &mut ViewContext<Self>,
-    ) {
-        if self.visible() {
-            self.cancel(&Cancel, cx);
-        } else {
-            let mut items = items.into_iter().peekable();
-            if items.peek().is_some() {
-                self.items = items.collect();
-                self.anchor_position = anchor_position;
-                self.anchor_corner = anchor_corner;
-                self.visible = true;
-                self.show_count += 1;
-                if !cx.is_self_focused() {
-                    self.previously_focused_view_id = cx.focused_view_id();
-                }
-                cx.focus_self();
-            } else {
-                self.visible = false;
-            }
-        }
-        cx.notify();
-    }
-
-    pub fn show(
-        &mut self,
-        anchor_position: Vector2F,
-        anchor_corner: AnchorCorner,
-        items: Vec<ContextMenuItem>,
-        cx: &mut ViewContext<Self>,
-    ) {
-        let mut items = items.into_iter().peekable();
-        if items.peek().is_some() {
-            self.items = items.collect();
-            self.anchor_position = anchor_position;
-            self.anchor_corner = anchor_corner;
-            self.visible = true;
-            self.show_count += 1;
-            if !cx.is_self_focused() {
-                self.previously_focused_view_id = cx.focused_view_id();
-            }
-            cx.focus_self();
-        } else {
-            self.visible = false;
-        }
-        cx.notify();
-    }
-
-    pub fn set_position_mode(&mut self, mode: OverlayPositionMode) {
-        self.position_mode = mode;
-    }
-
-    fn render_menu_for_measurement(&self, cx: &mut ViewContext<Self>) -> impl Element<ContextMenu> {
-        let style = theme::current(cx).context_menu.clone();
-        Flex::row()
-            .with_child(
-                Flex::column().with_children(self.items.iter().enumerate().map(|(ix, item)| {
-                    match item {
-                        ContextMenuItem::Item { label, .. } => {
-                            let style = style.item.in_state(self.selected_index == Some(ix));
-                            let style = style.style_for(&mut Default::default());
-
-                            match label {
-                                ContextMenuItemLabel::String(label) => {
-                                    Label::new(label.to_string(), style.label.clone())
-                                        .contained()
-                                        .with_style(style.container)
-                                        .into_any()
-                                }
-                                ContextMenuItemLabel::Element(element) => {
-                                    element(&mut Default::default(), style)
-                                }
-                            }
-                        }
-
-                        ContextMenuItem::Static(f) => f(cx),
-
-                        ContextMenuItem::Separator => Empty::new()
-                            .collapsed()
-                            .contained()
-                            .with_style(style.separator)
-                            .constrained()
-                            .with_height(1.)
-                            .into_any(),
-                    }
-                })),
-            )
-            .with_child(
-                Flex::column()
-                    .with_children(self.items.iter().enumerate().map(|(ix, item)| {
-                        match item {
-                            ContextMenuItem::Item { action, .. } => {
-                                let style = style.item.in_state(self.selected_index == Some(ix));
-                                let style = style.style_for(&mut Default::default());
-
-                                match action {
-                                    ContextMenuItemAction::Action(action) => KeystrokeLabel::new(
-                                        self.parent_view_id,
-                                        action.boxed_clone(),
-                                        style.keystroke.container,
-                                        style.keystroke.text.clone(),
-                                    )
-                                    .into_any(),
-                                    ContextMenuItemAction::Handler(_) => Empty::new().into_any(),
-                                }
-                            }
-
-                            ContextMenuItem::Static(_) => Empty::new().into_any(),
-
-                            ContextMenuItem::Separator => Empty::new()
-                                .collapsed()
-                                .constrained()
-                                .with_height(1.)
-                                .contained()
-                                .with_style(style.separator)
-                                .into_any(),
-                        }
-                    }))
-                    .contained()
-                    .with_margin_left(style.keystroke_margin),
-            )
-            .contained()
-            .with_style(style.container)
-    }
-
-    fn render_menu(&self, cx: &mut ViewContext<Self>) -> impl Element<ContextMenu> {
-        enum Menu {}
-        enum MenuItem {}
-
-        let style = theme::current(cx).context_menu.clone();
-
-        MouseEventHandler::new::<Menu, _>(0, cx, |_, cx| {
-            Flex::column()
-                .with_children(self.items.iter().enumerate().map(|(ix, item)| {
-                    match item {
-                        ContextMenuItem::Item { label, action } => {
-                            let action = action.clone();
-                            let view_id = self.parent_view_id;
-                            MouseEventHandler::new::<MenuItem, _>(ix, cx, |state, _| {
-                                let style = style.item.in_state(self.selected_index == Some(ix));
-                                let style = style.style_for(state);
-                                let keystroke = match &action {
-                                    ContextMenuItemAction::Action(action) => Some(
-                                        KeystrokeLabel::new(
-                                            view_id,
-                                            action.boxed_clone(),
-                                            style.keystroke.container,
-                                            style.keystroke.text.clone(),
-                                        )
-                                        .flex_float(),
-                                    ),
-                                    ContextMenuItemAction::Handler(_) => None,
-                                };
-
-                                Flex::row()
-                                    .with_child(match label {
-                                        ContextMenuItemLabel::String(label) => {
-                                            Label::new(label.clone(), style.label.clone())
-                                                .contained()
-                                                .into_any()
-                                        }
-                                        ContextMenuItemLabel::Element(element) => {
-                                            element(state, style)
-                                        }
-                                    })
-                                    .with_children(keystroke)
-                                    .contained()
-                                    .with_style(style.container)
-                            })
-                            .with_cursor_style(CursorStyle::PointingHand)
-                            .on_up(MouseButton::Left, |_, _, _| {}) // Capture these events
-                            .on_down(MouseButton::Left, |_, _, _| {}) // Capture these events
-                            .on_click(MouseButton::Left, move |_, menu, cx| {
-                                menu.cancel(&Default::default(), cx);
-                                let window = cx.window();
-                                match &action {
-                                    ContextMenuItemAction::Action(action) => {
-                                        let action = action.boxed_clone();
-                                        cx.app_context()
-                                            .spawn(|mut cx| async move {
-                                                window
-                                                    .dispatch_action(
-                                                        view_id,
-                                                        action.as_ref(),
-                                                        &mut cx,
-                                                    )
-                                                    .ok_or_else(|| anyhow!("window was closed"))
-                                            })
-                                            .detach_and_log_err(cx);
-                                    }
-                                    ContextMenuItemAction::Handler(handler) => handler(cx),
-                                }
-                            })
-                            .on_drag(MouseButton::Left, |_, _, _| {})
-                            .into_any()
-                        }
-
-                        ContextMenuItem::Static(f) => f(cx),
-
-                        ContextMenuItem::Separator => Empty::new()
-                            .constrained()
-                            .with_height(1.)
-                            .contained()
-                            .with_style(style.separator)
-                            .into_any(),
-                    }
-                }))
-                .contained()
-                .with_style(style.container)
-        })
-        .on_down_out(MouseButton::Left, |_, this, cx| {
-            this.cancel(&Default::default(), cx);
-        })
-        .on_down_out(MouseButton::Right, |_, this, cx| {
-            this.cancel(&Default::default(), cx);
-        })
-    }
-}

crates/drag_and_drop/Cargo.toml 🔗

@@ -1,16 +0,0 @@
-[package]
-name = "drag_and_drop"
-version = "0.1.0"
-edition = "2021"
-publish = false
-
-[lib]
-path = "src/drag_and_drop.rs"
-doctest = false
-
-[dependencies]
-collections = { path = "../collections" }
-gpui = { path = "../gpui" }
-
-[dev-dependencies]
-gpui = { path = "../gpui", features = ["test-support"] }

crates/drag_and_drop/src/drag_and_drop.rs 🔗

@@ -1,378 +0,0 @@
-use std::{any::Any, rc::Rc};
-
-use collections::HashSet;
-use gpui::{
-    elements::{Empty, MouseEventHandler, Overlay},
-    geometry::{rect::RectF, vector::Vector2F},
-    platform::{CursorStyle, Modifiers, MouseButton},
-    scene::{MouseDown, MouseDrag},
-    AnyElement, AnyWindowHandle, Element, View, ViewContext, WeakViewHandle, WindowContext,
-};
-
-const DEAD_ZONE: f32 = 4.;
-
-enum State<V> {
-    Down {
-        region_offset: Vector2F,
-        region: RectF,
-    },
-    DeadZone {
-        region_offset: Vector2F,
-        region: RectF,
-    },
-    Dragging {
-        modifiers: Modifiers,
-        window: AnyWindowHandle,
-        position: Vector2F,
-        region_offset: Vector2F,
-        region: RectF,
-        payload: Rc<dyn Any + 'static>,
-        render: Rc<dyn Fn(&Modifiers, Rc<dyn Any>, &mut ViewContext<V>) -> AnyElement<V>>,
-    },
-    Canceled,
-}
-
-impl<V> Clone for State<V> {
-    fn clone(&self) -> Self {
-        match self {
-            &State::Down {
-                region_offset,
-                region,
-            } => State::Down {
-                region_offset,
-                region,
-            },
-            &State::DeadZone {
-                region_offset,
-                region,
-            } => State::DeadZone {
-                region_offset,
-                region,
-            },
-            State::Dragging {
-                modifiers,
-                window,
-                position,
-                region_offset,
-                region,
-                payload,
-                render,
-            } => Self::Dragging {
-                window: window.clone(),
-                position: position.clone(),
-                region_offset: region_offset.clone(),
-                region: region.clone(),
-                payload: payload.clone(),
-                render: render.clone(),
-                modifiers: modifiers.clone(),
-            },
-            State::Canceled => State::Canceled,
-        }
-    }
-}
-
-pub struct DragAndDrop<V> {
-    containers: HashSet<WeakViewHandle<V>>,
-    currently_dragged: Option<State<V>>,
-}
-
-impl<V> Default for DragAndDrop<V> {
-    fn default() -> Self {
-        Self {
-            containers: Default::default(),
-            currently_dragged: Default::default(),
-        }
-    }
-}
-
-impl<V: 'static> DragAndDrop<V> {
-    pub fn register_container(&mut self, handle: WeakViewHandle<V>) {
-        self.containers.insert(handle);
-    }
-
-    pub fn currently_dragged<T: Any>(&self, window: AnyWindowHandle) -> Option<(Vector2F, Rc<T>)> {
-        self.currently_dragged.as_ref().and_then(|state| {
-            if let State::Dragging {
-                position,
-                payload,
-                window: window_dragged_from,
-                ..
-            } = state
-            {
-                if &window != window_dragged_from {
-                    return None;
-                }
-
-                payload
-                    .is::<T>()
-                    .then(|| payload.clone().downcast::<T>().ok())
-                    .flatten()
-                    .map(|payload| (position.clone(), payload))
-            } else {
-                None
-            }
-        })
-    }
-
-    pub fn any_currently_dragged(&self, window: AnyWindowHandle) -> bool {
-        self.currently_dragged
-            .as_ref()
-            .map(|state| {
-                if let State::Dragging {
-                    window: window_dragged_from,
-                    ..
-                } = state
-                {
-                    if &window != window_dragged_from {
-                        return false;
-                    }
-
-                    true
-                } else {
-                    false
-                }
-            })
-            .unwrap_or(false)
-    }
-
-    pub fn drag_started(event: MouseDown, cx: &mut WindowContext) {
-        cx.update_global(|this: &mut Self, _| {
-            this.currently_dragged = Some(State::Down {
-                region_offset: event.position - event.region.origin(),
-                region: event.region,
-            });
-        })
-    }
-
-    pub fn dragging<T: Any>(
-        event: MouseDrag,
-        payload: Rc<T>,
-        cx: &mut WindowContext,
-        render: Rc<impl 'static + Fn(&Modifiers, &T, &mut ViewContext<V>) -> AnyElement<V>>,
-    ) {
-        let window = cx.window();
-        cx.update_global(|this: &mut Self, cx| {
-            this.notify_containers_for_window(window, cx);
-
-            match this.currently_dragged.as_ref() {
-                Some(&State::Down {
-                    region_offset,
-                    region,
-                })
-                | Some(&State::DeadZone {
-                    region_offset,
-                    region,
-                }) => {
-                    if (event.position - (region.origin() + region_offset)).length() > DEAD_ZONE {
-                        this.currently_dragged = Some(State::Dragging {
-                            modifiers: event.modifiers,
-                            window,
-                            region_offset,
-                            region,
-                            position: event.position,
-                            payload,
-                            render: Rc::new(move |modifiers, payload, cx| {
-                                render(modifiers, payload.downcast_ref::<T>().unwrap(), cx)
-                            }),
-                        });
-                    } else {
-                        this.currently_dragged = Some(State::DeadZone {
-                            region_offset,
-                            region,
-                        })
-                    }
-                }
-                Some(&State::Dragging {
-                    region_offset,
-                    region,
-                    modifiers,
-                    ..
-                }) => {
-                    this.currently_dragged = Some(State::Dragging {
-                        modifiers,
-                        window,
-                        region_offset,
-                        region,
-                        position: event.position,
-                        payload,
-                        render: Rc::new(move |modifiers, payload, cx| {
-                            render(modifiers, payload.downcast_ref::<T>().unwrap(), cx)
-                        }),
-                    });
-                }
-                _ => {}
-            }
-        });
-    }
-
-    pub fn update_modifiers(new_modifiers: Modifiers, cx: &mut ViewContext<V>) -> bool {
-        let result = cx.update_global(|this: &mut Self, _| match &mut this.currently_dragged {
-            Some(state) => match state {
-                State::Dragging { modifiers, .. } => {
-                    *modifiers = new_modifiers;
-                    true
-                }
-                _ => false,
-            },
-            None => false,
-        });
-
-        if result {
-            cx.notify();
-        }
-
-        result
-    }
-
-    pub fn render(cx: &mut ViewContext<V>) -> Option<AnyElement<V>> {
-        enum DraggedElementHandler {}
-        cx.global::<Self>()
-            .currently_dragged
-            .clone()
-            .and_then(|state| {
-                match state {
-                    State::Down { .. } => None,
-                    State::DeadZone { .. } => None,
-                    State::Dragging {
-                        modifiers,
-                        window,
-                        region_offset,
-                        position,
-                        region,
-                        payload,
-                        render,
-                    } => {
-                        if cx.window() != window {
-                            return None;
-                        }
-
-                        let position = (position - region_offset).round();
-                        Some(
-                            Overlay::new(
-                                MouseEventHandler::new::<DraggedElementHandler, _>(
-                                    0,
-                                    cx,
-                                    |_, cx| render(&modifiers, payload, cx),
-                                )
-                                .with_cursor_style(CursorStyle::Arrow)
-                                .on_up(MouseButton::Left, |_, _, cx| {
-                                    cx.window_context().defer(|cx| {
-                                        cx.update_global::<Self, _, _>(|this, cx| {
-                                            this.finish_dragging(cx)
-                                        });
-                                    });
-                                    cx.propagate_event();
-                                })
-                                .on_up_out(MouseButton::Left, |_, _, cx| {
-                                    cx.window_context().defer(|cx| {
-                                        cx.update_global::<Self, _, _>(|this, cx| {
-                                            this.finish_dragging(cx)
-                                        });
-                                    });
-                                })
-                                // Don't block hover events or invalidations
-                                .with_hoverable(false)
-                                .constrained()
-                                .with_width(region.width())
-                                .with_height(region.height()),
-                            )
-                            .with_anchor_position(position)
-                            .into_any(),
-                        )
-                    }
-
-                    State::Canceled => Some(
-                        MouseEventHandler::new::<DraggedElementHandler, _>(0, cx, |_, _| {
-                            Empty::new().constrained().with_width(0.).with_height(0.)
-                        })
-                        .on_up(MouseButton::Left, |_, _, cx| {
-                            cx.window_context().defer(|cx| {
-                                cx.update_global::<Self, _, _>(|this, _| {
-                                    this.currently_dragged = None;
-                                });
-                            });
-                        })
-                        .on_up_out(MouseButton::Left, |_, _, cx| {
-                            cx.window_context().defer(|cx| {
-                                cx.update_global::<Self, _, _>(|this, _| {
-                                    this.currently_dragged = None;
-                                });
-                            });
-                        })
-                        .into_any(),
-                    ),
-                }
-            })
-    }
-
-    pub fn cancel_dragging<P: Any>(&mut self, cx: &mut WindowContext) {
-        if let Some(State::Dragging {
-            payload, window, ..
-        }) = &self.currently_dragged
-        {
-            if payload.is::<P>() {
-                let window = *window;
-                self.currently_dragged = Some(State::Canceled);
-                self.notify_containers_for_window(window, cx);
-            }
-        }
-    }
-
-    fn finish_dragging(&mut self, cx: &mut WindowContext) {
-        if let Some(State::Dragging { window, .. }) = self.currently_dragged.take() {
-            self.notify_containers_for_window(window, cx);
-        }
-    }
-
-    fn notify_containers_for_window(&mut self, window: AnyWindowHandle, cx: &mut WindowContext) {
-        self.containers.retain(|container| {
-            if let Some(container) = container.upgrade(cx) {
-                if container.window() == window {
-                    container.update(cx, |_, cx| cx.notify());
-                }
-                true
-            } else {
-                false
-            }
-        });
-    }
-}
-
-pub trait Draggable<V> {
-    fn as_draggable<D: View, P: Any>(
-        self,
-        payload: P,
-        render: impl 'static + Fn(&Modifiers, &P, &mut ViewContext<D>) -> AnyElement<D>,
-    ) -> Self
-    where
-        Self: Sized;
-}
-
-impl<V: 'static> Draggable<V> for MouseEventHandler<V> {
-    fn as_draggable<D: View, P: Any>(
-        self,
-        payload: P,
-        render: impl 'static + Fn(&Modifiers, &P, &mut ViewContext<D>) -> AnyElement<D>,
-    ) -> Self
-    where
-        Self: Sized,
-    {
-        let payload = Rc::new(payload);
-        let render = Rc::new(render);
-        self.on_down(MouseButton::Left, move |e, _, cx| {
-            cx.propagate_event();
-            DragAndDrop::<D>::drag_started(e, cx);
-        })
-        .on_drag(MouseButton::Left, move |e, _, cx| {
-            if e.end {
-                cx.update_global::<DragAndDrop<D>, _, _>(|drag_and_drop, cx| {
-                    drag_and_drop.finish_dragging(cx)
-                })
-            } else {
-                let payload = payload.clone();
-                let render = render.clone();
-                DragAndDrop::<D>::dragging(e, payload, cx, render)
-            }
-        })
-    }
-}

crates/gpui/Cargo.toml 🔗

@@ -15,7 +15,7 @@ doctest = false
 
 [dependencies]
 collections = { path = "../collections" }
-gpui2_macros = { path = "../gpui2_macros" }
+gpui_macros = { path = "../gpui_macros" }
 util = { path = "../util" }
 sum_tree = { path = "../sum_tree" }
 sqlez = { path = "../sqlez" }

crates/gpui/src/gpui.rs 🔗

@@ -47,7 +47,7 @@ pub use element::*;
 pub use elements::*;
 pub use executor::*;
 pub use geometry::*;
-pub use gpui2_macros::*;
+pub use gpui_macros::*;
 pub use image_cache::*;
 pub use input::*;
 pub use interactive::*;

crates/gpui/src/styled.rs 🔗

@@ -10,7 +10,7 @@ use taffy::style::Overflow;
 pub trait Styled: Sized {
     fn style(&mut self) -> &mut StyleRefinement;
 
-    gpui2_macros::style_helpers!();
+    gpui_macros::style_helpers!();
 
     fn z_index(mut self, z_index: u8) -> Self {
         self.style().z_index = Some(z_index);

crates/gpui/tests/action_macros.rs 🔗

@@ -1,11 +1,9 @@
-use gpui2::{actions, impl_actions};
-use gpui2_macros::register_action;
+use gpui::{actions, impl_actions};
+use gpui_macros::register_action;
 use serde_derive::Deserialize;
 
 #[test]
 fn test_action_macros() {
-    use gpui2 as gpui;
-
     actions!(test, [TestAction]);
 
     #[derive(PartialEq, Clone, Deserialize)]

crates/gpui2_macros/Cargo.toml 🔗

@@ -1,14 +0,0 @@
-[package]
-name = "gpui2_macros"
-version = "0.1.0"
-edition = "2021"
-publish = false
-
-[lib]
-path = "src/gpui2_macros.rs"
-proc-macro = true
-
-[dependencies]
-syn = { version = "1.0.72", features = ["full"] }
-quote = "1.0.9"
-proc-macro2 = "1.0.66"

crates/gpui2_macros/src/gpui2_macros.rs 🔗

@@ -1,32 +0,0 @@
-mod derive_into_element;
-mod derive_render;
-mod register_action;
-mod style_helpers;
-mod test;
-
-use proc_macro::TokenStream;
-
-#[proc_macro]
-pub fn register_action(ident: TokenStream) -> TokenStream {
-    register_action::register_action_macro(ident)
-}
-
-#[proc_macro_derive(IntoElement)]
-pub fn derive_into_element(input: TokenStream) -> TokenStream {
-    derive_into_element::derive_into_element(input)
-}
-
-#[proc_macro_derive(Render)]
-pub fn derive_render(input: TokenStream) -> TokenStream {
-    derive_render::derive_render(input)
-}
-
-#[proc_macro]
-pub fn style_helpers(input: TokenStream) -> TokenStream {
-    style_helpers::style_helpers(input)
-}
-
-#[proc_macro_attribute]
-pub fn test(args: TokenStream, function: TokenStream) -> TokenStream {
-    test::test(args, function)
-}

crates/gpui_macros/Cargo.toml 🔗

@@ -7,10 +7,8 @@ publish = false
 [lib]
 path = "src/gpui_macros.rs"
 proc-macro = true
-doctest = false
 
 [dependencies]
-lazy_static.workspace = true
-proc-macro2 = "1.0"
-syn = "1.0"
-quote = "1.0"
+syn = { version = "1.0.72", features = ["full"] }
+quote = "1.0.9"
+proc-macro2 = "1.0.66"

crates/gpui2_macros/src/derive_into_element.rs → crates/gpui_macros/src/derive_into_element.rs 🔗

@@ -13,7 +13,7 @@ pub fn derive_into_element(input: TokenStream) -> TokenStream {
         {
             type Element = gpui::Component<Self>;
 
-            fn element_id(&self) -> Option<ElementId> {
+            fn element_id(&self) -> Option<gpui::ElementId> {
                 None
             }
 

crates/gpui2_macros/src/derive_render.rs → crates/gpui_macros/src/derive_render.rs 🔗

@@ -11,7 +11,7 @@ pub fn derive_render(input: TokenStream) -> TokenStream {
         impl #impl_generics gpui::Render for #type_name #type_generics
         #where_clause
         {
-            fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl Element {
+            fn render(&mut self, _cx: &mut gpui::ViewContext<Self>) -> impl gpui::Element {
                 ()
             }
         }

crates/gpui_macros/src/gpui_macros.rs 🔗

@@ -1,381 +1,32 @@
-use proc_macro::TokenStream;
-use proc_macro2::Ident;
-use quote::{format_ident, quote};
-use std::mem;
-use syn::{
-    parse_macro_input, parse_quote, spanned::Spanned as _, AttributeArgs, DeriveInput, FnArg,
-    GenericParam, Generics, ItemFn, Lit, Meta, NestedMeta, Type, WhereClause,
-};
-
-#[proc_macro_attribute]
-pub fn test(args: TokenStream, function: TokenStream) -> TokenStream {
-    let mut namespace = format_ident!("gpui");
-
-    let args = syn::parse_macro_input!(args as AttributeArgs);
-    let mut max_retries = 0;
-    let mut num_iterations = 1;
-    let mut starting_seed = 0;
-    let mut detect_nondeterminism = false;
-    let mut on_failure_fn_name = quote!(None);
-
-    for arg in args {
-        match arg {
-            NestedMeta::Meta(Meta::Path(name))
-                if name.get_ident().map_or(false, |n| n == "self") =>
-            {
-                namespace = format_ident!("crate");
-            }
-            NestedMeta::Meta(Meta::NameValue(meta)) => {
-                let key_name = meta.path.get_ident().map(|i| i.to_string());
-                let result = (|| {
-                    match key_name.as_deref() {
-                        Some("detect_nondeterminism") => {
-                            detect_nondeterminism = parse_bool(&meta.lit)?
-                        }
-                        Some("retries") => max_retries = parse_int(&meta.lit)?,
-                        Some("iterations") => num_iterations = parse_int(&meta.lit)?,
-                        Some("seed") => starting_seed = parse_int(&meta.lit)?,
-                        Some("on_failure") => {
-                            if let Lit::Str(name) = meta.lit {
-                                let mut path = syn::Path {
-                                    leading_colon: None,
-                                    segments: Default::default(),
-                                };
-                                for part in name.value().split("::") {
-                                    path.segments.push(Ident::new(part, name.span()).into());
-                                }
-                                on_failure_fn_name = quote!(Some(#path));
-                            } else {
-                                return Err(TokenStream::from(
-                                    syn::Error::new(
-                                        meta.lit.span(),
-                                        "on_failure argument must be a string",
-                                    )
-                                    .into_compile_error(),
-                                ));
-                            }
-                        }
-                        _ => {
-                            return Err(TokenStream::from(
-                                syn::Error::new(meta.path.span(), "invalid argument")
-                                    .into_compile_error(),
-                            ))
-                        }
-                    }
-                    Ok(())
-                })();
-
-                if let Err(tokens) = result {
-                    return tokens;
-                }
-            }
-            other => {
-                return TokenStream::from(
-                    syn::Error::new_spanned(other, "invalid argument").into_compile_error(),
-                )
-            }
-        }
-    }
-
-    let mut inner_fn = parse_macro_input!(function as ItemFn);
-    if max_retries > 0 && num_iterations > 1 {
-        return TokenStream::from(
-            syn::Error::new_spanned(inner_fn, "retries and randomized iterations can't be mixed")
-                .into_compile_error(),
-        );
-    }
-    let inner_fn_attributes = mem::take(&mut inner_fn.attrs);
-    let inner_fn_name = format_ident!("_{}", inner_fn.sig.ident);
-    let outer_fn_name = mem::replace(&mut inner_fn.sig.ident, inner_fn_name.clone());
-
-    let mut outer_fn: ItemFn = if inner_fn.sig.asyncness.is_some() {
-        // Pass to the test function the number of app contexts that it needs,
-        // based on its parameter list.
-        let mut cx_vars = proc_macro2::TokenStream::new();
-        let mut cx_teardowns = proc_macro2::TokenStream::new();
-        let mut inner_fn_args = proc_macro2::TokenStream::new();
-        for (ix, arg) in inner_fn.sig.inputs.iter().enumerate() {
-            if let FnArg::Typed(arg) = arg {
-                if let Type::Path(ty) = &*arg.ty {
-                    let last_segment = ty.path.segments.last();
-                    match last_segment.map(|s| s.ident.to_string()).as_deref() {
-                        Some("StdRng") => {
-                            inner_fn_args.extend(quote!(rand::SeedableRng::seed_from_u64(seed),));
-                            continue;
-                        }
-                        Some("Arc") => {
-                            if let syn::PathArguments::AngleBracketed(args) =
-                                &last_segment.unwrap().arguments
-                            {
-                                if let Some(syn::GenericArgument::Type(syn::Type::Path(ty))) =
-                                    args.args.last()
-                                {
-                                    let last_segment = ty.path.segments.last();
-                                    if let Some("Deterministic") =
-                                        last_segment.map(|s| s.ident.to_string()).as_deref()
-                                    {
-                                        inner_fn_args.extend(quote!(deterministic.clone(),));
-                                        continue;
-                                    }
-                                }
-                            }
-                        }
-                        _ => {}
-                    }
-                } else if let Type::Reference(ty) = &*arg.ty {
-                    if let Type::Path(ty) = &*ty.elem {
-                        let last_segment = ty.path.segments.last();
-                        if let Some("TestAppContext") =
-                            last_segment.map(|s| s.ident.to_string()).as_deref()
-                        {
-                            let first_entity_id = ix * 100_000;
-                            let cx_varname = format_ident!("cx_{}", ix);
-                            cx_vars.extend(quote!(
-                                let mut #cx_varname = #namespace::TestAppContext::new(
-                                    foreground_platform.clone(),
-                                    cx.platform().clone(),
-                                    deterministic.build_foreground(#ix),
-                                    deterministic.build_background(),
-                                    cx.font_cache().clone(),
-                                    cx.leak_detector(),
-                                    #first_entity_id,
-                                    stringify!(#outer_fn_name).to_string(),
-                                );
-                            ));
-                            cx_teardowns.extend(quote!(
-                                #cx_varname.remove_all_windows();
-                                deterministic.run_until_parked();
-                                #cx_varname.update(|cx| cx.clear_globals());
-                            ));
-                            inner_fn_args.extend(quote!(&mut #cx_varname,));
-                            continue;
-                        }
-                    }
-                }
-            }
-
-            return TokenStream::from(
-                syn::Error::new_spanned(arg, "invalid argument").into_compile_error(),
-            );
-        }
-
-        parse_quote! {
-            #[test]
-            fn #outer_fn_name() {
-                #inner_fn
-
-                #namespace::test::run_test(
-                    #num_iterations as u64,
-                    #starting_seed as u64,
-                    #max_retries,
-                    #detect_nondeterminism,
-                    &mut |cx, foreground_platform, deterministic, seed| {
-                        // some of the macro contents do not use all variables, silence the warnings
-                        let _ = (&cx, &foreground_platform, &deterministic, &seed);
-                        #cx_vars
-                        cx.foreground().run(#inner_fn_name(#inner_fn_args));
-                        #cx_teardowns
-                    },
-                    #on_failure_fn_name,
-                    stringify!(#outer_fn_name).to_string(),
-                );
-            }
-        }
-    } else {
-        // Pass to the test function the number of app contexts that it needs,
-        // based on its parameter list.
-        let mut cx_vars = proc_macro2::TokenStream::new();
-        let mut cx_teardowns = proc_macro2::TokenStream::new();
-        let mut inner_fn_args = proc_macro2::TokenStream::new();
-        for (ix, arg) in inner_fn.sig.inputs.iter().enumerate() {
-            if let FnArg::Typed(arg) = arg {
-                if let Type::Path(ty) = &*arg.ty {
-                    let last_segment = ty.path.segments.last();
-
-                    if let Some("StdRng") = last_segment.map(|s| s.ident.to_string()).as_deref() {
-                        inner_fn_args.extend(quote!(rand::SeedableRng::seed_from_u64(seed),));
-                        continue;
-                    }
-                } else if let Type::Reference(ty) = &*arg.ty {
-                    if let Type::Path(ty) = &*ty.elem {
-                        let last_segment = ty.path.segments.last();
-                        match last_segment.map(|s| s.ident.to_string()).as_deref() {
-                            Some("AppContext") => {
-                                inner_fn_args.extend(quote!(cx,));
-                                continue;
-                            }
-                            Some("TestAppContext") => {
-                                let first_entity_id = ix * 100_000;
-                                let cx_varname = format_ident!("cx_{}", ix);
-                                cx_vars.extend(quote!(
-                                    let mut #cx_varname = #namespace::TestAppContext::new(
-                                        foreground_platform.clone(),
-                                        cx.platform().clone(),
-                                        deterministic.build_foreground(#ix),
-                                        deterministic.build_background(),
-                                        cx.font_cache().clone(),
-                                        cx.leak_detector(),
-                                        #first_entity_id,
-                                        stringify!(#outer_fn_name).to_string(),
-                                    );
-                                ));
-                                cx_teardowns.extend(quote!(
-                                    #cx_varname.remove_all_windows();
-                                    deterministic.run_until_parked();
-                                    #cx_varname.update(|cx| cx.clear_globals());
-                                ));
-                                inner_fn_args.extend(quote!(&mut #cx_varname,));
-                                continue;
-                            }
-                            _ => {}
-                        }
-                    }
-                }
-            }
-
-            return TokenStream::from(
-                syn::Error::new_spanned(arg, "invalid argument").into_compile_error(),
-            );
-        }
-
-        parse_quote! {
-            #[test]
-            fn #outer_fn_name() {
-                #inner_fn
+mod derive_into_element;
+mod derive_render;
+mod register_action;
+mod style_helpers;
+mod test;
 
-                #namespace::test::run_test(
-                    #num_iterations as u64,
-                    #starting_seed as u64,
-                    #max_retries,
-                    #detect_nondeterminism,
-                    &mut |cx, foreground_platform, deterministic, seed| {
-                        // some of the macro contents do not use all variables, silence the warnings
-                        let _ = (&cx, &foreground_platform, &deterministic, &seed);
-                        #cx_vars
-                        #inner_fn_name(#inner_fn_args);
-                        #cx_teardowns
-                    },
-                    #on_failure_fn_name,
-                    stringify!(#outer_fn_name).to_string(),
-                );
-            }
-        }
-    };
-    outer_fn.attrs.extend(inner_fn_attributes);
+use proc_macro::TokenStream;
 
-    TokenStream::from(quote!(#outer_fn))
+#[proc_macro]
+pub fn register_action(ident: TokenStream) -> TokenStream {
+    register_action::register_action_macro(ident)
 }
 
-fn parse_int(literal: &Lit) -> Result<usize, TokenStream> {
-    let result = if let Lit::Int(int) = &literal {
-        int.base10_parse()
-    } else {
-        Err(syn::Error::new(literal.span(), "must be an integer"))
-    };
-
-    result.map_err(|err| TokenStream::from(err.into_compile_error()))
+#[proc_macro_derive(IntoElement)]
+pub fn derive_into_element(input: TokenStream) -> TokenStream {
+    derive_into_element::derive_into_element(input)
 }
 
-fn parse_bool(literal: &Lit) -> Result<bool, TokenStream> {
-    let result = if let Lit::Bool(result) = &literal {
-        Ok(result.value)
-    } else {
-        Err(syn::Error::new(literal.span(), "must be a boolean"))
-    };
-
-    result.map_err(|err| TokenStream::from(err.into_compile_error()))
+#[proc_macro_derive(Render)]
+pub fn derive_render(input: TokenStream) -> TokenStream {
+    derive_render::derive_render(input)
 }
 
-#[proc_macro_derive(Element)]
-pub fn element_derive(input: TokenStream) -> TokenStream {
-    let ast = parse_macro_input!(input as DeriveInput);
-    let type_name = ast.ident;
-
-    let placeholder_view_generics: Generics = parse_quote! { <V: 'static> };
-    let placeholder_view_type_name: Ident = parse_quote! { V };
-    let view_type_name: Ident;
-    let impl_generics: syn::ImplGenerics<'_>;
-    let type_generics: Option<syn::TypeGenerics<'_>>;
-    let where_clause: Option<&'_ WhereClause>;
-
-    match ast.generics.params.iter().find_map(|param| {
-        if let GenericParam::Type(type_param) = param {
-            Some(type_param.ident.clone())
-        } else {
-            None
-        }
-    }) {
-        Some(type_name) => {
-            view_type_name = type_name;
-            let generics = ast.generics.split_for_impl();
-            impl_generics = generics.0;
-            type_generics = Some(generics.1);
-            where_clause = generics.2;
-        }
-        _ => {
-            view_type_name = placeholder_view_type_name;
-            let generics = placeholder_view_generics.split_for_impl();
-            impl_generics = generics.0;
-            type_generics = None;
-            where_clause = generics.2;
-        }
-    }
-
-    let gen = quote! {
-        impl #impl_generics Element<#view_type_name> for #type_name #type_generics
-        #where_clause
-        {
-
-            type LayoutState = gpui::elements::AnyElement<V>;
-            type PaintState = ();
-
-            fn layout(
-                &mut self,
-                constraint: gpui::SizeConstraint,
-                view: &mut V,
-                cx: &mut gpui::ViewContext<V>,
-            ) -> (gpui::geometry::vector::Vector2F, gpui::elements::AnyElement<V>) {
-                let mut element = self.render(view, cx).into_any();
-                let size = element.layout(constraint, view, cx);
-                (size, element)
-            }
-
-            fn paint(
-                &mut self,
-                bounds: gpui::geometry::rect::RectF,
-                visible_bounds: gpui::geometry::rect::RectF,
-                element: &mut gpui::elements::AnyElement<V>,
-                view: &mut V,
-                cx: &mut gpui::ViewContext<V>,
-            ) {
-                element.paint(bounds.origin(), visible_bounds, view, cx);
-            }
-
-            fn rect_for_text_range(
-                &self,
-                range_utf16: std::ops::Range<usize>,
-                _: gpui::geometry::rect::RectF,
-                _: gpui::geometry::rect::RectF,
-                element: &gpui::elements::AnyElement<V>,
-                _: &(),
-                view: &V,
-                cx: &gpui::ViewContext<V>,
-            ) -> Option<gpui::geometry::rect::RectF> {
-                element.rect_for_text_range(range_utf16, view, cx)
-            }
-
-            fn debug(
-                &self,
-                _: gpui::geometry::rect::RectF,
-                element: &gpui::elements::AnyElement<V>,
-                _: &(),
-                view: &V,
-                cx: &gpui::ViewContext<V>,
-            ) -> gpui::json::Value {
-                element.debug(view, cx)
-            }
-        }
-    };
+#[proc_macro]
+pub fn style_helpers(input: TokenStream) -> TokenStream {
+    style_helpers::style_helpers(input)
+}
 
-    gen.into()
+#[proc_macro_attribute]
+pub fn test(args: TokenStream, function: TokenStream) -> TokenStream {
+    test::test(args, function)
 }

crates/rpc/src/peer.rs 🔗

@@ -342,7 +342,7 @@ impl Peer {
     pub fn add_test_connection(
         self: &Arc<Self>,
         connection: Connection,
-        executor: Arc<gpui::executor::Background>,
+        executor: gpui::BackgroundExecutor,
     ) -> (
         ConnectionId,
         impl Future<Output = anyhow::Result<()>> + Send,
@@ -559,7 +559,6 @@ mod tests {
     use async_tungstenite::tungstenite::Message as WebSocketMessage;
     use gpui::TestAppContext;
 
-    #[ctor::ctor]
     fn init_logger() {
         if std::env::var("RUST_LOG").is_ok() {
             env_logger::init();
@@ -568,7 +567,9 @@ mod tests {
 
     #[gpui::test(iterations = 50)]
     async fn test_request_response(cx: &mut TestAppContext) {
-        let executor = cx.foreground();
+        init_logger();
+
+        let executor = cx.executor();
 
         // create 2 clients connected to 1 server
         let server = Peer::new(0);
@@ -576,18 +577,18 @@ mod tests {
         let client2 = Peer::new(0);
 
         let (client1_to_server_conn, server_to_client_1_conn, _kill) =
-            Connection::in_memory(cx.background());
+            Connection::in_memory(cx.executor());
         let (client1_conn_id, io_task1, client1_incoming) =
-            client1.add_test_connection(client1_to_server_conn, cx.background());
+            client1.add_test_connection(client1_to_server_conn, cx.executor());
         let (_, io_task2, server_incoming1) =
-            server.add_test_connection(server_to_client_1_conn, cx.background());
+            server.add_test_connection(server_to_client_1_conn, cx.executor());
 
         let (client2_to_server_conn, server_to_client_2_conn, _kill) =
-            Connection::in_memory(cx.background());
+            Connection::in_memory(cx.executor());
         let (client2_conn_id, io_task3, client2_incoming) =
-            client2.add_test_connection(client2_to_server_conn, cx.background());
+            client2.add_test_connection(client2_to_server_conn, cx.executor());
         let (_, io_task4, server_incoming2) =
-            server.add_test_connection(server_to_client_2_conn, cx.background());
+            server.add_test_connection(server_to_client_2_conn, cx.executor());
 
         executor.spawn(io_task1).detach();
         executor.spawn(io_task2).detach();
@@ -664,25 +665,25 @@ mod tests {
 
     #[gpui::test(iterations = 50)]
     async fn test_order_of_response_and_incoming(cx: &mut TestAppContext) {
-        let executor = cx.foreground();
+        let executor = cx.executor();
         let server = Peer::new(0);
         let client = Peer::new(0);
 
         let (client_to_server_conn, server_to_client_conn, _kill) =
-            Connection::in_memory(cx.background());
+            Connection::in_memory(executor.clone());
         let (client_to_server_conn_id, io_task1, mut client_incoming) =
-            client.add_test_connection(client_to_server_conn, cx.background());
+            client.add_test_connection(client_to_server_conn, executor.clone());
+
         let (server_to_client_conn_id, io_task2, mut server_incoming) =
-            server.add_test_connection(server_to_client_conn, cx.background());
+            server.add_test_connection(server_to_client_conn, executor.clone());
 
         executor.spawn(io_task1).detach();
         executor.spawn(io_task2).detach();
 
         executor
             .spawn(async move {
-                let request = server_incoming
-                    .next()
-                    .await
+                let future = server_incoming.next().await;
+                let request = future
                     .unwrap()
                     .into_any()
                     .downcast::<TypedEnvelope<proto::Ping>>()
@@ -762,16 +763,16 @@ mod tests {
 
     #[gpui::test(iterations = 50)]
     async fn test_dropping_request_before_completion(cx: &mut TestAppContext) {
-        let executor = cx.foreground();
+        let executor = cx.executor();
         let server = Peer::new(0);
         let client = Peer::new(0);
 
         let (client_to_server_conn, server_to_client_conn, _kill) =
-            Connection::in_memory(cx.background());
+            Connection::in_memory(cx.executor());
         let (client_to_server_conn_id, io_task1, mut client_incoming) =
-            client.add_test_connection(client_to_server_conn, cx.background());
+            client.add_test_connection(client_to_server_conn, cx.executor());
         let (server_to_client_conn_id, io_task2, mut server_incoming) =
-            server.add_test_connection(server_to_client_conn, cx.background());
+            server.add_test_connection(server_to_client_conn, cx.executor());
 
         executor.spawn(io_task1).detach();
         executor.spawn(io_task2).detach();
@@ -858,7 +859,7 @@ mod tests {
             .detach();
 
         // Allow the request to make some progress before dropping it.
-        cx.background().simulate_random_delay().await;
+        cx.executor().simulate_random_delay().await;
         drop(request1_task);
 
         request2_task.await;
@@ -874,13 +875,13 @@ mod tests {
 
     #[gpui::test(iterations = 50)]
     async fn test_disconnect(cx: &mut TestAppContext) {
-        let executor = cx.foreground();
+        let executor = cx.executor();
 
-        let (client_conn, mut server_conn, _kill) = Connection::in_memory(cx.background());
+        let (client_conn, mut server_conn, _kill) = Connection::in_memory(executor.clone());
 
         let client = Peer::new(0);
         let (connection_id, io_handler, mut incoming) =
-            client.add_test_connection(client_conn, cx.background());
+            client.add_test_connection(client_conn, executor.clone());
 
         let (io_ended_tx, io_ended_rx) = oneshot::channel();
         executor
@@ -910,12 +911,12 @@ mod tests {
 
     #[gpui::test(iterations = 50)]
     async fn test_io_error(cx: &mut TestAppContext) {
-        let executor = cx.foreground();
-        let (client_conn, mut server_conn, _kill) = Connection::in_memory(cx.background());
+        let executor = cx.executor();
+        let (client_conn, mut server_conn, _kill) = Connection::in_memory(executor.clone());
 
         let client = Peer::new(0);
         let (connection_id, io_handler, mut incoming) =
-            client.add_test_connection(client_conn, cx.background());
+            client.add_test_connection(client_conn, executor.clone());
         executor.spawn(io_handler).detach();
         executor
             .spawn(async move { incoming.next().await })

crates/storybook/Cargo.toml 🔗

@@ -31,6 +31,7 @@ smallvec.workspace = true
 story = { path = "../story" }
 theme = { path = "../theme" }
 menu = { path = "../menu" }
+ui = { path = "../ui", features = ["stories"] }
 util = { path = "../util" }
 picker = { path = "../picker" }
 

crates/ui/src/components/popover.rs 🔗

@@ -1,9 +1,8 @@
 use gpui::{
-    div, AnyElement, Element, ElementId, IntoElement, ParentElement, RenderOnce, Styled,
+    div, AnyElement, Element, IntoElement, ParentElement, RenderOnce, Styled,
     WindowContext,
 };
 use smallvec::SmallVec;
-
 use crate::prelude::*;
 use crate::v_stack;
 

crates/xtask/Cargo.toml 🔗

@@ -1,13 +0,0 @@
-[package]
-name = "xtask"
-version = "0.1.0"
-edition = "2021"
-publish = false
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-anyhow = "1.0"
-clap = {version = "4.0", features = ["derive"]}
-theme = {path = "../theme"}
-serde_json.workspace = true
-schemars.workspace = true

crates/xtask/src/cli.rs 🔗

@@ -1,23 +0,0 @@
-use clap::{Parser, Subcommand};
-use std::path::PathBuf;
-/// Common utilities for Zed developers.
-// For more information, see [matklad's repository README](https://github.com/matklad/cargo-xtask/)
-#[derive(Parser)]
-#[command(author, version, about, long_about = None)]
-#[command(propagate_version = true)]
-pub struct Cli {
-    #[command(subcommand)]
-    pub command: Commands,
-}
-
-/// Command to run.
-#[derive(Subcommand)]
-pub enum Commands {
-    /// Builds theme types for interop with Typescript.
-    BuildThemeTypes {
-        #[clap(short, long, default_value = "schemas")]
-        out_dir: PathBuf,
-        #[clap(short, long, default_value = "theme.json")]
-        file_name: PathBuf,
-    },
-}

crates/xtask/src/main.rs 🔗

@@ -1,29 +0,0 @@
-mod cli;
-
-use std::path::PathBuf;
-
-use anyhow::Result;
-use clap::Parser;
-use schemars::schema_for;
-use theme::Theme;
-
-fn build_themes(out_dir: PathBuf, file_name: PathBuf) -> Result<()> {
-    let theme = schema_for!(Theme);
-    let output = serde_json::to_string_pretty(&theme)?;
-
-    std::fs::create_dir(&out_dir)?;
-
-    let mut file_path = out_dir;
-    file_path.push(file_name);
-
-    std::fs::write(file_path, output)?;
-
-    Ok(())
-}
-
-fn main() -> Result<()> {
-    let args = cli::Cli::parse();
-    match args.command {
-        cli::Commands::BuildThemeTypes { out_dir, file_name } => build_themes(out_dir, file_name),
-    }
-}