Register actions globally before main
This commit is contained in:
parent
80630cd4d9
commit
814e62050c
8 changed files with 33 additions and 169 deletions
|
@ -80,7 +80,6 @@ pub fn init(client: &Arc<Client>, cx: &mut AppContext) {
|
|||
init_settings(cx);
|
||||
|
||||
let client = Arc::downgrade(client);
|
||||
cx.register_action_type::<SignIn>();
|
||||
cx.on_action({
|
||||
let client = client.clone();
|
||||
move |_: &SignIn, cx| {
|
||||
|
@ -93,7 +92,6 @@ pub fn init(client: &Arc<Client>, cx: &mut AppContext) {
|
|||
}
|
||||
});
|
||||
|
||||
cx.register_action_type::<SignOut>();
|
||||
cx.on_action({
|
||||
let client = client.clone();
|
||||
move |_: &SignOut, cx| {
|
||||
|
@ -106,7 +104,6 @@ pub fn init(client: &Arc<Client>, cx: &mut AppContext) {
|
|||
}
|
||||
});
|
||||
|
||||
cx.register_action_type::<Reconnect>();
|
||||
cx.on_action({
|
||||
let client = client.clone();
|
||||
move |_: &Reconnect, cx| {
|
||||
|
|
|
@ -406,130 +406,6 @@ 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::<MoveUp>();
|
||||
// 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);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use crate::SharedString;
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use collections::{HashMap, HashSet};
|
||||
use ctor::ctor;
|
||||
use parking_lot::Mutex;
|
||||
use lazy_static::lazy_static;
|
||||
use parking_lot::{MappedRwLockReadGuard, RwLock, RwLockReadGuard};
|
||||
use serde::Deserialize;
|
||||
use std::any::{type_name, Any};
|
||||
|
||||
|
@ -21,23 +21,41 @@ pub trait Action: std::fmt::Debug + 'static {
|
|||
|
||||
type ActionBuilder = fn(json: Option<serde_json::Value>) -> anyhow::Result<Box<dyn Action>>;
|
||||
|
||||
#[ctor]
|
||||
static ACTION_BUILDERS: Mutex<HashMap<SharedString, ActionBuilder>> = Mutex::default();
|
||||
lazy_static! {
|
||||
static ref ACTION_REGISTRY: RwLock<ActionRegistry> = RwLock::default();
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct ActionRegistry {
|
||||
builders_by_name: HashMap<SharedString, ActionBuilder>,
|
||||
all_names: Vec<SharedString>, // So we can return a static slice.
|
||||
}
|
||||
|
||||
/// Register an action type to allow it to be referenced in keymaps.
|
||||
pub fn register_action<A: Action>() {
|
||||
ACTION_BUILDERS.lock().insert(A::qualified_name(), A::build);
|
||||
let name = A::qualified_name();
|
||||
let mut lock = ACTION_REGISTRY.write();
|
||||
lock.builders_by_name.insert(name.clone(), A::build);
|
||||
lock.all_names.push(name);
|
||||
}
|
||||
|
||||
/// Construct an action based on its name and optional JSON parameters sourced from the keymap.
|
||||
pub fn build_action(name: &str, params: Option<serde_json::Value>) -> Result<Box<dyn Action>> {
|
||||
let lock = &ACTION_BUILDERS.lock();
|
||||
let lock = ACTION_REGISTRY.read();
|
||||
let build_action = lock
|
||||
.builders_by_name
|
||||
.get(name)
|
||||
.ok_or_else(|| anyhow!("no action type registered for {}", name))?;
|
||||
(build_action)(params)
|
||||
}
|
||||
|
||||
pub fn all_action_names() -> MappedRwLockReadGuard<'static, [SharedString]> {
|
||||
let lock = ACTION_REGISTRY.read();
|
||||
RwLockReadGuard::map(lock, |registry: &ActionRegistry| {
|
||||
registry.all_names.as_slice()
|
||||
})
|
||||
}
|
||||
|
||||
// actions defines structs that can be used as actions.
|
||||
#[macro_export]
|
||||
macro_rules! actions {
|
||||
|
|
|
@ -17,9 +17,9 @@ use crate::{
|
|||
current_platform, image_cache::ImageCache, Action, AnyBox, AnyView, AnyWindowHandle,
|
||||
AppMetadata, AssetSource, BackgroundExecutor, ClipboardItem, Context, DispatchPhase, DisplayId,
|
||||
Entity, FocusEvent, FocusHandle, FocusId, ForegroundExecutor, KeyBinding, Keymap, LayoutId,
|
||||
PathPromptOptions, Pixels, Platform, PlatformDisplay, Point, Render, SharedString,
|
||||
SubscriberSet, Subscription, SvgRenderer, Task, TextStyle, TextStyleRefinement, TextSystem,
|
||||
View, Window, WindowContext, WindowHandle, WindowId,
|
||||
PathPromptOptions, Pixels, Platform, PlatformDisplay, Point, Render, SubscriberSet,
|
||||
Subscription, SvgRenderer, Task, TextStyle, TextStyleRefinement, TextSystem, View, Window,
|
||||
WindowContext, WindowHandle, WindowId,
|
||||
};
|
||||
use anyhow::{anyhow, Result};
|
||||
use collections::{HashMap, HashSet, VecDeque};
|
||||
|
@ -140,7 +140,6 @@ impl App {
|
|||
}
|
||||
}
|
||||
|
||||
type ActionBuilder = fn(json: Option<serde_json::Value>) -> anyhow::Result<Box<dyn Action>>;
|
||||
pub(crate) type FrameCallback = Box<dyn FnOnce(&mut AppContext)>;
|
||||
type Handler = Box<dyn FnMut(&mut AppContext) -> bool + 'static>;
|
||||
type Listener = Box<dyn FnMut(&dyn Any, &mut AppContext) -> bool + 'static>;
|
||||
|
@ -176,7 +175,6 @@ pub struct AppContext {
|
|||
pub(crate) keymap: Arc<Mutex<Keymap>>,
|
||||
pub(crate) global_action_listeners:
|
||||
HashMap<TypeId, Vec<Box<dyn Fn(&dyn Action, DispatchPhase, &mut Self)>>>,
|
||||
action_builders: HashMap<SharedString, ActionBuilder>,
|
||||
pending_effects: VecDeque<Effect>,
|
||||
pub(crate) pending_notifications: HashSet<EntityId>,
|
||||
pub(crate) pending_global_notifications: HashSet<TypeId>,
|
||||
|
@ -234,7 +232,6 @@ impl AppContext {
|
|||
windows: SlotMap::with_key(),
|
||||
keymap: Arc::new(Mutex::new(Keymap::default())),
|
||||
global_action_listeners: HashMap::default(),
|
||||
action_builders: HashMap::default(),
|
||||
pending_effects: VecDeque::new(),
|
||||
pending_notifications: HashSet::default(),
|
||||
pending_global_notifications: HashSet::default(),
|
||||
|
@ -695,10 +692,6 @@ impl AppContext {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn all_action_names<'a>(&'a self) -> impl Iterator<Item = SharedString> + 'a {
|
||||
self.action_builders.keys().cloned()
|
||||
}
|
||||
|
||||
/// Move the global of the given type to the stack.
|
||||
pub(crate) fn lease_global<G: 'static>(&mut self) -> GlobalLease<G> {
|
||||
GlobalLease::new(
|
||||
|
@ -761,24 +754,6 @@ impl AppContext {
|
|||
}));
|
||||
}
|
||||
|
||||
/// Register an action type to allow it to be referenced in keymaps.
|
||||
pub fn register_action_type<A: Action>(&mut self) {
|
||||
self.action_builders.insert(A::qualified_name(), A::build);
|
||||
}
|
||||
|
||||
/// Construct an action based on its name and parameters.
|
||||
pub fn build_action(
|
||||
&mut self,
|
||||
name: &str,
|
||||
params: Option<serde_json::Value>,
|
||||
) -> Result<Box<dyn Action>> {
|
||||
let build = self
|
||||
.action_builders
|
||||
.get(name)
|
||||
.ok_or_else(|| anyhow!("no action type registered for {}", name))?;
|
||||
(build)(params)
|
||||
}
|
||||
|
||||
/// Event handlers propagate events by default. Call this method to stop dispatching to
|
||||
/// event handlers with a lower z-index (mouse) or higher in the tree (keyboard). This is
|
||||
/// the opposite of [propagate]. It's also possible to cancel a call to [propagate] by
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
// Input:
|
||||
//
|
||||
// struct Foo {}
|
||||
// struct FooBar {}
|
||||
|
||||
// Output:
|
||||
//
|
||||
// struct Foo {}
|
||||
// struct FooBar {}
|
||||
//
|
||||
// #[allow(non_snake_case)]
|
||||
// #[gpui2::ctor]
|
||||
// fn register_Foo_builder() {
|
||||
// fn register_foobar_builder() {
|
||||
// gpui2::register_action_builder::<Foo>()
|
||||
// }
|
||||
use proc_macro::TokenStream;
|
||||
|
|
|
@ -73,9 +73,9 @@ impl KeymapFile {
|
|||
"Expected first item in array to be a string."
|
||||
)));
|
||||
};
|
||||
cx.build_action(&name, Some(data))
|
||||
gpui::build_action(&name, Some(data))
|
||||
}
|
||||
Value::String(name) => cx.build_action(&name, None),
|
||||
Value::String(name) => gpui::build_action(&name, None),
|
||||
Value::Null => Ok(no_action()),
|
||||
_ => {
|
||||
return Some(Err(anyhow!("Expected two-element array, got {action:?}")))
|
||||
|
|
|
@ -15,8 +15,6 @@ impl FocusStory {
|
|||
KeyBinding::new("cmd-a", ActionB, Some("child-1")),
|
||||
KeyBinding::new("cmd-c", ActionC, None),
|
||||
]);
|
||||
cx.register_action_type::<ActionA>();
|
||||
cx.register_action_type::<ActionB>();
|
||||
|
||||
cx.build_view(move |cx| Self {})
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ impl LspAdapter for JsonLspAdapter {
|
|||
&self,
|
||||
cx: &mut AppContext,
|
||||
) -> BoxFuture<'static, serde_json::Value> {
|
||||
let action_names = cx.all_action_names().collect::<Vec<_>>();
|
||||
let action_names = gpui::all_action_names();
|
||||
let staff_mode = cx.is_staff();
|
||||
let language_names = &self.languages.language_names();
|
||||
let settings_schema = cx.global::<SettingsStore>().json_schema(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue