Detailed changes
@@ -26,8 +26,8 @@ use dap::{
};
use futures::{SinkExt, channel::mpsc};
use gpui::{
- Action as _, AnyView, AppContext, Axis, Entity, EntityId, EventEmitter, FocusHandle, Focusable,
- NoAction, Pixels, Point, Subscription, Task, WeakEntity,
+ AnyView, AppContext, Axis, Entity, EntityId, EventEmitter, FocusHandle, Focusable, Pixels,
+ Point, Subscription, Task, WeakEntity,
};
use language::Buffer;
use loaded_source_list::LoadedSourceList;
@@ -385,7 +385,7 @@ pub(crate) fn new_debugger_pane(
project.clone(),
Default::default(),
None,
- NoAction.boxed_clone(),
+ None,
window,
cx,
);
@@ -1,7 +1,7 @@
use anyhow::{Context as _, Result};
use collections::HashMap;
pub use gpui_macros::Action;
-pub use no_action::{NoAction, is_no_action};
+
use serde_json::json;
use std::{
any::{Any, TypeId},
@@ -419,22 +419,3 @@ pub fn generate_list_of_all_registered_actions() -> impl Iterator<Item = MacroAc
.into_iter()
.map(|builder| builder.0())
}
-
-mod no_action {
- use crate as gpui;
- use std::any::Any as _;
-
- 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.
- pub fn is_no_action(action: &dyn gpui::Action) -> bool {
- action.as_any().type_id() == (NoAction {}).type_id()
- }
-}
@@ -438,7 +438,11 @@ impl DispatchTree {
) -> bool {
let (bindings, _) = keymap.bindings_for_input(&binding.keystrokes, context_stack);
if let Some(found) = bindings.iter().next() {
- found.action.partial_eq(binding.action.as_ref())
+ match (found.action.as_deref(), binding.action.as_deref()) {
+ (None, None) => true,
+ (Some(f), Some(b)) => f.partial_eq(b),
+ (None, Some(_)) | (Some(_), None) => false,
+ }
} else {
false
}
@@ -677,7 +681,12 @@ mod tests {
let keybinding = tree.bindings_for_action(&TestAction, &contexts);
- assert!(keybinding[0].action.partial_eq(&TestAction))
+ assert!(
+ keybinding[0]
+ .action
+ .as_deref()
+ .is_some_and(|it| it.partial_eq(&TestAction))
+ );
}
#[crate::test]
@@ -4,7 +4,7 @@ mod context;
pub use binding::*;
pub use context::*;
-use crate::{Action, AsKeystroke, Keystroke, is_no_action};
+use crate::{Action, AsKeystroke, Keystroke};
use collections::{HashMap, HashSet};
use smallvec::SmallVec;
use std::any::TypeId;
@@ -43,14 +43,14 @@ impl Keymap {
/// Add more bindings to the keymap.
pub fn add_bindings<T: IntoIterator<Item = KeyBinding>>(&mut self, bindings: T) {
for binding in bindings {
- let action_id = binding.action().as_any().type_id();
- if is_no_action(&*binding.action) {
- self.no_action_binding_indices.push(self.bindings.len());
- } else {
+ if let Some(action) = binding.action.as_deref() {
+ let action_id = action.type_id();
self.binding_indices_by_action_id
.entry(action_id)
.or_default()
.push(self.bindings.len());
+ } else {
+ self.no_action_binding_indices.push(self.bindings.len());
}
self.bindings.push(binding);
}
@@ -86,7 +86,10 @@ impl Keymap {
binding_indices.filter_map(|ix| {
let binding = &self.bindings[*ix];
- if !binding.action().partial_eq(action) {
+ if binding
+ .action()
+ .is_none_or(|action| !action.partial_eq(action))
+ {
return None;
}
@@ -170,7 +173,7 @@ impl Keymap {
let mut first_binding_index = None;
for (_, ix, binding) in matched_bindings {
- if is_no_action(&*binding.action) {
+ if binding.action.is_none() {
// Only break if this is a user-defined NoAction binding
// This allows user keymaps to override base keymap NoAction bindings
if let Some(meta) = binding.meta {
@@ -195,7 +198,7 @@ impl Keymap {
{
continue;
}
- if is_no_action(&*binding.action) {
+ if binding.action.is_none() {
pending.remove(&&binding.keystrokes);
continue;
}
@@ -204,8 +207,9 @@ impl Keymap {
(bindings, !pending.is_empty())
}
+
/// Check if the given binding is enabled, given a certain key context.
- /// Returns the deepest depth at which the binding matches, or None if it doesn't match.
+ /// Returns the deepest depth at which the binding matches, or [`None`] if it doesn't match.
fn binding_enabled(&self, binding: &KeyBinding, contexts: &[KeyContext]) -> Option<usize> {
if let Some(predicate) = &binding.context_predicate {
predicate.depth_of(contexts)
@@ -219,7 +223,6 @@ impl Keymap {
mod tests {
use super::*;
use crate as gpui;
- use gpui::NoAction;
actions!(
test_only,
@@ -287,8 +290,18 @@ mod tests {
assert!(!pending);
assert_eq!(result.len(), 2);
- assert!(result[0].action.partial_eq(&ActionGamma {}));
- assert!(result[1].action.partial_eq(&ActionBeta {}));
+ assert!(
+ result[0]
+ .action
+ .as_deref()
+ .is_some_and(|it| it.partial_eq(&ActionGamma {}))
+ );
+ assert!(
+ result[1]
+ .action
+ .as_deref()
+ .is_some_and(|it| it.partial_eq(&ActionBeta {}))
+ );
}
#[test]
@@ -296,8 +309,8 @@ mod tests {
let bindings = [
KeyBinding::new("ctrl-a", ActionAlpha {}, Some("editor")),
KeyBinding::new("ctrl-b", ActionAlpha {}, Some("editor")),
- KeyBinding::new("ctrl-a", NoAction {}, Some("editor && mode==full")),
- KeyBinding::new("ctrl-b", NoAction {}, None),
+ KeyBinding::new_no_action("ctrl-a", Some("editor && mode==full")),
+ KeyBinding::new_no_action("ctrl-b", None),
];
let mut keymap = Keymap::default();
@@ -351,7 +364,7 @@ mod tests {
fn test_multiple_keystroke_binding_disabled() {
let bindings = [
KeyBinding::new("space w w", ActionAlpha {}, Some("workspace")),
- KeyBinding::new("space w w", NoAction {}, Some("editor")),
+ KeyBinding::new_no_action("space w w", Some("editor")),
];
let mut keymap = Keymap::default();
@@ -403,7 +416,7 @@ mod tests {
// that should result in pending
let bindings = [
KeyBinding::new("space w w", ActionAlpha {}, Some("workspace")),
- KeyBinding::new("space w w", NoAction {}, Some("editor")),
+ KeyBinding::new_no_action("space w w", Some("editor")),
KeyBinding::new("space w x", ActionAlpha {}, Some("editor")),
];
let mut keymap = Keymap::default();
@@ -418,7 +431,7 @@ mod tests {
let bindings = [
KeyBinding::new("space w w", ActionAlpha {}, Some("workspace")),
KeyBinding::new("space w x", ActionAlpha {}, Some("editor")),
- KeyBinding::new("space w w", NoAction {}, Some("editor")),
+ KeyBinding::new_no_action("space w w", Some("editor")),
];
let mut keymap = Keymap::default();
keymap.add_bindings(bindings);
@@ -432,7 +445,7 @@ mod tests {
let bindings = [
KeyBinding::new("space w w", ActionAlpha {}, Some("workspace")),
KeyBinding::new("space w x", ActionAlpha {}, Some("workspace")),
- KeyBinding::new("space w w", NoAction {}, Some("editor")),
+ KeyBinding::new_no_action("space w w", Some("editor")),
];
let mut keymap = Keymap::default();
keymap.add_bindings(bindings);
@@ -446,7 +459,7 @@ mod tests {
fn test_override_multikey() {
let bindings = [
KeyBinding::new("ctrl-w left", ActionAlpha {}, Some("editor")),
- KeyBinding::new("ctrl-w", NoAction {}, Some("editor")),
+ KeyBinding::new_no_action("ctrl-w", Some("editor")),
];
let mut keymap = Keymap::default();
@@ -481,7 +494,7 @@ mod tests {
fn test_simple_disable() {
let bindings = [
KeyBinding::new("ctrl-x", ActionAlpha {}, Some("editor")),
- KeyBinding::new("ctrl-x", NoAction {}, Some("editor")),
+ KeyBinding::new_no_action("ctrl-x", Some("editor")),
];
let mut keymap = Keymap::default();
@@ -501,7 +514,7 @@ mod tests {
// disabled at the wrong level
let bindings = [
KeyBinding::new("ctrl-x", ActionAlpha {}, Some("editor")),
- KeyBinding::new("ctrl-x", NoAction {}, Some("workspace")),
+ KeyBinding::new_no_action("ctrl-x", Some("workspace")),
];
let mut keymap = Keymap::default();
@@ -523,7 +536,7 @@ mod tests {
fn test_disable_deeper() {
let bindings = [
KeyBinding::new("ctrl-x", ActionAlpha {}, Some("workspace")),
- KeyBinding::new("ctrl-x", NoAction {}, Some("editor")),
+ KeyBinding::new_no_action("ctrl-x", Some("editor")),
];
let mut keymap = Keymap::default();
@@ -560,7 +573,12 @@ mod tests {
.map(Result::unwrap),
);
assert_eq!(matched.0.len(), 1);
- assert!(matched.0[0].action.partial_eq(&ActionBeta));
+ assert!(
+ matched.0[0]
+ .action
+ .as_deref()
+ .is_some_and(|it| it.partial_eq(&ActionBeta))
+ );
assert!(matched.1);
}
@@ -568,7 +586,7 @@ mod tests {
fn test_pending_match_enabled_extended() {
let bindings = [
KeyBinding::new("ctrl-x", ActionBeta, Some("vim_mode == normal")),
- KeyBinding::new("ctrl-x 0", NoAction, Some("Workspace")),
+ KeyBinding::new_no_action("ctrl-x 0", Some("Workspace")),
];
let mut keymap = Keymap::default();
keymap.add_bindings(bindings);
@@ -583,11 +601,16 @@ mod tests {
.map(Result::unwrap),
);
assert_eq!(matched.0.len(), 1);
- assert!(matched.0[0].action.partial_eq(&ActionBeta));
+ assert!(
+ matched.0[0]
+ .action
+ .as_deref()
+ .is_some_and(|it| it.partial_eq(&ActionBeta))
+ );
assert!(!matched.1);
let bindings = [
KeyBinding::new("ctrl-x", ActionBeta, Some("Workspace")),
- KeyBinding::new("ctrl-x 0", NoAction, Some("vim_mode == normal")),
+ KeyBinding::new_no_action("ctrl-x 0", Some("vim_mode == normal")),
];
let mut keymap = Keymap::default();
keymap.add_bindings(bindings);
@@ -602,7 +625,12 @@ mod tests {
.map(Result::unwrap),
);
assert_eq!(matched.0.len(), 1);
- assert!(matched.0[0].action.partial_eq(&ActionBeta));
+ assert!(
+ matched.0[0]
+ .action
+ .as_deref()
+ .is_some_and(|it| it.partial_eq(&ActionBeta))
+ );
assert!(!matched.1);
}
@@ -625,7 +653,12 @@ mod tests {
.map(Result::unwrap),
);
assert_eq!(matched.0.len(), 1);
- assert!(matched.0[0].action.partial_eq(&ActionBeta));
+ assert!(
+ matched.0[0]
+ .action
+ .as_deref()
+ .is_some_and(|it| it.partial_eq(&ActionBeta))
+ );
assert!(!matched.1);
}
@@ -652,8 +685,18 @@ mod tests {
// Both bindings should be returned, but Editor binding should be first (highest precedence)
assert_eq!(result.len(), 2);
- assert!(result[0].action.partial_eq(&ActionBeta {})); // Editor binding first
- assert!(result[1].action.partial_eq(&ActionAlpha {})); // Workspace binding second
+ assert!(
+ result[0]
+ .action
+ .as_deref()
+ .is_some_and(|it| it.partial_eq(&ActionBeta {}))
+ ); // Editor binding first
+ assert!(
+ result[1]
+ .action
+ .as_deref()
+ .is_some_and(|it| it.partial_eq(&ActionAlpha {}))
+ ); // Workspace binding second
}
#[test]
@@ -662,8 +705,8 @@ mod tests {
KeyBinding::new("ctrl-a", ActionAlpha {}, Some("pane")),
KeyBinding::new("ctrl-b", ActionBeta {}, Some("editor && mode == full")),
KeyBinding::new("ctrl-c", ActionGamma {}, Some("workspace")),
- KeyBinding::new("ctrl-a", NoAction {}, Some("pane && active")),
- KeyBinding::new("ctrl-b", NoAction {}, Some("editor")),
+ KeyBinding::new_no_action("ctrl-a", Some("pane && active")),
+ KeyBinding::new_no_action("ctrl-b", Some("editor")),
];
let mut keymap = Keymap::default();
@@ -707,7 +750,17 @@ mod tests {
// User binding should take precedence over default binding
assert_eq!(result.len(), 2);
- assert!(result[0].action.partial_eq(&ActionBeta {}));
- assert!(result[1].action.partial_eq(&ActionAlpha {}));
+ assert!(
+ result[0]
+ .action
+ .as_deref()
+ .is_some_and(|it| it.partial_eq(&ActionBeta {}))
+ );
+ assert!(
+ result[1]
+ .action
+ .as_deref()
+ .is_some_and(|it| it.partial_eq(&ActionAlpha {}))
+ );
}
}
@@ -8,7 +8,7 @@ use smallvec::SmallVec;
/// A keybinding and its associated metadata, from the keymap.
pub struct KeyBinding {
- pub(crate) action: Box<dyn Action>,
+ pub(crate) action: Option<Box<dyn Action>>,
pub(crate) keystrokes: SmallVec<[KeybindingKeystroke; 2]>,
pub(crate) context_predicate: Option<Rc<KeyBindingContextPredicate>>,
pub(crate) meta: Option<KeyBindingMetaIndex>,
@@ -19,7 +19,7 @@ pub struct KeyBinding {
impl Clone for KeyBinding {
fn clone(&self) -> Self {
KeyBinding {
- action: self.action.boxed_clone(),
+ action: self.action.as_ref().map(|action| action.boxed_clone()),
keystrokes: self.keystrokes.clone(),
context_predicate: self.context_predicate.clone(),
meta: self.meta,
@@ -35,7 +35,22 @@ impl KeyBinding {
context.map(|context| KeyBindingContextPredicate::parse(context).unwrap().into());
Self::load(
keystrokes,
- Box::new(action),
+ Some(Box::new(action) as Box<dyn Action>),
+ context_predicate,
+ false,
+ None,
+ &DummyKeyboardMapper,
+ )
+ .unwrap()
+ }
+
+ /// Construct a new keybinding from the given data with no action associated to it. Panics on parse error.
+ pub fn new_no_action(keystrokes: &str, context: Option<&str>) -> Self {
+ let context_predicate =
+ context.map(|context| KeyBindingContextPredicate::parse(context).unwrap().into());
+ Self::load(
+ keystrokes,
+ None,
context_predicate,
false,
None,
@@ -47,7 +62,7 @@ impl KeyBinding {
/// Load a keybinding from the given raw data.
pub fn load(
keystrokes: &str,
- action: Box<dyn Action>,
+ action: impl Into<Option<Box<dyn Action>>>,
context_predicate: Option<Rc<KeyBindingContextPredicate>>,
use_key_equivalents: bool,
action_input: Option<SharedString>,
@@ -67,7 +82,7 @@ impl KeyBinding {
Ok(Self {
keystrokes,
- action,
+ action: action.into(),
context_predicate,
meta: None,
action_input,
@@ -106,8 +121,8 @@ impl KeyBinding {
}
/// Get the action associated with this binding
- pub fn action(&self) -> &dyn Action {
- self.action.as_ref()
+ pub fn action(&self) -> Option<&dyn Action> {
+ self.action.as_deref()
}
/// Get the predicate used to match this binding
@@ -131,7 +146,10 @@ impl std::fmt::Debug for KeyBinding {
f.debug_struct("KeyBinding")
.field("keystrokes", &self.keystrokes)
.field("context_predicate", &self.context_predicate)
- .field("action", &self.action.name())
+ .field(
+ "action",
+ &self.action.as_deref().map_or("null", |it| it.name()),
+ )
.finish()
}
}
@@ -3800,11 +3800,13 @@ impl Window {
}
for binding in match_result.bindings {
- self.dispatch_action_on_node(node_id, binding.action.as_ref(), cx);
+ if let Some(action) = binding.action.as_deref() {
+ self.dispatch_action_on_node(node_id, action, cx);
+ }
if !cx.propagate_event {
self.dispatch_keystroke_observers(
event,
- Some(binding.action),
+ binding.action,
match_result.context_stack,
cx,
);
@@ -3922,14 +3924,11 @@ impl Window {
cx.propagate_event = true;
for binding in replay.bindings {
- self.dispatch_action_on_node(node_id, binding.action.as_ref(), cx);
+ if let Some(action) = binding.action.as_deref() {
+ self.dispatch_action_on_node(node_id, action, cx);
+ }
if !cx.propagate_event {
- self.dispatch_keystroke_observers(
- &event,
- Some(binding.action),
- Vec::default(),
- cx,
- );
+ self.dispatch_keystroke_observers(&event, binding.action, Vec::default(), cx);
continue 'replay;
}
}
@@ -677,6 +677,9 @@ impl KeymapEditor {
let mut string_match_candidates = Vec::new();
for key_binding in key_bindings {
+ let Some(action) = key_binding.action() else {
+ continue;
+ };
let source = key_binding
.meta()
.map(KeybindSource::from_meta)
@@ -696,7 +699,7 @@ impl KeymapEditor {
})
.unwrap_or(KeybindContextString::Global);
- let action_name = key_binding.action().name();
+ let action_name = action.name();
unmapped_action_names.remove(&action_name);
let action_arguments = key_binding
@@ -1814,7 +1817,7 @@ impl Render for KeymapEditor {
let action = div()
.id(("keymap action", index))
.child({
- if action_name != gpui::NoAction.name() {
+ if !action_name.is_empty() {
binding
.action()
.humanized_name
@@ -62,7 +62,7 @@ impl KeyContextView {
.map(|binding| {
let match_state = if let Some(predicate) = binding.predicate() {
if this.matches(&predicate) {
- if this.action_matches(&e.action, binding.action()) {
+ if this.action_matches(e.action.as_deref(), binding.action()) {
Some(true)
} else {
Some(false)
@@ -70,7 +70,7 @@ impl KeyContextView {
} else {
None
}
- } else if this.action_matches(&e.action, binding.action()) {
+ } else if this.action_matches(e.action.as_deref(), binding.action()) {
Some(true)
} else {
Some(false)
@@ -80,10 +80,7 @@ impl KeyContextView {
} else {
"".to_string()
};
- let mut name = binding.action().name();
- if name == "zed::NoAction" {
- name = "(null)"
- }
+ let name = binding.action().map_or("(null)", |action| action.name());
(
name.to_owned().into(),
@@ -130,12 +127,8 @@ impl KeyContextView {
predicate.depth_of(&self.context_stack).is_some()
}
- fn action_matches(&self, a: &Option<Box<dyn Action>>, b: &dyn Action) -> bool {
- if let Some(last_action) = a {
- last_action.partial_eq(b)
- } else {
- b.name() == "zed::NoAction"
- }
+ fn action_matches(&self, a: Option<&dyn Action>, b: Option<&dyn Action>) -> bool {
+ a.zip(b).is_some_and(|(a, b)| a.partial_eq(b))
}
}
@@ -2,9 +2,8 @@ use anyhow::{Context as _, Result};
use collections::{BTreeMap, HashMap, IndexMap};
use fs::Fs;
use gpui::{
- Action, ActionBuildError, App, InvalidKeystrokeError, KEYSTROKE_PARSE_EXPECTED_MESSAGE,
- KeyBinding, KeyBindingContextPredicate, KeyBindingMetaIndex, KeybindingKeystroke, Keystroke,
- NoAction, SharedString,
+ ActionBuildError, App, InvalidKeystrokeError, KEYSTROKE_PARSE_EXPECTED_MESSAGE, KeyBinding,
+ KeyBindingContextPredicate, KeyBindingMetaIndex, KeybindingKeystroke, Keystroke, SharedString,
};
use schemars::{JsonSchema, json_schema};
use serde::Deserialize;
@@ -350,12 +349,12 @@ impl KeymapFile {
let action_input = items[1].clone();
let action_input_string = action_input.to_string();
(
- cx.build_action(name, Some(action_input)),
+ cx.build_action(name, Some(action_input)).map(Some),
Some(action_input_string),
)
}
- Value::String(name) => (cx.build_action(name, None), None),
- Value::Null => (Ok(NoAction.boxed_clone()), None),
+ Value::String(name) => (cx.build_action(name, None).map(Some), None),
+ Value::Null => (Ok(None), None),
_ => {
return Err(format!(
"expected two-element array of `[name, input]`. \
@@ -410,7 +409,9 @@ impl KeymapFile {
}
};
- if let Some(validator) = KEY_BINDING_VALIDATORS.get(&key_binding.action().type_id()) {
+ if let Some(action) = key_binding.action()
+ && let Some(validator) = KEY_BINDING_VALIDATORS.get(&action.type_id())
+ {
match validator.validate(&key_binding) {
Ok(()) => Ok(key_binding),
Err(error) => Err(error.0),
@@ -502,7 +503,7 @@ impl KeymapFile {
let mut empty_schema_action_names = vec![];
for (name, action_schema) in action_schemas.into_iter() {
- let deprecation = if name == NoAction.name() {
+ let deprecation = if name.is_empty() {
Some("null")
} else {
deprecations.get(name).copied()
@@ -635,7 +636,7 @@ impl KeymapFile {
target_keybind_source,
} if target_keybind_source != KeybindSource::User => {
let mut source = target.clone();
- source.action_name = gpui::NoAction.name();
+ source.action_name = "";
source.action_arguments.take();
operation = KeybindUpdateOperation::Add {
source,
@@ -930,7 +931,7 @@ pub struct KeybindUpdateTarget<'a> {
impl<'a> KeybindUpdateTarget<'a> {
fn action_value(&self) -> Result<Value> {
- if self.action_name == gpui::NoAction.name() {
+ if self.action_name.is_empty() {
return Ok(Value::Null);
}
let action_name: Value = self.action_name.into();
@@ -1040,7 +1040,7 @@ pub fn new_terminal_pane(
project.clone(),
Default::default(),
None,
- NewTerminal.boxed_clone(),
+ Some(NewTerminal.boxed_clone()),
window,
cx,
);
@@ -528,7 +528,7 @@ impl Component for KeyBinding {
single_example(
"Default",
KeyBinding::new_from_gpui(
- gpui::KeyBinding::new("ctrl-s", gpui::NoAction, None),
+ gpui::KeyBinding::new_no_action("ctrl-s", None),
cx,
)
.into_any_element(),
@@ -536,7 +536,7 @@ impl Component for KeyBinding {
single_example(
"Mac Style",
KeyBinding::new_from_gpui(
- gpui::KeyBinding::new("cmd-s", gpui::NoAction, None),
+ gpui::KeyBinding::new_no_action("cmd-s", None),
cx,
)
.platform_style(PlatformStyle::Mac)
@@ -545,7 +545,7 @@ impl Component for KeyBinding {
single_example(
"Windows Style",
KeyBinding::new_from_gpui(
- gpui::KeyBinding::new("ctrl-s", gpui::NoAction, None),
+ gpui::KeyBinding::new_no_action("ctrl-s", None),
cx,
)
.platform_style(PlatformStyle::Windows)
@@ -558,7 +558,7 @@ impl Component for KeyBinding {
vec![single_example(
"Vim Mode Enabled",
KeyBinding::new_from_gpui(
- gpui::KeyBinding::new("dd", gpui::NoAction, None),
+ gpui::KeyBinding::new_no_action("dd", None),
cx,
)
.vim_mode(true)
@@ -571,7 +571,7 @@ impl Component for KeyBinding {
single_example(
"Multiple Keys",
KeyBinding::new_from_gpui(
- gpui::KeyBinding::new("ctrl-k ctrl-b", gpui::NoAction, None),
+ gpui::KeyBinding::new_no_action("ctrl-k ctrl-b", None),
cx,
)
.into_any_element(),
@@ -579,7 +579,7 @@ impl Component for KeyBinding {
single_example(
"With Shift",
KeyBinding::new_from_gpui(
- gpui::KeyBinding::new("shift-cmd-p", gpui::NoAction, None),
+ gpui::KeyBinding::new_no_action("shift-cmd-p", None),
cx,
)
.into_any_element(),
@@ -1,4 +1,3 @@
-use gpui::NoAction;
use gpui::Render;
use itertools::Itertools;
use story::Story;
@@ -8,7 +7,7 @@ use crate::{KeyBinding, prelude::*};
pub struct KeybindingStory;
pub fn binding(key: &str) -> gpui::KeyBinding {
- gpui::KeyBinding::new(key, NoAction {}, None)
+ gpui::KeyBinding::new_no_action(key, None)
}
impl Render for KeybindingStory {
@@ -42,7 +41,7 @@ impl Render for KeybindingStory {
.py_3()
.children(chunk.map(|permutation| {
KeyBinding::new_from_gpui(
- binding(&(permutation.join("-") + "-x")),
+ binding(&(permutation.into_iter().join("-") + "-x")),
cx,
)
}))
@@ -1244,14 +1244,14 @@ fn generate_commands(_: &App) -> Vec<VimCommand> {
.range(act_on_range),
VimCommand::str(("rev", "ert"), "git::Restore").range(act_on_range),
VimCommand::new(("d", "elete"), VisualDeleteLine).range(select_range),
- VimCommand::new(("y", "ank"), gpui::NoAction).range(|_, range| {
- Some(
- YankCommand {
- range: range.clone(),
- }
- .boxed_clone(),
- )
- }),
+ // VimCommand::new(("y", "ank"), gpui::NoAction).range(|_, range| {
+ // Some(
+ // YankCommand {
+ // range: range.clone(),
+ // }
+ // .boxed_clone(),
+ // )
+ // }),
VimCommand::new(("reg", "isters"), ToggleRegistersView).bang(ToggleRegistersView),
VimCommand::new(("di", "splay"), ToggleRegistersView).bang(ToggleRegistersView),
VimCommand::new(("marks", ""), ToggleMarksView).bang(ToggleMarksView),
@@ -370,7 +370,7 @@ pub struct Pane {
/// Is None if navigation buttons are permanently turned off (and should not react to setting changes).
/// Otherwise, when `display_nav_history_buttons` is Some, it determines whether nav buttons should be displayed.
display_nav_history_buttons: Option<bool>,
- double_click_dispatch_action: Box<dyn Action>,
+ double_click_dispatch_action: Option<Box<dyn Action>>,
save_modals_spawned: HashSet<EntityId>,
close_pane_if_empty: bool,
pub new_item_context_menu_handle: PopoverMenuHandle<ContextMenu>,
@@ -458,7 +458,7 @@ impl Pane {
project: Entity<Project>,
next_timestamp: Arc<AtomicUsize>,
can_drop_predicate: Option<Arc<dyn Fn(&dyn Any, &mut Window, &mut App) -> bool + 'static>>,
- double_click_dispatch_action: Box<dyn Action>,
+ double_click_dispatch_action: Option<Box<dyn Action>>,
window: &mut Window,
cx: &mut Context<Self>,
) -> Self {
@@ -3066,10 +3066,14 @@ impl Pane {
}))
.on_click(cx.listener(move |this, event: &ClickEvent, window, cx| {
if event.click_count() == 2 {
- window.dispatch_action(
- this.double_click_dispatch_action.boxed_clone(),
- cx,
- );
+ if let Some(double_click_dispatch_action) =
+ &this.double_click_dispatch_action
+ {
+ window.dispatch_action(
+ double_click_dispatch_action.boxed_clone(),
+ cx,
+ );
+ }
}
})),
),
@@ -3744,10 +3748,14 @@ impl Render for Pane {
.on_click(cx.listener(
move |this, event: &ClickEvent, window, cx| {
if event.click_count() == 2 {
- window.dispatch_action(
- this.double_click_dispatch_action.boxed_clone(),
- cx,
- );
+ if let Some(double_click_dispatch_action) =
+ &this.double_click_dispatch_action
+ {
+ window.dispatch_action(
+ double_click_dispatch_action.boxed_clone(),
+ cx,
+ );
+ }
}
},
));
@@ -1306,7 +1306,7 @@ impl Workspace {
project.clone(),
pane_history_timestamp.clone(),
None,
- NewFile.boxed_clone(),
+ Some(NewFile.boxed_clone()),
window,
cx,
);
@@ -3187,7 +3187,7 @@ impl Workspace {
self.project.clone(),
self.pane_history_timestamp.clone(),
None,
- NewFile.boxed_clone(),
+ Some(NewFile.boxed_clone()),
window,
cx,
);