emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 4306aba2d04: * lisp/imenu.el (imenu-flatten): New defcustom (bug#


From: Juri Linkov
Subject: master 4306aba2d04: * lisp/imenu.el (imenu-flatten): New defcustom (bug#70846).
Date: Fri, 10 May 2024 02:55:15 -0400 (EDT)

branch: master
commit 4306aba2d0447fd79c0b749a984ccd7bdbc92361
Author: Juri Linkov <juri@linkov.net>
Commit: Juri Linkov <juri@linkov.net>

    * 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.
---
 doc/emacs/programs.texi |  5 ++++-
 etc/NEWS                |  7 +++++++
 lisp/imenu.el           | 35 +++++++++++++++++++++++++++++++----
 3 files changed, 42 insertions(+), 5 deletions(-)

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 a0a06c58941..d2bedd64b2c 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -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
 
 +++
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.")
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]