Subject: bug#24774: 26.0.50; Menu display navigation commands

From: Stefan Kangas <[email-masked]>
Date: Tue, 23 Feb 2021 09:19:19 -0600

tags 24774 + patch
thanks

Lars Ingebrigtsen <[email-masked]> writes:

> Stefan Kangas <[email-masked]> writes:
>
>> Is preloading easy-menu.el excluded?
>
> If I do an "emacs -Q", then it turns out that easymenu.el is already
> present, so I think something is already loading it (even if it's not
> explicitly mentioned by lisp/loadup.el).
>
> So rewriting the emacs-lisp menus using easymenu should be
> uncontroversial.

How do the attached patches look?
From 73e00b8517ec97e5c7c6041eab30b4b0ddfb5d30 Mon Sep 17 00:00:00 2001
From: Stefan Kangas <[email-masked]>
Date: Thu, 19 Nov 2020 02:19:19 +0100
Subject: [PATCH 1/2] Preload easymenu.el

* lisp/loadup.el: Preload easymenu.  It turns out that it is already
loaded in a default Emacs 27.
---
 lisp/emacs-lisp/easymenu.el | 4 ----
 lisp/loadup.el              | 1 +
 2 files changed, 1 insertion(+), 4 deletions(-)

diff --git a/lisp/emacs-lisp/easymenu.el b/lisp/emacs-lisp/easymenu.el
index bcd5cfd99b..68b0a27b6a 100644
--- a/lisp/emacs-lisp/easymenu.el
+++ b/lisp/emacs-lisp/easymenu.el
@@ -35,7 +35,6 @@
 (defsubst easy-menu-intern (s)
   (if (stringp s) (intern s) s))
 
-;;;###autoload
 (defmacro easy-menu-define (symbol maps doc menu)
   "Define a pop-up menu and/or menu bar menu specified by MENU.
 If SYMBOL is non-nil, define SYMBOL as a function to pop up the
@@ -166,7 +165,6 @@ easy-menu-binding
                       ""))
                 (cons menu props)))))
 
-;;;###autoload
 (defun easy-menu-do-define (symbol maps doc menu)
   ;; We can't do anything that might differ between Emacs dialects in
   ;; `easy-menu-define' in order to make byte compiled files
@@ -218,7 +216,6 @@ easy-menu-avoid-duplicate-keys
 If it holds a list, this is expected to be a list of keys already seen in the
 menu we're processing.  Else it means we're not processing a menu.")
 
-;;;###autoload
 (defun easy-menu-create-menu (menu-name menu-items)
   "Create a menu called MENU-NAME with items described in MENU-ITEMS.
 MENU-NAME is a string, the name of the menu.  MENU-ITEMS is a list of items
@@ -474,7 +471,6 @@ easy-menu-make-symbol
 	    (eval `(lambda () (interactive) ,callback) t)))
     command))
 
-;;;###autoload
 (defun easy-menu-change (path name items &optional before map)
   "Change menu found at PATH as item NAME to contain ITEMS.
 PATH is a list of strings for locating the menu that
diff --git a/lisp/loadup.el b/lisp/loadup.el
index d60aa2ead2..c16cd61594 100644
--- a/lisp/loadup.el
+++ b/lisp/loadup.el
@@ -266,6 +266,7 @@
 (load "isearch")
 (load "rfn-eshadow")
 
+(load "emacs-lisp/easymenu")
 (load "menu-bar")
 (load "tab-bar")
 (load "emacs-lisp/lisp")
-- 
2.30.0

From 7613470112b5a5bcb492f1adda2947052b1e07c8 Mon Sep 17 00:00:00 2001
From: Stefan Kangas <[email-masked]>
Date: Tue, 23 Feb 2021 15:51:16 +0100
Subject: [PATCH 2/2] Convert emacs-lisp-mode menu to easy-menu-define

* lisp/progmodes/elisp-mode.el (emacs-lisp-mode-map): Convert menu to
use easy-menu-define.
---
 lisp/progmodes/elisp-mode.el | 215 +++++++++++++++--------------------
 1 file changed, 89 insertions(+), 126 deletions(-)

diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el
index 397eb269a7..9532cf692e 100644
--- a/lisp/progmodes/elisp-mode.el
+++ b/lisp/progmodes/elisp-mode.el
@@ -46,140 +46,103 @@ emacs-lisp-mode-syntax-table
   "Syntax table used in `emacs-lisp-mode'.")
 
 (defvar emacs-lisp-mode-map
-  (let ((map (make-sparse-keymap))
-	(menu-map (make-sparse-keymap "Emacs-Lisp"))
-	(lint-map (make-sparse-keymap))
-	(prof-map (make-sparse-keymap))
-	(tracing-map (make-sparse-keymap)))
+  (let ((map (make-sparse-keymap)))
     (set-keymap-parent map lisp-mode-shared-map)
     (define-key map "\e\t" 'completion-at-point)
     (define-key map "\e\C-x" 'eval-defun)
     (define-key map "\e\C-q" 'indent-pp-sexp)
-    (bindings--define-key map [menu-bar emacs-lisp]
-      (cons "Emacs-Lisp" menu-map))
-    (bindings--define-key menu-map [eldoc]
-      '(menu-item "Auto-Display Documentation Strings" eldoc-mode
-		  :button (:toggle . (bound-and-true-p eldoc-mode))
-		  :help "Display the documentation string for the item under cursor"))
-    (bindings--define-key menu-map [checkdoc]
-      '(menu-item "Check Documentation Strings" checkdoc
-		  :help "Check documentation strings for style requirements"))
-    (bindings--define-key menu-map [re-builder]
-      '(menu-item "Construct Regexp" re-builder
-		  :help "Construct a regexp interactively"))
-    (bindings--define-key menu-map [tracing] (cons "Tracing" tracing-map))
-    (bindings--define-key tracing-map [tr-a]
-      '(menu-item "Untrace All" untrace-all
-		  :help "Untrace all currently traced functions"))
-    (bindings--define-key tracing-map [tr-uf]
-      '(menu-item "Untrace Function..." untrace-function
-		  :help "Untrace function, and possibly activate all remaining advice"))
-    (bindings--define-key tracing-map [tr-sep] menu-bar-separator)
-    (bindings--define-key tracing-map [tr-q]
-      '(menu-item "Trace Function Quietly..." trace-function-background
-		  :help "Trace the function with trace output going quietly to a buffer"))
-    (bindings--define-key tracing-map [tr-f]
-      '(menu-item "Trace Function..." trace-function
-		  :help "Trace the function given as an argument"))
-    (bindings--define-key menu-map [profiling] (cons "Profiling" prof-map))
-    (bindings--define-key prof-map [prof-restall]
-      '(menu-item "Remove Instrumentation for All Functions" elp-restore-all
-		  :help "Restore the original definitions of all functions being profiled"))
-    (bindings--define-key prof-map [prof-restfunc]
-      '(menu-item "Remove Instrumentation for Function..." elp-restore-function
-		  :help "Restore an instrumented function to its original definition"))
-
-    (bindings--define-key prof-map [sep-rem] menu-bar-separator)
-    (bindings--define-key prof-map [prof-resall]
-      '(menu-item "Reset Counters for All Functions" elp-reset-all
-		  :help "Reset the profiling information for all functions being profiled"))
-    (bindings--define-key prof-map [prof-resfunc]
-      '(menu-item "Reset Counters for Function..." elp-reset-function
-		  :help "Reset the profiling information for a function"))
-    (bindings--define-key prof-map [prof-res]
-      '(menu-item "Show Profiling Results" elp-results
-		  :help "Display current profiling results"))
-    (bindings--define-key prof-map [prof-pack]
-      '(menu-item "Instrument Package..." elp-instrument-package
-		  :help "Instrument for profiling all function that start with a prefix"))
-    (bindings--define-key prof-map [prof-func]
-      '(menu-item "Instrument Function..." elp-instrument-function
-		  :help "Instrument a function for profiling"))
-    ;; Maybe this should be in a separate submenu from the ELP stuff?
-    (bindings--define-key prof-map [sep-natprof] menu-bar-separator)
-    (bindings--define-key prof-map [prof-natprof-stop]
-      '(menu-item "Stop Native Profiler" profiler-stop
-		  :help "Stop recording profiling information"
-		  :enable (and (featurep 'profiler)
-			       (profiler-running-p))))
-    (bindings--define-key prof-map [prof-natprof-report]
-      '(menu-item "Show Profiler Report" profiler-report
-		  :help "Show the current profiler report"
-		  :enable (and (featurep 'profiler)
-			       (profiler-running-p))))
-    (bindings--define-key prof-map [prof-natprof-start]
-      '(menu-item "Start Native Profiler..." profiler-start
-		  :help "Start recording profiling information"))
-
-    (bindings--define-key menu-map [lint] (cons "Linting" lint-map))
-    (bindings--define-key lint-map [lint-di]
-      '(menu-item "Lint Directory..." elint-directory
-		  :help "Lint a directory"))
-    (bindings--define-key lint-map [lint-f]
-      '(menu-item "Lint File..." elint-file
-		  :help "Lint a file"))
-    (bindings--define-key lint-map [lint-b]
-      '(menu-item "Lint Buffer" elint-current-buffer
-		  :help "Lint the current buffer"))
-    (bindings--define-key lint-map [lint-d]
-      '(menu-item "Lint Defun" elint-defun
-		  :help "Lint the function at point"))
-    (bindings--define-key menu-map [edebug-defun]
-      '(menu-item "Instrument Function for Debugging" edebug-defun
-		  :help "Evaluate the top level form point is in, stepping through with Edebug"
-		  :keys "C-u C-M-x"))
-    (bindings--define-key menu-map [separator-byte] menu-bar-separator)
-    (bindings--define-key menu-map [disas]
-      '(menu-item "Disassemble Byte Compiled Object..." disassemble
-		  :help "Print disassembled code for OBJECT in a buffer"))
-    (bindings--define-key menu-map [byte-recompile]
-      '(menu-item "Byte-recompile Directory..." byte-recompile-directory
-		  :help "Recompile every `.el' file in DIRECTORY that needs recompilation"))
-    (bindings--define-key menu-map [emacs-byte-compile-and-load]
-      '(menu-item "Byte-compile and Load" emacs-lisp-byte-compile-and-load
-		  :help "Byte-compile the current file (if it has changed), then load compiled code"))
-    (bindings--define-key menu-map [byte-compile]
-      '(menu-item "Byte-compile This File" emacs-lisp-byte-compile
-		  :help "Byte compile the file containing the current buffer"))
-    (bindings--define-key menu-map [separator-eval] menu-bar-separator)
-    (bindings--define-key menu-map [ielm]
-      '(menu-item "Interactive Expression Evaluation" ielm
-		  :help "Interactively evaluate Emacs Lisp expressions"))
-    (bindings--define-key menu-map [eval-buffer]
-      '(menu-item "Evaluate Buffer" eval-buffer
-		  :help "Execute the current buffer as Lisp code"))
-    (bindings--define-key menu-map [eval-region]
-      '(menu-item "Evaluate Region" eval-region
-		  :help "Execute the region as Lisp code"
-		  :enable mark-active))
-    (bindings--define-key menu-map [eval-sexp]
-      '(menu-item "Evaluate Last S-expression" eval-last-sexp
-		  :help "Evaluate sexp before point; print value in echo area"))
-    (bindings--define-key menu-map [separator-format] menu-bar-separator)
-    (bindings--define-key menu-map [comment-region]
-      '(menu-item "Comment Out Region" comment-region
-		  :help "Comment or uncomment each line in the region"
-		  :enable mark-active))
-    (bindings--define-key menu-map [indent-region]
-      '(menu-item "Indent Region" indent-region
-		  :help "Indent each nonblank line in the region"
-		  :enable mark-active))
-    (bindings--define-key menu-map [indent-line]
-      '(menu-item "Indent Line" lisp-indent-line))
     map)
   "Keymap for Emacs Lisp mode.
 All commands in `lisp-mode-shared-map' are inherited by this map.")
 
+(easy-menu-define emacs-lisp-mode-menu emacs-lisp-mode-map
+  "Menu for Emacs Lisp mode."
+  '("Emacs-Lisp"
+    ["Indent Line" lisp-indent-line]
+    ["Indent Region" indent-region
+     :help "Indent each nonblank line in the region"
+     :active mark-active]
+    ["Comment Out Region" comment-region
+     :help "Comment or uncomment each line in the region"
+     :active mark-active]
+    "---"
+    ["Evaluate Last S-expression" eval-last-sexp
+     :help "Evaluate sexp before point; print value in echo area"]
+    ["Evaluate Region" eval-region
+     :help "Execute the region as Lisp code"
+     :active mark-active]
+    ["Evaluate Buffer" eval-buffer
+     :help "Execute the current buffer as Lisp code"]
+    ["Interactive Expression Evaluation" ielm
+     :help "Interactively evaluate Emacs Lisp expressions"]
+    "---"
+    ["Byte-compile This File" emacs-lisp-byte-compile
+     :help "Byte compile the file containing the current buffer"]
+    ["Byte-compile and Load" emacs-lisp-byte-compile-and-load
+     :help "Byte-compile the current file (if it has changed), then load compiled code"]
+    ["Byte-recompile Directory..." byte-recompile-directory
+     :help "Recompile every `.el' file in DIRECTORY that needs recompilation"]
+    ["Disassemble Byte Compiled Object..." disassemble
+     :help "Print disassembled code for OBJECT in a buffer"]
+    "---"
+    ["Instrument Function for Debugging" edebug-defun
+     :help "Evaluate the top level form point is in, stepping through with Edebug"
+     :keys "C-u C-M-x"]
+    ["Linting"
+     ["Lint Defun" elint-defun
+      :help "Lint the function at point"]
+     ["Lint Buffer" elint-current-buffer
+      :help "Lint the current buffer"]
+     ["Lint File..." elint-file
+      :help "Lint a file"]
+     ["Lint Directory..." elint-directory
+      :help "Lint a directory"]]
+    ["Profiling"
+     ;; Maybe this should be in a separate submenu from the ELP stuff?
+     ["Start Native Profiler..." profiler-start
+      :help "Start recording profiling information"]
+     ["Show Profiler Report" profiler-report
+      :help "Show the current profiler report"
+      :active (and (featurep 'profiler)
+                   (profiler-running-p))]
+     ["Stop Native Profiler" profiler-stop
+      :help "Stop recording profiling information"
+      :active (and (featurep 'profiler)
+                   (profiler-running-p))]
+     "---"
+     ["Instrument Function..." elp-instrument-function
+      :help "Instrument a function for profiling"]
+     ["Instrument Package..." elp-instrument-package
+      :help "Instrument for profiling all function that start with a prefix"]
+     ["Show Profiling Results" elp-results
+      :help "Display current profiling results"]
+     ["Reset Counters for Function..." elp-reset-function
+      :help "Reset the profiling information for a function"]
+     ["Reset Counters for All Functions" elp-reset-all
+      :help "Reset the profiling information for all functions being profiled"]
+     "---"
+     ["Remove Instrumentation for All Functions" elp-restore-all
+      :help "Restore the original definitions of all functions being profiled"]
+     ["Remove Instrumentation for Function..." elp-restore-function
+      :help "Restore an instrumented function to its original definition"]]
+    ["Tracing"
+     ["Trace Function..." trace-function
+      :help "Trace the function given as an argument"]
+     ["Trace Function Quietly..." trace-function-background
+      :help "Trace the function with trace output going quietly to a buffer"]
+     "---"
+     ["Untrace All" untrace-all
+      :help "Untrace all currently traced functions"]
+     ["Untrace Function..." untrace-function
+      :help "Untrace function, and possibly activate all remaining advice"]]
+    ["Construct Regexp" re-builder
+     :help "Construct a regexp interactively"]
+    ["Check Documentation Strings" checkdoc
+     :help "Check documentation strings for style requirements"]
+    ["Auto-Display Documentation Strings" eldoc-mode
+     :button (:toggle . (bound-and-true-p eldoc-mode))
+     :help "Display the documentation string for the item under cursor"]))
+
 (defun emacs-lisp-byte-compile ()
   "Byte compile the file containing the current buffer."
   (interactive)
-- 
2.30.0