From 8a8f2804012874a5fae2f75b8e3847595a9bff6d Mon Sep 17 00:00:00 2001 From: TomZz Date: Wed, 17 Jun 2026 02:40:24 +0800 Subject: [PATCH] feat: group keybindings and set keybindings page as default in settings --- locales/en.yml | 4 + locales/zh-CN.yml | 4 + src/app/dialogs.rs | 12 ++- src/app/keybinding_recorder.rs | 157 +++++++++++++++++++++------------ 4 files changed, 115 insertions(+), 62 deletions(-) diff --git a/locales/en.yml b/locales/en.yml index 1a43dcd..080b32c 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -124,6 +124,10 @@ settings_about: "About" settings_group_appearance: "Appearance" settings_group_font: "Font" settings_group_other: "Other" +settings_group_keybind_general: "General" +settings_group_keybind_zoom: "Zoom" +settings_group_keybind_focus: "Focus" +settings_group_keybind_panel: "Panel" theme: "Theme" theme_mode: "Theme Mode" clear_transfers: "Clear History" diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml index cc6c060..03a378a 100644 --- a/locales/zh-CN.yml +++ b/locales/zh-CN.yml @@ -127,6 +127,10 @@ settings_about: "关于" settings_group_appearance: "外观" settings_group_font: "字体" settings_group_other: "其它" +settings_group_keybind_general: "常规" +settings_group_keybind_zoom: "缩放" +settings_group_keybind_focus: "焦点" +settings_group_keybind_panel: "面板" theme: "主题" theme_mode: "主题模式" clear_transfers: "清空记录" diff --git a/src/app/dialogs.rs b/src/app/dialogs.rs index 3c6250a..bd866ed 100644 --- a/src/app/dialogs.rs +++ b/src/app/dialogs.rs @@ -1541,11 +1541,15 @@ impl Ashell { ) ) ) - .page( - SettingPage::new(t!("settings_key_bindings").to_string()) + .page({ + let mut page = SettingPage::new(t!("settings_key_bindings").to_string()) .icon(IconName::SquareTerminal) - .group(crate::app::keybinding_recorder::KeybindingsPage::render(&view, cx)) - ) + .default_open(true); + for group in crate::app::keybinding_recorder::KeybindingsPage::render_groups(&view, cx) { + page = page.group(group); + } + page + }) .page( SettingPage::new(t!("settings_help").to_string()) .icon(IconName::BookOpen) diff --git a/src/app/keybinding_recorder.rs b/src/app/keybinding_recorder.rs index 8269404..664d462 100644 --- a/src/app/keybinding_recorder.rs +++ b/src/app/keybinding_recorder.rs @@ -269,74 +269,115 @@ fn bind_workspace_actions(cx: &mut App, config: &ConfigStore) { } impl KeybindingsPage { - pub fn render(view: &Entity, cx: &mut App) -> SettingGroup { - let mut group = SettingGroup::new(); + pub fn render_groups(view: &Entity, cx: &mut App) -> Vec { + let groups = [ + ( + "settings_group_keybind_general", + vec!["OpenSettings", "OpenSession", "NewSsh"], + ), + ( + "settings_group_keybind_zoom", + vec!["ToggleSidebar", "ToggleSftpZoom"], + ), + ( + "settings_group_keybind_focus", + vec![ + "FocusPaneLeft", + "FocusPaneRight", + "FocusPaneUp", + "FocusPaneDown", + ], + ), + ( + "settings_group_keybind_panel", + vec![ + "SplitPaneLeft", + "SplitPaneRight", + "SplitPaneUp", + "SplitPaneDown", + "ClosePane", + ], + ), + ]; - for action in WORKSPACE_ACTIONS { - let recording = view.read(cx).recording_action.as_deref() == Some(action.id); - let has_error = view - .read(cx) - .keybind_error - .as_ref() - .is_some_and(|(id, _)| id == action.id); - let error_msg = if has_error { - view.read(cx) + let mut result = Vec::new(); + + for (group_label, action_ids) in groups { + let mut group = SettingGroup::new().title(t!(group_label).to_string()); + + for action_id in action_ids { + let action = WORKSPACE_ACTIONS + .iter() + .find(|a| a.id == action_id) + .expect("action exists"); + + let recording = view.read(cx).recording_action.as_deref() == Some(action.id); + let has_error = view + .read(cx) .keybind_error .as_ref() - .map(|(_, msg)| msg.clone()) - } else { - None - }; + .is_some_and(|(id, _)| id == action.id); + let error_msg = if has_error { + view.read(cx) + .keybind_error + .as_ref() + .map(|(_, msg)| msg.clone()) + } else { + None + }; - let keystroke = { - let config = &view.read(cx).config; - configured_keystroke(config, action.id).unwrap_or_default() - }; + let keystroke = { + let config = &view.read(cx).config; + configured_keystroke(config, action.id).unwrap_or_default() + }; - let btn_label = if recording { - t!("press_new_key").to_string() - } else if keystroke.is_empty() { - t!("none").to_string() - } else { - format_keystroke(&keystroke) - }; + let btn_label = if recording { + t!("press_new_key").to_string() + } else if keystroke.is_empty() { + t!("none").to_string() + } else { + format_keystroke(&keystroke) + }; - let mut item = SettingItem::new( - t!(action.label_key).to_string(), - SettingField::render({ - let view = view.clone(); - let action_id = action.id.to_string(); - move |_, _window, _cx| { - Button::new(gpui::SharedString::from(format!("keybind-{action_id}"))) - .label(btn_label.clone()) - .small() - .when(recording, |this| this.primary()) - .when(has_error, |this| this.danger()) - .on_click({ - let view = view.clone(); - let action_id = action_id.clone(); - move |_event, window, cx| { - view.update(cx, |this, cx| { - // Clear any previous error when starting new recording - this.keybind_error = None; - this.recording_action = Some(action_id.clone()); - this.focus_handle.focus(window, cx); - cx.notify(); - }); - } - }) - .into_any_element() - } - }), - ); + let mut item = SettingItem::new( + t!(action.label_key).to_string(), + SettingField::render({ + let view = view.clone(); + let action_id = action.id.to_string(); + move |_, _window, _cx| { + Button::new(gpui::SharedString::from(format!("keybind-{action_id}"))) + .label(btn_label.clone()) + .small() + .when(recording, |this| this.primary()) + .when(has_error, |this| this.danger()) + .on_click({ + let view = view.clone(); + let action_id = action_id.clone(); + move |_event, window, cx| { + view.update(cx, |this, cx| { + // Clear any previous error when starting new recording + this.keybind_error = None; + this.recording_action = Some(action_id.clone()); + this.focus_handle.focus(window, cx); + cx.notify(); + }); + } + }) + .into_any_element() + } + }), + ); - if let Some(msg) = error_msg { - item = item.description(msg); + if let Some(msg) = error_msg { + item = item.description(msg); + } + + group = group.item(item); } - group = group.item(item); + result.push(group); } - group + result } }