unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Stefan Kangas <stefan@marxist.se>
To: Lars Ingebrigtsen <larsi@gnus.org>
Cc: Shuguang Sun <shuguang79@qq.com>, 50752@debbugs.gnu.org
Subject: bug#50752: 28.0.50; easy-menu-define lowers the menu-bar key
Date: Tue, 12 Oct 2021 15:22:59 -0700	[thread overview]
Message-ID: <CADwFkmmFnixKo6xeuV0mpQ4a+nXnYEXuq-8pcr7=AFTP0rRMKw@mail.gmail.com> (raw)
In-Reply-To: <87bl4jvudm.fsf@gnus.org> (Lars Ingebrigtsen's message of "Thu, 23 Sep 2021 23:45:25 +0200")

[-- Attachment #1: Type: text/plain, Size: 1100 bytes --]

tags 50752 + patch
thanks

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Yes, the names have changed in Emacs 28, so external packages that alter
> the menus like this have to be adjusted.  But I wonder whether we could
> make `lookup-key' be case-insensitive in this case...

As Glenn points out, we discussed this here:
https://lists.gnu.org/r/emacs-devel/2021-03/msg00031.html

We also discussed it here:
https://lists.gnu.org/r/emacs-devel/2021-03/msg00014.html

I had an incomplete patch in the works, but I dropped the ball here.

Please find attached an updated and complete patch that should fix the
above issue.  In addition to the new tests, I have tested it locally,
and without the patch, I can reproduce the issue reported here by
Shuguang, i.e. I get this error:

    popup-menu: Empty menu

With the patch, the menu is correctly displayed, as is expected.  This
is tested with pdf-tools-20211004.514 installed from MELPA, which should
be equivalent to the latest version in the git repository at:

    http://github.com/vedang/pdf-tools

Review and additional testing is very welcome.

[-- Attachment #2: 0001-Be-more-allowing-when-looking-for-menu-bar-items.patch --]
[-- Type: text/x-diff, Size: 6222 bytes --]

From 0ee56b91506b445161bf2e839f4caa5ed78972bf Mon Sep 17 00:00:00 2001
From: Stefan Kangas <stefan@marxist.se>
Date: Wed, 13 Oct 2021 00:04:23 +0200
Subject: [PATCH] Be more allowing when looking for menu-bar items

* src/keymap.c (lookup_key_1): Factor out function from
Flookup_key.
(Flookup_key): Be case insensitive, and treat spaces as dashes,
when looking for Qmenu_bar items.  (Bug#50752)
* test/src/keymap-tests.el (keymap-lookup-key/mixed-case)
(subr-test-lookup-keymap/with-spaces): New tests.
---
 src/keymap.c             | 110 +++++++++++++++++++++++++++++++--------
 test/src/keymap-tests.el |  11 ++++
 2 files changed, 100 insertions(+), 21 deletions(-)

diff --git a/src/keymap.c b/src/keymap.c
index be45d2be1e..2fb5d8f41e 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -1180,27 +1180,8 @@ DEFUN ("command-remapping", Fcommand_remapping, Scommand_remapping, 1, 3, 0,
   return FIXNUMP (command) ? Qnil : command;
 }
 
-/* Value is number if KEY is too long; nil if valid but has no definition.  */
-/* GC is possible in this function.  */
-
-DEFUN ("lookup-key", Flookup_key, Slookup_key, 2, 3, 0,
-       doc: /* Look up key sequence KEY in KEYMAP.  Return the definition.
-A value of nil means undefined.  See doc of `define-key'
-for kinds of definitions.
-
-A number as value means KEY is "too long";
-that is, characters or symbols in it except for the last one
-fail to be a valid sequence of prefix characters in KEYMAP.
-The number is how many characters at the front of KEY
-it takes to reach a non-prefix key.
-KEYMAP can also be a list of keymaps.
-
-Normally, `lookup-key' ignores bindings for t, which act as default
-bindings, used when nothing else in the keymap applies; this makes it
-usable as a general function for probing keymaps.  However, if the
-third optional argument ACCEPT-DEFAULT is non-nil, `lookup-key' will
-recognize the default bindings, just as `read-key-sequence' does.  */)
-  (Lisp_Object keymap, Lisp_Object key, Lisp_Object accept_default)
+static Lisp_Object
+lookup_key_1 (Lisp_Object keymap, Lisp_Object key, Lisp_Object accept_default)
 {
   bool t_ok = !NILP (accept_default);
 
@@ -1240,6 +1221,93 @@ DEFUN ("lookup-key", Flookup_key, Slookup_key, 2, 3, 0,
     }
 }
 
+/* Value is number if KEY is too long; nil if valid but has no definition.  */
+/* GC is possible in this function.  */
+
+DEFUN ("lookup-key", Flookup_key, Slookup_key, 2, 3, 0,
+       doc: /* Look up key sequence KEY in KEYMAP.  Return the definition.
+A value of nil means undefined.  See doc of `define-key'
+for kinds of definitions.
+
+A number as value means KEY is "too long";
+that is, characters or symbols in it except for the last one
+fail to be a valid sequence of prefix characters in KEYMAP.
+The number is how many characters at the front of KEY
+it takes to reach a non-prefix key.
+KEYMAP can also be a list of keymaps.
+
+Normally, `lookup-key' ignores bindings for t, which act as default
+bindings, used when nothing else in the keymap applies; this makes it
+usable as a general function for probing keymaps.  However, if the
+third optional argument ACCEPT-DEFAULT is non-nil, `lookup-key' will
+recognize the default bindings, just as `read-key-sequence' does.  */)
+  (Lisp_Object keymap, Lisp_Object key, Lisp_Object accept_default)
+{
+  Lisp_Object found = lookup_key_1 (keymap, key, accept_default);
+
+  if (!NILP (found) && !NUMBERP (found))
+    goto end;
+
+  /* Menu definitions might use mixed case symbols (notably in old
+     versions of `easy-menu-define'), or use " " instead of "-".  */
+  if (VECTORP (key) && EQ (AREF (key, 0), Qmenu_bar))
+    {
+      ptrdiff_t key_len = ASIZE (key);
+      Lisp_Object new_key = make_vector (key_len, Qnil);
+
+      /* First, let's try converting all symbols like "Foo-Bar-Baz" to
+	 "foo-bar-baz".  */
+      for (int i = 0; i < key_len; i++)
+	{
+	  Lisp_Object lc_key = Fdowncase (Fsymbol_name (AREF (key, i)));
+	  ASET (new_key, i, Fintern (lc_key, Qnil));
+	}
+      found = lookup_key_1 (keymap, new_key, accept_default);
+
+      if (!NILP (found) && !NUMBERP (found))
+	goto end;
+
+      /* If we still don't have a match, let's convert any spaces in
+	 our lowercased string into dashes, e.g. "foo bar baz" to
+	 "foo-bar-baz". */
+      for (int i = 0; i < key_len; i++)
+	{
+	  Lisp_Object lc_key = Fdowncase (Fsymbol_name (AREF (key, i)));
+
+	  USE_SAFE_ALLOCA;
+	  ptrdiff_t size = SCHARS (lc_key), n;
+	  if (INT_MULTIPLY_WRAPV (size, MAX_MULTIBYTE_LENGTH, &n))
+	    n = PTRDIFF_MAX;
+	  unsigned char *dst = SAFE_ALLOCA (n);
+	  unsigned char *o = dst;
+	  ptrdiff_t j = 0, j_byte = 0, chars = 0;
+
+	  while (j < SCHARS (lc_key))
+	    {
+	      int ch = fetch_string_char_advance (lc_key, &j, &j_byte);
+	      if (ch == ' ')
+		*o = '-';
+	      else
+		*o = ch;
+	      chars++;
+
+	      int len;
+	      string_char_and_length (o, &len);
+	      o += len;
+	    }
+	  eassert (o <= dst + n);
+	  Lisp_Object
+	    new_it = make_multibyte_string ((char *) dst, chars, o - dst);
+	  ASET (new_key, i, Fintern (new_it, Qnil));
+	  SAFE_FREE ();
+	}
+      found = lookup_key_1 (keymap, new_key, accept_default);
+    }
+
+ end:
+  return found;
+}
+
 /* Make KEYMAP define event C as a keymap (i.e., as a prefix).
    Assume that currently it does not define C at all.
    Return the keymap.  */
diff --git a/test/src/keymap-tests.el b/test/src/keymap-tests.el
index 68b42c346c..8f3dff2acb 100644
--- a/test/src/keymap-tests.el
+++ b/test/src/keymap-tests.el
@@ -124,6 +124,17 @@ keymap-lookup-key/too-long
 ;; (ert-deftest keymap-lookup-key/accept-default ()
 ;;   ...)
 
+(ert-deftest keymap-lookup-key/mixed-case ()
+  (let ((map (make-keymap)))
+    (define-key map [menu-bar foo bar] 'foo)
+    (should (eq (lookup-key map [menu-bar foo bar]) 'foo))
+    (should (eq (lookup-key map [menu-bar Foo Bar]) 'foo))))
+
+(ert-deftest subr-test-lookup-keymap/with-spaces ()
+  (let ((map (make-keymap)))
+    (define-key map [menu-bar foo-bar] 'foo)
+    (should (eq (lookup-key map [menu-bar Foo\ Bar]) 'foo))))
+
 (ert-deftest describe-buffer-bindings/header-in-current-buffer ()
   "Header should be inserted into the current buffer.
 https://debbugs.gnu.org/39149#31"
-- 
2.30.2


  reply	other threads:[~2021-10-12 22:22 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-23  8:39 bug#50752: 28.0.50; easy-menu-define lowers the menu-bar key Shuguang Sun via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-09-23 17:15 ` Juri Linkov
2021-09-23 21:45 ` Lars Ingebrigtsen
2021-10-12 22:22   ` Stefan Kangas [this message]
2021-10-13 11:28     ` Lars Ingebrigtsen
2021-10-13 11:59     ` Eli Zaretskii
2021-10-13 12:04       ` Lars Ingebrigtsen
2021-10-13 12:19         ` Stefan Kangas
2021-10-13 12:58           ` Lars Ingebrigtsen
2021-10-13 15:26             ` Stefan Kangas
2021-10-13 15:42               ` Lars Ingebrigtsen
2021-10-19  3:22                 ` Stefan Kangas
2021-10-19  3:40                   ` Lars Ingebrigtsen
2021-10-19  3:52                     ` Lars Ingebrigtsen
2021-10-19 11:56                       ` Eli Zaretskii
2021-10-19 12:07                         ` Lars Ingebrigtsen
2021-10-19 12:17                           ` Lars Ingebrigtsen
2021-10-19 12:37                           ` Eli Zaretskii
2021-10-19 12:45                             ` Lars Ingebrigtsen
2021-10-19 13:24                               ` Lars Ingebrigtsen
2021-10-19 16:01                                 ` Eli Zaretskii
2021-10-19 15:41                               ` Eli Zaretskii
2021-10-19 15:57                                 ` Lars Ingebrigtsen
2021-10-19 16:12                                   ` Eli Zaretskii
2021-10-19 16:15                                     ` Lars Ingebrigtsen
2021-10-19 16:21                                     ` Lars Ingebrigtsen
2021-10-19 16:30                                       ` Eli Zaretskii
2021-10-19 17:12                                         ` Lars Ingebrigtsen
2021-10-19 17:37                                           ` Eli Zaretskii
2021-10-19 18:21                                             ` Lars Ingebrigtsen
2021-10-20 11:28                                               ` Eli Zaretskii
2021-10-20 11:55                                                 ` Glenn Morris
2021-10-24 20:11                                                   ` Stefan Kangas
2021-10-25 13:06                                                     ` Lars Ingebrigtsen
2021-10-25 13:19                                                       ` Eli Zaretskii
2021-10-25 13:21                                                         ` Lars Ingebrigtsen
2021-10-25 13:51                                                           ` Eli Zaretskii
2021-10-25 13:55                                                             ` Lars Ingebrigtsen
2021-10-25 14:12                                                               ` Eli Zaretskii
2021-10-26  8:38                                                                 ` Stefan Kangas
2021-10-26 13:04                                                                   ` Eli Zaretskii
2021-10-26 20:24                                                                     ` Stefan Kangas
2021-10-27 14:00                                                                       ` Eli Zaretskii
2021-10-28  5:29                                                                         ` Stefan Kangas
2021-10-28  7:33                                                                           ` Eli Zaretskii
2021-10-28  8:06                                                                             ` Stefan Kangas
2021-10-28  9:35                                                                               ` Eli Zaretskii
2021-10-28 10:49                                                                                 ` Stefan Kangas
2021-10-28 12:49                                                                                   ` Eli Zaretskii
2021-10-28 20:44                                                                                     ` Stefan Kangas
2021-10-21  2:45                                                 ` Lars Ingebrigtsen
2021-10-21  7:26                                                   ` Eli Zaretskii
2021-10-21 13:04                                                     ` Lars Ingebrigtsen
2021-10-20  7:45                                             ` Lars Ingebrigtsen
2021-10-20 12:24                                               ` Eli Zaretskii
2021-10-19 11:43                   ` Eli Zaretskii
2021-10-19 21:54                     ` Stefan Kangas
2021-10-20 12:59                       ` Eli Zaretskii
2021-10-13 16:09               ` Eli Zaretskii
2021-10-15  5:59       ` Eli Zaretskii
2021-10-15 18:34         ` Stefan Kangas
2021-10-19  3:18       ` Stefan Kangas
2021-09-23 22:28 ` Glenn Morris

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CADwFkmmFnixKo6xeuV0mpQ4a+nXnYEXuq-8pcr7=AFTP0rRMKw@mail.gmail.com' \
    --to=stefan@marxist.se \
    --cc=50752@debbugs.gnu.org \
    --cc=larsi@gnus.org \
    --cc=shuguang79@qq.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).