gpui: Simplify Action
macros + support doc comments in actions!
(#33263)
Instead of a menagerie of macros for implementing `Action`, now there are just two: * `actions!(editor, [MoveLeft, MoveRight])` * `#[derive(..., Action)]` with `#[action(namespace = editor)]` In both contexts, `///` doc comments can be provided and will be used in `JsonSchema`. In both contexts, parameters can provided in `#[action(...)]`: - `namespace = some_namespace` sets the namespace. In Zed this is required. - `name = "ActionName"` overrides the action's name. This must not contain "::". - `no_json` causes the `build` method to always error and `action_json_schema` to return `None` and allows actions not implement `serde::Serialize` and `schemars::JsonSchema`. - `no_register` skips registering the action. This is useful for implementing the `Action` trait while not supporting invocation by name or JSON deserialization. - `deprecated_aliases = ["editor::SomeAction"]` specifies deprecated old names for the action. These action names should *not* correspond to any actions that are registered. These old names can then still be used to refer to invoke this action. In Zed, the keymap JSON schema will accept these old names and provide warnings. - `deprecated = "Message about why this action is deprecation"` specifies a deprecation message. In Zed, the keymap JSON schema will cause this to be displayed as a warning. This is a new feature. Also makes the following changes since this seems like a good time to make breaking changes: * In `zed.rs` tests adds a test with an explicit list of namespaces. The rationale for this is that there is otherwise no checking of `namespace = ...` attributes. * `Action::debug_name` renamed to `name_for_type`, since its only difference with `name` was that it * `Action::name` now returns `&'static str` instead of `&str` to match the return of `name_for_type`. This makes the action trait more limited, but the code was already assuming that `name_for_type` is the same as `name`, and it requires `&'static`. So really this just makes the trait harder to misuse. * Various action reflection methods now use `&'static str` instead of `SharedString`. Release Notes: - N/A
This commit is contained in:
parent
21f985a018
commit
24c94d474e
44 changed files with 878 additions and 789 deletions
4
.rules
4
.rules
|
@ -100,9 +100,7 @@ Often event handlers will want to update the entity that's in the current `Conte
|
||||||
|
|
||||||
Actions are dispatched via user keyboard interaction or in code via `window.dispatch_action(SomeAction.boxed_clone(), cx)` or `focus_handle.dispatch_action(&SomeAction, window, cx)`.
|
Actions are dispatched via user keyboard interaction or in code via `window.dispatch_action(SomeAction.boxed_clone(), cx)` or `focus_handle.dispatch_action(&SomeAction, window, cx)`.
|
||||||
|
|
||||||
Actions which have no data inside are created and registered with the `actions!(some_namespace, [SomeAction, AnotherAction])` macro call.
|
Actions with no data defined with the `actions!(some_namespace, [SomeAction, AnotherAction])` macro call. Otherwise the `Action` derive macro is used. Doc comments on actions are displayed to the user.
|
||||||
|
|
||||||
Actions that do have data must implement `Clone, Default, PartialEq, Deserialize, JsonSchema` and can be registered with an `impl_actions!(some_namespace, [SomeActionWithData])` macro call.
|
|
||||||
|
|
||||||
Action handlers can be registered on an element via the event handler `.on_action(|action, window, cx| ...)`. Like other event handlers, this is often used with `cx.listener`.
|
Action handlers can be registered on an element via the event handler `.on_action(|action, window, cx| ...)`. Like other event handlers, this is often used with `cx.listener`.
|
||||||
|
|
||||||
|
|
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -19970,6 +19970,7 @@ dependencies = [
|
||||||
"inline_completion_button",
|
"inline_completion_button",
|
||||||
"inspector_ui",
|
"inspector_ui",
|
||||||
"install_cli",
|
"install_cli",
|
||||||
|
"itertools 0.14.0",
|
||||||
"jj_ui",
|
"jj_ui",
|
||||||
"journal",
|
"journal",
|
||||||
"language",
|
"language",
|
||||||
|
@ -19994,6 +19995,7 @@ dependencies = [
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"paths",
|
"paths",
|
||||||
"picker",
|
"picker",
|
||||||
|
"pretty_assertions",
|
||||||
"profiling",
|
"profiling",
|
||||||
"project",
|
"project",
|
||||||
"project_panel",
|
"project_panel",
|
||||||
|
|
|
@ -27,7 +27,7 @@ use assistant_slash_command::SlashCommandRegistry;
|
||||||
use client::Client;
|
use client::Client;
|
||||||
use feature_flags::FeatureFlagAppExt as _;
|
use feature_flags::FeatureFlagAppExt as _;
|
||||||
use fs::Fs;
|
use fs::Fs;
|
||||||
use gpui::{App, Entity, actions, impl_actions};
|
use gpui::{Action, App, Entity, actions};
|
||||||
use language::LanguageRegistry;
|
use language::LanguageRegistry;
|
||||||
use language_model::{
|
use language_model::{
|
||||||
ConfiguredModel, LanguageModel, LanguageModelId, LanguageModelProviderId, LanguageModelRegistry,
|
ConfiguredModel, LanguageModel, LanguageModelId, LanguageModelProviderId, LanguageModelRegistry,
|
||||||
|
@ -84,13 +84,15 @@ actions!(
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
#[derive(Default, Clone, PartialEq, Deserialize, JsonSchema)]
|
#[derive(Default, Clone, PartialEq, Deserialize, JsonSchema, Action)]
|
||||||
|
#[action(namespace = agent)]
|
||||||
pub struct NewThread {
|
pub struct NewThread {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
from_thread_id: Option<ThreadId>,
|
from_thread_id: Option<ThreadId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
|
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema, Action)]
|
||||||
|
#[action(namespace = agent)]
|
||||||
pub struct ManageProfiles {
|
pub struct ManageProfiles {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub customize_tools: Option<AgentProfileId>,
|
pub customize_tools: Option<AgentProfileId>,
|
||||||
|
@ -104,8 +106,6 @@ impl ManageProfiles {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_actions!(agent, [NewThread, ManageProfiles]);
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(crate) enum ModelUsageContext {
|
pub(crate) enum ModelUsageContext {
|
||||||
Thread(Entity<Thread>),
|
Thread(Entity<Thread>),
|
||||||
|
|
|
@ -27,11 +27,11 @@ use editor::{FoldPlaceholder, display_map::CreaseId};
|
||||||
use fs::Fs;
|
use fs::Fs;
|
||||||
use futures::FutureExt;
|
use futures::FutureExt;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
Animation, AnimationExt, AnyElement, AnyView, App, ClipboardEntry, ClipboardItem, Empty,
|
Action, Animation, AnimationExt, AnyElement, AnyView, App, ClipboardEntry, ClipboardItem,
|
||||||
Entity, EventEmitter, FocusHandle, Focusable, FontWeight, Global, InteractiveElement,
|
Empty, Entity, EventEmitter, FocusHandle, Focusable, FontWeight, Global, InteractiveElement,
|
||||||
IntoElement, ParentElement, Pixels, Render, RenderImage, SharedString, Size,
|
IntoElement, ParentElement, Pixels, Render, RenderImage, SharedString, Size,
|
||||||
StatefulInteractiveElement, Styled, Subscription, Task, Transformation, WeakEntity, actions,
|
StatefulInteractiveElement, Styled, Subscription, Task, Transformation, WeakEntity, actions,
|
||||||
div, img, impl_internal_actions, percentage, point, prelude::*, pulsating_between, size,
|
div, img, percentage, point, prelude::*, pulsating_between, size,
|
||||||
};
|
};
|
||||||
use indexed_docs::IndexedDocsStore;
|
use indexed_docs::IndexedDocsStore;
|
||||||
use language::{
|
use language::{
|
||||||
|
@ -99,14 +99,13 @@ actions!(
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
#[derive(PartialEq, Clone)]
|
#[derive(PartialEq, Clone, Action)]
|
||||||
|
#[action(namespace = assistant, no_json, no_register)]
|
||||||
pub enum InsertDraggedFiles {
|
pub enum InsertDraggedFiles {
|
||||||
ProjectPaths(Vec<ProjectPath>),
|
ProjectPaths(Vec<ProjectPath>),
|
||||||
ExternalFiles(Vec<PathBuf>),
|
ExternalFiles(Vec<PathBuf>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_internal_actions!(assistant, [InsertDraggedFiles]);
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
struct ScrollPosition {
|
struct ScrollPosition {
|
||||||
offset_before_cursor: gpui::Point<f32>,
|
offset_before_cursor: gpui::Point<f32>,
|
||||||
|
|
|
@ -4,8 +4,7 @@ use collections::{HashSet, IndexMap};
|
||||||
use feature_flags::ZedProFeatureFlag;
|
use feature_flags::ZedProFeatureFlag;
|
||||||
use fuzzy::{StringMatch, StringMatchCandidate, match_strings};
|
use fuzzy::{StringMatch, StringMatchCandidate, match_strings};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
Action, AnyElement, App, BackgroundExecutor, DismissEvent, Subscription, Task,
|
Action, AnyElement, App, BackgroundExecutor, DismissEvent, Subscription, Task, actions,
|
||||||
action_with_deprecated_aliases,
|
|
||||||
};
|
};
|
||||||
use language_model::{
|
use language_model::{
|
||||||
AuthenticateError, ConfiguredModel, LanguageModel, LanguageModelProviderId,
|
AuthenticateError, ConfiguredModel, LanguageModel, LanguageModelProviderId,
|
||||||
|
@ -16,12 +15,11 @@ use picker::{Picker, PickerDelegate};
|
||||||
use proto::Plan;
|
use proto::Plan;
|
||||||
use ui::{ListItem, ListItemSpacing, prelude::*};
|
use ui::{ListItem, ListItemSpacing, prelude::*};
|
||||||
|
|
||||||
action_with_deprecated_aliases!(
|
actions!(
|
||||||
agent,
|
agent,
|
||||||
ToggleModelSelector,
|
|
||||||
[
|
[
|
||||||
"assistant::ToggleModelSelector",
|
#[action(deprecated_aliases = ["assistant::ToggleModelSelector", "assistant2::ToggleModelSelector"])]
|
||||||
"assistant2::ToggleModelSelector"
|
ToggleModelSelector
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -247,7 +247,7 @@ fn dump_all_gpui_actions() -> Vec<ActionDef> {
|
||||||
.map(|action| ActionDef {
|
.map(|action| ActionDef {
|
||||||
name: action.name,
|
name: action.name,
|
||||||
human_name: command_palette::humanize_action_name(action.name),
|
human_name: command_palette::humanize_action_name(action.name),
|
||||||
deprecated_aliases: action.aliases,
|
deprecated_aliases: action.deprecated_aliases,
|
||||||
})
|
})
|
||||||
.collect::<Vec<ActionDef>>();
|
.collect::<Vec<ActionDef>>();
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,27 @@
|
||||||
//! This module contains all actions supported by [`Editor`].
|
//! This module contains all actions supported by [`Editor`].
|
||||||
use super::*;
|
use super::*;
|
||||||
use gpui::{action_as, action_with_deprecated_aliases, actions};
|
use gpui::{Action, actions};
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use util::serde::default_true;
|
use util::serde::default_true;
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct SelectNext {
|
pub struct SelectNext {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub replace_newest: bool,
|
pub replace_newest: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct SelectPrevious {
|
pub struct SelectPrevious {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub replace_newest: bool,
|
pub replace_newest: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct MoveToBeginningOfLine {
|
pub struct MoveToBeginningOfLine {
|
||||||
#[serde(default = "default_true")]
|
#[serde(default = "default_true")]
|
||||||
|
@ -27,7 +30,8 @@ pub struct MoveToBeginningOfLine {
|
||||||
pub stop_at_indent: bool,
|
pub stop_at_indent: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct SelectToBeginningOfLine {
|
pub struct SelectToBeginningOfLine {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
@ -36,42 +40,48 @@ pub struct SelectToBeginningOfLine {
|
||||||
pub stop_at_indent: bool,
|
pub stop_at_indent: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct DeleteToBeginningOfLine {
|
pub struct DeleteToBeginningOfLine {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub(super) stop_at_indent: bool,
|
pub(super) stop_at_indent: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct MovePageUp {
|
pub struct MovePageUp {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub(super) center_cursor: bool,
|
pub(super) center_cursor: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct MovePageDown {
|
pub struct MovePageDown {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub(super) center_cursor: bool,
|
pub(super) center_cursor: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct MoveToEndOfLine {
|
pub struct MoveToEndOfLine {
|
||||||
#[serde(default = "default_true")]
|
#[serde(default = "default_true")]
|
||||||
pub stop_at_soft_wraps: bool,
|
pub stop_at_soft_wraps: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct SelectToEndOfLine {
|
pub struct SelectToEndOfLine {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub(super) stop_at_soft_wraps: bool,
|
pub(super) stop_at_soft_wraps: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct ToggleCodeActions {
|
pub struct ToggleCodeActions {
|
||||||
// Source from which the action was deployed.
|
// Source from which the action was deployed.
|
||||||
|
@ -91,28 +101,32 @@ pub enum CodeActionSource {
|
||||||
QuickActionBar,
|
QuickActionBar,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct ConfirmCompletion {
|
pub struct ConfirmCompletion {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub item_ix: Option<usize>,
|
pub item_ix: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct ComposeCompletion {
|
pub struct ComposeCompletion {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub item_ix: Option<usize>,
|
pub item_ix: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct ConfirmCodeAction {
|
pub struct ConfirmCodeAction {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub item_ix: Option<usize>,
|
pub item_ix: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct ToggleComments {
|
pub struct ToggleComments {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
@ -121,83 +135,96 @@ pub struct ToggleComments {
|
||||||
pub ignore_indent: bool,
|
pub ignore_indent: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct MoveUpByLines {
|
pub struct MoveUpByLines {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub(super) lines: u32,
|
pub(super) lines: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct MoveDownByLines {
|
pub struct MoveDownByLines {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub(super) lines: u32,
|
pub(super) lines: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct SelectUpByLines {
|
pub struct SelectUpByLines {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub(super) lines: u32,
|
pub(super) lines: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct SelectDownByLines {
|
pub struct SelectDownByLines {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub(super) lines: u32,
|
pub(super) lines: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct ExpandExcerpts {
|
pub struct ExpandExcerpts {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub(super) lines: u32,
|
pub(super) lines: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct ExpandExcerptsUp {
|
pub struct ExpandExcerptsUp {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub(super) lines: u32,
|
pub(super) lines: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct ExpandExcerptsDown {
|
pub struct ExpandExcerptsDown {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub(super) lines: u32,
|
pub(super) lines: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct ShowCompletions {
|
pub struct ShowCompletions {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub(super) trigger: Option<String>,
|
pub(super) trigger: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
pub struct HandleInput(pub String);
|
pub struct HandleInput(pub String);
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct DeleteToNextWordEnd {
|
pub struct DeleteToNextWordEnd {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub ignore_newlines: bool,
|
pub ignore_newlines: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct DeleteToPreviousWordStart {
|
pub struct DeleteToPreviousWordStart {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub ignore_newlines: bool,
|
pub ignore_newlines: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
pub struct FoldAtLevel(pub u32);
|
pub struct FoldAtLevel(pub u32);
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = editor)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct SpawnNearestTask {
|
pub struct SpawnNearestTask {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
@ -211,41 +238,16 @@ pub enum UuidVersion {
|
||||||
V7,
|
V7,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_actions!(
|
actions!(debugger, [RunToCursor, EvaluateSelectedText]);
|
||||||
editor,
|
|
||||||
|
actions!(
|
||||||
|
go_to_line,
|
||||||
[
|
[
|
||||||
ComposeCompletion,
|
#[action(name = "Toggle")]
|
||||||
ConfirmCodeAction,
|
ToggleGoToLine
|
||||||
ConfirmCompletion,
|
|
||||||
DeleteToBeginningOfLine,
|
|
||||||
DeleteToNextWordEnd,
|
|
||||||
DeleteToPreviousWordStart,
|
|
||||||
ExpandExcerpts,
|
|
||||||
ExpandExcerptsDown,
|
|
||||||
ExpandExcerptsUp,
|
|
||||||
HandleInput,
|
|
||||||
MoveDownByLines,
|
|
||||||
MovePageDown,
|
|
||||||
MovePageUp,
|
|
||||||
MoveToBeginningOfLine,
|
|
||||||
MoveToEndOfLine,
|
|
||||||
MoveUpByLines,
|
|
||||||
SelectDownByLines,
|
|
||||||
SelectNext,
|
|
||||||
SelectPrevious,
|
|
||||||
SelectToBeginningOfLine,
|
|
||||||
SelectToEndOfLine,
|
|
||||||
SelectUpByLines,
|
|
||||||
SpawnNearestTask,
|
|
||||||
ShowCompletions,
|
|
||||||
ToggleCodeActions,
|
|
||||||
ToggleComments,
|
|
||||||
FoldAtLevel,
|
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
actions!(debugger, [RunToCursor, EvaluateSelectedText]);
|
|
||||||
|
|
||||||
actions!(
|
actions!(
|
||||||
editor,
|
editor,
|
||||||
[
|
[
|
||||||
|
@ -296,6 +298,8 @@ actions!(
|
||||||
DuplicateLineDown,
|
DuplicateLineDown,
|
||||||
DuplicateLineUp,
|
DuplicateLineUp,
|
||||||
DuplicateSelection,
|
DuplicateSelection,
|
||||||
|
#[action(deprecated_aliases = ["editor::ExpandAllHunkDiffs"])]
|
||||||
|
ExpandAllDiffHunks,
|
||||||
ExpandMacroRecursively,
|
ExpandMacroRecursively,
|
||||||
FindAllReferences,
|
FindAllReferences,
|
||||||
FindNextMatch,
|
FindNextMatch,
|
||||||
|
@ -365,6 +369,8 @@ actions!(
|
||||||
OpenProposedChangesEditor,
|
OpenProposedChangesEditor,
|
||||||
OpenDocs,
|
OpenDocs,
|
||||||
OpenPermalinkToLine,
|
OpenPermalinkToLine,
|
||||||
|
#[action(deprecated_aliases = ["editor::OpenFile"])]
|
||||||
|
OpenSelectedFilename,
|
||||||
OpenSelectionsInMultibuffer,
|
OpenSelectionsInMultibuffer,
|
||||||
OpenUrl,
|
OpenUrl,
|
||||||
OrganizeImports,
|
OrganizeImports,
|
||||||
|
@ -443,6 +449,8 @@ actions!(
|
||||||
SwapSelectionEnds,
|
SwapSelectionEnds,
|
||||||
SetMark,
|
SetMark,
|
||||||
ToggleRelativeLineNumbers,
|
ToggleRelativeLineNumbers,
|
||||||
|
#[action(deprecated_aliases = ["editor::ToggleHunkDiff"])]
|
||||||
|
ToggleSelectedDiffHunks,
|
||||||
ToggleSelectionMenu,
|
ToggleSelectionMenu,
|
||||||
ToggleSoftWrap,
|
ToggleSoftWrap,
|
||||||
ToggleTabBar,
|
ToggleTabBar,
|
||||||
|
@ -456,9 +464,3 @@ actions!(
|
||||||
UniqueLinesCaseSensitive,
|
UniqueLinesCaseSensitive,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
action_as!(go_to_line, ToggleGoToLine as Toggle);
|
|
||||||
|
|
||||||
action_with_deprecated_aliases!(editor, OpenSelectedFilename, ["editor::OpenFile"]);
|
|
||||||
action_with_deprecated_aliases!(editor, ToggleSelectedDiffHunks, ["editor::ToggleHunkDiff"]);
|
|
||||||
action_with_deprecated_aliases!(editor, ExpandAllDiffHunks, ["editor::ExpandAllHunkDiffs"]);
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ use gpui::{
|
||||||
MouseButton, MouseDownEvent, PaintQuad, ParentElement, Pixels, Render, ScrollHandle,
|
MouseButton, MouseDownEvent, PaintQuad, ParentElement, Pixels, Render, ScrollHandle,
|
||||||
SharedString, Size, Stateful, Styled, Subscription, Task, TextStyle, TextStyleRefinement,
|
SharedString, Size, Stateful, Styled, Subscription, Task, TextStyle, TextStyleRefinement,
|
||||||
UTF16Selection, UnderlineStyle, UniformListScrollHandle, WeakEntity, WeakFocusHandle, Window,
|
UTF16Selection, UnderlineStyle, UniformListScrollHandle, WeakEntity, WeakFocusHandle, Window,
|
||||||
div, impl_actions, point, prelude::*, pulsating_between, px, relative, size,
|
div, point, prelude::*, pulsating_between, px, relative, size,
|
||||||
};
|
};
|
||||||
use highlight_matching_bracket::refresh_matching_bracket_highlights;
|
use highlight_matching_bracket::refresh_matching_bracket_highlights;
|
||||||
use hover_links::{HoverLink, HoveredLinkState, InlayHighlight, find_file};
|
use hover_links::{HoverLink, HoveredLinkState, InlayHighlight, find_file};
|
||||||
|
|
|
@ -9,9 +9,7 @@ pub use crate::hosting_provider::*;
|
||||||
pub use crate::remote::*;
|
pub use crate::remote::*;
|
||||||
use anyhow::{Context as _, Result};
|
use anyhow::{Context as _, Result};
|
||||||
pub use git2 as libgit;
|
pub use git2 as libgit;
|
||||||
use gpui::action_with_deprecated_aliases;
|
use gpui::{Action, actions};
|
||||||
use gpui::actions;
|
|
||||||
use gpui::impl_action_with_deprecated_aliases;
|
|
||||||
pub use repository::WORK_DIRECTORY_REPO_PATH;
|
pub use repository::WORK_DIRECTORY_REPO_PATH;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -36,7 +34,11 @@ actions!(
|
||||||
ToggleStaged,
|
ToggleStaged,
|
||||||
StageAndNext,
|
StageAndNext,
|
||||||
UnstageAndNext,
|
UnstageAndNext,
|
||||||
|
#[action(deprecated_aliases = ["editor::RevertSelectedHunks"])]
|
||||||
|
Restore,
|
||||||
// per-file
|
// per-file
|
||||||
|
#[action(deprecated_aliases = ["editor::ToggleGitBlame"])]
|
||||||
|
Blame,
|
||||||
StageFile,
|
StageFile,
|
||||||
UnstageFile,
|
UnstageFile,
|
||||||
// repo-wide
|
// repo-wide
|
||||||
|
@ -61,16 +63,13 @@ actions!(
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, PartialEq, Deserialize, JsonSchema)]
|
#[derive(Clone, Debug, Default, PartialEq, Deserialize, JsonSchema, Action)]
|
||||||
|
#[action(namespace = git, deprecated_aliases = ["editor::RevertFile"])]
|
||||||
pub struct RestoreFile {
|
pub struct RestoreFile {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub skip_prompt: bool,
|
pub skip_prompt: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_action_with_deprecated_aliases!(git, RestoreFile, ["editor::RevertFile"]);
|
|
||||||
action_with_deprecated_aliases!(git, Restore, ["editor::RevertSelectedHunks"]);
|
|
||||||
action_with_deprecated_aliases!(git, Blame, ["editor::ToggleGitBlame"]);
|
|
||||||
|
|
||||||
/// The length of a Git short SHA.
|
/// The length of a Git short SHA.
|
||||||
pub const SHORT_SHA_LENGTH: usize = 7;
|
pub const SHORT_SHA_LENGTH: usize = 7;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::SharedString;
|
|
||||||
use anyhow::{Context as _, Result};
|
use anyhow::{Context as _, Result};
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
|
pub use gpui_macros::Action;
|
||||||
pub use no_action::{NoAction, is_no_action};
|
pub use no_action::{NoAction, is_no_action};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -8,28 +8,87 @@ use std::{
|
||||||
fmt::Display,
|
fmt::Display,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Actions are used to implement keyboard-driven UI.
|
/// Defines and registers unit structs that can be used as actions. For more complex data types, derive `Action`.
|
||||||
/// 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
|
/// For example:
|
||||||
/// action for each listed action name in the given namespace.
|
///
|
||||||
/// ```rust
|
/// ```
|
||||||
/// actions!(editor, [MoveUp, MoveDown, MoveLeft, MoveRight, Newline]);
|
/// actions!(editor, [MoveUp, MoveDown, MoveLeft, MoveRight, Newline]);
|
||||||
/// ```
|
/// ```
|
||||||
/// More complex data types can also be actions, providing they implement Clone, PartialEq,
|
///
|
||||||
/// and serde_derive::Deserialize.
|
/// This will create actions with names like `editor::MoveUp`, `editor::MoveDown`, etc.
|
||||||
/// Use `impl_actions!` to automatically implement the action in the given namespace.
|
///
|
||||||
|
/// The namespace argument `editor` can also be omitted, though it is required for Zed actions.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! actions {
|
||||||
|
($namespace:path, [ $( $(#[$attr:meta])* $name:ident),* $(,)? ]) => {
|
||||||
|
$(
|
||||||
|
#[derive(::std::clone::Clone, ::std::cmp::PartialEq, ::std::default::Default, ::std::fmt::Debug, gpui::Action)]
|
||||||
|
#[action(namespace = $namespace)]
|
||||||
|
$(#[$attr])*
|
||||||
|
pub struct $name;
|
||||||
|
)*
|
||||||
|
};
|
||||||
|
([ $( $(#[$attr:meta])* $name:ident),* $(,)? ]) => {
|
||||||
|
$(
|
||||||
|
#[derive(::std::clone::Clone, ::std::cmp::PartialEq, ::std::default::Default, ::std::fmt::Debug, gpui::Action)]
|
||||||
|
$(#[$attr])*
|
||||||
|
pub struct $name;
|
||||||
|
)*
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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 in the given namespace.
|
||||||
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #[derive(Clone, PartialEq, serde_derive::Deserialize)]
|
/// actions!(editor, [MoveUp, MoveDown, MoveLeft, MoveRight, Newline]);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Derive Macro
|
||||||
|
///
|
||||||
|
/// More complex data types can also be actions, by using the derive macro for `Action`:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #[derive(Clone, PartialEq, serde::Deserialize, schemars::JsonSchema, Action)]
|
||||||
|
/// #[action(namespace = editor)]
|
||||||
/// pub struct SelectNext {
|
/// pub struct SelectNext {
|
||||||
/// pub replace_newest: bool,
|
/// pub replace_newest: bool,
|
||||||
/// }
|
/// }
|
||||||
/// impl_actions!(editor, [SelectNext]);
|
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// If you want to control the behavior of the action trait manually, you can use the lower-level `#[register_action]`
|
/// The derive macro for `Action` requires that the type implement `Clone` and `PartialEq`. It also
|
||||||
/// macro, which only generates the code needed to register your action before `main`.
|
/// requires `serde::Deserialize` and `schemars::JsonSchema` unless `#[action(no_json)]` is
|
||||||
|
/// specified. In Zed these trait impls are used to load keymaps from JSON.
|
||||||
|
///
|
||||||
|
/// Multiple arguments separated by commas may be specified in `#[action(...)]`:
|
||||||
|
///
|
||||||
|
/// - `namespace = some_namespace` sets the namespace. In Zed this is required.
|
||||||
|
///
|
||||||
|
/// - `name = "ActionName"` overrides the action's name. This must not contain `::`.
|
||||||
|
///
|
||||||
|
/// - `no_json` causes the `build` method to always error and `action_json_schema` to return `None`,
|
||||||
|
/// and allows actions not implement `serde::Serialize` and `schemars::JsonSchema`.
|
||||||
|
///
|
||||||
|
/// - `no_register` skips registering the action. This is useful for implementing the `Action` trait
|
||||||
|
/// while not supporting invocation by name or JSON deserialization.
|
||||||
|
///
|
||||||
|
/// - `deprecated_aliases = ["editor::SomeAction"]` specifies deprecated old names for the action.
|
||||||
|
/// These action names should *not* correspond to any actions that are registered. These old names
|
||||||
|
/// can then still be used to refer to invoke this action. In Zed, the keymap JSON schema will
|
||||||
|
/// accept these old names and provide warnings.
|
||||||
|
///
|
||||||
|
/// - `deprecated = "Message about why this action is deprecation"` specifies a deprecation message.
|
||||||
|
/// In Zed, the keymap JSON schema will cause this to be displayed as a warning.
|
||||||
|
///
|
||||||
|
/// # Manual Implementation
|
||||||
|
///
|
||||||
|
/// If you want to control the behavior of the action trait manually, you can use the lower-level
|
||||||
|
/// `#[register_action]` macro, which only generates the code needed to register your action before
|
||||||
|
/// `main`.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #[derive(gpui::private::serde::Deserialize, std::cmp::PartialEq, std::clone::Clone)]
|
/// #[derive(gpui::private::serde::Deserialize, std::cmp::PartialEq, std::clone::Clone)]
|
||||||
|
@ -50,10 +109,10 @@ pub trait Action: Any + Send {
|
||||||
fn partial_eq(&self, action: &dyn Action) -> bool;
|
fn partial_eq(&self, action: &dyn Action) -> bool;
|
||||||
|
|
||||||
/// Get the name of this action, for displaying in UI
|
/// Get the name of this action, for displaying in UI
|
||||||
fn name(&self) -> &str;
|
fn name(&self) -> &'static str;
|
||||||
|
|
||||||
/// Get the name of this action for debugging
|
/// Get the name of this action type (static)
|
||||||
fn debug_name() -> &'static str
|
fn name_for_type() -> &'static str
|
||||||
where
|
where
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
|
|
||||||
|
@ -73,13 +132,24 @@ pub trait Action: Any + Send {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A list of alternate, deprecated names for this action.
|
/// A list of alternate, deprecated names for this action. These names can still be used to
|
||||||
|
/// invoke the action. In Zed, the keymap JSON schema will accept these old names and provide
|
||||||
|
/// warnings.
|
||||||
fn deprecated_aliases() -> &'static [&'static str]
|
fn deprecated_aliases() -> &'static [&'static str]
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
&[]
|
&[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the deprecation message for this action, if any. In Zed, the keymap JSON schema will
|
||||||
|
/// cause this to be displayed as a warning.
|
||||||
|
fn deprecation_message() -> Option<&'static str>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for dyn Action {
|
impl std::fmt::Debug for dyn Action {
|
||||||
|
@ -141,10 +211,11 @@ impl Display for ActionBuildError {
|
||||||
type ActionBuilder = fn(json: serde_json::Value) -> anyhow::Result<Box<dyn Action>>;
|
type ActionBuilder = fn(json: serde_json::Value) -> anyhow::Result<Box<dyn Action>>;
|
||||||
|
|
||||||
pub(crate) struct ActionRegistry {
|
pub(crate) struct ActionRegistry {
|
||||||
by_name: HashMap<SharedString, ActionData>,
|
by_name: HashMap<&'static str, ActionData>,
|
||||||
names_by_type_id: HashMap<TypeId, SharedString>,
|
names_by_type_id: HashMap<TypeId, &'static str>,
|
||||||
all_names: Vec<SharedString>, // So we can return a static slice.
|
all_names: Vec<&'static str>, // So we can return a static slice.
|
||||||
deprecations: HashMap<SharedString, SharedString>,
|
deprecated_aliases: HashMap<&'static str, &'static str>, // deprecated name -> preferred name
|
||||||
|
deprecation_messages: HashMap<&'static str, &'static str>, // action name -> deprecation message
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ActionRegistry {
|
impl Default for ActionRegistry {
|
||||||
|
@ -153,7 +224,8 @@ impl Default for ActionRegistry {
|
||||||
by_name: Default::default(),
|
by_name: Default::default(),
|
||||||
names_by_type_id: Default::default(),
|
names_by_type_id: Default::default(),
|
||||||
all_names: Default::default(),
|
all_names: Default::default(),
|
||||||
deprecations: Default::default(),
|
deprecated_aliases: Default::default(),
|
||||||
|
deprecation_messages: Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
this.load_actions();
|
this.load_actions();
|
||||||
|
@ -177,10 +249,11 @@ pub struct MacroActionBuilder(pub fn() -> MacroActionData);
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct MacroActionData {
|
pub struct MacroActionData {
|
||||||
pub name: &'static str,
|
pub name: &'static str,
|
||||||
pub aliases: &'static [&'static str],
|
|
||||||
pub type_id: TypeId,
|
pub type_id: TypeId,
|
||||||
pub build: ActionBuilder,
|
pub build: ActionBuilder,
|
||||||
pub json_schema: fn(&mut schemars::r#gen::SchemaGenerator) -> Option<schemars::schema::Schema>,
|
pub json_schema: fn(&mut schemars::r#gen::SchemaGenerator) -> Option<schemars::schema::Schema>,
|
||||||
|
pub deprecated_aliases: &'static [&'static str],
|
||||||
|
pub deprecation_message: Option<&'static str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
inventory::collect!(MacroActionBuilder);
|
inventory::collect!(MacroActionBuilder);
|
||||||
|
@ -197,37 +270,40 @@ impl ActionRegistry {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) fn load_action<A: Action>(&mut self) {
|
pub(crate) fn load_action<A: Action>(&mut self) {
|
||||||
self.insert_action(MacroActionData {
|
self.insert_action(MacroActionData {
|
||||||
name: A::debug_name(),
|
name: A::name_for_type(),
|
||||||
aliases: A::deprecated_aliases(),
|
|
||||||
type_id: TypeId::of::<A>(),
|
type_id: TypeId::of::<A>(),
|
||||||
build: A::build,
|
build: A::build,
|
||||||
json_schema: A::action_json_schema,
|
json_schema: A::action_json_schema,
|
||||||
|
deprecated_aliases: A::deprecated_aliases(),
|
||||||
|
deprecation_message: A::deprecation_message(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_action(&mut self, action: MacroActionData) {
|
fn insert_action(&mut self, action: MacroActionData) {
|
||||||
let name: SharedString = action.name.into();
|
|
||||||
self.by_name.insert(
|
self.by_name.insert(
|
||||||
name.clone(),
|
action.name,
|
||||||
ActionData {
|
ActionData {
|
||||||
build: action.build,
|
build: action.build,
|
||||||
json_schema: action.json_schema,
|
json_schema: action.json_schema,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
for &alias in action.aliases {
|
for &alias in action.deprecated_aliases {
|
||||||
let alias: SharedString = alias.into();
|
|
||||||
self.by_name.insert(
|
self.by_name.insert(
|
||||||
alias.clone(),
|
alias,
|
||||||
ActionData {
|
ActionData {
|
||||||
build: action.build,
|
build: action.build,
|
||||||
json_schema: action.json_schema,
|
json_schema: action.json_schema,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
self.deprecations.insert(alias.clone(), name.clone());
|
self.deprecated_aliases.insert(alias, action.name);
|
||||||
self.all_names.push(alias);
|
self.all_names.push(alias);
|
||||||
}
|
}
|
||||||
self.names_by_type_id.insert(action.type_id, name.clone());
|
self.names_by_type_id.insert(action.type_id, action.name);
|
||||||
self.all_names.push(name);
|
self.all_names.push(action.name);
|
||||||
|
if let Some(deprecation_msg) = action.deprecation_message {
|
||||||
|
self.deprecation_messages
|
||||||
|
.insert(action.name, deprecation_msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct an action based on its name and optional JSON parameters sourced from the keymap.
|
/// Construct an action based on its name and optional JSON parameters sourced from the keymap.
|
||||||
|
@ -235,10 +311,9 @@ impl ActionRegistry {
|
||||||
let name = self
|
let name = self
|
||||||
.names_by_type_id
|
.names_by_type_id
|
||||||
.get(type_id)
|
.get(type_id)
|
||||||
.with_context(|| format!("no action type registered for {type_id:?}"))?
|
.with_context(|| format!("no action type registered for {type_id:?}"))?;
|
||||||
.clone();
|
|
||||||
|
|
||||||
Ok(self.build_action(&name, None)?)
|
Ok(self.build_action(name, None)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct an action based on its name and optional JSON parameters sourced from the keymap.
|
/// Construct an action based on its name and optional JSON parameters sourced from the keymap.
|
||||||
|
@ -262,14 +337,14 @@ impl ActionRegistry {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn all_action_names(&self) -> &[SharedString] {
|
pub fn all_action_names(&self) -> &[&'static str] {
|
||||||
self.all_names.as_slice()
|
self.all_names.as_slice()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn action_schemas(
|
pub fn action_schemas(
|
||||||
&self,
|
&self,
|
||||||
generator: &mut schemars::r#gen::SchemaGenerator,
|
generator: &mut schemars::r#gen::SchemaGenerator,
|
||||||
) -> Vec<(SharedString, Option<schemars::schema::Schema>)> {
|
) -> Vec<(&'static str, Option<schemars::schema::Schema>)> {
|
||||||
// Use the order from all_names so that the resulting schema has sensible order.
|
// Use the order from all_names so that the resulting schema has sensible order.
|
||||||
self.all_names
|
self.all_names
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -278,13 +353,17 @@ impl ActionRegistry {
|
||||||
.by_name
|
.by_name
|
||||||
.get(name)
|
.get(name)
|
||||||
.expect("All actions in all_names should be registered");
|
.expect("All actions in all_names should be registered");
|
||||||
(name.clone(), (action_data.json_schema)(generator))
|
(*name, (action_data.json_schema)(generator))
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn action_deprecations(&self) -> &HashMap<SharedString, SharedString> {
|
pub fn deprecated_aliases(&self) -> &HashMap<&'static str, &'static str> {
|
||||||
&self.deprecations
|
&self.deprecated_aliases
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deprecation_messages(&self) -> &HashMap<&'static str, &'static str> {
|
||||||
|
&self.deprecation_messages
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,285 +379,18 @@ pub fn generate_list_of_all_registered_actions() -> Vec<MacroActionData> {
|
||||||
actions
|
actions
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines and registers unit structs that can be used as actions.
|
|
||||||
///
|
|
||||||
/// To use more complex data types as actions, use `impl_actions!`
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! actions {
|
|
||||||
($namespace:path, [ $($name:ident),* $(,)? ]) => {
|
|
||||||
$(
|
|
||||||
// Unfortunately rust-analyzer doesn't display the name due to
|
|
||||||
// https://github.com/rust-lang/rust-analyzer/issues/8092
|
|
||||||
#[doc = stringify!($name)]
|
|
||||||
#[doc = "action generated by `gpui::actions!`"]
|
|
||||||
#[derive(::std::clone::Clone,::std::cmp::PartialEq, ::std::default::Default)]
|
|
||||||
pub struct $name;
|
|
||||||
|
|
||||||
gpui::__impl_action!($namespace, $name, $name,
|
|
||||||
fn build(_: gpui::private::serde_json::Value) -> gpui::Result<::std::boxed::Box<dyn gpui::Action>> {
|
|
||||||
Ok(Box::new(Self))
|
|
||||||
},
|
|
||||||
fn action_json_schema(
|
|
||||||
_: &mut gpui::private::schemars::r#gen::SchemaGenerator,
|
|
||||||
) -> Option<gpui::private::schemars::schema::Schema> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
gpui::register_action!($name);
|
|
||||||
)*
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Defines and registers a unit struct that can be used as an actions, with a name that differs
|
|
||||||
/// from it's type name.
|
|
||||||
///
|
|
||||||
/// To use more complex data types as actions, and rename them use `impl_action_as!`
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! action_as {
|
|
||||||
($namespace:path, $name:ident as $visual_name:ident) => {
|
|
||||||
// Unfortunately rust-analyzer doesn't display the name due to
|
|
||||||
// https://github.com/rust-lang/rust-analyzer/issues/8092
|
|
||||||
#[doc = stringify!($name)]
|
|
||||||
#[doc = "action generated by `gpui::action_as!`"]
|
|
||||||
#[derive(
|
|
||||||
::std::clone::Clone, ::std::default::Default, ::std::fmt::Debug, ::std::cmp::PartialEq,
|
|
||||||
)]
|
|
||||||
pub struct $name;
|
|
||||||
gpui::__impl_action!(
|
|
||||||
$namespace,
|
|
||||||
$name,
|
|
||||||
$visual_name,
|
|
||||||
fn build(
|
|
||||||
_: gpui::private::serde_json::Value,
|
|
||||||
) -> gpui::Result<::std::boxed::Box<dyn gpui::Action>> {
|
|
||||||
Ok(Box::new(Self))
|
|
||||||
},
|
|
||||||
fn action_json_schema(
|
|
||||||
generator: &mut gpui::private::schemars::r#gen::SchemaGenerator,
|
|
||||||
) -> Option<gpui::private::schemars::schema::Schema> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
gpui::register_action!($name);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Defines and registers a unit struct that can be used as an action, with some deprecated aliases.
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! action_with_deprecated_aliases {
|
|
||||||
($namespace:path, $name:ident, [$($alias:literal),* $(,)?]) => {
|
|
||||||
// Unfortunately rust-analyzer doesn't display the name due to
|
|
||||||
// https://github.com/rust-lang/rust-analyzer/issues/8092
|
|
||||||
#[doc = stringify!($name)]
|
|
||||||
#[doc = "action, generated by `gpui::action_with_deprecated_aliases!`"]
|
|
||||||
#[derive(
|
|
||||||
::std::clone::Clone, ::std::default::Default, ::std::fmt::Debug, ::std::cmp::PartialEq,
|
|
||||||
)]
|
|
||||||
pub struct $name;
|
|
||||||
|
|
||||||
gpui::__impl_action!(
|
|
||||||
$namespace,
|
|
||||||
$name,
|
|
||||||
$name,
|
|
||||||
fn build(
|
|
||||||
value: gpui::private::serde_json::Value,
|
|
||||||
) -> gpui::Result<::std::boxed::Box<dyn gpui::Action>> {
|
|
||||||
Ok(Box::new(Self))
|
|
||||||
},
|
|
||||||
|
|
||||||
fn action_json_schema(
|
|
||||||
generator: &mut gpui::private::schemars::r#gen::SchemaGenerator,
|
|
||||||
) -> Option<gpui::private::schemars::schema::Schema> {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
|
|
||||||
fn deprecated_aliases() -> &'static [&'static str] {
|
|
||||||
&[
|
|
||||||
$($alias),*
|
|
||||||
]
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
gpui::register_action!($name);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Registers the action and implements the Action trait for any struct that implements Clone,
|
|
||||||
/// Default, PartialEq, serde_deserialize::Deserialize, and schemars::JsonSchema.
|
|
||||||
///
|
|
||||||
/// Similar to `impl_actions!`, but only handles one struct, and registers some deprecated aliases.
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! impl_action_with_deprecated_aliases {
|
|
||||||
($namespace:path, $name:ident, [$($alias:literal),* $(,)?]) => {
|
|
||||||
gpui::__impl_action!(
|
|
||||||
$namespace,
|
|
||||||
$name,
|
|
||||||
$name,
|
|
||||||
fn build(
|
|
||||||
value: gpui::private::serde_json::Value,
|
|
||||||
) -> gpui::Result<::std::boxed::Box<dyn gpui::Action>> {
|
|
||||||
Ok(std::boxed::Box::new(gpui::private::serde_json::from_value::<Self>(value)?))
|
|
||||||
},
|
|
||||||
|
|
||||||
fn action_json_schema(
|
|
||||||
generator: &mut gpui::private::schemars::r#gen::SchemaGenerator,
|
|
||||||
) -> Option<gpui::private::schemars::schema::Schema> {
|
|
||||||
Some(<Self as gpui::private::schemars::JsonSchema>::json_schema(
|
|
||||||
generator,
|
|
||||||
))
|
|
||||||
},
|
|
||||||
|
|
||||||
fn deprecated_aliases() -> &'static [&'static str] {
|
|
||||||
&[
|
|
||||||
$($alias),*
|
|
||||||
]
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
gpui::register_action!($name);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Registers the action and implements the Action trait for any struct that implements Clone,
|
|
||||||
/// Default, PartialEq, serde_deserialize::Deserialize, and schemars::JsonSchema.
|
|
||||||
///
|
|
||||||
/// Similar to `actions!`, but accepts structs with fields.
|
|
||||||
///
|
|
||||||
/// Fields and variants that don't make sense for user configuration should be annotated with
|
|
||||||
/// #[serde(skip)].
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! impl_actions {
|
|
||||||
($namespace:path, [ $($name:ident),* $(,)? ]) => {
|
|
||||||
$(
|
|
||||||
gpui::__impl_action!($namespace, $name, $name,
|
|
||||||
fn build(value: gpui::private::serde_json::Value) -> gpui::Result<::std::boxed::Box<dyn gpui::Action>> {
|
|
||||||
Ok(std::boxed::Box::new(gpui::private::serde_json::from_value::<Self>(value)?))
|
|
||||||
},
|
|
||||||
fn action_json_schema(
|
|
||||||
generator: &mut gpui::private::schemars::r#gen::SchemaGenerator,
|
|
||||||
) -> Option<gpui::private::schemars::schema::Schema> {
|
|
||||||
Some(<Self as gpui::private::schemars::JsonSchema>::json_schema(
|
|
||||||
generator,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
gpui::register_action!($name);
|
|
||||||
)*
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implements the Action trait for internal action structs that implement Clone, Default,
|
|
||||||
/// PartialEq. The purpose of this is to conveniently define values that can be passed in `dyn
|
|
||||||
/// Action`.
|
|
||||||
///
|
|
||||||
/// These actions are internal and so are not registered and do not support deserialization.
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! impl_internal_actions {
|
|
||||||
($namespace:path, [ $($name:ident),* $(,)? ]) => {
|
|
||||||
$(
|
|
||||||
gpui::__impl_action!($namespace, $name, $name,
|
|
||||||
fn build(value: gpui::private::serde_json::Value) -> gpui::Result<::std::boxed::Box<dyn gpui::Action>> {
|
|
||||||
gpui::Result::Err(gpui::private::anyhow::anyhow!(
|
|
||||||
concat!(
|
|
||||||
stringify!($namespace),
|
|
||||||
"::",
|
|
||||||
stringify!($visual_name),
|
|
||||||
" is an internal action, so cannot be built from JSON."
|
|
||||||
)))
|
|
||||||
},
|
|
||||||
fn action_json_schema(
|
|
||||||
generator: &mut gpui::private::schemars::r#gen::SchemaGenerator,
|
|
||||||
) -> Option<gpui::private::schemars::schema::Schema> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
);
|
|
||||||
)*
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implements the Action trait for a struct that implements Clone, Default, PartialEq, and
|
|
||||||
/// serde_deserialize::Deserialize. Allows you to rename the action visually, without changing the
|
|
||||||
/// struct's name.
|
|
||||||
///
|
|
||||||
/// Fields and variants that don't make sense for user configuration should be annotated with
|
|
||||||
/// #[serde(skip)].
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! impl_action_as {
|
|
||||||
($namespace:path, $name:ident as $visual_name:tt ) => {
|
|
||||||
gpui::__impl_action!(
|
|
||||||
$namespace,
|
|
||||||
$name,
|
|
||||||
$visual_name,
|
|
||||||
fn build(
|
|
||||||
value: gpui::private::serde_json::Value,
|
|
||||||
) -> gpui::Result<::std::boxed::Box<dyn gpui::Action>> {
|
|
||||||
Ok(std::boxed::Box::new(
|
|
||||||
gpui::private::serde_json::from_value::<Self>(value)?,
|
|
||||||
))
|
|
||||||
},
|
|
||||||
fn action_json_schema(
|
|
||||||
generator: &mut gpui::private::schemars::r#gen::SchemaGenerator,
|
|
||||||
) -> Option<gpui::private::schemars::schema::Schema> {
|
|
||||||
Some(<Self as gpui::private::schemars::JsonSchema>::json_schema(
|
|
||||||
generator,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
gpui::register_action!($name);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! __impl_action {
|
|
||||||
($namespace:path, $name:ident, $visual_name:tt, $($items:item),*) => {
|
|
||||||
impl gpui::Action for $name {
|
|
||||||
fn name(&self) -> &'static str
|
|
||||||
{
|
|
||||||
concat!(
|
|
||||||
stringify!($namespace),
|
|
||||||
"::",
|
|
||||||
stringify!($visual_name),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn debug_name() -> &'static str
|
|
||||||
where
|
|
||||||
Self: ::std::marker::Sized
|
|
||||||
{
|
|
||||||
concat!(
|
|
||||||
stringify!($namespace),
|
|
||||||
"::",
|
|
||||||
stringify!($visual_name),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn partial_eq(&self, action: &dyn gpui::Action) -> bool {
|
|
||||||
action
|
|
||||||
.as_any()
|
|
||||||
.downcast_ref::<Self>()
|
|
||||||
.map_or(false, |a| self == a)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn boxed_clone(&self) -> std::boxed::Box<dyn gpui::Action> {
|
|
||||||
::std::boxed::Box::new(self.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$($items)*
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
mod no_action {
|
mod no_action {
|
||||||
use crate as gpui;
|
use crate as gpui;
|
||||||
use std::any::Any as _;
|
use std::any::Any as _;
|
||||||
|
|
||||||
actions!(zed, [NoAction]);
|
actions!(
|
||||||
|
zed,
|
||||||
|
[
|
||||||
|
/// Action with special handling which unbinds the keybinding this is associated with,
|
||||||
|
/// if it is the highest precedence match.
|
||||||
|
NoAction
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
/// Returns whether or not this action represents a removed key binding.
|
/// Returns whether or not this action represents a removed key binding.
|
||||||
pub fn is_no_action(action: &dyn gpui::Action) -> bool {
|
pub fn is_no_action(action: &dyn gpui::Action) -> bool {
|
||||||
|
|
|
@ -39,8 +39,8 @@ use crate::{
|
||||||
Keymap, Keystroke, LayoutId, Menu, MenuItem, OwnedMenu, PathPromptOptions, Pixels, Platform,
|
Keymap, Keystroke, LayoutId, Menu, MenuItem, OwnedMenu, PathPromptOptions, Pixels, Platform,
|
||||||
PlatformDisplay, PlatformKeyboardLayout, Point, PromptBuilder, PromptButton, PromptHandle,
|
PlatformDisplay, PlatformKeyboardLayout, Point, PromptBuilder, PromptButton, PromptHandle,
|
||||||
PromptLevel, Render, RenderImage, RenderablePromptHandle, Reservation, ScreenCaptureSource,
|
PromptLevel, Render, RenderImage, RenderablePromptHandle, Reservation, ScreenCaptureSource,
|
||||||
SharedString, SubscriberSet, Subscription, SvgRenderer, Task, TextSystem, Window,
|
SubscriberSet, Subscription, SvgRenderer, Task, TextSystem, Window, WindowAppearance,
|
||||||
WindowAppearance, WindowHandle, WindowId, WindowInvalidator,
|
WindowHandle, WindowId, WindowInvalidator,
|
||||||
colors::{Colors, GlobalColors},
|
colors::{Colors, GlobalColors},
|
||||||
current_platform, hash, init_app_menus,
|
current_platform, hash, init_app_menus,
|
||||||
};
|
};
|
||||||
|
@ -1374,7 +1374,7 @@ impl App {
|
||||||
|
|
||||||
/// Get all action names that have been registered. Note that registration only allows for
|
/// Get all action names that have been registered. Note that registration only allows for
|
||||||
/// actions to be built dynamically, and is unrelated to binding actions in the element tree.
|
/// actions to be built dynamically, and is unrelated to binding actions in the element tree.
|
||||||
pub fn all_action_names(&self) -> &[SharedString] {
|
pub fn all_action_names(&self) -> &[&'static str] {
|
||||||
self.actions.all_action_names()
|
self.actions.all_action_names()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1389,13 +1389,18 @@ impl App {
|
||||||
pub fn action_schemas(
|
pub fn action_schemas(
|
||||||
&self,
|
&self,
|
||||||
generator: &mut schemars::r#gen::SchemaGenerator,
|
generator: &mut schemars::r#gen::SchemaGenerator,
|
||||||
) -> Vec<(SharedString, Option<schemars::schema::Schema>)> {
|
) -> Vec<(&'static str, Option<schemars::schema::Schema>)> {
|
||||||
self.actions.action_schemas(generator)
|
self.actions.action_schemas(generator)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a list of all deprecated action aliases and their canonical names.
|
/// Get a map from a deprecated action name to the canonical name.
|
||||||
pub fn action_deprecations(&self) -> &HashMap<SharedString, SharedString> {
|
pub fn deprecated_actions_to_preferred_actions(&self) -> &HashMap<&'static str, &'static str> {
|
||||||
self.actions.action_deprecations()
|
self.actions.deprecated_aliases()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a list of all action deprecation messages.
|
||||||
|
pub fn action_deprecation_messages(&self) -> &HashMap<&'static str, &'static str> {
|
||||||
|
self.actions.deprecation_messages()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Register a callback to be invoked when the application is about to quit.
|
/// Register a callback to be invoked when the application is about to quit.
|
||||||
|
|
|
@ -493,7 +493,7 @@ mod test {
|
||||||
focus_handle: FocusHandle,
|
focus_handle: FocusHandle,
|
||||||
}
|
}
|
||||||
|
|
||||||
actions!(test, [TestAction]);
|
actions!(test_only, [TestAction]);
|
||||||
|
|
||||||
impl Render for TestView {
|
impl Render for TestView {
|
||||||
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
|
|
|
@ -634,7 +634,7 @@ mod tests {
|
||||||
"test::TestAction"
|
"test::TestAction"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn debug_name() -> &'static str
|
fn name_for_type() -> &'static str
|
||||||
where
|
where
|
||||||
Self: ::std::marker::Sized,
|
Self: ::std::marker::Sized,
|
||||||
{
|
{
|
||||||
|
|
|
@ -261,10 +261,10 @@ impl Keymap {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate as gpui;
|
use crate as gpui;
|
||||||
use gpui::{NoAction, actions};
|
use gpui::NoAction;
|
||||||
|
|
||||||
actions!(
|
actions!(
|
||||||
keymap_test,
|
test_only,
|
||||||
[ActionAlpha, ActionBeta, ActionGamma, ActionDelta,]
|
[ActionAlpha, ActionBeta, ActionGamma, ActionDelta,]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -425,12 +425,12 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_actions_definition() {
|
fn test_actions_definition() {
|
||||||
{
|
{
|
||||||
actions!(test, [A, B, C, D, E, F, G]);
|
actions!(test_only, [A, B, C, D, E, F, G]);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
actions!(
|
actions!(
|
||||||
test,
|
test_only,
|
||||||
[
|
[
|
||||||
A, B, C, D, E, F, G, // Don't wrap, test the trailing comma
|
A, B, C, D, E, F, G, // Don't wrap, test the trailing comma
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,16 +1,22 @@
|
||||||
use gpui::{actions, impl_actions};
|
use gpui::{Action, actions};
|
||||||
use gpui_macros::register_action;
|
use gpui_macros::register_action;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_action_macros() {
|
fn test_action_macros() {
|
||||||
actions!(test, [TestAction]);
|
actions!(
|
||||||
|
test_only,
|
||||||
|
[
|
||||||
|
SomeAction,
|
||||||
|
/// Documented action
|
||||||
|
SomeActionWithDocs,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, JsonSchema, Action)]
|
||||||
struct AnotherTestAction;
|
#[action(namespace = test_only)]
|
||||||
|
struct AnotherSomeAction;
|
||||||
impl_actions!(test, [AnotherTestAction]);
|
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, gpui::private::serde_derive::Deserialize)]
|
#[derive(PartialEq, Clone, gpui::private::serde_derive::Deserialize)]
|
||||||
struct RegisterableAction {}
|
struct RegisterableAction {}
|
||||||
|
@ -26,11 +32,11 @@ fn test_action_macros() {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &'static str {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn debug_name() -> &'static str
|
fn name_for_type() -> &'static str
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
|
|
176
crates/gpui_macros/src/derive_action.rs
Normal file
176
crates/gpui_macros/src/derive_action.rs
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
use crate::register_action::generate_register_action;
|
||||||
|
use proc_macro::TokenStream;
|
||||||
|
use proc_macro2::Ident;
|
||||||
|
use quote::quote;
|
||||||
|
use syn::{Data, DeriveInput, LitStr, Token, parse::ParseStream};
|
||||||
|
|
||||||
|
pub(crate) fn derive_action(input: TokenStream) -> TokenStream {
|
||||||
|
let input = syn::parse_macro_input!(input as DeriveInput);
|
||||||
|
|
||||||
|
let struct_name = &input.ident;
|
||||||
|
let mut name_argument = None;
|
||||||
|
let mut deprecated_aliases = Vec::new();
|
||||||
|
let mut no_json = false;
|
||||||
|
let mut no_register = false;
|
||||||
|
let mut namespace = None;
|
||||||
|
let mut deprecated = None;
|
||||||
|
|
||||||
|
for attr in &input.attrs {
|
||||||
|
if attr.path().is_ident("action") {
|
||||||
|
attr.parse_nested_meta(|meta| {
|
||||||
|
if meta.path.is_ident("name") {
|
||||||
|
if name_argument.is_some() {
|
||||||
|
return Err(meta.error("'name' argument specified multiple times"));
|
||||||
|
}
|
||||||
|
meta.input.parse::<Token![=]>()?;
|
||||||
|
let lit: LitStr = meta.input.parse()?;
|
||||||
|
name_argument = Some(lit.value());
|
||||||
|
} else if meta.path.is_ident("namespace") {
|
||||||
|
if namespace.is_some() {
|
||||||
|
return Err(meta.error("'namespace' argument specified multiple times"));
|
||||||
|
}
|
||||||
|
meta.input.parse::<Token![=]>()?;
|
||||||
|
let ident: Ident = meta.input.parse()?;
|
||||||
|
namespace = Some(ident.to_string());
|
||||||
|
} else if meta.path.is_ident("no_json") {
|
||||||
|
if no_json {
|
||||||
|
return Err(meta.error("'no_json' argument specified multiple times"));
|
||||||
|
}
|
||||||
|
no_json = true;
|
||||||
|
} else if meta.path.is_ident("no_register") {
|
||||||
|
if no_register {
|
||||||
|
return Err(meta.error("'no_register' argument specified multiple times"));
|
||||||
|
}
|
||||||
|
no_register = true;
|
||||||
|
} else if meta.path.is_ident("deprecated_aliases") {
|
||||||
|
if !deprecated_aliases.is_empty() {
|
||||||
|
return Err(
|
||||||
|
meta.error("'deprecated_aliases' argument specified multiple times")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
meta.input.parse::<Token![=]>()?;
|
||||||
|
// Parse array of string literals
|
||||||
|
let content;
|
||||||
|
syn::bracketed!(content in meta.input);
|
||||||
|
let aliases = content.parse_terminated(
|
||||||
|
|input: ParseStream| input.parse::<LitStr>(),
|
||||||
|
Token![,],
|
||||||
|
)?;
|
||||||
|
deprecated_aliases.extend(aliases.into_iter().map(|lit| lit.value()));
|
||||||
|
} else if meta.path.is_ident("deprecated") {
|
||||||
|
if deprecated.is_some() {
|
||||||
|
return Err(meta.error("'deprecated' argument specified multiple times"));
|
||||||
|
}
|
||||||
|
meta.input.parse::<Token![=]>()?;
|
||||||
|
let lit: LitStr = meta.input.parse()?;
|
||||||
|
deprecated = Some(lit.value());
|
||||||
|
} else {
|
||||||
|
return Err(meta.error(format!(
|
||||||
|
"'{:?}' argument not recognized, expected \
|
||||||
|
'namespace', 'no_json', 'no_register, 'deprecated_aliases', or 'deprecated'",
|
||||||
|
meta.path
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|e| panic!("in #[action] attribute: {}", e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let name = name_argument.unwrap_or_else(|| struct_name.to_string());
|
||||||
|
|
||||||
|
if name.contains("::") {
|
||||||
|
panic!(
|
||||||
|
"in #[action] attribute: `name = \"{name}\"` must not contain `::`, \
|
||||||
|
also specify `namespace` instead"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let full_name = if let Some(namespace) = namespace {
|
||||||
|
format!("{namespace}::{name}")
|
||||||
|
} else {
|
||||||
|
name
|
||||||
|
};
|
||||||
|
|
||||||
|
let is_unit_struct = matches!(&input.data, Data::Struct(data) if data.fields.is_empty());
|
||||||
|
|
||||||
|
let build_fn_body = if no_json {
|
||||||
|
let error_msg = format!("{} cannot be built from JSON", full_name);
|
||||||
|
quote! { Err(gpui::private::anyhow::anyhow!(#error_msg)) }
|
||||||
|
} else if is_unit_struct {
|
||||||
|
quote! { Ok(Box::new(Self)) }
|
||||||
|
} else {
|
||||||
|
quote! { Ok(Box::new(gpui::private::serde_json::from_value::<Self>(_value)?)) }
|
||||||
|
};
|
||||||
|
|
||||||
|
let json_schema_fn_body = if no_json || is_unit_struct {
|
||||||
|
quote! { None }
|
||||||
|
} else {
|
||||||
|
quote! { Some(<Self as gpui::private::schemars::JsonSchema>::json_schema(_generator)) }
|
||||||
|
};
|
||||||
|
|
||||||
|
let deprecated_aliases_fn_body = if deprecated_aliases.is_empty() {
|
||||||
|
quote! { &[] }
|
||||||
|
} else {
|
||||||
|
let aliases = deprecated_aliases.iter();
|
||||||
|
quote! { &[#(#aliases),*] }
|
||||||
|
};
|
||||||
|
|
||||||
|
let deprecation_fn_body = if let Some(message) = deprecated {
|
||||||
|
quote! { Some(#message) }
|
||||||
|
} else {
|
||||||
|
quote! { None }
|
||||||
|
};
|
||||||
|
|
||||||
|
let registration = if no_register {
|
||||||
|
quote! {}
|
||||||
|
} else {
|
||||||
|
generate_register_action(struct_name)
|
||||||
|
};
|
||||||
|
|
||||||
|
TokenStream::from(quote! {
|
||||||
|
#registration
|
||||||
|
|
||||||
|
impl gpui::Action for #struct_name {
|
||||||
|
fn name(&self) -> &'static str {
|
||||||
|
#full_name
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name_for_type() -> &'static str
|
||||||
|
where
|
||||||
|
Self: Sized
|
||||||
|
{
|
||||||
|
#full_name
|
||||||
|
}
|
||||||
|
|
||||||
|
fn partial_eq(&self, action: &dyn gpui::Action) -> bool {
|
||||||
|
action
|
||||||
|
.as_any()
|
||||||
|
.downcast_ref::<Self>()
|
||||||
|
.map_or(false, |a| self == a)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn boxed_clone(&self) -> Box<dyn gpui::Action> {
|
||||||
|
Box::new(self.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build(_value: gpui::private::serde_json::Value) -> gpui::Result<Box<dyn gpui::Action>> {
|
||||||
|
#build_fn_body
|
||||||
|
}
|
||||||
|
|
||||||
|
fn action_json_schema(
|
||||||
|
_generator: &mut gpui::private::schemars::r#gen::SchemaGenerator,
|
||||||
|
) -> Option<gpui::private::schemars::schema::Schema> {
|
||||||
|
#json_schema_fn_body
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deprecated_aliases() -> &'static [&'static str] {
|
||||||
|
#deprecated_aliases_fn_body
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deprecation_message() -> Option<&'static str> {
|
||||||
|
#deprecation_fn_body
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
mod derive_action;
|
||||||
mod derive_app_context;
|
mod derive_app_context;
|
||||||
mod derive_into_element;
|
mod derive_into_element;
|
||||||
mod derive_render;
|
mod derive_render;
|
||||||
|
@ -12,12 +13,18 @@ mod derive_inspector_reflection;
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use syn::{DeriveInput, Ident};
|
use syn::{DeriveInput, Ident};
|
||||||
|
|
||||||
/// register_action! can be used to register an action with the GPUI runtime.
|
/// `Action` derive macro - see the trait documentation for details.
|
||||||
/// You should typically use `gpui::actions!` or `gpui::impl_actions!` instead,
|
#[proc_macro_derive(Action, attributes(action))]
|
||||||
/// but this can be used for fine grained customization.
|
pub fn derive_action(input: TokenStream) -> TokenStream {
|
||||||
|
derive_action::derive_action(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This can be used to register an action with the GPUI runtime when you want to manually implement
|
||||||
|
/// the `Action` trait. Typically you should use the `Action` derive macro or `actions!` macro
|
||||||
|
/// instead.
|
||||||
#[proc_macro]
|
#[proc_macro]
|
||||||
pub fn register_action(ident: TokenStream) -> TokenStream {
|
pub fn register_action(ident: TokenStream) -> TokenStream {
|
||||||
register_action::register_action_macro(ident)
|
register_action::register_action(ident)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// #[derive(IntoElement)] is used to create a Component out of anything that implements
|
/// #[derive(IntoElement)] is used to create a Component out of anything that implements
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use proc_macro2::Ident;
|
use proc_macro2::{Ident, TokenStream as TokenStream2};
|
||||||
use quote::{format_ident, quote};
|
use quote::{format_ident, quote};
|
||||||
use syn::parse_macro_input;
|
use syn::parse_macro_input;
|
||||||
|
|
||||||
pub fn register_action_macro(ident: TokenStream) -> TokenStream {
|
pub(crate) fn register_action(ident: TokenStream) -> TokenStream {
|
||||||
let name = parse_macro_input!(ident as Ident);
|
let name = parse_macro_input!(ident as Ident);
|
||||||
let registration = register_action(&name);
|
let registration = generate_register_action(&name);
|
||||||
|
|
||||||
TokenStream::from(quote! {
|
TokenStream::from(quote! {
|
||||||
#registration
|
#registration
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn register_action(type_name: &Ident) -> proc_macro2::TokenStream {
|
pub(crate) fn generate_register_action(type_name: &Ident) -> TokenStream2 {
|
||||||
let action_builder_fn_name = format_ident!(
|
let action_builder_fn_name = format_ident!(
|
||||||
"__gpui_actions_builder_{}",
|
"__gpui_actions_builder_{}",
|
||||||
type_name.to_string().to_lowercase()
|
type_name.to_string().to_lowercase()
|
||||||
|
@ -28,11 +28,12 @@ pub(crate) fn register_action(type_name: &Ident) -> proc_macro2::TokenStream {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
fn #action_builder_fn_name() -> gpui::MacroActionData {
|
fn #action_builder_fn_name() -> gpui::MacroActionData {
|
||||||
gpui::MacroActionData {
|
gpui::MacroActionData {
|
||||||
name: <#type_name as gpui::Action>::debug_name(),
|
name: <#type_name as gpui::Action>::name_for_type(),
|
||||||
aliases: <#type_name as gpui::Action>::deprecated_aliases(),
|
|
||||||
type_id: ::std::any::TypeId::of::<#type_name>(),
|
type_id: ::std::any::TypeId::of::<#type_name>(),
|
||||||
build: <#type_name as gpui::Action>::build,
|
build: <#type_name as gpui::Action>::build,
|
||||||
json_schema: <#type_name as gpui::Action>::action_json_schema,
|
json_schema: <#type_name as gpui::Action>::action_json_schema,
|
||||||
|
deprecated_aliases: <#type_name as gpui::Action>::deprecated_aliases(),
|
||||||
|
deprecation_message: <#type_name as gpui::Action>::deprecation_message(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +42,5 @@ pub(crate) fn register_action(type_name: &Ident) -> proc_macro2::TokenStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,10 @@ use editor::{
|
||||||
scroll::Autoscroll,
|
scroll::Autoscroll,
|
||||||
};
|
};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
AnyElement, App, ClickEvent, Context, DismissEvent, Entity, EventEmitter, FocusHandle,
|
Action, AnyElement, App, ClickEvent, Context, DismissEvent, Entity, EventEmitter, FocusHandle,
|
||||||
Focusable, Length, ListSizingBehavior, ListState, MouseButton, MouseUpEvent, Render,
|
Focusable, Length, ListSizingBehavior, ListState, MouseButton, MouseUpEvent, Render,
|
||||||
ScrollStrategy, Stateful, Task, UniformListScrollHandle, Window, actions, div, impl_actions,
|
ScrollStrategy, Stateful, Task, UniformListScrollHandle, Window, actions, div, list,
|
||||||
list, prelude::*, uniform_list,
|
prelude::*, uniform_list,
|
||||||
};
|
};
|
||||||
use head::Head;
|
use head::Head;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
|
@ -38,14 +38,13 @@ actions!(picker, [ConfirmCompletion]);
|
||||||
|
|
||||||
/// ConfirmInput is an alternative editor action which - instead of selecting active picker entry - treats pickers editor input literally,
|
/// ConfirmInput is an alternative editor action which - instead of selecting active picker entry - treats pickers editor input literally,
|
||||||
/// performing some kind of action on it.
|
/// performing some kind of action on it.
|
||||||
#[derive(Clone, PartialEq, Deserialize, JsonSchema, Default)]
|
#[derive(Clone, PartialEq, Deserialize, JsonSchema, Default, Action)]
|
||||||
|
#[action(namespace = picker)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct ConfirmInput {
|
pub struct ConfirmInput {
|
||||||
pub secondary: bool,
|
pub secondary: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_actions!(picker, [ConfirmInput]);
|
|
||||||
|
|
||||||
struct PendingUpdateMatches {
|
struct PendingUpdateMatches {
|
||||||
delegate_update_matches: Option<Task<()>>,
|
delegate_update_matches: Option<Task<()>>,
|
||||||
_task: Task<Result<()>>,
|
_task: Task<Result<()>>,
|
||||||
|
|
|
@ -23,7 +23,7 @@ use gpui::{
|
||||||
ListSizingBehavior, Modifiers, ModifiersChangedEvent, MouseButton, MouseDownEvent,
|
ListSizingBehavior, Modifiers, ModifiersChangedEvent, MouseButton, MouseDownEvent,
|
||||||
ParentElement, Pixels, Point, PromptLevel, Render, ScrollStrategy, Stateful, Styled,
|
ParentElement, Pixels, Point, PromptLevel, Render, ScrollStrategy, Stateful, Styled,
|
||||||
Subscription, Task, UniformListScrollHandle, WeakEntity, Window, actions, anchored, deferred,
|
Subscription, Task, UniformListScrollHandle, WeakEntity, Window, actions, anchored, deferred,
|
||||||
div, impl_actions, point, px, size, transparent_white, uniform_list,
|
div, point, px, size, transparent_white, uniform_list,
|
||||||
};
|
};
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use language::DiagnosticSeverity;
|
use language::DiagnosticSeverity;
|
||||||
|
@ -181,22 +181,22 @@ struct EntryDetails {
|
||||||
canonical_path: Option<Arc<Path>>,
|
canonical_path: Option<Arc<Path>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
|
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema, Action)]
|
||||||
|
#[action(namespace = project_panel)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct Delete {
|
struct Delete {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub skip_prompt: bool,
|
pub skip_prompt: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
|
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema, Action)]
|
||||||
|
#[action(namespace = project_panel)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct Trash {
|
struct Trash {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub skip_prompt: bool,
|
pub skip_prompt: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_actions!(project_panel, [Delete, Trash]);
|
|
||||||
|
|
||||||
actions!(
|
actions!(
|
||||||
project_panel,
|
project_panel,
|
||||||
[
|
[
|
||||||
|
|
|
@ -16,7 +16,7 @@ use futures::channel::oneshot;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
Action, App, ClickEvent, Context, Entity, EventEmitter, FocusHandle, Focusable,
|
Action, App, ClickEvent, Context, Entity, EventEmitter, FocusHandle, Focusable,
|
||||||
InteractiveElement as _, IntoElement, KeyContext, ParentElement as _, Render, ScrollHandle,
|
InteractiveElement as _, IntoElement, KeyContext, ParentElement as _, Render, ScrollHandle,
|
||||||
Styled, Subscription, Task, TextStyle, Window, actions, div, impl_actions,
|
Styled, Subscription, Task, TextStyle, Window, actions, div,
|
||||||
};
|
};
|
||||||
use language::{Language, LanguageRegistry};
|
use language::{Language, LanguageRegistry};
|
||||||
use project::{
|
use project::{
|
||||||
|
@ -46,7 +46,8 @@ use registrar::{ForDeployed, ForDismissed, SearchActionsRegistrar, WithResults};
|
||||||
|
|
||||||
const MAX_BUFFER_SEARCH_HISTORY_SIZE: usize = 50;
|
const MAX_BUFFER_SEARCH_HISTORY_SIZE: usize = 50;
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, JsonSchema, Action)]
|
||||||
|
#[action(namespace = buffer_search)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct Deploy {
|
pub struct Deploy {
|
||||||
#[serde(default = "util::serde::default_true")]
|
#[serde(default = "util::serde::default_true")]
|
||||||
|
@ -57,8 +58,6 @@ pub struct Deploy {
|
||||||
pub selection_search_enabled: bool,
|
pub selection_search_enabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_actions!(buffer_search, [Deploy]);
|
|
||||||
|
|
||||||
actions!(buffer_search, [DeployReplace, Dismiss, FocusEditor]);
|
actions!(buffer_search, [DeployReplace, Dismiss, FocusEditor]);
|
||||||
|
|
||||||
impl Deploy {
|
impl Deploy {
|
||||||
|
|
|
@ -3,7 +3,7 @@ use collections::{BTreeMap, HashMap, IndexMap};
|
||||||
use fs::Fs;
|
use fs::Fs;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
Action, ActionBuildError, App, InvalidKeystrokeError, KEYSTROKE_PARSE_EXPECTED_MESSAGE,
|
Action, ActionBuildError, App, InvalidKeystrokeError, KEYSTROKE_PARSE_EXPECTED_MESSAGE,
|
||||||
KeyBinding, KeyBindingContextPredicate, NoAction, SharedString,
|
KeyBinding, KeyBindingContextPredicate, NoAction,
|
||||||
};
|
};
|
||||||
use schemars::{
|
use schemars::{
|
||||||
JsonSchema,
|
JsonSchema,
|
||||||
|
@ -414,14 +414,21 @@ impl KeymapFile {
|
||||||
.into_generator();
|
.into_generator();
|
||||||
|
|
||||||
let action_schemas = cx.action_schemas(&mut generator);
|
let action_schemas = cx.action_schemas(&mut generator);
|
||||||
let deprecations = cx.action_deprecations();
|
let deprecations = cx.deprecated_actions_to_preferred_actions();
|
||||||
KeymapFile::generate_json_schema(generator, action_schemas, deprecations)
|
let deprecation_messages = cx.action_deprecation_messages();
|
||||||
|
KeymapFile::generate_json_schema(
|
||||||
|
generator,
|
||||||
|
action_schemas,
|
||||||
|
deprecations,
|
||||||
|
deprecation_messages,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_json_schema(
|
fn generate_json_schema(
|
||||||
generator: SchemaGenerator,
|
generator: SchemaGenerator,
|
||||||
action_schemas: Vec<(SharedString, Option<Schema>)>,
|
action_schemas: Vec<(&'static str, Option<Schema>)>,
|
||||||
deprecations: &HashMap<SharedString, SharedString>,
|
deprecations: &HashMap<&'static str, &'static str>,
|
||||||
|
deprecation_messages: &HashMap<&'static str, &'static str>,
|
||||||
) -> serde_json::Value {
|
) -> serde_json::Value {
|
||||||
fn set<I, O>(input: I) -> Option<O>
|
fn set<I, O>(input: I) -> Option<O>
|
||||||
where
|
where
|
||||||
|
@ -492,9 +499,9 @@ impl KeymapFile {
|
||||||
};
|
};
|
||||||
let mut keymap_action_alternatives = vec![plain_action.into(), action_with_input.into()];
|
let mut keymap_action_alternatives = vec![plain_action.into(), action_with_input.into()];
|
||||||
|
|
||||||
for (name, action_schema) in action_schemas.iter() {
|
for (name, action_schema) in action_schemas.into_iter() {
|
||||||
let schema = if let Some(Schema::Object(schema)) = action_schema {
|
let schema = if let Some(Schema::Object(schema)) = action_schema {
|
||||||
Some(schema.clone())
|
Some(schema)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
@ -509,7 +516,7 @@ impl KeymapFile {
|
||||||
let deprecation = if name == NoAction.name() {
|
let deprecation = if name == NoAction.name() {
|
||||||
Some("null")
|
Some("null")
|
||||||
} else {
|
} else {
|
||||||
deprecations.get(name).map(|new_name| new_name.as_ref())
|
deprecations.get(name).copied()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add an alternative for plain action names.
|
// Add an alternative for plain action names.
|
||||||
|
@ -518,7 +525,9 @@ impl KeymapFile {
|
||||||
const_value: Some(Value::String(name.to_string())),
|
const_value: Some(Value::String(name.to_string())),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
if let Some(new_name) = deprecation {
|
if let Some(message) = deprecation_messages.get(name) {
|
||||||
|
add_deprecation(&mut plain_action, message.to_string());
|
||||||
|
} else if let Some(new_name) = deprecation {
|
||||||
add_deprecation_preferred_name(&mut plain_action, new_name);
|
add_deprecation_preferred_name(&mut plain_action, new_name);
|
||||||
}
|
}
|
||||||
if let Some(description) = description.clone() {
|
if let Some(description) = description.clone() {
|
||||||
|
@ -538,9 +547,11 @@ impl KeymapFile {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
if let Some(description) = description.clone() {
|
if let Some(description) = description.clone() {
|
||||||
add_description(&mut matches_action_name, description.to_string());
|
add_description(&mut matches_action_name, description);
|
||||||
}
|
}
|
||||||
if let Some(new_name) = deprecation {
|
if let Some(message) = deprecation_messages.get(name) {
|
||||||
|
add_deprecation(&mut matches_action_name, message.to_string());
|
||||||
|
} else if let Some(new_name) = deprecation {
|
||||||
add_deprecation_preferred_name(&mut matches_action_name, new_name);
|
add_deprecation_preferred_name(&mut matches_action_name, new_name);
|
||||||
}
|
}
|
||||||
let action_with_input = SchemaObject {
|
let action_with_input = SchemaObject {
|
||||||
|
|
|
@ -8,8 +8,7 @@ use editor::EditorSettingsControls;
|
||||||
use feature_flags::{FeatureFlag, FeatureFlagViewExt};
|
use feature_flags::{FeatureFlag, FeatureFlagViewExt};
|
||||||
use fs::Fs;
|
use fs::Fs;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
App, AsyncWindowContext, Entity, EventEmitter, FocusHandle, Focusable, Task, actions,
|
Action, App, AsyncWindowContext, Entity, EventEmitter, FocusHandle, Focusable, Task, actions,
|
||||||
impl_actions,
|
|
||||||
};
|
};
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
@ -27,19 +26,19 @@ impl FeatureFlag for SettingsUiFeatureFlag {
|
||||||
const NAME: &'static str = "settings-ui";
|
const NAME: &'static str = "settings-ui";
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Default, PartialEq, Deserialize, JsonSchema)]
|
#[derive(Copy, Clone, Debug, Default, PartialEq, Deserialize, JsonSchema, Action)]
|
||||||
|
#[action(namespace = zed)]
|
||||||
pub struct ImportVsCodeSettings {
|
pub struct ImportVsCodeSettings {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub skip_prompt: bool,
|
pub skip_prompt: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Default, PartialEq, Deserialize, JsonSchema)]
|
#[derive(Copy, Clone, Debug, Default, PartialEq, Deserialize, JsonSchema, Action)]
|
||||||
|
#[action(namespace = zed)]
|
||||||
pub struct ImportCursorSettings {
|
pub struct ImportCursorSettings {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub skip_prompt: bool,
|
pub skip_prompt: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_actions!(zed, [ImportVsCodeSettings, ImportCursorSettings]);
|
|
||||||
actions!(zed, [OpenSettingsEditor]);
|
actions!(zed, [OpenSettingsEditor]);
|
||||||
|
|
||||||
pub fn init(cx: &mut App) {
|
pub fn init(cx: &mut App) {
|
||||||
|
|
|
@ -7,7 +7,7 @@ use fuzzy::StringMatchCandidate;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
Action, AnyElement, App, Context, DismissEvent, Entity, EntityId, EventEmitter, FocusHandle,
|
Action, AnyElement, App, Context, DismissEvent, Entity, EntityId, EventEmitter, FocusHandle,
|
||||||
Focusable, Modifiers, ModifiersChangedEvent, MouseButton, MouseUpEvent, ParentElement, Render,
|
Focusable, Modifiers, ModifiersChangedEvent, MouseButton, MouseUpEvent, ParentElement, Render,
|
||||||
Styled, Task, WeakEntity, Window, actions, impl_actions, rems,
|
Styled, Task, WeakEntity, Window, actions, rems,
|
||||||
};
|
};
|
||||||
use picker::{Picker, PickerDelegate};
|
use picker::{Picker, PickerDelegate};
|
||||||
use project::Project;
|
use project::Project;
|
||||||
|
@ -25,14 +25,13 @@ use workspace::{
|
||||||
|
|
||||||
const PANEL_WIDTH_REMS: f32 = 28.;
|
const PANEL_WIDTH_REMS: f32 = 28.;
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, JsonSchema, Default)]
|
#[derive(PartialEq, Clone, Deserialize, JsonSchema, Default, Action)]
|
||||||
|
#[action(namespace = tab_switcher)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct Toggle {
|
pub struct Toggle {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub select_last: bool,
|
pub select_last: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_actions!(tab_switcher, [Toggle]);
|
|
||||||
actions!(tab_switcher, [CloseSelectedItem, ToggleAll]);
|
actions!(tab_switcher, [CloseSelectedItem, ToggleAll]);
|
||||||
|
|
||||||
pub struct TabSwitcher {
|
pub struct TabSwitcher {
|
||||||
|
|
|
@ -8,10 +8,10 @@ pub mod terminal_tab_tooltip;
|
||||||
use assistant_slash_command::SlashCommandRegistry;
|
use assistant_slash_command::SlashCommandRegistry;
|
||||||
use editor::{Editor, EditorSettings, actions::SelectAll, scroll::ScrollbarAutoHide};
|
use editor::{Editor, EditorSettings, actions::SelectAll, scroll::ScrollbarAutoHide};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
AnyElement, App, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, KeyContext,
|
Action, AnyElement, App, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable,
|
||||||
KeyDownEvent, Keystroke, MouseButton, MouseDownEvent, Pixels, Render, ScrollWheelEvent,
|
KeyContext, KeyDownEvent, Keystroke, MouseButton, MouseDownEvent, Pixels, Render,
|
||||||
Stateful, Styled, Subscription, Task, WeakEntity, actions, anchored, deferred, div,
|
ScrollWheelEvent, Stateful, Styled, Subscription, Task, WeakEntity, actions, anchored,
|
||||||
impl_actions,
|
deferred, div,
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use persistence::TERMINAL_DB;
|
use persistence::TERMINAL_DB;
|
||||||
|
@ -70,16 +70,16 @@ const GIT_DIFF_PATH_PREFIXES: &[&str] = &["a", "b"];
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct ScrollTerminal(pub i32);
|
pub struct ScrollTerminal(pub i32);
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Debug, Default, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = terminal)]
|
||||||
pub struct SendText(String);
|
pub struct SendText(String);
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Debug, Default, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = terminal)]
|
||||||
pub struct SendKeystroke(String);
|
pub struct SendKeystroke(String);
|
||||||
|
|
||||||
actions!(terminal, [RerunTask]);
|
actions!(terminal, [RerunTask]);
|
||||||
|
|
||||||
impl_actions!(terminal, [SendText, SendKeystroke]);
|
|
||||||
|
|
||||||
pub fn init(cx: &mut App) {
|
pub fn init(cx: &mut App) {
|
||||||
assistant_slash_command::init(cx);
|
assistant_slash_command::init(cx);
|
||||||
terminal_panel::init(cx);
|
terminal_panel::init(cx);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use gpui::{Entity, OwnedMenu, OwnedMenuItem};
|
use gpui::{Entity, OwnedMenu, OwnedMenuItem};
|
||||||
|
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
use gpui::{actions, impl_actions};
|
use gpui::{Action, actions};
|
||||||
|
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
|
@ -11,14 +11,12 @@ use serde::Deserialize;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use ui::{ContextMenu, PopoverMenu, PopoverMenuHandle, Tooltip, prelude::*};
|
use ui::{ContextMenu, PopoverMenu, PopoverMenuHandle, Tooltip, prelude::*};
|
||||||
|
|
||||||
#[cfg(not(target_os = "macos"))]
|
|
||||||
impl_actions!(app_menu, [OpenApplicationMenu]);
|
|
||||||
|
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
actions!(app_menu, [ActivateMenuRight, ActivateMenuLeft]);
|
actions!(app_menu, [ActivateMenuRight, ActivateMenuLeft]);
|
||||||
|
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Default)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Default, Action)]
|
||||||
|
#[action(namespace = app_menu)]
|
||||||
pub struct OpenApplicationMenu(String);
|
pub struct OpenApplicationMenu(String);
|
||||||
|
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
|
|
|
@ -11,10 +11,7 @@ use workspace::notifications::DetachAndPromptErr;
|
||||||
|
|
||||||
use crate::TitleBar;
|
use crate::TitleBar;
|
||||||
|
|
||||||
actions!(
|
actions!(collab, [ToggleScreenSharing, ToggleMute, ToggleDeafen]);
|
||||||
collab,
|
|
||||||
[ToggleScreenSharing, ToggleMute, ToggleDeafen, LeaveCall]
|
|
||||||
);
|
|
||||||
|
|
||||||
fn toggle_screen_sharing(_: &ToggleScreenSharing, window: &mut Window, cx: &mut App) {
|
fn toggle_screen_sharing(_: &ToggleScreenSharing, window: &mut Window, cx: &mut App) {
|
||||||
let call = ActiveCall::global(cx).read(cx);
|
let call = ActiveCall::global(cx).read(cx);
|
||||||
|
|
|
@ -4,7 +4,7 @@ use story::Story;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::{ContextMenu, Label, right_click_menu};
|
use crate::{ContextMenu, Label, right_click_menu};
|
||||||
|
|
||||||
actions!(context_menu, [PrintCurrentDate, PrintBestFood]);
|
actions!(stories, [PrintCurrentDate, PrintBestFood]);
|
||||||
|
|
||||||
fn build_menu(
|
fn build_menu(
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
|
|
|
@ -7,7 +7,7 @@ use editor::{
|
||||||
display_map::ToDisplayPoint,
|
display_map::ToDisplayPoint,
|
||||||
scroll::Autoscroll,
|
scroll::Autoscroll,
|
||||||
};
|
};
|
||||||
use gpui::{Action, App, AppContext as _, Context, Global, Window, actions, impl_internal_actions};
|
use gpui::{Action, App, AppContext as _, Context, Global, Window, actions};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use language::Point;
|
use language::Point;
|
||||||
use multi_buffer::MultiBufferRow;
|
use multi_buffer::MultiBufferRow;
|
||||||
|
@ -45,24 +45,28 @@ use crate::{
|
||||||
visual::VisualDeleteLine,
|
visual::VisualDeleteLine,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim, no_json, no_register)]
|
||||||
pub struct GoToLine {
|
pub struct GoToLine {
|
||||||
range: CommandRange,
|
range: CommandRange,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim, no_json, no_register)]
|
||||||
pub struct YankCommand {
|
pub struct YankCommand {
|
||||||
range: CommandRange,
|
range: CommandRange,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim, no_json, no_register)]
|
||||||
pub struct WithRange {
|
pub struct WithRange {
|
||||||
restore_selection: bool,
|
restore_selection: bool,
|
||||||
range: CommandRange,
|
range: CommandRange,
|
||||||
action: WrappedAction,
|
action: WrappedAction,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim, no_json, no_register)]
|
||||||
pub struct WithCount {
|
pub struct WithCount {
|
||||||
count: u32,
|
count: u32,
|
||||||
action: WrappedAction,
|
action: WrappedAction,
|
||||||
|
@ -152,21 +156,21 @@ impl VimOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim, no_json, no_register)]
|
||||||
pub struct VimSet {
|
pub struct VimSet {
|
||||||
options: Vec<VimOption>,
|
options: Vec<VimOption>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Clone, PartialEq, Action)]
|
||||||
struct WrappedAction(Box<dyn Action>);
|
#[action(namespace = vim, no_json, no_register)]
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
|
||||||
struct VimSave {
|
struct VimSave {
|
||||||
pub save_intent: Option<SaveIntent>,
|
pub save_intent: Option<SaveIntent>,
|
||||||
pub filename: String,
|
pub filename: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim, no_json, no_register)]
|
||||||
enum DeleteMarks {
|
enum DeleteMarks {
|
||||||
Marks(String),
|
Marks(String),
|
||||||
AllLocal,
|
AllLocal,
|
||||||
|
@ -176,26 +180,14 @@ actions!(
|
||||||
vim,
|
vim,
|
||||||
[VisualCommand, CountCommand, ShellCommand, ArgumentRequired]
|
[VisualCommand, CountCommand, ShellCommand, ArgumentRequired]
|
||||||
);
|
);
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim, no_json, no_register)]
|
||||||
struct VimEdit {
|
struct VimEdit {
|
||||||
pub filename: String,
|
pub filename: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_internal_actions!(
|
#[derive(Debug)]
|
||||||
vim,
|
struct WrappedAction(Box<dyn Action>);
|
||||||
[
|
|
||||||
GoToLine,
|
|
||||||
YankCommand,
|
|
||||||
WithRange,
|
|
||||||
WithCount,
|
|
||||||
OnMatchingLines,
|
|
||||||
ShellExec,
|
|
||||||
VimSet,
|
|
||||||
VimSave,
|
|
||||||
DeleteMarks,
|
|
||||||
VimEdit,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
impl PartialEq for WrappedAction {
|
impl PartialEq for WrappedAction {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
@ -1289,7 +1281,8 @@ fn generate_positions(string: &str, query: &str) -> Vec<usize> {
|
||||||
positions
|
positions
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone, Action)]
|
||||||
|
#[action(namespace = vim, no_json, no_register)]
|
||||||
pub(crate) struct OnMatchingLines {
|
pub(crate) struct OnMatchingLines {
|
||||||
range: CommandRange,
|
range: CommandRange,
|
||||||
search: String,
|
search: String,
|
||||||
|
@ -1481,7 +1474,8 @@ impl OnMatchingLines {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim, no_json, no_register)]
|
||||||
pub struct ShellExec {
|
pub struct ShellExec {
|
||||||
command: String,
|
command: String,
|
||||||
range: Option<CommandRange>,
|
range: Option<CommandRange>,
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use editor::Editor;
|
use editor::Editor;
|
||||||
use gpui::{App, Context, Keystroke, KeystrokeEvent, Window, impl_actions};
|
use gpui::{Action, App, Context, Keystroke, KeystrokeEvent, Window};
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
|
@ -12,9 +12,9 @@ use crate::{Vim, VimSettings, state::Operator};
|
||||||
|
|
||||||
mod default;
|
mod default;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Debug, Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
struct Literal(String, char);
|
struct Literal(String, char);
|
||||||
impl_actions!(vim, [Literal]);
|
|
||||||
|
|
||||||
pub(crate) fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
pub(crate) fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||||
Vim::action(editor, cx, Vim::literal)
|
Vim::action(editor, cx, Vim::literal)
|
||||||
|
|
|
@ -6,7 +6,7 @@ use editor::{
|
||||||
},
|
},
|
||||||
scroll::Autoscroll,
|
scroll::Autoscroll,
|
||||||
};
|
};
|
||||||
use gpui::{Context, Window, action_with_deprecated_aliases, actions, impl_actions, px};
|
use gpui::{Action, Context, Window, actions, px};
|
||||||
use language::{CharKind, Point, Selection, SelectionGoal};
|
use language::{CharKind, Point, Selection, SelectionGoal};
|
||||||
use multi_buffer::MultiBufferRow;
|
use multi_buffer::MultiBufferRow;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
|
@ -177,147 +177,143 @@ enum IndentType {
|
||||||
Same,
|
Same,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct NextWordStart {
|
struct NextWordStart {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
ignore_punctuation: bool,
|
ignore_punctuation: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct NextWordEnd {
|
struct NextWordEnd {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
ignore_punctuation: bool,
|
ignore_punctuation: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct PreviousWordStart {
|
struct PreviousWordStart {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
ignore_punctuation: bool,
|
ignore_punctuation: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct PreviousWordEnd {
|
struct PreviousWordEnd {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
ignore_punctuation: bool,
|
ignore_punctuation: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub(crate) struct NextSubwordStart {
|
pub(crate) struct NextSubwordStart {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub(crate) ignore_punctuation: bool,
|
pub(crate) ignore_punctuation: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub(crate) struct NextSubwordEnd {
|
pub(crate) struct NextSubwordEnd {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub(crate) ignore_punctuation: bool,
|
pub(crate) ignore_punctuation: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub(crate) struct PreviousSubwordStart {
|
pub(crate) struct PreviousSubwordStart {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub(crate) ignore_punctuation: bool,
|
pub(crate) ignore_punctuation: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub(crate) struct PreviousSubwordEnd {
|
pub(crate) struct PreviousSubwordEnd {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub(crate) ignore_punctuation: bool,
|
pub(crate) ignore_punctuation: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub(crate) struct Up {
|
pub(crate) struct Up {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub(crate) display_lines: bool,
|
pub(crate) display_lines: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub(crate) struct Down {
|
pub(crate) struct Down {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub(crate) display_lines: bool,
|
pub(crate) display_lines: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct FirstNonWhitespace {
|
struct FirstNonWhitespace {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
display_lines: bool,
|
display_lines: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct EndOfLine {
|
struct EndOfLine {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
display_lines: bool,
|
display_lines: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct StartOfLine {
|
pub struct StartOfLine {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub(crate) display_lines: bool,
|
pub(crate) display_lines: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct MiddleOfLine {
|
struct MiddleOfLine {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
display_lines: bool,
|
display_lines: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct UnmatchedForward {
|
struct UnmatchedForward {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
char: char,
|
char: char,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct UnmatchedBackward {
|
struct UnmatchedBackward {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
char: char,
|
char: char,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_actions!(
|
|
||||||
vim,
|
|
||||||
[
|
|
||||||
StartOfLine,
|
|
||||||
MiddleOfLine,
|
|
||||||
EndOfLine,
|
|
||||||
FirstNonWhitespace,
|
|
||||||
Down,
|
|
||||||
Up,
|
|
||||||
NextWordStart,
|
|
||||||
NextWordEnd,
|
|
||||||
PreviousWordStart,
|
|
||||||
PreviousWordEnd,
|
|
||||||
NextSubwordStart,
|
|
||||||
NextSubwordEnd,
|
|
||||||
PreviousSubwordStart,
|
|
||||||
PreviousSubwordEnd,
|
|
||||||
UnmatchedForward,
|
|
||||||
UnmatchedBackward
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
actions!(
|
actions!(
|
||||||
vim,
|
vim,
|
||||||
[
|
[
|
||||||
Left,
|
Left,
|
||||||
Backspace,
|
#[action(deprecated_aliases = ["vim::Backspace"])]
|
||||||
|
WrappingLeft,
|
||||||
Right,
|
Right,
|
||||||
Space,
|
#[action(deprecated_aliases = ["vim::Space"])]
|
||||||
|
WrappingRight,
|
||||||
CurrentLine,
|
CurrentLine,
|
||||||
SentenceForward,
|
SentenceForward,
|
||||||
SentenceBackward,
|
SentenceBackward,
|
||||||
|
@ -356,9 +352,6 @@ actions!(
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
action_with_deprecated_aliases!(vim, WrappingLeft, ["vim::Backspace"]);
|
|
||||||
action_with_deprecated_aliases!(vim, WrappingRight, ["vim::Space"]);
|
|
||||||
|
|
||||||
pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||||
Vim::action(editor, cx, |vim, _: &Left, window, cx| {
|
Vim::action(editor, cx, |vim, _: &Left, window, cx| {
|
||||||
vim.motion(Motion::Left, window, cx)
|
vim.motion(Motion::Left, window, cx)
|
||||||
|
@ -366,10 +359,6 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||||
Vim::action(editor, cx, |vim, _: &WrappingLeft, window, cx| {
|
Vim::action(editor, cx, |vim, _: &WrappingLeft, window, cx| {
|
||||||
vim.motion(Motion::WrappingLeft, window, cx)
|
vim.motion(Motion::WrappingLeft, window, cx)
|
||||||
});
|
});
|
||||||
// Deprecated.
|
|
||||||
Vim::action(editor, cx, |vim, _: &Backspace, window, cx| {
|
|
||||||
vim.motion(Motion::WrappingLeft, window, cx)
|
|
||||||
});
|
|
||||||
Vim::action(editor, cx, |vim, action: &Down, window, cx| {
|
Vim::action(editor, cx, |vim, action: &Down, window, cx| {
|
||||||
vim.motion(
|
vim.motion(
|
||||||
Motion::Down {
|
Motion::Down {
|
||||||
|
@ -394,10 +383,6 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||||
Vim::action(editor, cx, |vim, _: &WrappingRight, window, cx| {
|
Vim::action(editor, cx, |vim, _: &WrappingRight, window, cx| {
|
||||||
vim.motion(Motion::WrappingRight, window, cx)
|
vim.motion(Motion::WrappingRight, window, cx)
|
||||||
});
|
});
|
||||||
// Deprecated.
|
|
||||||
Vim::action(editor, cx, |vim, _: &Space, window, cx| {
|
|
||||||
vim.motion(Motion::WrappingRight, window, cx)
|
|
||||||
});
|
|
||||||
Vim::action(
|
Vim::action(
|
||||||
editor,
|
editor,
|
||||||
cx,
|
cx,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use editor::{Editor, MultiBufferSnapshot, ToOffset, ToPoint, scroll::Autoscroll};
|
use editor::{Editor, MultiBufferSnapshot, ToOffset, ToPoint, scroll::Autoscroll};
|
||||||
use gpui::{Context, Window, impl_actions};
|
use gpui::{Action, Context, Window};
|
||||||
use language::{Bias, Point};
|
use language::{Bias, Point};
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
@ -9,22 +9,22 @@ use crate::{Vim, state::Mode};
|
||||||
|
|
||||||
const BOOLEAN_PAIRS: &[(&str, &str)] = &[("true", "false"), ("yes", "no"), ("on", "off")];
|
const BOOLEAN_PAIRS: &[(&str, &str)] = &[("true", "false"), ("yes", "no"), ("on", "off")];
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct Increment {
|
struct Increment {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
step: bool,
|
step: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct Decrement {
|
struct Decrement {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
step: bool,
|
step: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_actions!(vim, [Increment, Decrement]);
|
|
||||||
|
|
||||||
pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||||
Vim::action(editor, cx, |vim, action: &Increment, window, cx| {
|
Vim::action(editor, cx, |vim, action: &Increment, window, cx| {
|
||||||
vim.record_current_action(cx);
|
vim.record_current_action(cx);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use editor::{DisplayPoint, RowExt, display_map::ToDisplayPoint, movement, scroll::Autoscroll};
|
use editor::{DisplayPoint, RowExt, display_map::ToDisplayPoint, movement, scroll::Autoscroll};
|
||||||
use gpui::{Context, Window, impl_actions};
|
use gpui::{Action, Context, Window};
|
||||||
use language::{Bias, SelectionGoal};
|
use language::{Bias, SelectionGoal};
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
@ -14,7 +14,8 @@ use crate::{
|
||||||
state::{Mode, Register},
|
state::{Mode, Register},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct Paste {
|
pub struct Paste {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
@ -23,8 +24,6 @@ pub struct Paste {
|
||||||
preserve_clipboard: bool,
|
preserve_clipboard: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_actions!(vim, [Paste]);
|
|
||||||
|
|
||||||
impl Vim {
|
impl Vim {
|
||||||
pub fn paste(&mut self, action: &Paste, window: &mut Window, cx: &mut Context<Self>) {
|
pub fn paste(&mut self, action: &Paste, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
self.record_current_action(cx);
|
self.record_current_action(cx);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use editor::{Editor, EditorSettings};
|
use editor::{Editor, EditorSettings};
|
||||||
use gpui::{Context, Window, actions, impl_actions, impl_internal_actions};
|
use gpui::{Action, Context, Window, actions};
|
||||||
use language::Point;
|
use language::Point;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use search::{BufferSearchBar, SearchOptions, buffer_search};
|
use search::{BufferSearchBar, SearchOptions, buffer_search};
|
||||||
|
@ -16,7 +16,8 @@ use crate::{
|
||||||
state::{Mode, SearchState},
|
state::{Mode, SearchState},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub(crate) struct MoveToNext {
|
pub(crate) struct MoveToNext {
|
||||||
#[serde(default = "default_true")]
|
#[serde(default = "default_true")]
|
||||||
|
@ -27,7 +28,8 @@ pub(crate) struct MoveToNext {
|
||||||
regex: bool,
|
regex: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub(crate) struct MoveToPrevious {
|
pub(crate) struct MoveToPrevious {
|
||||||
#[serde(default = "default_true")]
|
#[serde(default = "default_true")]
|
||||||
|
@ -38,7 +40,8 @@ pub(crate) struct MoveToPrevious {
|
||||||
regex: bool,
|
regex: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub(crate) struct Search {
|
pub(crate) struct Search {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
@ -47,14 +50,16 @@ pub(crate) struct Search {
|
||||||
regex: bool,
|
regex: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct FindCommand {
|
pub struct FindCommand {
|
||||||
pub query: String,
|
pub query: String,
|
||||||
pub backwards: bool,
|
pub backwards: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim, no_json, no_register)]
|
||||||
pub struct ReplaceCommand {
|
pub struct ReplaceCommand {
|
||||||
pub(crate) range: CommandRange,
|
pub(crate) range: CommandRange,
|
||||||
pub(crate) replacement: Replacement,
|
pub(crate) replacement: Replacement,
|
||||||
|
@ -69,8 +74,6 @@ pub(crate) struct Replacement {
|
||||||
}
|
}
|
||||||
|
|
||||||
actions!(vim, [SearchSubmit, MoveToNextMatch, MoveToPreviousMatch]);
|
actions!(vim, [SearchSubmit, MoveToNextMatch, MoveToPreviousMatch]);
|
||||||
impl_actions!(vim, [FindCommand, Search, MoveToPrevious, MoveToNext]);
|
|
||||||
impl_internal_actions!(vim, [ReplaceCommand]);
|
|
||||||
|
|
||||||
pub(crate) fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
pub(crate) fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||||
Vim::action(editor, cx, Vim::move_to_next);
|
Vim::action(editor, cx, Vim::move_to_next);
|
||||||
|
|
|
@ -10,7 +10,7 @@ use editor::{
|
||||||
display_map::{DisplaySnapshot, ToDisplayPoint},
|
display_map::{DisplaySnapshot, ToDisplayPoint},
|
||||||
movement::{self, FindRange},
|
movement::{self, FindRange},
|
||||||
};
|
};
|
||||||
use gpui::{Window, actions, impl_actions};
|
use gpui::{Action, Window, actions};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use language::{BufferSnapshot, CharKind, Point, Selection, TextObject, TreeSitterOptions};
|
use language::{BufferSnapshot, CharKind, Point, Selection, TextObject, TreeSitterOptions};
|
||||||
use multi_buffer::MultiBufferRow;
|
use multi_buffer::MultiBufferRow;
|
||||||
|
@ -46,20 +46,23 @@ pub enum Object {
|
||||||
EntireFile,
|
EntireFile,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct Word {
|
struct Word {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
ignore_punctuation: bool,
|
ignore_punctuation: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct Subword {
|
struct Subword {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
ignore_punctuation: bool,
|
ignore_punctuation: bool,
|
||||||
}
|
}
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct IndentObj {
|
struct IndentObj {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
@ -252,8 +255,6 @@ fn find_mini_brackets(
|
||||||
find_mini_delimiters(map, display_point, around, &is_bracket_delimiter)
|
find_mini_delimiters(map, display_point, around, &is_bracket_delimiter)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_actions!(vim, [Word, Subword, IndentObj]);
|
|
||||||
|
|
||||||
actions!(
|
actions!(
|
||||||
vim,
|
vim,
|
||||||
[
|
[
|
||||||
|
|
|
@ -27,7 +27,7 @@ use editor::{
|
||||||
};
|
};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
Action, App, AppContext, Axis, Context, Entity, EventEmitter, KeyContext, KeystrokeEvent,
|
Action, App, AppContext, Axis, Context, Entity, EventEmitter, KeyContext, KeystrokeEvent,
|
||||||
Render, Subscription, Task, WeakEntity, Window, actions, impl_actions,
|
Render, Subscription, Task, WeakEntity, Window, actions,
|
||||||
};
|
};
|
||||||
use insert::{NormalBefore, TemporaryNormal};
|
use insert::{NormalBefore, TemporaryNormal};
|
||||||
use language::{CharKind, CursorShape, Point, Selection, SelectionGoal, TransactionId};
|
use language::{CharKind, CursorShape, Point, Selection, SelectionGoal, TransactionId};
|
||||||
|
@ -52,65 +52,77 @@ use crate::state::ReplayableAction;
|
||||||
|
|
||||||
/// Number is used to manage vim's count. Pushing a digit
|
/// Number is used to manage vim's count. Pushing a digit
|
||||||
/// multiplies the current value by 10 and adds the digit.
|
/// multiplies the current value by 10 and adds the digit.
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
struct Number(usize);
|
struct Number(usize);
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
struct SelectRegister(String);
|
struct SelectRegister(String);
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct PushObject {
|
struct PushObject {
|
||||||
around: bool,
|
around: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct PushFindForward {
|
struct PushFindForward {
|
||||||
before: bool,
|
before: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct PushFindBackward {
|
struct PushFindBackward {
|
||||||
after: bool,
|
after: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct PushSneak {
|
struct PushSneak {
|
||||||
first_char: Option<char>,
|
first_char: Option<char>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct PushSneakBackward {
|
struct PushSneakBackward {
|
||||||
first_char: Option<char>,
|
first_char: Option<char>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct PushAddSurrounds {}
|
struct PushAddSurrounds;
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct PushChangeSurrounds {
|
struct PushChangeSurrounds {
|
||||||
target: Option<Object>,
|
target: Option<Object>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct PushJump {
|
struct PushJump {
|
||||||
line: bool,
|
line: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct PushDigraph {
|
struct PushDigraph {
|
||||||
first_char: Option<char>,
|
first_char: Option<char>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
|
||||||
|
#[action(namespace = vim)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct PushLiteral {
|
struct PushLiteral {
|
||||||
prefix: Option<String>,
|
prefix: Option<String>,
|
||||||
|
@ -169,24 +181,6 @@ actions!(
|
||||||
// in the workspace namespace so it's not filtered out when vim is disabled.
|
// in the workspace namespace so it's not filtered out when vim is disabled.
|
||||||
actions!(workspace, [ToggleVimMode,]);
|
actions!(workspace, [ToggleVimMode,]);
|
||||||
|
|
||||||
impl_actions!(
|
|
||||||
vim,
|
|
||||||
[
|
|
||||||
Number,
|
|
||||||
SelectRegister,
|
|
||||||
PushObject,
|
|
||||||
PushFindForward,
|
|
||||||
PushFindBackward,
|
|
||||||
PushSneak,
|
|
||||||
PushSneakBackward,
|
|
||||||
PushAddSurrounds,
|
|
||||||
PushChangeSurrounds,
|
|
||||||
PushJump,
|
|
||||||
PushDigraph,
|
|
||||||
PushLiteral
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Initializes the `vim` crate.
|
/// Initializes the `vim` crate.
|
||||||
pub fn init(cx: &mut App) {
|
pub fn init(cx: &mut App) {
|
||||||
vim_mode_setting::init(cx);
|
vim_mode_setting::init(cx);
|
||||||
|
|
|
@ -955,7 +955,7 @@ pub mod test {
|
||||||
pub focus_handle: FocusHandle,
|
pub focus_handle: FocusHandle,
|
||||||
pub size: Pixels,
|
pub size: Pixels,
|
||||||
}
|
}
|
||||||
actions!(test, [ToggleTestPanel]);
|
actions!(test_only, [ToggleTestPanel]);
|
||||||
|
|
||||||
impl EventEmitter<PanelEvent> for TestPanel {}
|
impl EventEmitter<PanelEvent> for TestPanel {}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ use gpui::{
|
||||||
DragMoveEvent, Entity, EntityId, EventEmitter, ExternalPaths, FocusHandle, FocusOutEvent,
|
DragMoveEvent, Entity, EntityId, EventEmitter, ExternalPaths, FocusHandle, FocusOutEvent,
|
||||||
Focusable, KeyContext, MouseButton, MouseDownEvent, NavigationDirection, Pixels, Point,
|
Focusable, KeyContext, MouseButton, MouseDownEvent, NavigationDirection, Pixels, Point,
|
||||||
PromptLevel, Render, ScrollHandle, Subscription, Task, WeakEntity, WeakFocusHandle, Window,
|
PromptLevel, Render, ScrollHandle, Subscription, Task, WeakEntity, WeakFocusHandle, Window,
|
||||||
actions, anchored, deferred, impl_actions, prelude::*,
|
actions, anchored, deferred, prelude::*,
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use language::DiagnosticSeverity;
|
use language::DiagnosticSeverity;
|
||||||
|
@ -95,10 +95,12 @@ pub enum SaveIntent {
|
||||||
Skip,
|
Skip,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default)]
|
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default, Action)]
|
||||||
|
#[action(namespace = pane)]
|
||||||
pub struct ActivateItem(pub usize);
|
pub struct ActivateItem(pub usize);
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default)]
|
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default, Action)]
|
||||||
|
#[action(namespace = pane)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct CloseActiveItem {
|
pub struct CloseActiveItem {
|
||||||
pub save_intent: Option<SaveIntent>,
|
pub save_intent: Option<SaveIntent>,
|
||||||
|
@ -106,7 +108,8 @@ pub struct CloseActiveItem {
|
||||||
pub close_pinned: bool,
|
pub close_pinned: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default)]
|
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default, Action)]
|
||||||
|
#[action(namespace = pane)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct CloseInactiveItems {
|
pub struct CloseInactiveItems {
|
||||||
pub save_intent: Option<SaveIntent>,
|
pub save_intent: Option<SaveIntent>,
|
||||||
|
@ -114,7 +117,8 @@ pub struct CloseInactiveItems {
|
||||||
pub close_pinned: bool,
|
pub close_pinned: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default)]
|
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default, Action)]
|
||||||
|
#[action(namespace = pane)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct CloseAllItems {
|
pub struct CloseAllItems {
|
||||||
pub save_intent: Option<SaveIntent>,
|
pub save_intent: Option<SaveIntent>,
|
||||||
|
@ -122,35 +126,40 @@ pub struct CloseAllItems {
|
||||||
pub close_pinned: bool,
|
pub close_pinned: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default)]
|
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default, Action)]
|
||||||
|
#[action(namespace = pane)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct CloseCleanItems {
|
pub struct CloseCleanItems {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub close_pinned: bool,
|
pub close_pinned: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default)]
|
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default, Action)]
|
||||||
|
#[action(namespace = pane)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct CloseItemsToTheRight {
|
pub struct CloseItemsToTheRight {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub close_pinned: bool,
|
pub close_pinned: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default)]
|
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default, Action)]
|
||||||
|
#[action(namespace = pane)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct CloseItemsToTheLeft {
|
pub struct CloseItemsToTheLeft {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub close_pinned: bool,
|
pub close_pinned: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default)]
|
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default, Action)]
|
||||||
|
#[action(namespace = pane)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct RevealInProjectPanel {
|
pub struct RevealInProjectPanel {
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub entry_id: Option<u64>,
|
pub entry_id: Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default)]
|
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default, Action)]
|
||||||
|
#[action(namespace = pane)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct DeploySearch {
|
pub struct DeploySearch {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
@ -161,21 +170,6 @@ pub struct DeploySearch {
|
||||||
pub excluded_files: Option<String>,
|
pub excluded_files: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_actions!(
|
|
||||||
pane,
|
|
||||||
[
|
|
||||||
CloseAllItems,
|
|
||||||
CloseActiveItem,
|
|
||||||
CloseCleanItems,
|
|
||||||
CloseItemsToTheLeft,
|
|
||||||
CloseItemsToTheRight,
|
|
||||||
CloseInactiveItems,
|
|
||||||
ActivateItem,
|
|
||||||
RevealInProjectPanel,
|
|
||||||
DeploySearch,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
actions!(
|
actions!(
|
||||||
pane,
|
pane,
|
||||||
[
|
[
|
||||||
|
|
|
@ -39,8 +39,8 @@ use gpui::{
|
||||||
CursorStyle, Decorations, DragMoveEvent, Entity, EntityId, EventEmitter, FocusHandle,
|
CursorStyle, Decorations, DragMoveEvent, Entity, EntityId, EventEmitter, FocusHandle,
|
||||||
Focusable, Global, HitboxBehavior, Hsla, KeyContext, Keystroke, ManagedView, MouseButton,
|
Focusable, Global, HitboxBehavior, Hsla, KeyContext, Keystroke, ManagedView, MouseButton,
|
||||||
PathPromptOptions, Point, PromptLevel, Render, ResizeEdge, Size, Stateful, Subscription, Task,
|
PathPromptOptions, Point, PromptLevel, Render, ResizeEdge, Size, Stateful, Subscription, Task,
|
||||||
Tiling, WeakEntity, WindowBounds, WindowHandle, WindowId, WindowOptions, action_as, actions,
|
Tiling, WeakEntity, WindowBounds, WindowHandle, WindowId, WindowOptions, actions, canvas,
|
||||||
canvas, impl_action_as, impl_actions, point, relative, size, transparent_black,
|
point, relative, size, transparent_black,
|
||||||
};
|
};
|
||||||
pub use history_manager::*;
|
pub use history_manager::*;
|
||||||
pub use item::{
|
pub use item::{
|
||||||
|
@ -213,10 +213,12 @@ pub struct OpenPaths {
|
||||||
pub paths: Vec<PathBuf>,
|
pub paths: Vec<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, PartialEq, JsonSchema)]
|
#[derive(Clone, Deserialize, PartialEq, JsonSchema, Action)]
|
||||||
|
#[action(namespace = workspace)]
|
||||||
pub struct ActivatePane(pub usize);
|
pub struct ActivatePane(pub usize);
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, PartialEq, JsonSchema)]
|
#[derive(Clone, Deserialize, PartialEq, JsonSchema, Action)]
|
||||||
|
#[action(namespace = workspace)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct MoveItemToPane {
|
pub struct MoveItemToPane {
|
||||||
pub destination: usize,
|
pub destination: usize,
|
||||||
|
@ -226,7 +228,8 @@ pub struct MoveItemToPane {
|
||||||
pub clone: bool,
|
pub clone: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, PartialEq, JsonSchema)]
|
#[derive(Clone, Deserialize, PartialEq, JsonSchema, Action)]
|
||||||
|
#[action(namespace = workspace)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct MoveItemToPaneInDirection {
|
pub struct MoveItemToPaneInDirection {
|
||||||
pub direction: SplitDirection,
|
pub direction: SplitDirection,
|
||||||
|
@ -236,65 +239,60 @@ pub struct MoveItemToPaneInDirection {
|
||||||
pub clone: bool,
|
pub clone: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema)]
|
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Action)]
|
||||||
|
#[action(namespace = workspace)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct SaveAll {
|
pub struct SaveAll {
|
||||||
pub save_intent: Option<SaveIntent>,
|
pub save_intent: Option<SaveIntent>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema)]
|
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Action)]
|
||||||
|
#[action(namespace = workspace)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct Save {
|
pub struct Save {
|
||||||
pub save_intent: Option<SaveIntent>,
|
pub save_intent: Option<SaveIntent>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug, Deserialize, Default, JsonSchema)]
|
#[derive(Clone, PartialEq, Debug, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = workspace)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct CloseAllItemsAndPanes {
|
pub struct CloseAllItemsAndPanes {
|
||||||
pub save_intent: Option<SaveIntent>,
|
pub save_intent: Option<SaveIntent>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug, Deserialize, Default, JsonSchema)]
|
#[derive(Clone, PartialEq, Debug, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = workspace)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct CloseInactiveTabsAndPanes {
|
pub struct CloseInactiveTabsAndPanes {
|
||||||
pub save_intent: Option<SaveIntent>,
|
pub save_intent: Option<SaveIntent>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, PartialEq, JsonSchema)]
|
#[derive(Clone, Deserialize, PartialEq, JsonSchema, Action)]
|
||||||
|
#[action(namespace = workspace)]
|
||||||
pub struct SendKeystrokes(pub String);
|
pub struct SendKeystrokes(pub String);
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, PartialEq, Default, JsonSchema)]
|
#[derive(Clone, Deserialize, PartialEq, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = workspace)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct Reload {
|
pub struct Reload {
|
||||||
pub binary_path: Option<PathBuf>,
|
pub binary_path: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
action_as!(project_symbols, ToggleProjectSymbols as Toggle);
|
actions!(
|
||||||
|
project_symbols,
|
||||||
|
[
|
||||||
|
#[action(name = "Toggle")]
|
||||||
|
ToggleProjectSymbols
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
#[derive(Default, PartialEq, Eq, Clone, Deserialize, JsonSchema)]
|
#[derive(Default, PartialEq, Eq, Clone, Deserialize, JsonSchema, Action)]
|
||||||
|
#[action(namespace = file_finder, name = "Toggle")]
|
||||||
pub struct ToggleFileFinder {
|
pub struct ToggleFileFinder {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub separate_history: bool,
|
pub separate_history: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_action_as!(file_finder, ToggleFileFinder as Toggle);
|
|
||||||
|
|
||||||
impl_actions!(
|
|
||||||
workspace,
|
|
||||||
[
|
|
||||||
ActivatePane,
|
|
||||||
CloseAllItemsAndPanes,
|
|
||||||
CloseInactiveTabsAndPanes,
|
|
||||||
MoveItemToPane,
|
|
||||||
MoveItemToPaneInDirection,
|
|
||||||
OpenTerminal,
|
|
||||||
Reload,
|
|
||||||
Save,
|
|
||||||
SaveAll,
|
|
||||||
SendKeystrokes,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
actions!(
|
actions!(
|
||||||
workspace,
|
workspace,
|
||||||
[
|
[
|
||||||
|
@ -360,7 +358,8 @@ impl PartialEq for Toast {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Deserialize, PartialEq, JsonSchema)]
|
#[derive(Debug, Default, Clone, Deserialize, PartialEq, JsonSchema, Action)]
|
||||||
|
#[action(namespace = workspace)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct OpenTerminal {
|
pub struct OpenTerminal {
|
||||||
pub working_directory: PathBuf,
|
pub working_directory: PathBuf,
|
||||||
|
@ -6492,6 +6491,11 @@ pub fn last_session_workspace_locations(
|
||||||
actions!(
|
actions!(
|
||||||
collab,
|
collab,
|
||||||
[
|
[
|
||||||
|
/// Opens the channel notes for the current call.
|
||||||
|
///
|
||||||
|
/// If you want to open a specific channel, use `zed::OpenZedUrl` with a channel notes URL -
|
||||||
|
/// can be copied via "Copy link to section" in the context menu of the channel notes
|
||||||
|
/// buffer. These URLs look like `https://zed.dev/channel/channel-name-CHANNEL_ID/notes`.
|
||||||
OpenChannelNotes,
|
OpenChannelNotes,
|
||||||
Mute,
|
Mute,
|
||||||
Deafen,
|
Deafen,
|
||||||
|
|
|
@ -168,7 +168,9 @@ dap = { workspace = true, features = ["test-support"] }
|
||||||
editor = { workspace = true, features = ["test-support"] }
|
editor = { workspace = true, features = ["test-support"] }
|
||||||
gpui = { workspace = true, features = ["test-support"] }
|
gpui = { workspace = true, features = ["test-support"] }
|
||||||
image_viewer = { workspace = true, features = ["test-support"] }
|
image_viewer = { workspace = true, features = ["test-support"] }
|
||||||
|
itertools.workspace = true
|
||||||
language = { workspace = true, features = ["test-support"] }
|
language = { workspace = true, features = ["test-support"] }
|
||||||
|
pretty_assertions.workspace = true
|
||||||
project = { workspace = true, features = ["test-support"] }
|
project = { workspace = true, features = ["test-support"] }
|
||||||
terminal_view = { workspace = true, features = ["test-support"] }
|
terminal_view = { workspace = true, features = ["test-support"] }
|
||||||
tree-sitter-md.workspace = true
|
tree-sitter-md.workspace = true
|
||||||
|
|
|
@ -1308,7 +1308,7 @@ fn dump_all_gpui_actions() {
|
||||||
.map(|action| ActionDef {
|
.map(|action| ActionDef {
|
||||||
name: action.name,
|
name: action.name,
|
||||||
human_name: command_palette::humanize_action_name(action.name),
|
human_name: command_palette::humanize_action_name(action.name),
|
||||||
aliases: action.aliases,
|
aliases: action.deprecated_aliases,
|
||||||
})
|
})
|
||||||
.collect::<Vec<ActionDef>>();
|
.collect::<Vec<ActionDef>>();
|
||||||
|
|
||||||
|
|
|
@ -1762,6 +1762,7 @@ mod tests {
|
||||||
TestAppContext, UpdateGlobal, VisualTestContext, WindowHandle, actions,
|
TestAppContext, UpdateGlobal, VisualTestContext, WindowHandle, actions,
|
||||||
};
|
};
|
||||||
use language::{LanguageMatcher, LanguageRegistry};
|
use language::{LanguageMatcher, LanguageRegistry};
|
||||||
|
use pretty_assertions::{assert_eq, assert_ne};
|
||||||
use project::{Project, ProjectPath, WorktreeSettings, project_settings::ProjectSettings};
|
use project::{Project, ProjectPath, WorktreeSettings, project_settings::ProjectSettings};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use settings::{SettingsStore, watch_config_file};
|
use settings::{SettingsStore, watch_config_file};
|
||||||
|
@ -3926,6 +3927,8 @@ mod tests {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
actions!(test_only, [ActionA, ActionB]);
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_base_keymap(cx: &mut gpui::TestAppContext) {
|
async fn test_base_keymap(cx: &mut gpui::TestAppContext) {
|
||||||
let executor = cx.executor();
|
let executor = cx.executor();
|
||||||
|
@ -3934,7 +3937,6 @@ mod tests {
|
||||||
let workspace =
|
let workspace =
|
||||||
cx.add_window(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
cx.add_window(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||||
|
|
||||||
actions!(test1, [A, B]);
|
|
||||||
// From the Atom keymap
|
// From the Atom keymap
|
||||||
use workspace::ActivatePreviousPane;
|
use workspace::ActivatePreviousPane;
|
||||||
// From the JetBrains keymap
|
// From the JetBrains keymap
|
||||||
|
@ -3954,7 +3956,7 @@ mod tests {
|
||||||
.fs
|
.fs
|
||||||
.save(
|
.save(
|
||||||
"/keymap.json".as_ref(),
|
"/keymap.json".as_ref(),
|
||||||
&r#"[{"bindings": {"backspace": "test1::A"}}]"#.into(),
|
&r#"[{"bindings": {"backspace": "test_only::ActionA"}}]"#.into(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
@ -3981,8 +3983,8 @@ mod tests {
|
||||||
});
|
});
|
||||||
workspace
|
workspace
|
||||||
.update(cx, |workspace, _, cx| {
|
.update(cx, |workspace, _, cx| {
|
||||||
workspace.register_action(|_, _: &A, _window, _cx| {});
|
workspace.register_action(|_, _: &ActionA, _window, _cx| {});
|
||||||
workspace.register_action(|_, _: &B, _window, _cx| {});
|
workspace.register_action(|_, _: &ActionB, _window, _cx| {});
|
||||||
workspace.register_action(|_, _: &ActivatePreviousPane, _window, _cx| {});
|
workspace.register_action(|_, _: &ActivatePreviousPane, _window, _cx| {});
|
||||||
workspace.register_action(|_, _: &ActivatePreviousItem, _window, _cx| {});
|
workspace.register_action(|_, _: &ActivatePreviousItem, _window, _cx| {});
|
||||||
cx.notify();
|
cx.notify();
|
||||||
|
@ -3993,7 +3995,7 @@ mod tests {
|
||||||
assert_key_bindings_for(
|
assert_key_bindings_for(
|
||||||
workspace.into(),
|
workspace.into(),
|
||||||
cx,
|
cx,
|
||||||
vec![("backspace", &A), ("k", &ActivatePreviousPane)],
|
vec![("backspace", &ActionA), ("k", &ActivatePreviousPane)],
|
||||||
line!(),
|
line!(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -4002,7 +4004,7 @@ mod tests {
|
||||||
.fs
|
.fs
|
||||||
.save(
|
.save(
|
||||||
"/keymap.json".as_ref(),
|
"/keymap.json".as_ref(),
|
||||||
&r#"[{"bindings": {"backspace": "test1::B"}}]"#.into(),
|
&r#"[{"bindings": {"backspace": "test_only::ActionB"}}]"#.into(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
@ -4013,7 +4015,7 @@ mod tests {
|
||||||
assert_key_bindings_for(
|
assert_key_bindings_for(
|
||||||
workspace.into(),
|
workspace.into(),
|
||||||
cx,
|
cx,
|
||||||
vec![("backspace", &B), ("k", &ActivatePreviousPane)],
|
vec![("backspace", &ActionB), ("k", &ActivatePreviousPane)],
|
||||||
line!(),
|
line!(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -4033,7 +4035,7 @@ mod tests {
|
||||||
assert_key_bindings_for(
|
assert_key_bindings_for(
|
||||||
workspace.into(),
|
workspace.into(),
|
||||||
cx,
|
cx,
|
||||||
vec![("backspace", &B), ("{", &ActivatePreviousItem)],
|
vec![("backspace", &ActionB), ("{", &ActivatePreviousItem)],
|
||||||
line!(),
|
line!(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -4046,7 +4048,6 @@ mod tests {
|
||||||
let workspace =
|
let workspace =
|
||||||
cx.add_window(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
cx.add_window(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||||
|
|
||||||
actions!(test2, [A, B]);
|
|
||||||
// From the Atom keymap
|
// From the Atom keymap
|
||||||
use workspace::ActivatePreviousPane;
|
use workspace::ActivatePreviousPane;
|
||||||
// From the JetBrains keymap
|
// From the JetBrains keymap
|
||||||
|
@ -4054,8 +4055,8 @@ mod tests {
|
||||||
|
|
||||||
workspace
|
workspace
|
||||||
.update(cx, |workspace, _, _| {
|
.update(cx, |workspace, _, _| {
|
||||||
workspace.register_action(|_, _: &A, _window, _cx| {});
|
workspace.register_action(|_, _: &ActionA, _window, _cx| {});
|
||||||
workspace.register_action(|_, _: &B, _window, _cx| {});
|
workspace.register_action(|_, _: &ActionB, _window, _cx| {});
|
||||||
workspace.register_action(|_, _: &Deploy, _window, _cx| {});
|
workspace.register_action(|_, _: &Deploy, _window, _cx| {});
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -4072,7 +4073,7 @@ mod tests {
|
||||||
.fs
|
.fs
|
||||||
.save(
|
.save(
|
||||||
"/keymap.json".as_ref(),
|
"/keymap.json".as_ref(),
|
||||||
&r#"[{"bindings": {"backspace": "test2::A"}}]"#.into(),
|
&r#"[{"bindings": {"backspace": "test_only::ActionA"}}]"#.into(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
@ -4106,7 +4107,7 @@ mod tests {
|
||||||
assert_key_bindings_for(
|
assert_key_bindings_for(
|
||||||
workspace.into(),
|
workspace.into(),
|
||||||
cx,
|
cx,
|
||||||
vec![("backspace", &A), ("k", &ActivatePreviousPane)],
|
vec![("backspace", &ActionA), ("k", &ActivatePreviousPane)],
|
||||||
line!(),
|
line!(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -4219,6 +4220,122 @@ mod tests {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Checks that action namespaces are the expected set. The purpose of this is to prevent typos
|
||||||
|
/// and let you know when introducing a new namespace.
|
||||||
|
#[gpui::test]
|
||||||
|
async fn test_action_namespaces(cx: &mut gpui::TestAppContext) {
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
init_keymap_test(cx);
|
||||||
|
cx.update(|cx| {
|
||||||
|
let all_actions = cx.all_action_names();
|
||||||
|
|
||||||
|
let mut actions_without_namespace = Vec::new();
|
||||||
|
let all_namespaces = all_actions
|
||||||
|
.iter()
|
||||||
|
.filter_map(|action_name| {
|
||||||
|
let namespace = action_name
|
||||||
|
.split("::")
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.into_iter()
|
||||||
|
.rev()
|
||||||
|
.skip(1)
|
||||||
|
.rev()
|
||||||
|
.join("::");
|
||||||
|
if namespace.is_empty() {
|
||||||
|
actions_without_namespace.push(*action_name);
|
||||||
|
}
|
||||||
|
if &namespace == "test_only" || &namespace == "stories" {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(namespace)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.sorted()
|
||||||
|
.dedup()
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
assert_eq!(actions_without_namespace, Vec::<&str>::new());
|
||||||
|
|
||||||
|
let expected_namespaces = vec![
|
||||||
|
"activity_indicator",
|
||||||
|
"agent",
|
||||||
|
#[cfg(not(target_os = "macos"))]
|
||||||
|
"app_menu",
|
||||||
|
"assistant",
|
||||||
|
"assistant2",
|
||||||
|
"auto_update",
|
||||||
|
"branches",
|
||||||
|
"buffer_search",
|
||||||
|
"channel_modal",
|
||||||
|
"chat_panel",
|
||||||
|
"cli",
|
||||||
|
"client",
|
||||||
|
"collab",
|
||||||
|
"collab_panel",
|
||||||
|
"command_palette",
|
||||||
|
"console",
|
||||||
|
"context_server",
|
||||||
|
"copilot",
|
||||||
|
"debug_panel",
|
||||||
|
"debugger",
|
||||||
|
"dev",
|
||||||
|
"diagnostics",
|
||||||
|
"edit_prediction",
|
||||||
|
"editor",
|
||||||
|
"feedback",
|
||||||
|
"file_finder",
|
||||||
|
"git",
|
||||||
|
"git_onboarding",
|
||||||
|
"git_panel",
|
||||||
|
"go_to_line",
|
||||||
|
"icon_theme_selector",
|
||||||
|
"jj",
|
||||||
|
"journal",
|
||||||
|
"language_selector",
|
||||||
|
"markdown",
|
||||||
|
"menu",
|
||||||
|
"notebook",
|
||||||
|
"notification_panel",
|
||||||
|
"outline",
|
||||||
|
"outline_panel",
|
||||||
|
"pane",
|
||||||
|
"panel",
|
||||||
|
"picker",
|
||||||
|
"project_panel",
|
||||||
|
"project_search",
|
||||||
|
"project_symbols",
|
||||||
|
"projects",
|
||||||
|
"repl",
|
||||||
|
"rules_library",
|
||||||
|
"search",
|
||||||
|
"snippets",
|
||||||
|
"supermaven",
|
||||||
|
"tab_switcher",
|
||||||
|
"task",
|
||||||
|
"terminal",
|
||||||
|
"terminal_panel",
|
||||||
|
"theme_selector",
|
||||||
|
"toast",
|
||||||
|
"toolchain",
|
||||||
|
"variable_list",
|
||||||
|
"vim",
|
||||||
|
"welcome",
|
||||||
|
"workspace",
|
||||||
|
"zed",
|
||||||
|
"zed_predict_onboarding",
|
||||||
|
"zeta",
|
||||||
|
];
|
||||||
|
assert_eq!(
|
||||||
|
all_namespaces,
|
||||||
|
expected_namespaces
|
||||||
|
.into_iter()
|
||||||
|
.map(|namespace| namespace.to_string())
|
||||||
|
.sorted()
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_bundled_settings_and_themes(cx: &mut App) {
|
fn test_bundled_settings_and_themes(cx: &mut App) {
|
||||||
cx.text_system()
|
cx.text_system()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use gpui::{actions, impl_actions};
|
use gpui::{Action, actions};
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
@ -11,20 +11,20 @@ use serde::{Deserialize, Serialize};
|
||||||
// https://github.com/mmastrac/rust-ctor/issues/280
|
// https://github.com/mmastrac/rust-ctor/issues/280
|
||||||
pub fn init() {}
|
pub fn init() {}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Deserialize, JsonSchema)]
|
#[derive(Clone, PartialEq, Deserialize, JsonSchema, Action)]
|
||||||
|
#[action(namespace = zed)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct OpenBrowser {
|
pub struct OpenBrowser {
|
||||||
pub url: String,
|
pub url: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Deserialize, JsonSchema)]
|
#[derive(Clone, PartialEq, Deserialize, JsonSchema, Action)]
|
||||||
|
#[action(namespace = zed)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct OpenZedUrl {
|
pub struct OpenZedUrl {
|
||||||
pub url: String,
|
pub url: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_actions!(zed, [OpenBrowser, OpenZedUrl]);
|
|
||||||
|
|
||||||
actions!(
|
actions!(
|
||||||
zed,
|
zed,
|
||||||
[
|
[
|
||||||
|
@ -56,62 +56,56 @@ pub enum ExtensionCategoryFilter {
|
||||||
DebugAdapters,
|
DebugAdapters,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
|
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema, Action)]
|
||||||
|
#[action(namespace = zed)]
|
||||||
pub struct Extensions {
|
pub struct Extensions {
|
||||||
/// Filters the extensions page down to extensions that are in the specified category.
|
/// Filters the extensions page down to extensions that are in the specified category.
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub category_filter: Option<ExtensionCategoryFilter>,
|
pub category_filter: Option<ExtensionCategoryFilter>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
|
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema, Action)]
|
||||||
|
#[action(namespace = zed)]
|
||||||
pub struct DecreaseBufferFontSize {
|
pub struct DecreaseBufferFontSize {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub persist: bool,
|
pub persist: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
|
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema, Action)]
|
||||||
|
#[action(namespace = zed)]
|
||||||
pub struct IncreaseBufferFontSize {
|
pub struct IncreaseBufferFontSize {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub persist: bool,
|
pub persist: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
|
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema, Action)]
|
||||||
|
#[action(namespace = zed)]
|
||||||
pub struct ResetBufferFontSize {
|
pub struct ResetBufferFontSize {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub persist: bool,
|
pub persist: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
|
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema, Action)]
|
||||||
|
#[action(namespace = zed)]
|
||||||
pub struct DecreaseUiFontSize {
|
pub struct DecreaseUiFontSize {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub persist: bool,
|
pub persist: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
|
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema, Action)]
|
||||||
|
#[action(namespace = zed)]
|
||||||
pub struct IncreaseUiFontSize {
|
pub struct IncreaseUiFontSize {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub persist: bool,
|
pub persist: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
|
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema, Action)]
|
||||||
|
#[action(namespace = zed)]
|
||||||
pub struct ResetUiFontSize {
|
pub struct ResetUiFontSize {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub persist: bool,
|
pub persist: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_actions!(
|
|
||||||
zed,
|
|
||||||
[
|
|
||||||
Extensions,
|
|
||||||
DecreaseBufferFontSize,
|
|
||||||
IncreaseBufferFontSize,
|
|
||||||
ResetBufferFontSize,
|
|
||||||
DecreaseUiFontSize,
|
|
||||||
IncreaseUiFontSize,
|
|
||||||
ResetUiFontSize,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
pub mod dev {
|
pub mod dev {
|
||||||
use gpui::actions;
|
use gpui::actions;
|
||||||
|
|
||||||
|
@ -119,34 +113,32 @@ pub mod dev {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod workspace {
|
pub mod workspace {
|
||||||
use gpui::action_with_deprecated_aliases;
|
use gpui::actions;
|
||||||
|
|
||||||
action_with_deprecated_aliases!(
|
actions!(
|
||||||
workspace,
|
workspace,
|
||||||
CopyPath,
|
|
||||||
[
|
[
|
||||||
"editor::CopyPath",
|
#[action(deprecated_aliases = ["editor::CopyPath", "outline_panel::CopyPath", "project_panel::CopyPath"])]
|
||||||
"outline_panel::CopyPath",
|
CopyPath,
|
||||||
"project_panel::CopyPath"
|
#[action(deprecated_aliases = ["editor::CopyRelativePath", "outline_panel::CopyRelativePath", "project_panel::CopyRelativePath"])]
|
||||||
]
|
CopyRelativePath
|
||||||
);
|
|
||||||
|
|
||||||
action_with_deprecated_aliases!(
|
|
||||||
workspace,
|
|
||||||
CopyRelativePath,
|
|
||||||
[
|
|
||||||
"editor::CopyRelativePath",
|
|
||||||
"outline_panel::CopyRelativePath",
|
|
||||||
"project_panel::CopyRelativePath"
|
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod git {
|
pub mod git {
|
||||||
use gpui::{action_with_deprecated_aliases, actions};
|
use gpui::actions;
|
||||||
|
|
||||||
actions!(git, [CheckoutBranch, Switch, SelectRepo]);
|
actions!(
|
||||||
action_with_deprecated_aliases!(git, Branch, ["branches::OpenRecent"]);
|
git,
|
||||||
|
[
|
||||||
|
CheckoutBranch,
|
||||||
|
Switch,
|
||||||
|
SelectRepo,
|
||||||
|
#[action(deprecated_aliases = ["branches::OpenRecent"])]
|
||||||
|
Branch
|
||||||
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod jj {
|
pub mod jj {
|
||||||
|
@ -174,33 +166,31 @@ pub mod feedback {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod theme_selector {
|
pub mod theme_selector {
|
||||||
use gpui::impl_actions;
|
use gpui::Action;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
|
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema, Action)]
|
||||||
|
#[action(namespace = theme_selector)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct Toggle {
|
pub struct Toggle {
|
||||||
/// A list of theme names to filter the theme selector down to.
|
/// A list of theme names to filter the theme selector down to.
|
||||||
pub themes_filter: Option<Vec<String>>,
|
pub themes_filter: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_actions!(theme_selector, [Toggle]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod icon_theme_selector {
|
pub mod icon_theme_selector {
|
||||||
use gpui::impl_actions;
|
use gpui::Action;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
|
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema, Action)]
|
||||||
|
#[action(namespace = icon_theme_selector)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct Toggle {
|
pub struct Toggle {
|
||||||
/// A list of icon theme names to filter the theme selector down to.
|
/// A list of icon theme names to filter the theme selector down to.
|
||||||
pub themes_filter: Option<Vec<String>>,
|
pub themes_filter: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_actions!(icon_theme_selector, [Toggle]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod agent {
|
pub mod agent {
|
||||||
|
@ -213,40 +203,35 @@ pub mod agent {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod assistant {
|
pub mod assistant {
|
||||||
use gpui::{
|
use gpui::{Action, actions};
|
||||||
action_with_deprecated_aliases, actions, impl_action_with_deprecated_aliases, impl_actions,
|
|
||||||
};
|
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
action_with_deprecated_aliases!(agent, ToggleFocus, ["assistant::ToggleFocus"]);
|
actions!(
|
||||||
|
agent,
|
||||||
|
[
|
||||||
|
#[action(deprecated_aliases = ["assistant::ToggleFocus"])]
|
||||||
|
ToggleFocus
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
actions!(assistant, [ShowConfiguration]);
|
actions!(assistant, [ShowConfiguration]);
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
|
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema, Action)]
|
||||||
|
#[action(namespace = agent, deprecated_aliases = ["assistant::OpenRulesLibrary", "assistant::DeployPromptLibrary"])]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct OpenRulesLibrary {
|
pub struct OpenRulesLibrary {
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub prompt_to_select: Option<Uuid>,
|
pub prompt_to_select: Option<Uuid>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_action_with_deprecated_aliases!(
|
#[derive(Clone, Default, Deserialize, PartialEq, JsonSchema, Action)]
|
||||||
agent,
|
#[action(namespace = assistant)]
|
||||||
OpenRulesLibrary,
|
|
||||||
[
|
|
||||||
"assistant::OpenRulesLibrary",
|
|
||||||
"assistant::DeployPromptLibrary"
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
#[derive(Clone, Default, Deserialize, PartialEq, JsonSchema)]
|
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct InlineAssist {
|
pub struct InlineAssist {
|
||||||
pub prompt: Option<String>,
|
pub prompt: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_actions!(assistant, [InlineAssist]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod debugger {
|
pub mod debugger {
|
||||||
|
@ -255,14 +240,16 @@ pub mod debugger {
|
||||||
actions!(debugger, [OpenOnboardingModal, ResetOnboarding]);
|
actions!(debugger, [OpenOnboardingModal, ResetOnboarding]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = projects)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct OpenRecent {
|
pub struct OpenRecent {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub create_new_window: bool,
|
pub create_new_window: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = projects)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct OpenRemote {
|
pub struct OpenRemote {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
@ -271,8 +258,6 @@ pub struct OpenRemote {
|
||||||
pub create_new_window: bool,
|
pub create_new_window: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_actions!(projects, [OpenRecent, OpenRemote]);
|
|
||||||
|
|
||||||
/// Where to spawn the task in the UI.
|
/// Where to spawn the task in the UI.
|
||||||
#[derive(Default, Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
#[derive(Default, Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
|
@ -285,7 +270,8 @@ pub enum RevealTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Spawn a task with name or open tasks modal.
|
/// Spawn a task with name or open tasks modal.
|
||||||
#[derive(Debug, PartialEq, Clone, Deserialize, JsonSchema)]
|
#[derive(Debug, PartialEq, Clone, Deserialize, JsonSchema, Action)]
|
||||||
|
#[action(namespace = task)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub enum Spawn {
|
pub enum Spawn {
|
||||||
/// Spawns a task by the name given.
|
/// Spawns a task by the name given.
|
||||||
|
@ -317,7 +303,8 @@ impl Spawn {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rerun the last task.
|
/// Rerun the last task.
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
|
||||||
|
#[action(namespace = task)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct Rerun {
|
pub struct Rerun {
|
||||||
/// Controls whether the task context is reevaluated prior to execution of a task.
|
/// Controls whether the task context is reevaluated prior to execution of a task.
|
||||||
|
@ -340,14 +327,18 @@ pub struct Rerun {
|
||||||
pub task_id: Option<String>,
|
pub task_id: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_actions!(task, [Spawn, Rerun]);
|
|
||||||
|
|
||||||
pub mod outline {
|
pub mod outline {
|
||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
use gpui::{AnyView, App, Window, action_as};
|
use gpui::{AnyView, App, Window, actions};
|
||||||
|
|
||||||
action_as!(outline, ToggleOutline as Toggle);
|
actions!(
|
||||||
|
outline,
|
||||||
|
[
|
||||||
|
#[action(name = "Toggle")]
|
||||||
|
ToggleOutline
|
||||||
|
]
|
||||||
|
);
|
||||||
/// A pointer to outline::toggle function, exposed here to sewer the breadcrumbs <-> outline dependency.
|
/// A pointer to outline::toggle function, exposed here to sewer the breadcrumbs <-> outline dependency.
|
||||||
pub static TOGGLE_OUTLINE: OnceLock<fn(AnyView, &mut Window, &mut App)> = OnceLock::new();
|
pub static TOGGLE_OUTLINE: OnceLock<fn(AnyView, &mut Window, &mut App)> = OnceLock::new();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue