Derive application menu key equivalents from the keymap

This commit is contained in:
Max Brunsfeld 2022-05-19 10:04:01 -07:00
parent 8dd6ad3116
commit 7445197f4d
6 changed files with 23 additions and 34 deletions

View File

@ -18,7 +18,8 @@
"cmd-s": "workspace::Save",
"cmd-=": "zed::IncreaseBufferFontSize",
"cmd--": "zed::DecreaseBufferFontSize",
"cmd-,": "zed::OpenSettings"
"cmd-,": "zed::OpenSettings",
"cmd-q": "zed::Quit"
}
},
{

View File

@ -154,7 +154,6 @@ pub struct Menu<'a> {
pub enum MenuItem<'a> {
Action {
name: &'a str,
keystroke: Option<&'a str>,
action: Box<dyn Action>,
},
Separator,
@ -1070,7 +1069,8 @@ impl MutableAppContext {
}
pub fn set_menus(&mut self, menus: Vec<Menu>) {
self.foreground_platform.set_menus(menus);
self.foreground_platform
.set_menus(menus, &self.keystroke_matcher);
}
fn prompt(

View File

@ -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<dyn FnOnce() -> ()>);
fn on_menu_command(&self, callback: Box<dyn FnMut(&dyn Action)>);
fn set_menus(&self, menus: Vec<Menu>);
fn set_menus(&self, menus: Vec<Menu>, matcher: &keymap::Matcher);
fn prompt_for_paths(
&self,
options: PathPromptOptions,

View File

@ -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<Menu>) -> id {
unsafe fn create_menu_bar(&self, menus: Vec<Menu>, 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<Menu>) {
fn set_menus(&self, menus: Vec<Menu>, 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));
}
}

View File

@ -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<dyn FnMut(&dyn Action)>) {}
fn set_menus(&self, _: Vec<crate::Menu>) {}
fn set_menus(&self, _: Vec<crate::Menu>, _: &keymap::Matcher) {}
fn prompt_for_paths(
&self,

View File

@ -10,24 +10,20 @@ pub fn menus(state: &Arc<AppState>) -> Vec<Menu<'static>> {
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<AppState>) -> Vec<Menu<'static>> {
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<AppState>) -> Vec<Menu<'static>> {
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),
},
],