* lisp/imenu.el (imenu-flatten): New defcustom (bug#70846).

(imenu-level-separator): Adjust the docstring.
(imenu--flatten-index-alist): New function revived
from the initial implementation of this package.
(imenu-choose-buffer-index): Use imenu--flatten-index-alist
when imenu-flatten is non-nil.
(imenu-buffer-menubar): Remove obsolete variable.

* doc/emacs/programs.texi (Imenu): Document imenu-flatten.
This commit is contained in:
Juri Linkov 2024-05-10 09:52:09 +03:00
parent 33878f29d1
commit 4306aba2d0
3 changed files with 42 additions and 5 deletions

View file

@ -338,10 +338,13 @@ where it treats each chapter, section, etc., as a definition.
together.)
@findex imenu
@vindex imenu-flatten
If you type @kbd{M-g i} (@code{imenu}), it reads the name of a
definition using the minibuffer, then moves point to that definition.
You can use completion to specify the name; the command always
displays the whole list of valid names.
displays the whole list of valid names. If you set @code{imenu-flatten}
to a non-@code{nil} value, then instead of the nested menu
you can select a completion candidate from the flat list.
@findex imenu-add-menubar-index
Alternatively, you can bind the command @code{imenu} to a mouse

View file

@ -1039,6 +1039,13 @@ docstring, or a comment, or (re)indents the surrounding defun if
point is not in a comment or a string. It is by default bound to
'M-q' in 'prog-mode' and all its descendants.
** Imenu
+++
*** New user option 'imenu-flatten'.
It defines whether to flatten the list of sections in an imenu
or show it nested.
** Which Function mode
+++

View file

@ -142,10 +142,17 @@ names work as tokens."
(defcustom imenu-level-separator ":"
"The separator between index names of different levels.
Used for making mouse-menu titles and for flattening nested indexes
with name concatenation."
Used for flattening nested indexes with name concatenation."
:type 'string)
(defcustom imenu-flatten nil
"Whether to flatten the list of sections in an imenu or show it nested.
If non-nil, popup the completion buffer with a flattened menu.
The string from `imenu-level-separator' is used to separate names of
nested levels while flattening nested indexes with name concatenation."
:type 'boolean
:version "30.1")
(defcustom imenu-generic-skip-comments-and-strings t
"When non-nil, ignore text inside comments and strings.
Only affects `imenu-default-create-index-function' (and any
@ -763,6 +770,26 @@ Returns t for rescan and otherwise an element or subelement of INDEX-ALIST."
menu)))))
(popup-menu map event)))
(defun imenu--flatten-index-alist (index-alist &optional concat-names prefix)
;; Takes a nested INDEX-ALIST and returns a flat index alist.
;; If optional CONCAT-NAMES is non-nil, then a nested index has its
;; name and a space concatenated to the names of the children.
;; Third argument PREFIX is for internal use only.
(mapcan
(lambda (item)
(let* ((name (car item))
(pos (cdr item))
(new-prefix (and concat-names
(if prefix
(concat prefix imenu-level-separator name)
name))))
(cond
((or (markerp pos) (numberp pos))
(list (cons new-prefix pos)))
(t
(imenu--flatten-index-alist pos concat-names new-prefix)))))
index-alist))
(defun imenu-choose-buffer-index (&optional prompt alist)
"Let the user select from a buffer index and return the chosen index.
@ -792,6 +819,8 @@ The returned value is of the form (INDEX-NAME . INDEX-POSITION)."
;; Create a list for this buffer only when needed.
(while (eq result t)
(setq index-alist (if alist alist (imenu--make-index-alist)))
(when imenu-flatten
(setq index-alist (imenu--flatten-index-alist index-alist t)))
(setq result
(if (and imenu-use-popup-menu
(or (eq imenu-use-popup-menu t) mouse-triggered))
@ -836,8 +865,6 @@ A trivial interface to `imenu-add-to-menubar' suitable for use in a hook."
(interactive)
(imenu-add-to-menubar "Index"))
(defvar imenu-buffer-menubar nil)
(defvar-local imenu-menubar-modified-tick 0
"Value of (buffer-chars-modified-tick) when `imenu-update-menubar' was called.")