notes from /dev/null

by Charles Choi 최민수


Customizing the Emacs Help Menu

18 Jul 2025  Charles Choi

NGL, I’ve always found the default Emacs Help menu to be a bit too extra.

img

While the Help menu is commendable in trying to assist new users, I’ve long outgrown it as most of its offerings I can access via the keyboard. The Help menu though lacks a feature that I sorely miss from other apps: The ability to open a separate GUI window (in Emacs parlance, a frame) to read help in.

As always though with Emacs, you can customize nearly everything about it and that includes the Help menu which this post will cover. Readers are invited to adopt or adapt these customizations for their own. Consider this a followup to an earlier post of mine “Customizing the Emacs Tools Menu”.

A design challenge to building a menu for Emacs Help is that there are no less than four different help subsystems provided by it:

  • The Emacs Info reader for Texinfo files.
  • Elisp docstrings rendered by the describe- family of functions.
  • The Man page reader for troff formatted files.
  • shortdoc for an overview of functions relevant for a topic.

For my Help menu I’ve decided to make three ways to create a new frame:

  • Info in New Frame: Create a new frame with the Emacs Info reader.
  • New Info in New Frame: Create a new frame with a different Emacs Info reader instance. The user will be prompted for a manual to render.
  • Man Page in New Frame: Create a new frame with a Man page reader. The user will be prompted for a man page to render.

I’ve found the relatively recent addition of describe-symbol to generalize search of all docstrings to be a welcome one. Promoting it and describe-key to the first level of the menu seemed appropriate.

A recent TIL is the command finder-commentary which will display the commentary section of an Elisp library. I’ve found this command nice to have around but its name to be completely unmemorable, which makes it perfect to put in the menu labeled as “Library Commentary…”.

With existing Help menu items, I’ve decided to either remove or re-arrange them to taste. The result of my customizations looks like this:

img

Be forewarned, some Elisp ahead.

Implementation

To customize the Help menu it helps to know the internal key of a menu item. These keys are Elisp symbols. Here’s a utility function to help show these key symbols in string form:

1
2
3
4
5
6
(defun cc/show-global-map-keys (keypath)
  "Show formatted keys for keymap in `global-map' given KEYPATH."
  (interactive)
  (mapcar (lambda (x) (format "%s" x))
          (mapcar (lambda (x) (if (listp x) (car x)))
                  (cdr (lookup-key global-map keypath)))))

With cc/show-global-map-keys evaluated, we can run it in IELM as shown below for the keypath [menu-bar help-menu].

1
2
3
4
5
6
7
8
ELISP> (cc/show-global-map-keys [menu-bar help-menu])
("emacs-tutorial" "emacs-tutorial-language-specific" "emacs-faq"
 "emacs-news" "emacs-known-problems" "emacs-manual-bug"
 "send-emacs-bug-report" "emacs-psychotherapist" "sep1"
 "search-documentation" "describe" "emacs-manual" "more-manuals"
 "find-emacs-packages" "external-packages" "sep2"
 "getting-new-versions" "describe-copying" "describe-no-warranty"
 "sep4" "about-emacs" "about-gnu-project" "nil")

We’ll return back to these keys later.

Opening a new frame (aka GUI window) can be achieved with the function other-frame-prefix. We can wrap this function so that any interactive command can be invoked in a new frame as shown below.

1
2
3
4
5
(defun cc/--command-in-new-frame (cmd)
  "Invoke CMD in a new frame.
This command creates a new frame populated by CMD."
  (other-frame-prefix)
  (call-interactively cmd))

With cc/--command-in-new-frame in place, we can now add menu items using easy-menu-add-item. The next code example shows how to invoke info in a new frame as a menu item added before emacs-tutorial.

