Docs and cleanup

Nathan Sobo created

Change summary

crates/editor2/src/editor.rs | 123 ++++++++++++++++++++++++++++++++++++++
crates/gpui2/src/action.rs   | 118 +++++++++++++++++++++++++-----------
2 files changed, 204 insertions(+), 37 deletions(-)

Detailed changes

crates/editor2/src/editor.rs 🔗

@@ -406,6 +406,129 @@ pub fn init_settings(cx: &mut AppContext) {
 
 pub fn init(cx: &mut AppContext) {
     init_settings(cx);
+    // cx.register_action_type(Editor::new_file);
+    // cx.register_action_type(Editor::new_file_in_direction);
+    // cx.register_action_type(Editor::cancel);
+    // cx.register_action_type(Editor::newline);
+    // cx.register_action_type(Editor::newline_above);
+    // cx.register_action_type(Editor::newline_below);
+    // cx.register_action_type(Editor::backspace);
+    // cx.register_action_type(Editor::delete);
+    // cx.register_action_type(Editor::tab);
+    // cx.register_action_type(Editor::tab_prev);
+    // cx.register_action_type(Editor::indent);
+    // cx.register_action_type(Editor::outdent);
+    // cx.register_action_type(Editor::delete_line);
+    // cx.register_action_type(Editor::join_lines);
+    // cx.register_action_type(Editor::sort_lines_case_sensitive);
+    // cx.register_action_type(Editor::sort_lines_case_insensitive);
+    // cx.register_action_type(Editor::reverse_lines);
+    // cx.register_action_type(Editor::shuffle_lines);
+    // cx.register_action_type(Editor::convert_to_upper_case);
+    // cx.register_action_type(Editor::convert_to_lower_case);
+    // cx.register_action_type(Editor::convert_to_title_case);
+    // cx.register_action_type(Editor::convert_to_snake_case);
+    // cx.register_action_type(Editor::convert_to_kebab_case);
+    // cx.register_action_type(Editor::convert_to_upper_camel_case);
+    // cx.register_action_type(Editor::convert_to_lower_camel_case);
+    // cx.register_action_type(Editor::delete_to_previous_word_start);
+    // cx.register_action_type(Editor::delete_to_previous_subword_start);
+    // cx.register_action_type(Editor::delete_to_next_word_end);
+    // cx.register_action_type(Editor::delete_to_next_subword_end);
+    // cx.register_action_type(Editor::delete_to_beginning_of_line);
+    // cx.register_action_type(Editor::delete_to_end_of_line);
+    // cx.register_action_type(Editor::cut_to_end_of_line);
+    // cx.register_action_type(Editor::duplicate_line);
+    // cx.register_action_type(Editor::move_line_up);
+    // cx.register_action_type(Editor::move_line_down);
+    // cx.register_action_type(Editor::transpose);
+    // cx.register_action_type(Editor::cut);
+    // cx.register_action_type(Editor::copy);
+    // cx.register_action_type(Editor::paste);
+    // cx.register_action_type(Editor::undo);
+    // cx.register_action_type(Editor::redo);
+    // cx.register_action_type(Editor::move_page_up);
+    // cx.register_action_type::<MoveDown>();
+    // cx.register_action_type(Editor::move_page_down);
+    // cx.register_action_type(Editor::next_screen);
+    // cx.register_action_type::<MoveLeft>();
+    // cx.register_action_type::<MoveRight>();
+    // cx.register_action_type(Editor::move_to_previous_word_start);
+    // cx.register_action_type(Editor::move_to_previous_subword_start);
+    // cx.register_action_type(Editor::move_to_next_word_end);
+    // cx.register_action_type(Editor::move_to_next_subword_end);
+    // cx.register_action_type(Editor::move_to_beginning_of_line);
+    // cx.register_action_type(Editor::move_to_end_of_line);
+    // cx.register_action_type(Editor::move_to_start_of_paragraph);
+    // cx.register_action_type(Editor::move_to_end_of_paragraph);
+    // cx.register_action_type(Editor::move_to_beginning);
+    // cx.register_action_type(Editor::move_to_end);
+    // cx.register_action_type(Editor::select_up);
+    // cx.register_action_type(Editor::select_down);
+    // cx.register_action_type(Editor::select_left);
+    // cx.register_action_type(Editor::select_right);
+    // cx.register_action_type(Editor::select_to_previous_word_start);
+    // cx.register_action_type(Editor::select_to_previous_subword_start);
+    // cx.register_action_type(Editor::select_to_next_word_end);
+    // cx.register_action_type(Editor::select_to_next_subword_end);
+    // cx.register_action_type(Editor::select_to_beginning_of_line);
+    // cx.register_action_type(Editor::select_to_end_of_line);
+    // cx.register_action_type(Editor::select_to_start_of_paragraph);
+    // cx.register_action_type(Editor::select_to_end_of_paragraph);
+    // cx.register_action_type(Editor::select_to_beginning);
+    // cx.register_action_type(Editor::select_to_end);
+    // cx.register_action_type(Editor::select_all);
+    // cx.register_action_type(Editor::select_all_matches);
+    // cx.register_action_type(Editor::select_line);
+    // cx.register_action_type(Editor::split_selection_into_lines);
+    // cx.register_action_type(Editor::add_selection_above);
+    // cx.register_action_type(Editor::add_selection_below);
+    // cx.register_action_type(Editor::select_next);
+    // cx.register_action_type(Editor::select_previous);
+    // cx.register_action_type(Editor::toggle_comments);
+    // cx.register_action_type(Editor::select_larger_syntax_node);
+    // cx.register_action_type(Editor::select_smaller_syntax_node);
+    // cx.register_action_type(Editor::move_to_enclosing_bracket);
+    // cx.register_action_type(Editor::undo_selection);
+    // cx.register_action_type(Editor::redo_selection);
+    // cx.register_action_type(Editor::go_to_diagnostic);
+    // cx.register_action_type(Editor::go_to_prev_diagnostic);
+    // cx.register_action_type(Editor::go_to_hunk);
+    // cx.register_action_type(Editor::go_to_prev_hunk);
+    // cx.register_action_type(Editor::go_to_definition);
+    // cx.register_action_type(Editor::go_to_definition_split);
+    // cx.register_action_type(Editor::go_to_type_definition);
+    // cx.register_action_type(Editor::go_to_type_definition_split);
+    // cx.register_action_type(Editor::fold);
+    // cx.register_action_type(Editor::fold_at);
+    // cx.register_action_type(Editor::unfold_lines);
+    // cx.register_action_type(Editor::unfold_at);
+    // cx.register_action_type(Editor::gutter_hover);
+    // cx.register_action_type(Editor::fold_selected_ranges);
+    // cx.register_action_type(Editor::show_completions);
+    // cx.register_action_type(Editor::toggle_code_actions);
+    // cx.register_action_type(Editor::open_excerpts);
+    // cx.register_action_type(Editor::toggle_soft_wrap);
+    // cx.register_action_type(Editor::toggle_inlay_hints);
+    // cx.register_action_type(Editor::reveal_in_finder);
+    // cx.register_action_type(Editor::copy_path);
+    // cx.register_action_type(Editor::copy_relative_path);
+    // cx.register_action_type(Editor::copy_highlight_json);
+    // cx.add_async_action(Editor::format);
+    // cx.register_action_type(Editor::restart_language_server);
+    // cx.register_action_type(Editor::show_character_palette);
+    // cx.add_async_action(Editor::confirm_completion);
+    // cx.add_async_action(Editor::confirm_code_action);
+    // cx.add_async_action(Editor::rename);
+    // cx.add_async_action(Editor::confirm_rename);
+    // cx.add_async_action(Editor::find_all_references);
+    // cx.register_action_type(Editor::next_copilot_suggestion);
+    // cx.register_action_type(Editor::previous_copilot_suggestion);
+    // cx.register_action_type(Editor::copilot_suggest);
+    // cx.register_action_type(Editor::context_menu_first);
+    // cx.register_action_type(Editor::context_menu_prev);
+    // cx.register_action_type(Editor::context_menu_next);
+    // cx.register_action_type(Editor::context_menu_last);
 
     hover_popover::init(cx);
     scroll::actions::init(cx);

crates/gpui2/src/action.rs 🔗

@@ -6,6 +6,49 @@ use parking_lot::{MappedRwLockReadGuard, RwLock, RwLockReadGuard};
 use serde::Deserialize;
 use std::any::{type_name, Any};
 
+/// Actions are used to implement keyboard-driven UI.
+/// When you declare an action, you can bind keys to the action in the keymap and
+/// listeners for that action in the element tree.
+///
+/// To declare a list of simple actions, you can use the actions! macro, which defines a simple unit struct
+/// action for each listed action name.
+/// ```rust
+/// actions!(MoveUp, MoveDown, MoveLeft, MoveRight, Newline);
+/// ```
+/// More complex data types can also be actions. If you annotate your type with the `#[action]` proc macro,
+/// it will automatically
+/// ```
+/// #[action]
+/// pub struct SelectNext {
+///     pub replace_newest: bool,
+/// }
+///
+/// Any type A that satisfies the following bounds is automatically an action:
+///
+/// ```
+/// A: for<'a> Deserialize<'a> + PartialEq + Clone + Default + std::fmt::Debug + 'static,
+/// ```
+///
+/// The `#[action]` annotation will derive these implementations for your struct automatically. If you
+/// want to control them manually, you can use the lower-level `#[register_action]` macro, which only
+/// generates the code needed to register your action before `main`. Then you'll need to implement all
+/// the traits manually.
+///
+/// ```
+/// #[gpui::register_action]
+/// #[derive(gpui::serde::Deserialize, std::cmp::PartialEq, std::clone::Clone, std::fmt::Debug)]
+/// pub struct Paste {
+///     pub content: SharedString,
+/// }
+///
+/// impl std::default::Default for Paste {
+///     fn default() -> Self {
+///         Self {
+///             content: SharedString::from("🍝"),
+///         }
+///     }
+/// }
+/// ```
 pub trait Action: std::fmt::Debug + 'static {
     fn qualified_name() -> SharedString
     where
@@ -19,6 +62,44 @@ pub trait Action: std::fmt::Debug + 'static {
     fn as_any(&self) -> &dyn Any;
 }
 
+// Types become actions by satisfying a list of trait bounds.
+impl<A> Action for A
+where
+    A: for<'a> Deserialize<'a> + PartialEq + Clone + Default + std::fmt::Debug + 'static,
+{
+    fn qualified_name() -> SharedString {
+        // todo!() remove the 2 replacement when migration is done
+        type_name::<A>().replace("2::", "::").into()
+    }
+
+    fn build(params: Option<serde_json::Value>) -> Result<Box<dyn Action>>
+    where
+        Self: Sized,
+    {
+        let action = if let Some(params) = params {
+            serde_json::from_value(params).context("failed to deserialize action")?
+        } else {
+            Self::default()
+        };
+        Ok(Box::new(action))
+    }
+
+    fn partial_eq(&self, action: &dyn Action) -> bool {
+        action
+            .as_any()
+            .downcast_ref::<Self>()
+            .map_or(false, |a| self == a)
+    }
+
+    fn boxed_clone(&self) -> Box<dyn Action> {
+        Box::new(self.clone())
+    }
+
+    fn as_any(&self) -> &dyn Any {
+        self
+    }
+}
+
 type ActionBuilder = fn(json: Option<serde_json::Value>) -> anyhow::Result<Box<dyn Action>>;
 
 lazy_static! {
@@ -84,43 +165,6 @@ macro_rules! actions {
     };
 }
 
-impl<A> Action for A
-where
-    A: for<'a> Deserialize<'a> + PartialEq + Clone + Default + std::fmt::Debug + 'static,
-{
-    fn qualified_name() -> SharedString {
-        // todo!() remove the 2 replacement when migration is done
-        type_name::<A>().replace("2::", "::").into()
-    }
-
-    fn build(params: Option<serde_json::Value>) -> Result<Box<dyn Action>>
-    where
-        Self: Sized,
-    {
-        let action = if let Some(params) = params {
-            serde_json::from_value(params).context("failed to deserialize action")?
-        } else {
-            Self::default()
-        };
-        Ok(Box::new(action))
-    }
-
-    fn partial_eq(&self, action: &dyn Action) -> bool {
-        action
-            .as_any()
-            .downcast_ref::<Self>()
-            .map_or(false, |a| self == a)
-    }
-
-    fn boxed_clone(&self) -> Box<dyn Action> {
-        Box::new(self.clone())
-    }
-
-    fn as_any(&self) -> &dyn Any {
-        self
-    }
-}
-
 #[derive(Clone, Debug, Default, Eq, PartialEq)]
 pub struct DispatchContext {
     set: HashSet<SharedString>,