settings_ui: Add Edit keybindings button (#44914)
Closes #ISSUE Release Notes: - settings_ui: Added an "Open Keymap Editor" item under the Keymap section
This commit is contained in:
1 parent
6d45b1a226
commit
897303e0d0
3 files changed
+155
-43
No files matched your search
@@ -81,50 +81,61 @@ pub fn init(cx: &mut App) {
|
||||
let keymap_event_channel = KeymapEventChannel::new();
|
||||
cx.set_global(keymap_event_channel);
|
||||
|
||||
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, move |workspace, window, cx| {
|
||||
let existing = workspace
|
||||
.active_pane()
|
||||
.read(cx)
|
||||
.items()
|
||||
.find_map(|item| item.downcast::<KeymapEditor>());
|
||||
fn open_keymap_editor(
|
||||
filter: Option<String>,
|
||||
workspace: &mut Workspace,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Workspace>,
|
||||
) {
|
||||
workspace
|
||||
.with_local_workspace(window, cx, |workspace, window, cx| {
|
||||
let existing = workspace
|
||||
.active_pane()
|
||||
.read(cx)
|
||||
.items()
|
||||
.find_map(|item| item.downcast::<KeymapEditor>());
|
||||
|
||||
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.clone()),
|
||||
None,
|
||||
true,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
keymap_editor
|
||||
};
|
||||
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.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();
|
||||
})
|
||||
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_and_log_err(cx);
|
||||
}
|
||||
|
||||
cx.on_action(|_: &OpenKeymap, cx| common(None, cx))
|
||||
.on_action(|action: &ChangeKeybinding, cx| common(Some(action.action.clone()), cx));
|
||||
cx.observe_new(|workspace: &mut Workspace, _window, _cx| {
|
||||
workspace
|
||||
.register_action(|workspace, _: &OpenKeymap, window, cx| {
|
||||
open_keymap_editor(None, workspace, window, cx);
|
||||
})
|
||||
.register_action(|workspace, action: &ChangeKeybinding, window, cx| {
|
||||
open_keymap_editor(Some(action.action.clone()), workspace, window, cx);
|
||||
});
|
||||
})
|
||||
.detach();
|
||||
|
||||
register_serializable_item::<KeymapEditor>(cx);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use gpui::App;
|
||||
use gpui::{Action as _, App};
|
||||
use settings::{LanguageSettingsContent, SettingsContent};
|
||||
use std::sync::Arc;
|
||||
use strum::IntoDiscriminant as _;
|
||||
use ui::{IntoElement, SharedString};
|
||||
|
||||
use crate::{
|
||||
DynamicItem, PROJECT, SettingField, SettingItem, SettingsFieldMetadata, SettingsPage,
|
||||
SettingsPageItem, SubPageLink, USER, all_language_names, sub_page_stack,
|
||||
ActionLink, DynamicItem, PROJECT, SettingField, SettingItem, SettingsFieldMetadata,
|
||||
SettingsPage, SettingsPageItem, SubPageLink, USER, all_language_names, sub_page_stack,
|
||||
};
|
||||
|
||||
const DEFAULT_STRING: String = String::new();
|
||||
@@ -1054,6 +1054,25 @@ pub(crate) fn settings_data(cx: &App) -> Vec<SettingsPage> {
|
||||
SettingsPage {
|
||||
title: "Keymap",
|
||||
items: vec![
|
||||
SettingsPageItem::SectionHeader("Keybindings"),
|
||||
SettingsPageItem::ActionLink(ActionLink {
|
||||
title: "Edit Keybindings".into(),
|
||||
description: Some("Customize keybindings in the keymap editor.".into()),
|
||||
button_text: "Open Keymap".into(),
|
||||
on_click: Arc::new(|settings_window, window, cx| {
|
||||
let Some(original_window) = settings_window.original_window else {
|
||||
return;
|
||||
};
|
||||
original_window
|
||||
.update(cx, |_workspace, original_window, cx| {
|
||||
original_window
|
||||
.dispatch_action(zed_actions::OpenKeymap.boxed_clone(), cx);
|
||||
original_window.activate_window();
|
||||
})
|
||||
.ok();
|
||||
window.remove_window();
|
||||
}),
|
||||
}),
|
||||
SettingsPageItem::SectionHeader("Base Keymap"),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Base Keymap",
|
||||
|
||||
@@ -731,6 +731,7 @@ enum SettingsPageItem {
|
||||
SettingItem(SettingItem),
|
||||
SubPageLink(SubPageLink),
|
||||
DynamicItem(DynamicItem),
|
||||
ActionLink(ActionLink),
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for SettingsPageItem {
|
||||
@@ -746,6 +747,9 @@ impl std::fmt::Debug for SettingsPageItem {
|
||||
SettingsPageItem::DynamicItem(dynamic_item) => {
|
||||
write!(f, "DynamicItem({})", dynamic_item.discriminant.title)
|
||||
}
|
||||
SettingsPageItem::ActionLink(action_link) => {
|
||||
write!(f, "ActionLink({})", action_link.title)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -973,6 +977,55 @@ impl SettingsPageItem {
|
||||
|
||||
return content.into_any_element();
|
||||
}
|
||||
SettingsPageItem::ActionLink(action_link) => v_flex()
|
||||
.group("setting-item")
|
||||
.px_8()
|
||||
.child(
|
||||
h_flex()
|
||||
.id(action_link.title.clone())
|
||||
.w_full()
|
||||
.min_w_0()
|
||||
.justify_between()
|
||||
.map(apply_padding)
|
||||
.child(
|
||||
v_flex()
|
||||
.relative()
|
||||
.w_full()
|
||||
.max_w_1_2()
|
||||
.child(Label::new(action_link.title.clone()))
|
||||
.when_some(
|
||||
action_link.description.as_ref(),
|
||||
|this, description| {
|
||||
this.child(
|
||||
Label::new(description.clone())
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Muted),
|
||||
)
|
||||
},
|
||||
),
|
||||
)
|
||||
.child(
|
||||
Button::new(
|
||||
("action-link".into(), action_link.title.clone()),
|
||||
action_link.button_text.clone(),
|
||||
)
|
||||
.icon(IconName::ArrowUpRight)
|
||||
.tab_index(0_isize)
|
||||
.icon_position(IconPosition::End)
|
||||
.icon_color(Color::Muted)
|
||||
.icon_size(IconSize::Small)
|
||||
.style(ButtonStyle::OutlinedGhost)
|
||||
.size(ButtonSize::Medium)
|
||||
.on_click({
|
||||
let on_click = action_link.on_click.clone();
|
||||
cx.listener(move |this, _, window, cx| {
|
||||
on_click(this, window, cx);
|
||||
})
|
||||
}),
|
||||
),
|
||||
)
|
||||
.when(!is_last, |this| this.child(Divider::horizontal()))
|
||||
.into_any_element(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1207,6 +1260,20 @@ impl PartialEq for SubPageLink {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct ActionLink {
|
||||
title: SharedString,
|
||||
description: Option<SharedString>,
|
||||
button_text: SharedString,
|
||||
on_click: Arc<dyn Fn(&mut SettingsWindow, &mut Window, &mut App) + Send + Sync>,
|
||||
}
|
||||
|
||||
impl PartialEq for ActionLink {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.title == other.title
|
||||
}
|
||||
}
|
||||
|
||||
fn all_language_names(cx: &App) -> Vec<SharedString> {
|
||||
workspace::AppState::global(cx)
|
||||
.upgrade()
|
||||
@@ -1626,6 +1693,9 @@ impl SettingsWindow {
|
||||
any_found_since_last_header = true;
|
||||
}
|
||||
}
|
||||
SettingsPageItem::ActionLink(_) => {
|
||||
any_found_since_last_header = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(last_header) = page_filter.get_mut(header_index)
|
||||
@@ -1864,6 +1934,18 @@ impl SettingsWindow {
|
||||
sub_page_link.title.as_ref(),
|
||||
);
|
||||
}
|
||||
SettingsPageItem::ActionLink(action_link) => {
|
||||
documents.push(bm25::Document {
|
||||
id: key_index,
|
||||
contents: [page.title, header_str, action_link.title.as_ref()]
|
||||
.join("\n"),
|
||||
});
|
||||
push_candidates(
|
||||
&mut fuzzy_match_candidates,
|
||||
key_index,
|
||||
action_link.title.as_ref(),
|
||||
);
|
||||
}
|
||||
}
|
||||
push_candidates(&mut fuzzy_match_candidates, key_index, page.title);
|
||||
push_candidates(&mut fuzzy_match_candidates, key_index, header_str);
|
||||
|
||||
Reference in new issue
Block a user