diff --git a/crates/settings/src/keymap_file.rs b/crates/settings/src/keymap_file.rs index b61d30e405..d738e30c4f 100644 --- a/crates/settings/src/keymap_file.rs +++ b/crates/settings/src/keymap_file.rs @@ -881,6 +881,9 @@ pub struct KeybindUpdateTarget<'a> { impl<'a> KeybindUpdateTarget<'a> { fn action_value(&self) -> Result { + if self.action_name == gpui::NoAction.name() { + return Ok(Value::Null); + } let action_name: Value = self.action_name.into(); let value = match self.action_arguments { Some(args) => { @@ -1479,10 +1482,6 @@ mod tests { ]"# .unindent(), ); - } - - #[test] - fn test_append() { check_keymap_update( r#"[ { @@ -1529,5 +1528,43 @@ mod tests { ]"# .unindent(), ); + + check_keymap_update( + r#"[ + { + "context": "SomeOtherContext", + "use_key_equivalents": true, + "bindings": { + "b": "foo::bar", + } + }, + ]"# + .unindent(), + KeybindUpdateOperation::Remove { + target: KeybindUpdateTarget { + context: Some("SomeContext"), + keystrokes: &parse_keystrokes("a"), + action_name: "foo::baz", + action_arguments: Some("true"), + }, + target_keybind_source: KeybindSource::Default, + }, + r#"[ + { + "context": "SomeOtherContext", + "use_key_equivalents": true, + "bindings": { + "b": "foo::bar", + } + }, + { + "context": "SomeContext", + "bindings": { + "a": null + } + } + ]"# + .unindent(), + ); } } diff --git a/crates/settings_ui/src/keybindings.rs b/crates/settings_ui/src/keybindings.rs index 2bfa6f820e..281b01df27 100644 --- a/crates/settings_ui/src/keybindings.rs +++ b/crates/settings_ui/src/keybindings.rs @@ -297,6 +297,7 @@ struct KeymapEditor { selected_index: Option, context_menu: Option<(Entity, Point, Subscription)>, previous_edit: Option, + humanized_action_names: HashMap<&'static str, SharedString>, } enum PreviousEdit { @@ -309,7 +310,7 @@ enum PreviousEdit { /// and if we don't find it, we scroll to 0 and don't set a selected index Keybinding { action_mapping: ActionMapping, - action_name: SharedString, + action_name: &'static str, /// The scrollbar position to fallback to if we don't find the keybinding during a refresh /// this can happen if there's a filter applied to the search and the keybinding modification /// filters the binding from the search results @@ -360,6 +361,14 @@ impl KeymapEditor { }) .detach(); + let humanized_action_names = + HashMap::from_iter(cx.all_action_names().into_iter().map(|&action_name| { + ( + action_name, + command_palette::humanize_action_name(action_name).into(), + ) + })); + let mut this = Self { workspace, keybindings: vec![], @@ -376,6 +385,7 @@ impl KeymapEditor { selected_index: None, context_menu: None, previous_edit: None, + humanized_action_names, }; this.on_keymap_changed(cx); @@ -487,7 +497,7 @@ impl KeymapEditor { Some(Default) => 3, None => 4, }; - return (source_precedence, keybind.action_name.as_ref()); + return (source_precedence, keybind.action_name); }); } this.selected_index.take(); @@ -557,7 +567,7 @@ impl KeymapEditor { processed_bindings.push(ProcessedKeybinding { keystroke_text: keystroke_text.into(), ui_key_binding, - action_name: action_name.into(), + action_name, action_arguments, action_docs, action_schema: action_schema.get(action_name).cloned(), @@ -574,7 +584,7 @@ impl KeymapEditor { processed_bindings.push(ProcessedKeybinding { keystroke_text: empty.clone(), ui_key_binding: None, - action_name: action_name.into(), + action_name, action_arguments: None, action_docs: action_documentation.get(action_name).copied(), action_schema: action_schema.get(action_name).cloned(), @@ -1024,7 +1034,7 @@ impl KeymapEditor { struct ProcessedKeybinding { keystroke_text: SharedString, ui_key_binding: Option, - action_name: SharedString, + action_name: &'static str, action_arguments: Option, action_docs: Option<&'static str>, action_schema: Option, @@ -1270,7 +1280,7 @@ impl Render for KeymapEditor { .filter_map(|index| { let candidate_id = this.matches.get(index)?.candidate_id; let binding = &this.keybindings[candidate_id]; - let action_name = binding.action_name.clone(); + let action_name = binding.action_name; let icon = (this.filter_state != FilterState::Conflicts && this.has_conflict(index)) @@ -1317,13 +1327,26 @@ impl Render for KeymapEditor { let action = div() .id(("keymap action", index)) - .child(command_palette::humanize_action_name(&action_name)) + .child({ + if action_name != gpui::NoAction.name() { + this.humanized_action_names + .get(action_name) + .cloned() + .unwrap_or(action_name.into()) + .into_any_element() + } else { + const NULL: SharedString = + SharedString::new_static(""); + muted_styled_text(NULL.clone(), cx) + .into_any_element() + } + }) .when(!context_menu_deployed, |this| { this.tooltip({ - let action_name = binding.action_name.clone(); + let action_name = binding.action_name; let action_docs = binding.action_docs; move |_, cx| { - let action_tooltip = Tooltip::new(&action_name); + let action_tooltip = Tooltip::new(action_name); let action_tooltip = match action_docs { Some(docs) => action_tooltip.meta(docs), None => action_tooltip, @@ -1773,7 +1796,7 @@ impl KeybindingEditorModal { .read(cx) .keybindings .get(first_conflicting_index) - .map(|keybind| keybind.action_name.clone()); + .map(|keybind| keybind.action_name); let warning_message = match conflicting_action_name { Some(name) => { @@ -1823,7 +1846,7 @@ impl KeybindingEditorModal { .log_err(); cx.spawn(async move |this, cx| { - let action_name = existing_keybind.action_name.clone(); + let action_name = existing_keybind.action_name; if let Err(err) = save_keybinding_update( create,