Improve keymap json schema (#23044)
Also: * Adds `impl_internal_actions!` for deriving the `Action` trait without registering. * Removes some deserializers that immediately fail in favor of `#[serde(skip)]` on fields where they were used. This also omits them from the schema. Release Notes: - Keymap settings file now has more JSON schema information to inform `json-language-server` completions and info, particularly for actions that take input.
This commit is contained in:
parent
4c50201036
commit
6aba3950d2
37 changed files with 506 additions and 283 deletions
6
Cargo.lock
generated
6
Cargo.lock
generated
|
@ -6817,6 +6817,7 @@ dependencies = [
|
|||
"regex",
|
||||
"rope",
|
||||
"rust-embed",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"settings",
|
||||
|
@ -9332,6 +9333,7 @@ dependencies = [
|
|||
"env_logger 0.11.6",
|
||||
"gpui",
|
||||
"menu",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"ui",
|
||||
|
@ -11278,6 +11280,7 @@ dependencies = [
|
|||
"language",
|
||||
"menu",
|
||||
"project",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"settings",
|
||||
|
@ -12659,6 +12662,7 @@ dependencies = [
|
|||
"menu",
|
||||
"picker",
|
||||
"project",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"settings",
|
||||
|
@ -12852,6 +12856,7 @@ dependencies = [
|
|||
"language",
|
||||
"project",
|
||||
"rand 0.8.5",
|
||||
"schemars",
|
||||
"search",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -13186,6 +13191,7 @@ dependencies = [
|
|||
"project",
|
||||
"remote",
|
||||
"rpc",
|
||||
"schemars",
|
||||
"serde",
|
||||
"settings",
|
||||
"smallvec",
|
||||
|
|
|
@ -26,7 +26,7 @@ pub use context::*;
|
|||
pub use context_store::*;
|
||||
use feature_flags::FeatureFlagAppExt;
|
||||
use fs::Fs;
|
||||
use gpui::impl_actions;
|
||||
use gpui::impl_internal_actions;
|
||||
use gpui::{actions, AppContext, Global, SharedString, UpdateGlobal};
|
||||
pub(crate) use inline_assistant::*;
|
||||
use language_model::{
|
||||
|
@ -74,13 +74,13 @@ actions!(
|
|||
]
|
||||
);
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize)]
|
||||
#[derive(PartialEq, Clone)]
|
||||
pub enum InsertDraggedFiles {
|
||||
ProjectPaths(Vec<PathBuf>),
|
||||
ExternalFiles(Vec<PathBuf>),
|
||||
}
|
||||
|
||||
impl_actions!(assistant, [InsertDraggedFiles]);
|
||||
impl_internal_actions!(assistant, [InsertDraggedFiles]);
|
||||
|
||||
const DEFAULT_CONTEXT_LINES: usize = 50;
|
||||
|
||||
|
|
|
@ -1,82 +1,84 @@
|
|||
//! This module contains all actions supported by [`Editor`].
|
||||
use super::*;
|
||||
use gpui::{action_aliases, action_as};
|
||||
use schemars::JsonSchema;
|
||||
use util::serde::default_true;
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct SelectNext {
|
||||
#[serde(default)]
|
||||
pub replace_newest: bool,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct SelectPrevious {
|
||||
#[serde(default)]
|
||||
pub replace_newest: bool,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct MoveToBeginningOfLine {
|
||||
#[serde(default = "default_true")]
|
||||
pub stop_at_soft_wraps: bool,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct SelectToBeginningOfLine {
|
||||
#[serde(default)]
|
||||
pub(super) stop_at_soft_wraps: bool,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct MovePageUp {
|
||||
#[serde(default)]
|
||||
pub(super) center_cursor: bool,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct MovePageDown {
|
||||
#[serde(default)]
|
||||
pub(super) center_cursor: bool,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct MoveToEndOfLine {
|
||||
#[serde(default = "default_true")]
|
||||
pub stop_at_soft_wraps: bool,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct SelectToEndOfLine {
|
||||
#[serde(default)]
|
||||
pub(super) stop_at_soft_wraps: bool,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct ToggleCodeActions {
|
||||
// Display row from which the action was deployed.
|
||||
#[serde(default)]
|
||||
#[serde(skip)]
|
||||
pub deployed_from_indicator: Option<DisplayRow>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct ConfirmCompletion {
|
||||
#[serde(default)]
|
||||
pub item_ix: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct ComposeCompletion {
|
||||
#[serde(default)]
|
||||
pub item_ix: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct ConfirmCodeAction {
|
||||
#[serde(default)]
|
||||
pub item_ix: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct ToggleComments {
|
||||
#[serde(default)]
|
||||
pub advance_downwards: bool,
|
||||
|
@ -84,84 +86,87 @@ pub struct ToggleComments {
|
|||
pub ignore_indent: bool,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct FoldAt {
|
||||
#[serde(skip)]
|
||||
pub buffer_row: MultiBufferRow,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct UnfoldAt {
|
||||
#[serde(skip)]
|
||||
pub buffer_row: MultiBufferRow,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct MoveUpByLines {
|
||||
#[serde(default)]
|
||||
pub(super) lines: u32,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct MoveDownByLines {
|
||||
#[serde(default)]
|
||||
pub(super) lines: u32,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct SelectUpByLines {
|
||||
#[serde(default)]
|
||||
pub(super) lines: u32,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct SelectDownByLines {
|
||||
#[serde(default)]
|
||||
pub(super) lines: u32,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct ExpandExcerpts {
|
||||
#[serde(default)]
|
||||
pub(super) lines: u32,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct ExpandExcerptsUp {
|
||||
#[serde(default)]
|
||||
pub(super) lines: u32,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct ExpandExcerptsDown {
|
||||
#[serde(default)]
|
||||
pub(super) lines: u32,
|
||||
}
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct ShowCompletions {
|
||||
#[serde(default)]
|
||||
pub(super) trigger: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct HandleInput(pub String);
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct DeleteToNextWordEnd {
|
||||
#[serde(default)]
|
||||
pub ignore_newlines: bool,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct DeleteToPreviousWordStart {
|
||||
#[serde(default)]
|
||||
pub ignore_newlines: bool,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct FoldAtLevel {
|
||||
pub level: u32,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct SpawnNearestTask {
|
||||
#[serde(default)]
|
||||
pub reveal: task::RevealStrategy,
|
||||
|
|
|
@ -63,6 +63,16 @@ pub trait Action: 'static + Send {
|
|||
where
|
||||
Self: Sized;
|
||||
|
||||
/// Optional JSON schema for the action's input data.
|
||||
fn action_json_schema(
|
||||
_: &mut schemars::gen::SchemaGenerator,
|
||||
) -> Option<schemars::schema::Schema>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
None
|
||||
}
|
||||
|
||||
/// A list of alternate, deprecated names for this action.
|
||||
fn deprecated_aliases() -> &'static [&'static str]
|
||||
where
|
||||
|
@ -90,16 +100,16 @@ impl dyn Action {
|
|||
type ActionBuilder = fn(json: serde_json::Value) -> anyhow::Result<Box<dyn Action>>;
|
||||
|
||||
pub(crate) struct ActionRegistry {
|
||||
builders_by_name: HashMap<SharedString, ActionBuilder>,
|
||||
by_name: HashMap<SharedString, ActionData>,
|
||||
names_by_type_id: HashMap<TypeId, SharedString>,
|
||||
all_names: Vec<SharedString>, // So we can return a static slice.
|
||||
deprecations: Vec<(SharedString, SharedString)>,
|
||||
deprecations: HashMap<SharedString, SharedString>,
|
||||
}
|
||||
|
||||
impl Default for ActionRegistry {
|
||||
fn default() -> Self {
|
||||
let mut this = ActionRegistry {
|
||||
builders_by_name: Default::default(),
|
||||
by_name: Default::default(),
|
||||
names_by_type_id: Default::default(),
|
||||
all_names: Default::default(),
|
||||
deprecations: Default::default(),
|
||||
|
@ -111,19 +121,25 @@ impl Default for ActionRegistry {
|
|||
}
|
||||
}
|
||||
|
||||
/// This type must be public so that our macros can build it in other crates.
|
||||
/// But this is an implementation detail and should not be used directly.
|
||||
#[doc(hidden)]
|
||||
pub type MacroActionBuilder = fn() -> ActionData;
|
||||
struct ActionData {
|
||||
pub build: ActionBuilder,
|
||||
pub json_schema: fn(&mut schemars::gen::SchemaGenerator) -> Option<schemars::schema::Schema>,
|
||||
}
|
||||
|
||||
/// This type must be public so that our macros can build it in other crates.
|
||||
/// But this is an implementation detail and should not be used directly.
|
||||
#[doc(hidden)]
|
||||
pub struct ActionData {
|
||||
pub type MacroActionBuilder = fn() -> MacroActionData;
|
||||
|
||||
/// This type must be public so that our macros can build it in other crates.
|
||||
/// But this is an implementation detail and should not be used directly.
|
||||
#[doc(hidden)]
|
||||
pub struct MacroActionData {
|
||||
pub name: &'static str,
|
||||
pub aliases: &'static [&'static str],
|
||||
pub type_id: TypeId,
|
||||
pub build: ActionBuilder,
|
||||
pub json_schema: fn(&mut schemars::gen::SchemaGenerator) -> Option<schemars::schema::Schema>,
|
||||
}
|
||||
|
||||
/// This constant must be public to be accessible from other crates.
|
||||
|
@ -143,20 +159,35 @@ impl ActionRegistry {
|
|||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn load_action<A: Action>(&mut self) {
|
||||
self.insert_action(ActionData {
|
||||
self.insert_action(MacroActionData {
|
||||
name: A::debug_name(),
|
||||
aliases: A::deprecated_aliases(),
|
||||
type_id: TypeId::of::<A>(),
|
||||
build: A::build,
|
||||
json_schema: A::action_json_schema,
|
||||
});
|
||||
}
|
||||
|
||||
fn insert_action(&mut self, action: ActionData) {
|
||||
fn insert_action(&mut self, action: MacroActionData) {
|
||||
let name: SharedString = action.name.into();
|
||||
self.builders_by_name.insert(name.clone(), action.build);
|
||||
self.by_name.insert(
|
||||
name.clone(),
|
||||
ActionData {
|
||||
build: action.build,
|
||||
json_schema: action.json_schema,
|
||||
},
|
||||
);
|
||||
for &alias in action.aliases {
|
||||
self.builders_by_name.insert(alias.into(), action.build);
|
||||
self.deprecations.push((alias.into(), name.clone()));
|
||||
let alias: SharedString = alias.into();
|
||||
self.by_name.insert(
|
||||
alias.clone(),
|
||||
ActionData {
|
||||
build: action.build,
|
||||
json_schema: action.json_schema,
|
||||
},
|
||||
);
|
||||
self.deprecations.insert(alias.clone(), name.clone());
|
||||
self.all_names.push(alias);
|
||||
}
|
||||
self.names_by_type_id.insert(action.type_id, name.clone());
|
||||
self.all_names.push(name);
|
||||
|
@ -180,9 +211,10 @@ impl ActionRegistry {
|
|||
params: Option<serde_json::Value>,
|
||||
) -> Result<Box<dyn Action>> {
|
||||
let build_action = self
|
||||
.builders_by_name
|
||||
.by_name
|
||||
.get(name)
|
||||
.ok_or_else(|| anyhow!("no action type registered for {}", name))?;
|
||||
.ok_or_else(|| anyhow!("No action type registered for {}", name))?
|
||||
.build;
|
||||
(build_action)(params.unwrap_or_else(|| json!({})))
|
||||
.with_context(|| format!("Attempting to build action {}", name))
|
||||
}
|
||||
|
@ -191,12 +223,30 @@ impl ActionRegistry {
|
|||
self.all_names.as_slice()
|
||||
}
|
||||
|
||||
pub fn action_deprecations(&self) -> &[(SharedString, SharedString)] {
|
||||
self.deprecations.as_slice()
|
||||
pub fn action_schemas(
|
||||
&self,
|
||||
generator: &mut schemars::gen::SchemaGenerator,
|
||||
) -> Vec<(SharedString, Option<schemars::schema::Schema>)> {
|
||||
// Use the order from all_names so that the resulting schema has sensible order.
|
||||
self.all_names
|
||||
.iter()
|
||||
.map(|name| {
|
||||
let action_data = self
|
||||
.by_name
|
||||
.get(name)
|
||||
.expect("All actions in all_names should be registered");
|
||||
(name.clone(), (action_data.json_schema)(generator))
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
pub fn action_deprecations(&self) -> &HashMap<SharedString, SharedString> {
|
||||
&self.deprecations
|
||||
}
|
||||
}
|
||||
|
||||
/// Defines unit structs that can be used as 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 {
|
||||
|
@ -211,6 +261,11 @@ macro_rules! actions {
|
|||
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::gen::SchemaGenerator,
|
||||
) -> Option<gpui::private::schemars::schema::Schema> {
|
||||
None
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -219,11 +274,10 @@ macro_rules! actions {
|
|||
};
|
||||
}
|
||||
|
||||
/// Defines a unit struct that can be used as an actions, with a name
|
||||
/// that differs from it's type 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!`
|
||||
/// 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) => {
|
||||
|
@ -241,6 +295,11 @@ macro_rules! action_as {
|
|||
_: 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::gen::SchemaGenerator,
|
||||
) -> Option<gpui::private::schemars::schema::Schema> {
|
||||
None
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -248,7 +307,7 @@ macro_rules! action_as {
|
|||
};
|
||||
}
|
||||
|
||||
/// Defines a unit struct that can be used as an action, with some deprecated aliases.
|
||||
/// Defines and registers a unit struct that can be used as an action, with some deprecated aliases.
|
||||
#[macro_export]
|
||||
macro_rules! action_aliases {
|
||||
($namespace:path, $name:ident, [$($alias:ident),* $(,)?]) => {
|
||||
|
@ -261,6 +320,7 @@ macro_rules! action_aliases {
|
|||
::std::default::Default,
|
||||
::std::fmt::Debug,
|
||||
gpui::private::serde_derive::Deserialize,
|
||||
gpui::private::schemars::JsonSchema,
|
||||
)]
|
||||
#[serde(crate = "gpui::private::serde")]
|
||||
pub struct $name;
|
||||
|
@ -274,6 +334,12 @@ macro_rules! action_aliases {
|
|||
) -> gpui::Result<::std::boxed::Box<dyn gpui::Action>> {
|
||||
Ok(Box::new(Self))
|
||||
},
|
||||
fn action_json_schema(
|
||||
generator: &mut gpui::private::schemars::gen::SchemaGenerator,
|
||||
) -> Option<gpui::private::schemars::schema::Schema> {
|
||||
None
|
||||
|
||||
},
|
||||
fn deprecated_aliases() -> &'static [&'static str] {
|
||||
&[
|
||||
$(concat!(stringify!($namespace), "::", stringify!($alias))),*
|
||||
|
@ -285,7 +351,11 @@ macro_rules! action_aliases {
|
|||
};
|
||||
}
|
||||
|
||||
/// Implements the Action trait for any struct that implements Clone, Default, PartialEq, and serde_deserialize::Deserialize
|
||||
/// Registers the action and implements the Action trait for any struct that implements Clone,
|
||||
/// Default, PartialEq, serde_deserialize::Deserialize, and schemars::JsonSchema.
|
||||
///
|
||||
/// 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),* $(,)? ]) => {
|
||||
|
@ -293,6 +363,13 @@ macro_rules! impl_actions {
|
|||
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::gen::SchemaGenerator,
|
||||
) -> Option<gpui::private::schemars::schema::Schema> {
|
||||
Some(<Self as gpui::private::schemars::JsonSchema>::json_schema(
|
||||
generator,
|
||||
))
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -301,8 +378,41 @@ macro_rules! impl_actions {
|
|||
};
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// 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::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 ) => {
|
||||
|
@ -316,6 +426,13 @@ macro_rules! impl_action_as {
|
|||
Ok(std::boxed::Box::new(
|
||||
gpui::private::serde_json::from_value::<Self>(value)?,
|
||||
))
|
||||
},
|
||||
fn action_json_schema(
|
||||
generator: &mut gpui::private::schemars::gen::SchemaGenerator,
|
||||
) -> Option<gpui::private::schemars::schema::Schema> {
|
||||
Some(<Self as gpui::private::schemars::JsonSchema>::json_schema(
|
||||
generator,
|
||||
))
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ use parking_lot::RwLock;
|
|||
use slotmap::SlotMap;
|
||||
|
||||
pub use async_context::*;
|
||||
use collections::{FxHashMap, FxHashSet, VecDeque};
|
||||
use collections::{FxHashMap, FxHashSet, HashMap, VecDeque};
|
||||
pub use entity_map::*;
|
||||
use http_client::HttpClient;
|
||||
pub use model_context::*;
|
||||
|
@ -1218,16 +1218,22 @@ impl AppContext {
|
|||
self.actions.build_action(name, data)
|
||||
}
|
||||
|
||||
/// Get a list of all action names that have been registered.
|
||||
/// in the application. Note that registration only allows for
|
||||
/// actions to be built dynamically, and is unrelated to binding
|
||||
/// actions in the element tree.
|
||||
/// 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.
|
||||
pub fn all_action_names(&self) -> &[SharedString] {
|
||||
self.actions.all_action_names()
|
||||
}
|
||||
|
||||
/// Get all non-internal actions that have been registered, along with their schemas.
|
||||
pub fn action_schemas(
|
||||
&self,
|
||||
generator: &mut schemars::gen::SchemaGenerator,
|
||||
) -> Vec<(SharedString, Option<schemars::schema::Schema>)> {
|
||||
self.actions.action_schemas(generator)
|
||||
}
|
||||
|
||||
/// Get a list of all deprecated action aliases and their canonical names.
|
||||
pub fn action_deprecations(&self) -> &[(SharedString, SharedString)] {
|
||||
pub fn action_deprecations(&self) -> &HashMap<SharedString, SharedString> {
|
||||
self.actions.action_deprecations()
|
||||
}
|
||||
|
||||
|
|
|
@ -102,7 +102,9 @@ mod window;
|
|||
/// Do not touch, here be dragons for use by gpui_macros and such.
|
||||
#[doc(hidden)]
|
||||
pub mod private {
|
||||
pub use anyhow;
|
||||
pub use linkme;
|
||||
pub use schemars;
|
||||
pub use serde;
|
||||
pub use serde_derive;
|
||||
pub use serde_json;
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
use gpui::{actions, impl_actions};
|
||||
use gpui_macros::register_action;
|
||||
use schemars::JsonSchema;
|
||||
use serde_derive::Deserialize;
|
||||
|
||||
#[test]
|
||||
fn test_action_macros() {
|
||||
actions!(test, [TestAction]);
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize)]
|
||||
#[derive(PartialEq, Clone, Deserialize, JsonSchema)]
|
||||
struct AnotherTestAction;
|
||||
|
||||
impl_actions!(test, [AnotherTestAction]);
|
||||
|
|
|
@ -29,12 +29,13 @@ pub(crate) fn register_action(type_name: &Ident) -> proc_macro2::TokenStream {
|
|||
fn __autogenerated() {
|
||||
/// This is an auto generated function, do not use.
|
||||
#[doc(hidden)]
|
||||
fn #action_builder_fn_name() -> gpui::ActionData {
|
||||
gpui::ActionData {
|
||||
fn #action_builder_fn_name() -> gpui::MacroActionData {
|
||||
gpui::MacroActionData {
|
||||
name: <#type_name as gpui::Action>::debug_name(),
|
||||
aliases: <#type_name as gpui::Action>::deprecated_aliases(),
|
||||
type_id: ::std::any::TypeId::of::<#type_name>(),
|
||||
build: <#type_name as gpui::Action>::build,
|
||||
json_schema: <#type_name as gpui::Action>::action_json_schema,
|
||||
}
|
||||
}
|
||||
#[doc(hidden)]
|
||||
|
|
|
@ -662,8 +662,7 @@ pub struct LanguageConfigOverride {
|
|||
pub line_comments: Override<Vec<Arc<str>>>,
|
||||
#[serde(default)]
|
||||
pub block_comment: Override<(Arc<str>, Arc<str>)>,
|
||||
#[serde(skip_deserializing)]
|
||||
#[schemars(skip)]
|
||||
#[serde(skip)]
|
||||
pub disabled_bracket_ixs: Vec<u16>,
|
||||
#[serde(default)]
|
||||
pub word_characters: Override<HashSet<char>>,
|
||||
|
@ -776,7 +775,7 @@ pub struct BracketPairConfig {
|
|||
pub pairs: Vec<BracketPair>,
|
||||
/// A list of tree-sitter scopes for which a given bracket should not be active.
|
||||
/// N-th entry in `[Self::disabled_scopes_by_bracket_ix]` contains a list of disabled scopes for an n-th entry in `[Self::pairs]`
|
||||
#[schemars(skip)]
|
||||
#[serde(skip)]
|
||||
pub disabled_scopes_by_bracket_ix: Vec<Vec<String>>,
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ project.workspace = true
|
|||
regex.workspace = true
|
||||
rope.workspace = true
|
||||
rust-embed.workspace = true
|
||||
schemars.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
settings.workspace = true
|
||||
|
|
|
@ -10,6 +10,7 @@ use language::{LanguageRegistry, LanguageToolchainStore, LspAdapter, LspAdapterD
|
|||
use lsp::{LanguageServerBinary, LanguageServerName};
|
||||
use node_runtime::NodeRuntime;
|
||||
use project::{lsp_store::language_server_settings, ContextProviderWithTasks};
|
||||
use schemars::gen::SchemaSettings;
|
||||
use serde_json::{json, Value};
|
||||
use settings::{KeymapFile, SettingsJsonSchemaParams, SettingsStore};
|
||||
use smol::{
|
||||
|
@ -75,9 +76,6 @@ impl JsonLspAdapter {
|
|||
}
|
||||
|
||||
fn get_workspace_config(language_names: Vec<String>, cx: &mut AppContext) -> Value {
|
||||
let action_names = cx.all_action_names();
|
||||
let deprecations = cx.action_deprecations();
|
||||
|
||||
let font_names = &cx.text_system().all_font_names();
|
||||
let settings_schema = cx.global::<SettingsStore>().json_schema(
|
||||
&SettingsJsonSchemaParams {
|
||||
|
@ -117,7 +115,7 @@ impl JsonLspAdapter {
|
|||
},
|
||||
{
|
||||
"fileMatch": [schema_file_match(paths::keymap_file())],
|
||||
"schema": KeymapFile::generate_json_schema(action_names, deprecations),
|
||||
"schema": Self::generate_keymap_schema(cx),
|
||||
},
|
||||
{
|
||||
"fileMatch": [
|
||||
|
@ -131,6 +129,16 @@ impl JsonLspAdapter {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn generate_keymap_schema(cx: &mut AppContext) -> Value {
|
||||
let mut generator = SchemaSettings::draft07()
|
||||
.with(|settings| settings.option_add_null_type = false)
|
||||
.into_generator();
|
||||
|
||||
let action_schemas = cx.action_schemas(&mut generator);
|
||||
let deprecations = cx.action_deprecations();
|
||||
KeymapFile::generate_json_schema(generator, action_schemas, deprecations)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
|
|
|
@ -20,6 +20,7 @@ anyhow.workspace = true
|
|||
editor.workspace = true
|
||||
gpui.workspace = true
|
||||
menu.workspace = true
|
||||
schemars.workspace = true
|
||||
serde.workspace = true
|
||||
ui.workspace = true
|
||||
workspace.workspace = true
|
||||
|
|
|
@ -7,6 +7,7 @@ use gpui::{
|
|||
ViewContext, WindowContext,
|
||||
};
|
||||
use head::Head;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
use std::{sync::Arc, time::Duration};
|
||||
use ui::{prelude::*, v_flex, Color, Divider, Label, ListItem, ListItemSpacing};
|
||||
|
@ -24,7 +25,7 @@ actions!(picker, [ConfirmCompletion]);
|
|||
|
||||
/// 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.
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(Clone, PartialEq, Deserialize, JsonSchema, Default)]
|
||||
pub struct ConfirmInput {
|
||||
pub secondary: bool,
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
mod project_panel_settings;
|
||||
mod utils;
|
||||
|
||||
use anyhow::{anyhow, Context as _, Result};
|
||||
use client::{ErrorCode, ErrorExt};
|
||||
use language::DiagnosticSeverity;
|
||||
use settings::{Settings, SettingsStore};
|
||||
|
||||
use collections::{hash_map, BTreeSet, HashMap};
|
||||
use command_palette_hooks::CommandPaletteFilter;
|
||||
use db::kvp::KEY_VALUE_STORE;
|
||||
use editor::{
|
||||
items::{
|
||||
|
@ -15,10 +15,6 @@ use editor::{
|
|||
Editor, EditorEvent, EditorSettings, ShowScrollbar,
|
||||
};
|
||||
use file_icons::FileIcons;
|
||||
|
||||
use anyhow::{anyhow, Context as _, Result};
|
||||
use collections::{hash_map, BTreeSet, HashMap};
|
||||
use command_palette_hooks::CommandPaletteFilter;
|
||||
use git::repository::GitFileStatus;
|
||||
use gpui::{
|
||||
actions, anchored, deferred, div, impl_actions, point, px, size, uniform_list, Action,
|
||||
|
@ -30,6 +26,7 @@ use gpui::{
|
|||
VisualContext as _, WeakView, WindowContext,
|
||||
};
|
||||
use indexmap::IndexMap;
|
||||
use language::DiagnosticSeverity;
|
||||
use menu::{Confirm, SelectFirst, SelectLast, SelectNext, SelectPrev};
|
||||
use project::{
|
||||
relativize_path, Entry, EntryKind, Fs, Project, ProjectEntryId, ProjectPath, Worktree,
|
||||
|
@ -38,7 +35,9 @@ use project::{
|
|||
use project_panel_settings::{
|
||||
ProjectPanelDockPosition, ProjectPanelSettings, ShowDiagnostics, ShowIndentGuides,
|
||||
};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use settings::{Settings, SettingsStore};
|
||||
use smallvec::SmallVec;
|
||||
use std::any::TypeId;
|
||||
use std::{
|
||||
|
@ -152,13 +151,13 @@ struct EntryDetails {
|
|||
canonical_path: Option<Box<Path>>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize)]
|
||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
|
||||
struct Delete {
|
||||
#[serde(default)]
|
||||
pub skip_prompt: bool,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize)]
|
||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
|
||||
struct Trash {
|
||||
#[serde(default)]
|
||||
pub skip_prompt: bool,
|
||||
|
|
|
@ -31,6 +31,7 @@ gpui.workspace = true
|
|||
language.workspace = true
|
||||
menu.workspace = true
|
||||
project.workspace = true
|
||||
schemars.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
settings.workspace = true
|
||||
|
|
|
@ -22,6 +22,7 @@ use project::{
|
|||
search::SearchQuery,
|
||||
search_history::{SearchHistory, SearchHistoryCursor},
|
||||
};
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
use settings::Settings;
|
||||
use std::sync::Arc;
|
||||
|
@ -43,7 +44,7 @@ use registrar::{ForDeployed, ForDismissed, SearchActionsRegistrar, WithResults};
|
|||
|
||||
const MAX_BUFFER_SEARCH_HISTORY_SIZE: usize = 50;
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize)]
|
||||
#[derive(PartialEq, Clone, Deserialize, JsonSchema)]
|
||||
pub struct Deploy {
|
||||
#[serde(default = "util::serde::default_true")]
|
||||
pub focus: bool,
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use crate::{settings_store::parse_json_with_comments, SettingsAssets};
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use collections::BTreeMap;
|
||||
use collections::{BTreeMap, HashMap};
|
||||
use gpui::{Action, AppContext, KeyBinding, SharedString};
|
||||
use schemars::{
|
||||
gen::{SchemaGenerator, SchemaSettings},
|
||||
schema::{InstanceType, Schema, SchemaObject, SingleOrVec, SubschemaValidation},
|
||||
JsonSchema, Map,
|
||||
gen::SchemaGenerator,
|
||||
schema::{ArrayValidation, InstanceType, Metadata, Schema, SchemaObject, SubschemaValidation},
|
||||
JsonSchema,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use serde_json::Value;
|
||||
|
@ -140,55 +140,117 @@ impl KeymapFile {
|
|||
}
|
||||
|
||||
pub fn generate_json_schema(
|
||||
action_names: &[SharedString],
|
||||
deprecations: &[(SharedString, SharedString)],
|
||||
generator: SchemaGenerator,
|
||||
action_schemas: Vec<(SharedString, Option<Schema>)>,
|
||||
deprecations: &HashMap<SharedString, SharedString>,
|
||||
) -> serde_json::Value {
|
||||
let mut root_schema = SchemaSettings::draft07()
|
||||
.with(|settings| settings.option_add_null_type = false)
|
||||
.into_generator()
|
||||
.into_root_schema_for::<KeymapFile>();
|
||||
|
||||
let mut alternatives = vec![
|
||||
Schema::Object(SchemaObject {
|
||||
instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::String))),
|
||||
enum_values: Some(
|
||||
action_names
|
||||
.iter()
|
||||
.map(|name| Value::String(name.to_string()))
|
||||
.collect(),
|
||||
),
|
||||
..Default::default()
|
||||
}),
|
||||
Schema::Object(SchemaObject {
|
||||
instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::Array))),
|
||||
..Default::default()
|
||||
}),
|
||||
Schema::Object(SchemaObject {
|
||||
instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::Null))),
|
||||
..Default::default()
|
||||
}),
|
||||
];
|
||||
for (old, new) in deprecations {
|
||||
alternatives.push(Schema::Object(SchemaObject {
|
||||
instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::String))),
|
||||
const_value: Some(Value::String(old.to_string())),
|
||||
extensions: Map::from_iter([(
|
||||
// deprecationMessage is not part of the JSON Schema spec,
|
||||
// but json-language-server recognizes it.
|
||||
"deprecationMessage".to_owned(),
|
||||
format!("Deprecated, use {new}").into(),
|
||||
)]),
|
||||
..Default::default()
|
||||
}));
|
||||
fn set<I, O>(input: I) -> Option<O>
|
||||
where
|
||||
I: Into<O>,
|
||||
{
|
||||
Some(input.into())
|
||||
}
|
||||
let action_schema = Schema::Object(SchemaObject {
|
||||
subschemas: Some(Box::new(SubschemaValidation {
|
||||
one_of: Some(alternatives),
|
||||
..Default::default()
|
||||
})),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
fn add_deprecation_notice(schema_object: &mut SchemaObject, new_name: &SharedString) {
|
||||
schema_object.extensions.insert(
|
||||
// deprecationMessage is not part of the JSON Schema spec,
|
||||
// but json-language-server recognizes it.
|
||||
"deprecationMessage".to_owned(),
|
||||
format!("Deprecated, use {new_name}").into(),
|
||||
);
|
||||
}
|
||||
|
||||
let empty_object: SchemaObject = SchemaObject {
|
||||
instance_type: set(InstanceType::Object),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut keymap_action_alternatives = Vec::new();
|
||||
for (name, action_schema) in action_schemas.iter() {
|
||||
let schema = if let Some(Schema::Object(schema)) = action_schema {
|
||||
Some(schema.clone())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// If the type has a description, also apply it to the value. Ideally it would be
|
||||
// removed and applied to the overall array, but `json-language-server` does not show
|
||||
// these descriptions.
|
||||
let description = schema.as_ref().and_then(|schema| {
|
||||
schema
|
||||
.metadata
|
||||
.as_ref()
|
||||
.and_then(|metadata| metadata.description.as_ref())
|
||||
});
|
||||
let mut matches_action_name = SchemaObject {
|
||||
const_value: Some(Value::String(name.to_string())),
|
||||
..Default::default()
|
||||
};
|
||||
if let Some(description) = description {
|
||||
matches_action_name.metadata = set(Metadata {
|
||||
description: Some(description.clone()),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
||||
// Add an alternative for plain action names.
|
||||
let deprecation = deprecations.get(name);
|
||||
let mut plain_action = SchemaObject {
|
||||
instance_type: set(InstanceType::String),
|
||||
const_value: Some(Value::String(name.to_string())),
|
||||
..Default::default()
|
||||
};
|
||||
if let Some(new_name) = deprecation {
|
||||
add_deprecation_notice(&mut plain_action, new_name);
|
||||
}
|
||||
keymap_action_alternatives.push(plain_action.into());
|
||||
|
||||
// When all fields are skipped or an empty struct is added with impl_actions! /
|
||||
// impl_actions_as! an empty struct is produced. The action should be invoked without
|
||||
// data in this case.
|
||||
if let Some(schema) = schema {
|
||||
if schema != empty_object {
|
||||
let mut action_with_data = SchemaObject {
|
||||
instance_type: set(InstanceType::Array),
|
||||
array: Some(
|
||||
ArrayValidation {
|
||||
items: set(vec![matches_action_name.into(), schema.into()]),
|
||||
min_items: Some(2),
|
||||
max_items: Some(2),
|
||||
..Default::default()
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
..Default::default()
|
||||
};
|
||||
if let Some(new_name) = deprecation {
|
||||
add_deprecation_notice(&mut action_with_data, new_name);
|
||||
}
|
||||
keymap_action_alternatives.push(action_with_data.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Placing null first causes json-language-server to default assuming actions should be
|
||||
// null, so place it last.
|
||||
keymap_action_alternatives.push(
|
||||
SchemaObject {
|
||||
instance_type: set(InstanceType::Null),
|
||||
..Default::default()
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
|
||||
let action_schema = SchemaObject {
|
||||
subschemas: set(SubschemaValidation {
|
||||
one_of: Some(keymap_action_alternatives),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
}
|
||||
.into();
|
||||
|
||||
let mut root_schema = generator.into_root_schema_for::<KeymapFile>();
|
||||
root_schema
|
||||
.definitions
|
||||
.insert("KeymapAction".to_owned(), action_schema);
|
||||
|
|
|
@ -19,6 +19,7 @@ gpui.workspace = true
|
|||
menu.workspace = true
|
||||
picker.workspace = true
|
||||
project.workspace = true
|
||||
schemars.workspace = true
|
||||
serde.workspace = true
|
||||
settings.workspace = true
|
||||
ui.workspace = true
|
||||
|
|
|
@ -10,6 +10,7 @@ use gpui::{
|
|||
};
|
||||
use picker::{Picker, PickerDelegate};
|
||||
use project::Project;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
use settings::Settings;
|
||||
use std::sync::Arc;
|
||||
|
@ -23,7 +24,7 @@ use workspace::{
|
|||
|
||||
const PANEL_WIDTH_REMS: f32 = 28.;
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, JsonSchema, Default)]
|
||||
pub struct Toggle {
|
||||
#[serde(default)]
|
||||
pub select_last: bool,
|
||||
|
|
|
@ -29,6 +29,7 @@ itertools.workspace = true
|
|||
language.workspace = true
|
||||
project.workspace = true
|
||||
task.workspace = true
|
||||
schemars.workspace = true
|
||||
search.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
|
|
|
@ -15,6 +15,7 @@ use gpui::{
|
|||
use language::Bias;
|
||||
use persistence::TERMINAL_DB;
|
||||
use project::{search::SearchQuery, terminals::TerminalKind, Fs, Metadata, Project};
|
||||
use schemars::JsonSchema;
|
||||
use terminal::{
|
||||
alacritty_terminal::{
|
||||
index::Point,
|
||||
|
@ -66,14 +67,14 @@ const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500);
|
|||
|
||||
const GIT_DIFF_PATH_PREFIXES: &[char] = &['a', 'b'];
|
||||
|
||||
///Event to transmit the scroll from the element to the view
|
||||
/// Event to transmit the scroll from the element to the view
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct ScrollTerminal(pub i32);
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Debug, Default, Deserialize, JsonSchema, PartialEq)]
|
||||
pub struct SendText(String);
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Debug, Default, Deserialize, JsonSchema, PartialEq)]
|
||||
pub struct SendKeystroke(String);
|
||||
|
||||
impl_actions!(terminal, [SendText, SendKeystroke]);
|
||||
|
|
|
@ -36,6 +36,7 @@ notifications.workspace = true
|
|||
project.workspace = true
|
||||
remote.workspace = true
|
||||
rpc.workspace = true
|
||||
schemars.workspace = true
|
||||
serde.workspace = true
|
||||
settings.workspace = true
|
||||
smallvec.workspace = true
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
use gpui::{impl_actions, OwnedMenu, OwnedMenuItem, View};
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
use smallvec::SmallVec;
|
||||
use ui::{prelude::*, ContextMenu, PopoverMenu, PopoverMenuHandle, Tooltip};
|
||||
|
||||
impl_actions!(
|
||||
app_menu,
|
||||
[OpenApplicationMenu, NavigateApplicationMenuInDirection,]
|
||||
[OpenApplicationMenu, NavigateApplicationMenuInDirection]
|
||||
);
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq, Default)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Default)]
|
||||
pub struct OpenApplicationMenu(String);
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq, Default)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Default)]
|
||||
pub struct NavigateApplicationMenuInDirection(String);
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
use std::{
|
||||
iter::Peekable,
|
||||
ops::{Deref, Range},
|
||||
str::Chars,
|
||||
sync::OnceLock,
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use command_palette_hooks::CommandInterceptResult;
|
||||
use editor::{
|
||||
|
@ -13,12 +5,22 @@ use editor::{
|
|||
display_map::ToDisplayPoint,
|
||||
Bias, Editor, ToPoint,
|
||||
};
|
||||
use gpui::{actions, impl_actions, Action, AppContext, Global, ViewContext, WindowContext};
|
||||
use gpui::{
|
||||
actions, impl_internal_actions, Action, AppContext, Global, ViewContext, WindowContext,
|
||||
};
|
||||
use language::Point;
|
||||
use multi_buffer::MultiBufferRow;
|
||||
use regex::Regex;
|
||||
use schemars::JsonSchema;
|
||||
use search::{BufferSearchBar, SearchOptions};
|
||||
use serde::Deserialize;
|
||||
use std::{
|
||||
iter::Peekable,
|
||||
ops::{Deref, Range},
|
||||
str::Chars,
|
||||
sync::OnceLock,
|
||||
time::Instant,
|
||||
};
|
||||
use util::ResultExt;
|
||||
use workspace::{notifications::NotifyResultExt, SaveIntent};
|
||||
|
||||
|
@ -33,24 +35,24 @@ use crate::{
|
|||
Vim,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct GoToLine {
|
||||
range: CommandRange,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct YankCommand {
|
||||
range: CommandRange,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct WithRange {
|
||||
restore_selection: bool,
|
||||
range: CommandRange,
|
||||
action: WrappedAction,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct WithCount {
|
||||
count: u32,
|
||||
action: WrappedAction,
|
||||
|
@ -60,20 +62,11 @@ pub struct WithCount {
|
|||
struct WrappedAction(Box<dyn Action>);
|
||||
|
||||
actions!(vim, [VisualCommand, CountCommand]);
|
||||
impl_actions!(
|
||||
impl_internal_actions!(
|
||||
vim,
|
||||
[GoToLine, YankCommand, WithRange, WithCount, OnMatchingLines]
|
||||
);
|
||||
|
||||
impl<'de> Deserialize<'de> for WrappedAction {
|
||||
fn deserialize<D>(_: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
Err(serde::de::Error::custom("Cannot deserialize WrappedAction"))
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for WrappedAction {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.0.partial_eq(&*other.0)
|
||||
|
@ -423,7 +416,7 @@ impl VimCommand {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
||||
#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq)]
|
||||
enum Position {
|
||||
Line { row: u32, offset: i32 },
|
||||
Mark { name: char, offset: i32 },
|
||||
|
@ -467,7 +460,7 @@ impl Position {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub(crate) struct CommandRange {
|
||||
start: Position,
|
||||
end: Option<Position>,
|
||||
|
@ -877,7 +870,7 @@ fn generate_positions(string: &str, query: &str) -> Vec<usize> {
|
|||
positions
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Deserialize, Clone)]
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub(crate) struct OnMatchingLines {
|
||||
range: CommandRange,
|
||||
search: String,
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::sync::Arc;
|
|||
use collections::HashMap;
|
||||
use editor::Editor;
|
||||
use gpui::{impl_actions, AppContext, Keystroke, KeystrokeEvent};
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
use settings::Settings;
|
||||
use std::sync::LazyLock;
|
||||
|
@ -12,7 +13,7 @@ use crate::{state::Operator, Vim, VimSettings};
|
|||
|
||||
mod default;
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize)]
|
||||
#[derive(Debug, Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
struct Literal(String, char);
|
||||
impl_actions!(vim, [Literal]);
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ use editor::{
|
|||
use gpui::{actions, impl_actions, px, ViewContext};
|
||||
use language::{CharKind, Point, Selection, SelectionGoal};
|
||||
use multi_buffer::MultiBufferRow;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
use std::ops::Range;
|
||||
use workspace::searchable::Direction;
|
||||
|
@ -139,105 +140,105 @@ pub enum Motion {
|
|||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct NextWordStart {
|
||||
#[serde(default)]
|
||||
ignore_punctuation: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct NextWordEnd {
|
||||
#[serde(default)]
|
||||
ignore_punctuation: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct PreviousWordStart {
|
||||
#[serde(default)]
|
||||
ignore_punctuation: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct PreviousWordEnd {
|
||||
#[serde(default)]
|
||||
ignore_punctuation: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub(crate) struct NextSubwordStart {
|
||||
#[serde(default)]
|
||||
pub(crate) ignore_punctuation: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub(crate) struct NextSubwordEnd {
|
||||
#[serde(default)]
|
||||
pub(crate) ignore_punctuation: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub(crate) struct PreviousSubwordStart {
|
||||
#[serde(default)]
|
||||
pub(crate) ignore_punctuation: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub(crate) struct PreviousSubwordEnd {
|
||||
#[serde(default)]
|
||||
pub(crate) ignore_punctuation: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub(crate) struct Up {
|
||||
#[serde(default)]
|
||||
pub(crate) display_lines: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub(crate) struct Down {
|
||||
#[serde(default)]
|
||||
pub(crate) display_lines: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct FirstNonWhitespace {
|
||||
#[serde(default)]
|
||||
display_lines: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct EndOfLine {
|
||||
#[serde(default)]
|
||||
display_lines: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct StartOfLine {
|
||||
#[serde(default)]
|
||||
pub(crate) display_lines: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct UnmatchedForward {
|
||||
#[serde(default)]
|
||||
char: char,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct UnmatchedBackward {
|
||||
#[serde(default)]
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
use std::ops::Range;
|
||||
|
||||
use editor::{scroll::Autoscroll, Editor, MultiBufferSnapshot, ToOffset, ToPoint};
|
||||
use gpui::{impl_actions, ViewContext};
|
||||
use language::{Bias, Point};
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
use std::ops::Range;
|
||||
|
||||
use crate::{state::Mode, Vim};
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct Increment {
|
||||
#[serde(default)]
|
||||
step: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct Decrement {
|
||||
#[serde(default)]
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
use std::cmp;
|
||||
|
||||
use editor::{display_map::ToDisplayPoint, movement, scroll::Autoscroll, DisplayPoint, RowExt};
|
||||
use gpui::{impl_actions, ViewContext};
|
||||
use language::{Bias, SelectionGoal};
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
use std::cmp;
|
||||
|
||||
use crate::{
|
||||
state::{Mode, Register},
|
||||
Vim,
|
||||
};
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Paste {
|
||||
#[serde(default)]
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use std::{iter::Peekable, str::Chars, time::Duration};
|
||||
|
||||
use editor::Editor;
|
||||
use gpui::{actions, impl_actions, ViewContext};
|
||||
use gpui::{actions, impl_actions, impl_internal_actions, ViewContext};
|
||||
use language::Point;
|
||||
use schemars::JsonSchema;
|
||||
use search::{buffer_search, BufferSearchBar, SearchOptions};
|
||||
use serde_derive::Deserialize;
|
||||
use std::{iter::Peekable, str::Chars, time::Duration};
|
||||
use util::serde::default_true;
|
||||
use workspace::{notifications::NotifyResultExt, searchable::Direction};
|
||||
|
||||
|
@ -15,7 +15,7 @@ use crate::{
|
|||
Vim,
|
||||
};
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub(crate) struct MoveToNext {
|
||||
#[serde(default = "default_true")]
|
||||
|
@ -26,7 +26,7 @@ pub(crate) struct MoveToNext {
|
|||
regex: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub(crate) struct MoveToPrev {
|
||||
#[serde(default = "default_true")]
|
||||
|
@ -37,7 +37,7 @@ pub(crate) struct MoveToPrev {
|
|||
regex: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq)]
|
||||
pub(crate) struct Search {
|
||||
#[serde(default)]
|
||||
backwards: bool,
|
||||
|
@ -45,19 +45,19 @@ pub(crate) struct Search {
|
|||
regex: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
||||
#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq)]
|
||||
pub struct FindCommand {
|
||||
pub query: String,
|
||||
pub backwards: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct ReplaceCommand {
|
||||
pub(crate) range: CommandRange,
|
||||
pub(crate) replacement: Replacement,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Deserialize, Clone)]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub(crate) struct Replacement {
|
||||
search: String,
|
||||
replacement: String,
|
||||
|
@ -66,10 +66,8 @@ pub(crate) struct Replacement {
|
|||
}
|
||||
|
||||
actions!(vim, [SearchSubmit, MoveToNextMatch, MoveToPrevMatch]);
|
||||
impl_actions!(
|
||||
vim,
|
||||
[FindCommand, ReplaceCommand, Search, MoveToPrev, MoveToNext]
|
||||
);
|
||||
impl_actions!(vim, [FindCommand, Search, MoveToPrev, MoveToNext]);
|
||||
impl_internal_actions!(vim, [ReplaceCommand]);
|
||||
|
||||
pub(crate) fn register(editor: &mut Editor, cx: &mut ViewContext<Vim>) {
|
||||
Vim::action(editor, cx, Vim::move_to_next);
|
||||
|
|
|
@ -10,15 +10,14 @@ use editor::{
|
|||
movement::{self, FindRange},
|
||||
Bias, DisplayPoint, Editor,
|
||||
};
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
use gpui::{actions, impl_actions, ViewContext};
|
||||
use itertools::Itertools;
|
||||
use language::{BufferSnapshot, CharKind, Point, Selection, TextObject, TreeSitterOptions};
|
||||
use multi_buffer::MultiBufferRow;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize, JsonSchema)]
|
||||
pub enum Object {
|
||||
Word { ignore_punctuation: bool },
|
||||
Sentence,
|
||||
|
@ -40,13 +39,14 @@ pub enum Object {
|
|||
Comment,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct Word {
|
||||
#[serde(default)]
|
||||
ignore_punctuation: bool,
|
||||
}
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct IndentObj {
|
||||
#[serde(default)]
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
use std::borrow::BorrowMut;
|
||||
use std::{fmt::Display, ops::Range, sync::Arc};
|
||||
|
||||
use crate::command::command_interceptor;
|
||||
use crate::normal::repeat::Replayer;
|
||||
use crate::surrounds::SurroundsType;
|
||||
|
@ -13,12 +10,15 @@ use gpui::{
|
|||
Action, AppContext, BorrowAppContext, ClipboardEntry, ClipboardItem, Global, View, WeakView,
|
||||
};
|
||||
use language::Point;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use settings::{Settings, SettingsStore};
|
||||
use std::borrow::BorrowMut;
|
||||
use std::{fmt::Display, ops::Range, sync::Arc};
|
||||
use ui::{SharedString, ViewContext};
|
||||
use workspace::searchable::Direction;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, JsonSchema, Serialize)]
|
||||
pub enum Mode {
|
||||
Normal,
|
||||
Insert,
|
||||
|
@ -59,22 +59,39 @@ impl Default for Mode {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, JsonSchema)]
|
||||
pub enum Operator {
|
||||
Change,
|
||||
Delete,
|
||||
Yank,
|
||||
Replace,
|
||||
Object { around: bool },
|
||||
FindForward { before: bool },
|
||||
FindBackward { after: bool },
|
||||
Sneak { first_char: Option<char> },
|
||||
SneakBackward { first_char: Option<char> },
|
||||
AddSurrounds { target: Option<SurroundsType> },
|
||||
ChangeSurrounds { target: Option<Object> },
|
||||
Object {
|
||||
around: bool,
|
||||
},
|
||||
FindForward {
|
||||
before: bool,
|
||||
},
|
||||
FindBackward {
|
||||
after: bool,
|
||||
},
|
||||
Sneak {
|
||||
first_char: Option<char>,
|
||||
},
|
||||
SneakBackward {
|
||||
first_char: Option<char>,
|
||||
},
|
||||
AddSurrounds {
|
||||
#[serde(skip)]
|
||||
target: Option<SurroundsType>,
|
||||
},
|
||||
ChangeSurrounds {
|
||||
target: Option<Object>,
|
||||
},
|
||||
DeleteSurrounds,
|
||||
Mark,
|
||||
Jump { line: bool },
|
||||
Jump {
|
||||
line: bool,
|
||||
},
|
||||
Indent,
|
||||
Outdent,
|
||||
AutoIndent,
|
||||
|
@ -82,8 +99,12 @@ pub enum Operator {
|
|||
Lowercase,
|
||||
Uppercase,
|
||||
OppositeCase,
|
||||
Digraph { first_char: Option<char> },
|
||||
Literal { prefix: Option<String> },
|
||||
Digraph {
|
||||
first_char: Option<char>,
|
||||
},
|
||||
Literal {
|
||||
prefix: Option<String>,
|
||||
},
|
||||
Register,
|
||||
RecordRegister,
|
||||
ReplayRegister,
|
||||
|
|
|
@ -6,7 +6,7 @@ use crate::{
|
|||
};
|
||||
use editor::{movement, scroll::Autoscroll, Bias};
|
||||
use language::BracketPair;
|
||||
use serde::Deserialize;
|
||||
|
||||
use std::sync::Arc;
|
||||
use ui::ViewContext;
|
||||
|
||||
|
@ -17,16 +17,6 @@ pub enum SurroundsType {
|
|||
Selection,
|
||||
}
|
||||
|
||||
// This exists so that we can have Deserialize on Operators, but not on Motions.
|
||||
impl<'de> Deserialize<'de> for SurroundsType {
|
||||
fn deserialize<D>(_: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
Err(serde::de::Error::custom("Cannot deserialize SurroundsType"))
|
||||
}
|
||||
}
|
||||
|
||||
impl Vim {
|
||||
pub fn add_surrounds(
|
||||
&mut self,
|
||||
|
|
|
@ -49,25 +49,25 @@ use workspace::{self, Pane, ResizeIntent, Workspace};
|
|||
use crate::state::ReplayableAction;
|
||||
|
||||
/// Used to resize the current pane
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
pub struct ResizePane(pub ResizeIntent);
|
||||
|
||||
/// An Action to Switch between modes
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
pub struct SwitchMode(pub Mode);
|
||||
|
||||
/// PushOperator is used to put vim into a "minor" mode,
|
||||
/// where it's waiting for a specific next set of keystrokes.
|
||||
/// For example 'd' needs a motion to complete.
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
pub struct PushOperator(pub Operator);
|
||||
|
||||
/// Number is used to manage vim's count. Pushing a digit
|
||||
/// multiplis the current value by 10 and adds the digit.
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
/// multiplies the current value by 10 and adds the digit.
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
struct Number(usize);
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
|
||||
struct SelectRegister(String);
|
||||
|
||||
actions!(
|
||||
|
|
|
@ -25,6 +25,7 @@ use itertools::Itertools;
|
|||
use language::DiagnosticSeverity;
|
||||
use parking_lot::Mutex;
|
||||
use project::{Project, ProjectEntryId, ProjectPath, WorktreeId};
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
use settings::{Settings, SettingsStore};
|
||||
use std::{
|
||||
|
@ -71,7 +72,7 @@ impl DraggedSelection {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Copy, Deserialize, Debug)]
|
||||
#[derive(Clone, Copy, PartialEq, Debug, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum SaveIntent {
|
||||
/// write all files (even if unchanged)
|
||||
|
@ -92,16 +93,16 @@ pub enum SaveIntent {
|
|||
Skip,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq, Debug)]
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default)]
|
||||
pub struct ActivateItem(pub usize);
|
||||
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize, Default)]
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CloseActiveItem {
|
||||
pub save_intent: Option<SaveIntent>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize, Default)]
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CloseInactiveItems {
|
||||
pub save_intent: Option<SaveIntent>,
|
||||
|
@ -109,7 +110,7 @@ pub struct CloseInactiveItems {
|
|||
pub close_pinned: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize, Default)]
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CloseAllItems {
|
||||
pub save_intent: Option<SaveIntent>,
|
||||
|
@ -117,34 +118,35 @@ pub struct CloseAllItems {
|
|||
pub close_pinned: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize, Default)]
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CloseCleanItems {
|
||||
#[serde(default)]
|
||||
pub close_pinned: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize, Default)]
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CloseItemsToTheRight {
|
||||
#[serde(default)]
|
||||
pub close_pinned: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize, Default)]
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CloseItemsToTheLeft {
|
||||
#[serde(default)]
|
||||
pub close_pinned: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize, Default)]
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RevealInProjectPanel {
|
||||
#[serde(skip)]
|
||||
pub entry_id: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Default, PartialEq, Clone, Deserialize)]
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default)]
|
||||
pub struct DeploySearch {
|
||||
#[serde(default)]
|
||||
pub replace_enabled: bool,
|
||||
|
|
|
@ -13,6 +13,7 @@ use gpui::{
|
|||
};
|
||||
use parking_lot::Mutex;
|
||||
use project::Project;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
use settings::Settings;
|
||||
use std::sync::Arc;
|
||||
|
@ -717,7 +718,7 @@ impl PaneAxis {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, JsonSchema)]
|
||||
pub enum SplitDirection {
|
||||
Up,
|
||||
Down,
|
||||
|
@ -800,7 +801,7 @@ impl SplitDirection {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, Deserialize, JsonSchema, PartialEq)]
|
||||
pub enum ResizeIntent {
|
||||
Lengthen,
|
||||
Shorten,
|
||||
|
|
|
@ -61,10 +61,9 @@ use persistence::{
|
|||
SerializedWindowBounds, DB,
|
||||
};
|
||||
use postage::stream::Stream;
|
||||
use project::{
|
||||
DirectoryLister, Project, ProjectEntryId, ProjectPath, ResolvedPath, Worktree, WorktreeId,
|
||||
};
|
||||
use project::{DirectoryLister, Project, ProjectEntryId, ProjectPath, ResolvedPath, Worktree};
|
||||
use remote::{ssh_session::ConnectionIdentifier, SshClientDelegate, SshConnectionOptions};
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
use session::AppSession;
|
||||
use settings::Settings;
|
||||
|
@ -119,9 +118,6 @@ static ZED_WINDOW_POSITION: LazyLock<Option<Point<Pixels>>> = LazyLock::new(|| {
|
|||
.and_then(parse_pixel_position_env_var)
|
||||
});
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct RemoveWorktreeFromProject(pub WorktreeId);
|
||||
|
||||
actions!(assistant, [ShowConfiguration]);
|
||||
|
||||
actions!(
|
||||
|
@ -165,64 +161,64 @@ pub struct OpenPaths {
|
|||
pub paths: Vec<PathBuf>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, PartialEq, JsonSchema)]
|
||||
pub struct ActivatePane(pub usize);
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, PartialEq, JsonSchema)]
|
||||
pub struct ActivatePaneInDirection(pub SplitDirection);
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, PartialEq, JsonSchema)]
|
||||
pub struct SwapPaneInDirection(pub SplitDirection);
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, PartialEq, JsonSchema)]
|
||||
pub struct MoveItemToPane {
|
||||
pub destination: usize,
|
||||
#[serde(default = "default_true")]
|
||||
pub focus: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, PartialEq, JsonSchema)]
|
||||
pub struct MoveItemToPaneInDirection {
|
||||
pub direction: SplitDirection,
|
||||
#[serde(default = "default_true")]
|
||||
pub focus: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize)]
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct SaveAll {
|
||||
pub save_intent: Option<SaveIntent>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize)]
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Save {
|
||||
pub save_intent: Option<SaveIntent>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize, Default)]
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize, Default, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CloseAllItemsAndPanes {
|
||||
pub save_intent: Option<SaveIntent>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize, Default)]
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize, Default, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CloseInactiveTabsAndPanes {
|
||||
pub save_intent: Option<SaveIntent>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Deserialize, PartialEq, JsonSchema)]
|
||||
pub struct SendKeystrokes(pub String);
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq, Default)]
|
||||
#[derive(Clone, Deserialize, PartialEq, Default, JsonSchema)]
|
||||
pub struct Reload {
|
||||
pub binary_path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
action_as!(project_symbols, ToggleProjectSymbols as Toggle);
|
||||
|
||||
#[derive(Default, PartialEq, Eq, Clone, serde::Deserialize)]
|
||||
#[derive(Default, PartialEq, Eq, Clone, Deserialize, JsonSchema)]
|
||||
pub struct ToggleFileFinder {
|
||||
#[serde(default)]
|
||||
pub separate_history: bool,
|
||||
|
@ -299,7 +295,7 @@ impl PartialEq for Toast {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Deserialize, PartialEq)]
|
||||
#[derive(Debug, Default, Clone, Deserialize, PartialEq, JsonSchema)]
|
||||
pub struct OpenTerminal {
|
||||
pub working_directory: PathBuf,
|
||||
}
|
||||
|
|
|
@ -11,12 +11,12 @@ use serde::{Deserialize, Serialize};
|
|||
// https://github.com/mmastrac/rust-ctor/issues/280
|
||||
pub fn init() {}
|
||||
|
||||
#[derive(Clone, PartialEq, Deserialize)]
|
||||
#[derive(Clone, PartialEq, Deserialize, JsonSchema)]
|
||||
pub struct OpenBrowser {
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Deserialize)]
|
||||
#[derive(Clone, PartialEq, Deserialize, JsonSchema)]
|
||||
pub struct OpenZedUrl {
|
||||
pub url: String,
|
||||
}
|
||||
|
@ -65,9 +65,10 @@ pub mod feedback {
|
|||
|
||||
pub mod theme_selector {
|
||||
use gpui::impl_actions;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize)]
|
||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
|
||||
pub struct Toggle {
|
||||
/// A list of theme names to filter the theme selector down to.
|
||||
pub themes_filter: Option<Vec<String>>,
|
||||
|
@ -76,20 +77,21 @@ pub mod theme_selector {
|
|||
impl_actions!(theme_selector, [Toggle]);
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Default, Deserialize, PartialEq, JsonSchema)]
|
||||
pub struct InlineAssist {
|
||||
pub prompt: Option<String>,
|
||||
}
|
||||
|
||||
impl_actions!(assistant, [InlineAssist]);
|
||||
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct OpenRecent {
|
||||
#[serde(default)]
|
||||
pub create_new_window: bool,
|
||||
}
|
||||
gpui::impl_actions!(projects, [OpenRecent]);
|
||||
gpui::actions!(projects, [OpenRemote]);
|
||||
|
||||
impl_actions!(projects, [OpenRecent]);
|
||||
actions!(projects, [OpenRemote]);
|
||||
|
||||
/// Where to spawn the task in the UI.
|
||||
#[derive(Default, Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||
|
@ -102,8 +104,8 @@ pub enum RevealTarget {
|
|||
Dock,
|
||||
}
|
||||
|
||||
/// Spawn a task with name or open tasks modal
|
||||
#[derive(Debug, PartialEq, Clone, Deserialize)]
|
||||
/// Spawn a task with name or open tasks modal.
|
||||
#[derive(Debug, PartialEq, Clone, Deserialize, JsonSchema)]
|
||||
#[serde(untagged)]
|
||||
pub enum Spawn {
|
||||
/// Spawns a task by the name given.
|
||||
|
@ -128,8 +130,8 @@ impl Spawn {
|
|||
}
|
||||
}
|
||||
|
||||
/// Rerun last task
|
||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||
/// Rerun the last task.
|
||||
#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema)]
|
||||
pub struct Rerun {
|
||||
/// Controls whether the task context is reevaluated prior to execution of a task.
|
||||
/// If it is not, environment variables such as ZED_COLUMN, ZED_FILE are gonna be the same as in the last execution of a task
|
||||
|
@ -147,6 +149,7 @@ pub struct Rerun {
|
|||
pub use_new_terminal: Option<bool>,
|
||||
|
||||
/// If present, rerun the task with this ID, otherwise rerun the last task.
|
||||
#[serde(skip)]
|
||||
pub task_id: Option<String>,
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue