From: Juri Linkov Date: Fri, 10 May 2024 06:52:09 +0000 (+0300) Subject: * lisp/imenu.el (imenu-flatten): New defcustom (bug#70846). X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=3a32b647cf0a508cbd584e139fba522dfb3576c6;p=emacs.git * 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. (cherry picked from commit 4306aba2d0447fd79c0b749a984ccd7bdbc92361) --- diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi index de28a9f1dd4..01a1462044c 100644 --- a/doc/emacs/programs.texi +++ b/doc/emacs/programs.texi @@ -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 diff --git a/etc/NEWS b/etc/NEWS index ec98255c011..c9514910ee7 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1137,6 +1137,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 +++ diff --git a/lisp/imenu.el b/lisp/imenu.el index f628936cedc..dd924b449cf 100644 --- a/lisp/imenu.el +++ b/lisp/imenu.el @@ -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.")