Docs and cleanup

This commit is contained in:
Nathan Sobo 2023-11-07 21:26:51 -07:00
parent 814e62050c
commit fdc9ea7f9b
2 changed files with 204 additions and 37 deletions

View file

@ -406,6 +406,129 @@ pub fn init_settings(cx: &mut AppContext) {
pub fn init(cx: &mut AppContext) { pub fn init(cx: &mut AppContext) {
init_settings(cx); 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); hover_popover::init(cx);
scroll::actions::init(cx); scroll::actions::init(cx);

View file

@ -6,6 +6,49 @@ use parking_lot::{MappedRwLockReadGuard, RwLock, RwLockReadGuard};
use serde::Deserialize; use serde::Deserialize;
use std::any::{type_name, Any}; 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 { pub trait Action: std::fmt::Debug + 'static {
fn qualified_name() -> SharedString fn qualified_name() -> SharedString
where where
@ -19,6 +62,44 @@ pub trait Action: std::fmt::Debug + 'static {
fn as_any(&self) -> &dyn Any; 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>>; type ActionBuilder = fn(json: Option<serde_json::Value>) -> anyhow::Result<Box<dyn Action>>;
lazy_static! { 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)] #[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct DispatchContext { pub struct DispatchContext {
set: HashSet<SharedString>, set: HashSet<SharedString>,