1
2
3
4
5
6
7
8
(easy-menu-add-item
 global-map '(menu-bar help-menu)
 ["Info in New Frame"
  (lambda ()
    (interactive)
    (cc/--command-in-new-frame #'info))
  :help "Show Info manual in new frame."]
 'emacs-tutorial)

Let’s add some more menu items to support viewing a Man page and for describe-symbol and describe-key. In addition, we’ll re-arrange some existing menu items by replicating their entry in global-map in a desired position and later deleting the older menu item with the same command.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
(easy-menu-add-item
 global-map '(menu-bar help-menu)
 ["New Info in New Frame…"
  (lambda ()
    (interactive)
    (cc/--command-in-new-frame #'info-display-manual))
  :help "Show new Info manual in new frame."]
 'emacs-tutorial)

(easy-menu-add-item
 global-map '(menu-bar help-menu)
 ["Man Page in New Frame…"
  (lambda ()
    (interactive)
    (cc/--command-in-new-frame #'man))
  :help "Show man page in new frame."]
 'emacs-tutorial)

(easy-menu-add-item
 global-map '(menu-bar help-menu)
 ["Describe Symbol…"
  describe-symbol
  :help "Describe symbol."]
 'emacs-tutorial)

(easy-menu-add-item
 global-map '(menu-bar help-menu)
 ["Describe Key or Mouse…"
  describe-key
  :help "Describe key or mouse operation."]
 'emacs-tutorial)

(easy-menu-add-item
 global-map '(menu-bar help-menu)
 ["Library Commentary…"
  finder-commentary
  :help "Show commentary for Elisp library."]
 'emacs-tutorial)

(easy-menu-add-item
 global-map '(menu-bar help-menu)
 ["Emacs FAQ"
  view-emacs-FAQ
  :help "View Emacs FAQ."]
 'describe-copying)

(easy-menu-add-item
 global-map '(menu-bar help-menu)
 ["Emacs News"
  view-emacs-news
  :help "View Emacs news about this release."]
 'describe-copying)

(easy-menu-add-item
 global-map '(menu-bar help-menu)
 ["Emacs Known Problems"
  view-emacs-problems
  :help "View Emacs known problems."]
 'describe-copying)

(easy-menu-add-item
 global-map '(menu-bar help-menu)
 ["Send Bug Report…"
  report-emacs-bug
  :help "Send Emacs bug report."]
 'describe-copying)

So far all we’ve done is add more menu items. Here’s how to get rid of the items using the keys obtained via cc/show-global-map-keys.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
(define-key global-map [menu-bar help-menu emacs-tutorial] nil t)
(define-key global-map [menu-bar help-menu emacs-tutorial-language-specific] nil t)
(define-key global-map [menu-bar help-menu emacs-psychotherapist] nil t)
(define-key global-map [menu-bar help-menu more-manuals] nil t)
(define-key global-map [menu-bar help-menu emacs-manual] nil t)
(define-key global-map [menu-bar help-menu getting-new-versions] nil t)
(define-key global-map [menu-bar help-menu describe-copying] nil t)
(define-key global-map [menu-bar help-menu describe-no-warranty] nil t)
(define-key global-map [menu-bar help-menu about-gnu-project] nil t)
(define-key global-map [menu-bar help-menu external-packages] nil t)
(define-key global-map [menu-bar help-menu emacs-faq] nil t)
(define-key global-map [menu-bar help-menu emacs-news] nil t)
(define-key global-map [menu-bar help-menu emacs-known-problems] nil t)
(define-key global-map [menu-bar help-menu emacs-manual-bug] nil t)
(define-key global-map [menu-bar help-menu send-emacs-bug-report] nil t)
(define-key global-map [menu-bar help-menu getting-new-versions] nil t)
(define-key global-map [menu-bar help-menu about-gnu-project] nil t)

Closing Thoughts

I’ve been living with this customized Help menu for several months now and upon reflection a couple of thoughts:

  • How did I live so long without this?

    Easy and non-disruptive access to Help in a separate GUI window is baseline for a proper application. Vanilla Emacs makes doing this way more onerous than need be:

    1. Create a new frame either from the menu “Edit › New Frame” or by recalling the arcane incantation C-x 5 2. (really?)
    2. Run M-x info in the new frame.

    With my reconfigured Help menu, I can just go to “Help › Info in New Frame” via mouse and it does the right thing without altering any existing Emacs window configuration. Simple pleasures.

  • To my surprise, I use Info so much more now.

    Having the Info reader in a separate GUI window lets me treat it like a web browser window but with the benefits of:

    1. Local access - never worry about a network connection.
    2. You’re still in Emacs.

    Couple that with my Casual interface for Info and I’d argue that Info is actually pleasurable to use. (Alongside that the same goes for Casual Man and Help.)

    Info is not exclusive to just Emacs manuals. You can read manuals for GNU coreutils, Make, Bash, Gnuplot, and many others. These days, whenever I’m dealing with software, I actively look to see if there’s Texinfo documentation for it.

If you’ve made it to here, thanks for reading!

emacs

 

AboutMastodonBlueskyGitHub

Feeds & Tags
Get Scrim for macOSGet Captee for macOS

Powered by Pelican