]> git.eshelyaron.com Git - emacs.git/commitdiff
Use standard key symbols in NS menu entries
authorMattias Engdegård <mattiase@acm.org>
Wed, 30 Dec 2020 12:06:47 +0000 (13:06 +0100)
committerMattias Engdegård <mattiase@acm.org>
Wed, 30 Dec 2020 12:50:49 +0000 (13:50 +0100)
* src/nsmenu.m (skipspc): Remove.
(key_symbols, prettify_key): New.
([EmacsMenu fillWithWidgetValue:]): Call prettify_key.

src/nsmenu.m

index a356cffbea3b00c4640aceb4e27a869c75211b99..12506b9eb666479d8160617663a528d141c68c6c 100644 (file)
@@ -457,14 +457,6 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
 }
 
 
-static const char *
-skipspc (const char *s)
-{
-  while (*s == ' ')
-    s++;
-  return s;
-}
-
 - (NSMenuItem *)addItemWithWidgetValue: (void *)wvptr
                             attributes: (NSDictionary *)attributes
 {
@@ -484,7 +476,7 @@ skipspc (const char *s)
       item = [[[NSMenuItem alloc] init] autorelease];
       if (wv->key)
         {
-          NSString *key = [NSString stringWithUTF8String: skipspc (wv->key)];
+          NSString *key = [NSString stringWithUTF8String: wv->key];
 #ifdef NS_IMPL_COCOA
           /* Cocoa only permits a single key (with modifiers) as
              keyEquivalent, so we put them in the title string
@@ -536,6 +528,63 @@ skipspc (const char *s)
 }
 
 
+typedef struct {
+  const char *from, *to;
+} subst_t;
+
+/* Standard keyboard symbols used in menus. */
+static const subst_t key_symbols[] = {
+  {"<backspace>",  "⌫"},
+  {"DEL",          "⌫"},
+  {"<deletechar>", "⌦"},
+  {"<return>",     "↩"},
+  {"RET",          "↩"},
+  {"<left>",       "←"},
+  {"<right>",      "→"},
+  {"<up>",         "↑"},
+  {"<down>",       "↓"},
+  {"<prior>",      "⇞"},
+  {"<next>",       "⇟"},
+  {"<home>",       "↖"},
+  {"<end>",        "↘"},
+  {"<tab>",        "⇥"},
+  {"TAB",          "⇥"},
+  {"<backtab>",    "⇤"},
+};
+
+/* Transform the key sequence KEY into something prettier by
+   substituting keyboard symbols. */
+static char *
+prettify_key (const char *key)
+{
+  while (*key == ' ') key++;
+
+  int len = strlen (key);
+  char *buf = xmalloc (len + 1);
+  memcpy (buf, key, len + 1);
+  for (int i = 0; i < ARRAYELTS (key_symbols); i++)
+    {
+      ptrdiff_t fromlen = strlen (key_symbols[i].from);
+      char *p = buf;
+      while (p < buf + len)
+        {
+          char *match = memmem (buf, len, key_symbols[i].from, fromlen);
+          if (!match)
+            break;
+          ptrdiff_t tolen = strlen (key_symbols[i].to);
+          eassert (tolen <= fromlen);
+          memcpy (match, key_symbols[i].to, tolen);
+          memmove (match + tolen, match + fromlen,
+                   len - (match + fromlen - buf) + 1);
+          len -= fromlen - tolen;
+          p = match + tolen;
+        }
+    }
+  Lisp_Object result = build_string (buf);
+  xfree (buf);
+  return SSDATA (result);
+}
+
 - (void)fillWithWidgetValue: (void *)wvptr
 {
   widget_value *first_wv = (widget_value *)wvptr;
@@ -559,7 +608,8 @@ skipspc (const char *s)
         maxNameWidth = MAX(maxNameWidth, nameSize.width);
         if (wv->key)
           {
-            NSString *key = [NSString stringWithUTF8String: skipspc (wv->key)];
+            wv->key = prettify_key (wv->key);
+            NSString *key = [NSString stringWithUTF8String: wv->key];
             NSSize keySize = [key sizeWithAttributes: font_attribs];
             maxKeyWidth = MAX(maxKeyWidth, keySize.width);
           }