diff --git a/crates/editor/src/actions.rs b/crates/editor/src/actions.rs index 721b71ddec..ce68c24ae2 100644 --- a/crates/editor/src/actions.rs +++ b/crates/editor/src/actions.rs @@ -311,7 +311,6 @@ gpui::actions!( OpenExcerpts, OpenExcerptsSplit, OpenProposedChangesEditor, - OpenFile, OpenDocs, OpenPermalinkToLine, OpenUrl, @@ -391,3 +390,5 @@ gpui::actions!( action_as!(outline, ToggleOutline as Toggle); action_as!(go_to_line, ToggleGoToLine as Toggle); + +action_as!(editor, OpenSelectedFilename as [OpenFile]); diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 02f01dbaec..68aeda34e6 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -9479,7 +9479,7 @@ impl Editor { url_finder.detach(); } - pub fn open_file(&mut self, _: &OpenFile, cx: &mut ViewContext) { + pub fn open_selected_filename(&mut self, _: &OpenSelectedFilename, cx: &mut ViewContext) { let Some(workspace) = self.workspace() else { return; }; diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 1f8925e48a..026531bf19 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -344,7 +344,7 @@ impl EditorElement { .detach_and_log_err(cx); }); register_action(view, cx, Editor::open_url); - register_action(view, cx, Editor::open_file); + register_action(view, cx, Editor::open_selected_filename); register_action(view, cx, Editor::fold); register_action(view, cx, Editor::fold_at_level); register_action(view, cx, Editor::fold_all); diff --git a/crates/gpui/src/action.rs b/crates/gpui/src/action.rs index b81ba6136f..7bbad259dc 100644 --- a/crates/gpui/src/action.rs +++ b/crates/gpui/src/action.rs @@ -62,6 +62,14 @@ pub trait Action: 'static + Send { fn build(value: serde_json::Value) -> Result> where Self: Sized; + + /// A list of alternate names for this action. + fn aliases() -> &'static [&'static str] + where + Self: Sized, + { + &[] + } } impl std::fmt::Debug for dyn Action { @@ -111,6 +119,7 @@ pub type MacroActionBuilder = fn() -> ActionData; #[doc(hidden)] pub struct ActionData { pub name: &'static str, + pub aliases: &'static [&'static str], pub type_id: TypeId, pub build: ActionBuilder, } @@ -134,6 +143,7 @@ impl ActionRegistry { pub(crate) fn load_action(&mut self) { self.insert_action(ActionData { name: A::debug_name(), + aliases: A::aliases(), type_id: TypeId::of::(), build: A::build, }); @@ -142,6 +152,9 @@ impl ActionRegistry { fn insert_action(&mut self, action: ActionData) { let name: SharedString = action.name.into(); self.builders_by_name.insert(name.clone(), action.build); + for &alias in action.aliases { + self.builders_by_name.insert(alias.into(), action.build); + } self.names_by_type_id.insert(action.type_id, name.clone()); self.all_names.push(name); } @@ -207,7 +220,7 @@ macro_rules! actions { /// `impl_action_as!` #[macro_export] macro_rules! action_as { - ($namespace:path, $name:ident as $visual_name:tt) => { + ($namespace:path, $name:ident as $visual_name:ident) => { #[doc = "The `"] #[doc = stringify!($name)] #[doc = "` action, see [`gpui::actions!`]"] @@ -234,6 +247,39 @@ macro_rules! action_as { gpui::register_action!($name); }; + + ($namespace:path, $name:ident as [$($alias:ident),* $(,)?]) => { + #[doc = "The `"] + #[doc = stringify!($name)] + #[doc = "` action, see [`gpui::actions!`]"] + #[derive( + ::std::cmp::PartialEq, + ::std::clone::Clone, + ::std::default::Default, + ::std::fmt::Debug, + gpui::private::serde_derive::Deserialize, + )] + #[serde(crate = "gpui::private::serde")] + pub struct $name; + + gpui::__impl_action!( + $namespace, + $name, + $name, + fn build( + _: gpui::private::serde_json::Value, + ) -> gpui::Result<::std::boxed::Box> { + Ok(Box::new(Self)) + }, + fn aliases() -> &'static [&'static str] { + &[ + $(concat!(stringify!($namespace), "::", stringify!($alias))),* + ] + } + ); + + gpui::register_action!($name); + }; } /// Implements the Action trait for any struct that implements Clone, Default, PartialEq, and serde_deserialize::Deserialize @@ -277,7 +323,7 @@ macro_rules! impl_action_as { #[doc(hidden)] #[macro_export] macro_rules! __impl_action { - ($namespace:path, $name:ident, $visual_name:tt, $build:item) => { + ($namespace:path, $name:ident, $visual_name:tt, $($items:item),*) => { impl gpui::Action for $name { fn name(&self) -> &'static str { @@ -299,8 +345,6 @@ macro_rules! __impl_action { ) } - $build - fn partial_eq(&self, action: &dyn gpui::Action) -> bool { action .as_any() @@ -315,6 +359,8 @@ macro_rules! __impl_action { fn as_any(&self) -> &dyn ::std::any::Any { self } + + $($items)* } }; } diff --git a/crates/gpui_macros/src/register_action.rs b/crates/gpui_macros/src/register_action.rs index 7ec1d6dd4b..6ff7df7f43 100644 --- a/crates/gpui_macros/src/register_action.rs +++ b/crates/gpui_macros/src/register_action.rs @@ -32,6 +32,7 @@ pub(crate) fn register_action(type_name: &Ident) -> proc_macro2::TokenStream { fn #action_builder_fn_name() -> gpui::ActionData { gpui::ActionData { name: <#type_name as gpui::Action>::debug_name(), + aliases: <#type_name as gpui::Action>::aliases(), type_id: ::std::any::TypeId::of::<#type_name>(), build: <#type_name as gpui::Action>::build, }