Subject: 30.1.90; [PATCH] Let Imenu optionally allow duplicate menu entries

From: Drew Adams <[email-masked]>
Date: Mon, 30 Jun 2025 22:12:44 +0000

Emacs 29 removed useful behavior from Imenu, producing
backward-incompatible behavior by no longer allowing multiple menu
entries with the same name.  Only the first name among duplicates is
used in the menu.

This means that if you're working with a buffer that, for whatever
reason, has multiple definitions of a function, variable etc. - or any
duplication of something else that can be indexed in the menu, you lose
all ability to use the menu to navigate to those entries other than the
first one for a given name.

The attached patch fixes this.  It provides a Boolean user option,
`imenu-allow-duplicate-menu-items-flag' to choose the longstanding
pre-29 behavior or the behavior imposed since Emacs 29.

The updated file is also attached, as `imenu-patched.el'.

The only change in the code is to function `imenu--create-keymap',
causing it to respect the new option.

In `imenu--create-keymap' I also replaced the unnecessarily roundabout
(seq-filter #'identity alist) with the more transparent and simpler
(remq nil alist).  This change isn't necessary, but it should be
familiar enough to be accepted (and preferred).

I set the default value of the new option to `t', to allow dups by
default.  This means a default behavior change from Emacs 29.  If that's
unacceptable then change the default option value to `nil'.

And if you don't like the option name (e.g., if you disagree with RMS's
preference that Boolean options have suffix `-flag') then change the
name to whatever you want.

Note that the behavior introduced in Emacs 29 ensures that the key
bindings in the generated keymap (e.g. `imenu--menubar-keymap') have a
symbol as their car.  The longstanding pre-29 behavior, which allows
menu entries with the same name, uses a string instead of a symbol,
which works fine but is undocumented behavior.  The doc says that a
symbol or a character is used in that place; it doesn't mention that a
string can also be used.

If someone wants to use a different implementation to achieve the same
result, fine.  The solution proposed here is simple and
backward-compatibled.  It can always be replaced later by some other
implementation that solves the same problem.  (E.g., you could use
multiple symbols whose names are _almost_ the same, perhaps by suffixing
the names with <2>, <3>....)  I suggest you accept this patch now and
worry later about whether you want to try a different solution.  The
solution proposed here has worked for Imenu for 40-some years.

Finally, note that the allowance of duplicates applies only to the use
of an Imenu _menu_ (in the menubar or elsewhere), not also to the use of
command `imenu', which uses `completing-read' to read a menu item.

This is the pre-29 behavior.  To have `completing-read' allow duplicate
names requires jumping through some hoops.  It's possible, but it isn't
part of this patch.  This patch is just to provide both the Emacs
29-30.1 behavior and the pre-29 behavior.

In GNU Emacs 30.1.90 (build 2, x86_64-w64-mingw32) of 2025-05-20 built
 on AVALON
Windowing system distributor 'Microsoft Corp.', version 10.0.26100
System Description: Microsoft Windows 10 Pro (v10.0.2009.26100.4061)

Configured using:
 'configure --with-modules --without-dbus --with-native-compilation=aot
 --without-compress-install --with-tree-sitter CFLAGS=-O2
 prefix=/g/rel/install/emacs-30.1.90_1
 PKG_CONFIG_PATH=/mingw64/lib/pkgconfig:/mingw64/share/pkgconfig'

Configured features:
ACL GIF GMP GNUTLS HARFBUZZ JPEG LCMS2 LIBXML2 MODULES NATIVE_COMP
NOTIFY W32NOTIFY PDUMPER PNG RSVG SOUND SQLITE3 THREADS TIFF
TOOLKIT_SCROLL_BARS TREE_SITTER WEBP XPM ZLIB

(NATIVE_COMP present but libgccjit not available)

Important settings:
  value of $LANG: ENU
  locale-coding-system: cp1252