diff --git a/assets/keymaps/default.json b/assets/keymaps/default.json index 218ddc2dfe..a4ddab01fa 100644 --- a/assets/keymaps/default.json +++ b/assets/keymaps/default.json @@ -18,7 +18,8 @@ "cmd-s": "workspace::Save", "cmd-=": "zed::IncreaseBufferFontSize", "cmd--": "zed::DecreaseBufferFontSize", - "cmd-,": "zed::OpenSettings" + "cmd-,": "zed::OpenSettings", + "cmd-q": "zed::Quit" } }, { diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 826592daa0..9cd6267468 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -154,7 +154,6 @@ pub struct Menu<'a> { pub enum MenuItem<'a> { Action { name: &'a str, - keystroke: Option<&'a str>, action: Box, }, Separator, @@ -1070,7 +1069,8 @@ impl MutableAppContext { } pub fn set_menus(&mut self, menus: Vec) { - self.foreground_platform.set_menus(menus); + self.foreground_platform + .set_menus(menus, &self.keystroke_matcher); } fn prompt( diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index d851e195be..8b81302554 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -14,6 +14,7 @@ use crate::{ rect::{RectF, RectI}, vector::Vector2F, }, + keymap, text_layout::{LineLayout, RunStyle}, Action, ClipboardItem, Menu, Scene, }; @@ -72,7 +73,7 @@ pub(crate) trait ForegroundPlatform { fn run(&self, on_finish_launching: Box ()>); fn on_menu_command(&self, callback: Box); - fn set_menus(&self, menus: Vec); + fn set_menus(&self, menus: Vec, matcher: &keymap::Matcher); fn prompt_for_paths( &self, options: PathPromptOptions, diff --git a/crates/gpui/src/platform/mac/platform.rs b/crates/gpui/src/platform/mac/platform.rs index fc1b7e59d8..89b3389bbe 100644 --- a/crates/gpui/src/platform/mac/platform.rs +++ b/crates/gpui/src/platform/mac/platform.rs @@ -1,7 +1,6 @@ use super::{BoolExt as _, Dispatcher, FontSystem, Window}; use crate::{ - executor, - keymap::Keystroke, + executor, keymap, platform::{self, CursorStyle}, Action, ClipboardItem, Event, Menu, MenuItem, }; @@ -114,7 +113,7 @@ pub struct MacForegroundPlatformState { } impl MacForegroundPlatform { - unsafe fn create_menu_bar(&self, menus: Vec) -> id { + unsafe fn create_menu_bar(&self, menus: Vec, keystroke_matcher: &keymap::Matcher) -> id { let menu_bar = NSMenu::new(nil).autorelease(); let mut state = self.0.borrow_mut(); @@ -134,19 +133,18 @@ impl MacForegroundPlatform { MenuItem::Separator => { item = NSMenuItem::separatorItem(nil); } - MenuItem::Action { - name, - keystroke, - action, - } => { - if let Some(keystroke) = keystroke { - let keystroke = Keystroke::parse(keystroke).unwrap_or_else(|err| { - panic!( - "Invalid keystroke for menu item {}:{} - {:?}", - menu_name, name, err - ) - }); + MenuItem::Action { name, action } => { + let mut keystroke = None; + if let Some(binding) = keystroke_matcher + .bindings_for_action_type(action.as_any().type_id()) + .next() + { + if binding.keystrokes().len() == 1 { + keystroke = binding.keystrokes().first() + } + } + if let Some(keystroke) = keystroke { let mut mask = NSEventModifierFlags::empty(); for (modifier, flag) in &[ (keystroke.cmd, NSEventModifierFlags::NSCommandKeyMask), @@ -239,10 +237,10 @@ impl platform::ForegroundPlatform for MacForegroundPlatform { self.0.borrow_mut().menu_command = Some(callback); } - fn set_menus(&self, menus: Vec) { + fn set_menus(&self, menus: Vec, keystroke_matcher: &keymap::Matcher) { unsafe { let app: id = msg_send![APP_CLASS, sharedApplication]; - app.setMainMenu_(self.create_menu_bar(menus)); + app.setMainMenu_(self.create_menu_bar(menus, keystroke_matcher)); } } diff --git a/crates/gpui/src/platform/test.rs b/crates/gpui/src/platform/test.rs index 8786eff255..7c808d0fbb 100644 --- a/crates/gpui/src/platform/test.rs +++ b/crates/gpui/src/platform/test.rs @@ -1,7 +1,7 @@ use super::{AppVersion, CursorStyle, WindowBounds}; use crate::{ geometry::vector::{vec2f, Vector2F}, - Action, ClipboardItem, + keymap, Action, ClipboardItem, }; use anyhow::{anyhow, Result}; use parking_lot::Mutex; @@ -74,7 +74,7 @@ impl super::ForegroundPlatform for ForegroundPlatform { fn on_menu_command(&self, _: Box) {} - fn set_menus(&self, _: Vec) {} + fn set_menus(&self, _: Vec, _: &keymap::Matcher) {} fn prompt_for_paths( &self, diff --git a/crates/zed/src/menus.rs b/crates/zed/src/menus.rs index 3f19dcbdac..b80f726680 100644 --- a/crates/zed/src/menus.rs +++ b/crates/zed/src/menus.rs @@ -10,24 +10,20 @@ pub fn menus(state: &Arc) -> Vec> { items: vec![ MenuItem::Action { name: "About Zed…", - keystroke: None, action: Box::new(super::About), }, MenuItem::Action { name: "Check for Updates", - keystroke: None, action: Box::new(auto_update::Check), }, MenuItem::Separator, MenuItem::Action { name: "Install CLI", - keystroke: None, action: Box::new(super::InstallCommandLineInterface), }, MenuItem::Separator, MenuItem::Action { name: "Quit", - keystroke: Some("cmd-q"), action: Box::new(super::Quit), }, ], @@ -37,13 +33,11 @@ pub fn menus(state: &Arc) -> Vec> { items: vec![ MenuItem::Action { name: "New", - keystroke: Some("cmd-n"), action: Box::new(workspace::OpenNew(state.clone())), }, MenuItem::Separator, MenuItem::Action { name: "Open…", - keystroke: Some("cmd-o"), action: Box::new(workspace::Open(state.clone())), }, ], @@ -53,28 +47,23 @@ pub fn menus(state: &Arc) -> Vec> { items: vec![ MenuItem::Action { name: "Undo", - keystroke: Some("cmd-z"), action: Box::new(editor::Undo), }, MenuItem::Action { name: "Redo", - keystroke: Some("cmd-Z"), action: Box::new(editor::Redo), }, MenuItem::Separator, MenuItem::Action { name: "Cut", - keystroke: Some("cmd-x"), action: Box::new(editor::Cut), }, MenuItem::Action { name: "Copy", - keystroke: Some("cmd-c"), action: Box::new(editor::Copy), }, MenuItem::Action { name: "Paste", - keystroke: Some("cmd-v"), action: Box::new(editor::Paste), }, ],