diff --git a/lisp/imenu.el b/lisp/imenu.el index f628936cedc..ccc73fe42d2 100644 --- a/lisp/imenu.el +++ b/lisp/imenu.el @@ -66,6 +66,13 @@ imenu :group 'convenience :link '(custom-manual "(elisp)Imenu")) +(defcustom imenu-flatten nil + "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-use-markers t "Non-nil means use markers instead of integers for Imenu buffer positions. @@ -142,8 +149,7 @@ imenu-space-replacement (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-generic-skip-comments-and-strings t @@ -763,6 +770,26 @@ imenu--mouse-menu 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 @@ imenu-choose-buffer-index ;; 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))