Add character palette menu item

Antonio Scandurra created

Change summary

assets/keymaps/default.json            |  3 ++-
crates/editor/src/editor.rs            |  6 ++++++
crates/gpui/src/app.rs                 |  9 +++++++++
crates/gpui/src/platform.rs            |  1 +
crates/gpui/src/platform/mac/event.rs  | 18 ++++++++++--------
crates/gpui/src/platform/mac/window.rs |  9 +++++++++
crates/gpui/src/platform/test.rs       |  2 ++
crates/zed/src/menus.rs                |  4 ++++
8 files changed, 43 insertions(+), 9 deletions(-)

Detailed changes

assets/keymaps/default.json 🔗

@@ -113,7 +113,8 @@
                 }
             ],
             "pageup": "editor::PageUp",
-            "pagedown": "editor::PageDown"
+            "pagedown": "editor::PageDown",
+            "ctrl-cmd-space": "editor::ShowCharacterPalette"
         }
     },
     {

crates/editor/src/editor.rs 🔗

@@ -189,6 +189,7 @@ actions!(
         Tab,
         TabPrev,
         ToggleComments,
+        ShowCharacterPalette,
         SelectLargerSyntaxNode,
         SelectSmallerSyntaxNode,
         GoToDefinition,
@@ -313,6 +314,7 @@ pub fn init(cx: &mut MutableAppContext) {
     cx.add_action(Editor::open_excerpts);
     cx.add_action(Editor::jump);
     cx.add_action(Editor::restart_language_server);
+    cx.add_action(Editor::show_character_palette);
     cx.add_async_action(Editor::confirm_completion);
     cx.add_async_action(Editor::confirm_code_action);
     cx.add_async_action(Editor::rename);
@@ -5014,6 +5016,10 @@ impl Editor {
         }
     }
 
+    fn show_character_palette(&mut self, _: &ShowCharacterPalette, cx: &mut ViewContext<Self>) {
+        cx.show_character_palette();
+    }
+
     fn refresh_active_diagnostics(&mut self, cx: &mut ViewContext<Editor>) {
         if let Some(active_diagnostics) = self.active_diagnostics.as_mut() {
             let buffer = self.buffer.read(cx).snapshot(cx);

crates/gpui/src/app.rs 🔗

@@ -1195,6 +1195,11 @@ impl MutableAppContext {
             .set_menus(menus, &self.keystroke_matcher);
     }
 
+    fn show_character_palette(&self, window_id: usize) {
+        let (_, window) = &self.presenters_and_platform_windows[&window_id];
+        window.show_character_palette();
+    }
+
     fn prompt(
         &self,
         window_id: usize,
@@ -3489,6 +3494,10 @@ impl<'a, T: View> ViewContext<'a, T> {
         self.app.platform()
     }
 
+    pub fn show_character_palette(&self) {
+        self.app.show_character_palette(self.window_id);
+    }
+
     pub fn prompt(
         &self,
         level: PromptLevel,

crates/gpui/src/platform.rs 🔗

@@ -99,6 +99,7 @@ pub trait Window: WindowContext {
     fn activate(&self);
     fn set_title(&mut self, title: &str);
     fn set_edited(&mut self, edited: bool);
+    fn show_character_palette(&self);
 }
 
 pub trait WindowContext {

crates/gpui/src/platform/mac/event.rs 🔗

@@ -12,10 +12,19 @@ use cocoa::{
 };
 use std::{borrow::Cow, ffi::CStr, os::raw::c_char};
 
+const BACKSPACE_KEY: u16 = 0x7f;
+const SPACE_KEY: u16 = b' ' as u16;
+const ENTER_KEY: u16 = 0x0d;
+const NUMPAD_ENTER_KEY: u16 = 0x03;
+const ESCAPE_KEY: u16 = 0x1b;
+const TAB_KEY: u16 = 0x09;
+const SHIFT_TAB_KEY: u16 = 0x19;
+
 pub fn key_to_native(key: &str) -> Cow<str> {
     use cocoa::appkit::*;
     let code = match key {
-        "backspace" => 0x7F,
+        "space" => SPACE_KEY,
+        "backspace" => BACKSPACE_KEY,
         "up" => NSUpArrowFunctionKey,
         "down" => NSDownArrowFunctionKey,
         "left" => NSLeftArrowFunctionKey,
@@ -243,13 +252,6 @@ unsafe fn get_key_text(
     let mut input = None;
     let first_char = unmodified_chars.chars().next()?;
     use cocoa::appkit::*;
-    const BACKSPACE_KEY: u16 = 0x7f;
-    const ENTER_KEY: u16 = 0x0d;
-    const NUMPAD_ENTER_KEY: u16 = 0x03;
-    const ESCAPE_KEY: u16 = 0x1b;
-    const TAB_KEY: u16 = 0x09;
-    const SHIFT_TAB_KEY: u16 = 0x19;
-    const SPACE_KEY: u16 = b' ' as u16;
 
     #[allow(non_upper_case_globals)]
     let unmodified_chars = match first_char as u16 {

crates/gpui/src/platform/mac/window.rs 🔗

@@ -1,3 +1,4 @@
+use super::{geometry::RectFExt, renderer::Renderer};
 use crate::{
     executor,
     geometry::{
@@ -448,6 +449,14 @@ impl platform::Window for Window {
         // so we have to move it again.
         self.0.borrow().move_traffic_light();
     }
+
+    fn show_character_palette(&self) {
+        unsafe {
+            let app = NSApplication::sharedApplication(nil);
+            let window = self.0.borrow().native_window;
+            let _: () = msg_send![app, orderFrontCharacterPalette: window];
+        }
+    }
 }
 
 impl platform::WindowContext for Window {

crates/gpui/src/platform/test.rs 🔗

@@ -274,6 +274,8 @@ impl super::Window for Window {
     fn on_should_close(&mut self, callback: Box<dyn FnMut() -> bool>) {
         self.should_close_handler = Some(callback);
     }
+
+    fn show_character_palette(&self) {}
 }
 
 pub fn platform() -> Platform {

crates/zed/src/menus.rs 🔗

@@ -131,6 +131,10 @@ pub fn menus() -> Vec<Menu<'static>> {
                     name: "Toggle Line Comment",
                     action: Box::new(editor::ToggleComments),
                 },
+                MenuItem::Action {
+                    name: "Emoji & Symbols",
+                    action: Box::new(editor::ShowCharacterPalette),
+                },
             ],
         },
         Menu {