Open keymap editor from command palette entry (#40825)
Release Notes: - Adds footer to the command palette with buttons to add or change the selected actions keybinding. Both open the keymap editor though the add button takes you directly to the modal for recording a new keybind. https://github.com/user-attachments/assets/0ee6b91e-b1dd-4d7f-ad64-cc79689ceeb2 --------- Co-authored-by: Joseph T. Lyons <JosephTLyons@gmail.com> Co-authored-by: Julia Ryan <juliaryan3.14@gmail.com> Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
This commit is contained in:
co-authored by
Joseph T. Lyons
Julia Ryan
Danilo Leal
parent
c656101862
commit
233a1eb46e
@@ -1,9 +1,10 @@
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
cmp::{self},
|
||||
ops::{Not as _, Range},
|
||||
rc::Rc,
|
||||
sync::Arc,
|
||||
time::Duration,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
mod ui_components;
|
||||
@@ -41,7 +42,7 @@ use workspace::{
|
||||
};
|
||||
|
||||
pub use ui_components::*;
|
||||
use zed_actions::OpenKeymap;
|
||||
use zed_actions::{ChangeKeybinding, OpenKeymap};
|
||||
|
||||
use crate::{
|
||||
persistence::KEYBINDING_EDITORS,
|
||||
@@ -80,37 +81,77 @@ pub fn init(cx: &mut App) {
|
||||
let keymap_event_channel = KeymapEventChannel::new();
|
||||
cx.set_global(keymap_event_channel);
|
||||
|
||||
cx.on_action(|_: &OpenKeymap, cx| {
|
||||
fn common(filter: Option<String>, cx: &mut App) {
|
||||
workspace::with_active_or_new_workspace(cx, move |workspace, window, cx| {
|
||||
workspace
|
||||
.with_local_workspace(window, cx, |workspace, window, cx| {
|
||||
.with_local_workspace(window, cx, move |workspace, window, cx| {
|
||||
let existing = workspace
|
||||
.active_pane()
|
||||
.read(cx)
|
||||
.items()
|
||||
.find_map(|item| item.downcast::<KeymapEditor>());
|
||||
|
||||
if let Some(existing) = existing {
|
||||
let keymap_editor = if let Some(existing) = existing {
|
||||
workspace.activate_item(&existing, true, true, window, cx);
|
||||
existing
|
||||
} else {
|
||||
let keymap_editor =
|
||||
cx.new(|cx| KeymapEditor::new(workspace.weak_handle(), window, cx));
|
||||
workspace.add_item_to_active_pane(
|
||||
Box::new(keymap_editor),
|
||||
Box::new(keymap_editor.clone()),
|
||||
None,
|
||||
true,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
keymap_editor
|
||||
};
|
||||
|
||||
if let Some(filter) = filter {
|
||||
keymap_editor.update(cx, |editor, cx| {
|
||||
editor.filter_editor.update(cx, |editor, cx| {
|
||||
editor.clear(window, cx);
|
||||
editor.insert(&filter, window, cx);
|
||||
});
|
||||
if !editor.has_binding_for(&filter) {
|
||||
open_binding_modal_after_loading(cx)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
cx.on_action(|_: &OpenKeymap, cx| common(None, cx));
|
||||
cx.on_action(|action: &ChangeKeybinding, cx| common(Some(action.action.clone()), cx));
|
||||
|
||||
register_serializable_item::<KeymapEditor>(cx);
|
||||
}
|
||||
|
||||
fn open_binding_modal_after_loading(cx: &mut Context<KeymapEditor>) {
|
||||
let started_at = Instant::now();
|
||||
let observer = Rc::new(RefCell::new(None));
|
||||
let handle = {
|
||||
let observer = Rc::clone(&observer);
|
||||
cx.observe(&cx.entity(), move |editor, _, cx| {
|
||||
let subscription = observer.borrow_mut().take();
|
||||
|
||||
if started_at.elapsed().as_secs() > 10 {
|
||||
return;
|
||||
}
|
||||
if !editor.matches.is_empty() {
|
||||
editor.selected_index = Some(0);
|
||||
cx.dispatch_action(&CreateBinding);
|
||||
return;
|
||||
}
|
||||
|
||||
*observer.borrow_mut() = subscription;
|
||||
})
|
||||
};
|
||||
*observer.borrow_mut() = Some(handle);
|
||||
}
|
||||
|
||||
pub struct KeymapEventChannel {}
|
||||
|
||||
impl Global for KeymapEventChannel {}
|
||||
@@ -1325,6 +1366,13 @@ impl KeymapEditor {
|
||||
editor.set_keystrokes(keystrokes, cx);
|
||||
});
|
||||
}
|
||||
|
||||
fn has_binding_for(&self, action_name: &str) -> bool {
|
||||
self.keybindings
|
||||
.iter()
|
||||
.filter(|kb| kb.keystrokes().is_some())
|
||||
.any(|kb| kb.action().name == action_name)
|
||||
}
|
||||
}
|
||||
|
||||
struct HumanizedActionNameCache {
|
||||
|
||||
Reference in New Issue
Block a user