(defcustom imenu-flatten nil
"Whether to flatten the list of sections in an imenu or show it nested.
-If nil, use nested indexes.
-If the value is `prefix', pop up the completion buffer with a
-flattened menu where section names are prepended to completion
-candidates as prefixes.
-If the value is `annotation', annotate each completion candidate
-with a suffix that is the section name to which it belongs.
-If the value is `group', split completion candidates into groups
-according to the sections.
-Any other value is treated as `prefix'.
The value of `imenu-level-separator', a string, is used to separate
names from different flattened levels, such as section names, from the
names of completion candidates."
- :type '(choice (const :tag "Show nested list" nil)
- (const :tag "Flat list with sections as prefix" prefix)
- (const :tag "Flat list annotated with sections" annotation)
- (const :tag "Flat list grouped by sections" group))
+ :type 'boolean
:version "30.1")
(defcustom imenu-generic-skip-comments-and-strings t
;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; The item to use in the index for rescanning the buffer.
-(defconst imenu--rescan-item '("*Rescan*" . -99))
-
;; The latest buffer index.
(defvar-local imenu--index-alist nil
"The buffer index alist computed for this buffer in Imenu.
(defvar-local imenu--last-menubar-index-alist nil
"The latest buffer index alist used to update the menu bar menu.")
-(defvar imenu--history-list nil
+(defvar imenu--history nil
;; Making this buffer local caused it not to work!
"History list for `imenu-choose-buffer-index'.")
(defun imenu--split-menu (menulist title)
"Split the alist MENULIST into a nested alist, if it is long enough.
In any case, add TITLE to the front of the alist.
-If IMENU--RESCAN-ITEM is present in MENULIST, it is moved to the
-beginning of the returned alist.
The returned alist DOES NOT share structure with MENULIST."
(let ((menulist (copy-sequence menulist))
keep-at-top)
- (if (memq imenu--rescan-item menulist)
- (setq keep-at-top (list imenu--rescan-item)
- menulist (delq imenu--rescan-item menulist)))
(if imenu-submenus-on-top
(dolist (item menulist)
(when (imenu--subalist-p item)
(imenu--truncate-items (cdr item))))
menulist))
+(defun imenu-rescan ()
+ "Update Imenu index for current buffer."
+ (interactive)
+ ;; Get the index; truncate if necessary.
+ (progn
+ (setq imenu--index-alist
+ (save-excursion
+ (save-restriction
+ (widen)
+ (funcall imenu-create-index-function))))
+ (imenu--truncate-items imenu--index-alist)))
+
(defun imenu--make-index-alist (&optional noerror)
"Create an index alist for the definitions in the current buffer.
This works by using the hook function `imenu-create-index-function'.
(or (not imenu-auto-rescan)
(and imenu-auto-rescan
(> (buffer-size) imenu-auto-rescan-maxout))))
- ;; Get the index; truncate if necessary.
- (progn
- (setq imenu--index-alist
- (save-excursion
- (save-restriction
- (widen)
- (funcall imenu-create-index-function))))
- (imenu--truncate-items imenu--index-alist)))
+ (imenu-rescan))
(or imenu--index-alist noerror
(imenu-unavailable-error
"No items suitable for an index found in this buffer"))
(or imenu--index-alist
(setq imenu--index-alist (list nil)))
- (if imenu-auto-rescan
- imenu--index-alist
- ;; Add a rescan option to the index.
- (cons imenu--rescan-item imenu--index-alist)))
+ imenu--index-alist)
(defvar imenu--cleanup-seen nil)
;; Display the completion buffer.
(minibuffer-with-setup-hook
(lambda ()
- (setq-local completion-extra-properties
- `( :category imenu
- ,@(when (eq imenu-flatten 'annotation)
- `(:annotation-function
- ,(lambda (s) (get-text-property
- 0 'imenu-section s))))
- ,@(when (eq imenu-flatten 'group)
- `(:group-function
- ,(lambda (s transform)
- (if transform s
- (get-text-property
- 0 'imenu-section s)))))))
+ (setq-local completion-extra-properties '(:category imenu))
(when imenu-eager-completion-buffer (minibuffer-completion-help)))
(setq name (completing-read prompt
prepared-index-alist
- nil t nil 'imenu--history-list name)))
+ nil t nil 'imenu--history name)))
(when (stringp name)
- (or (get-text-property 0 'imenu-choice name)
- (progn
- (setq choice (assoc name prepared-index-alist))
- (if (imenu--subalist-p choice)
- (imenu--completion-buffer (cdr choice) prompt)
- choice))))))
+ (progn
+ (setq choice (assoc name prepared-index-alist))
+ (if (imenu--subalist-p choice)
+ (imenu--completion-buffer (cdr choice) prompt)
+ choice)))))
(defun imenu--mouse-menu (index-alist event &optional title)
"Let the user select from a buffer index from a mouse menu.
name))))
(cond
((not (imenu--subalist-p item))
- (list (cons (pcase imenu-flatten
- ('annotation
- (if prefix
- (propertize name
- 'imenu-section (format " (%s)" prefix)
- 'imenu-choice item)
- (propertize new-prefix 'imenu-choice item)))
- ('group (propertize name
- 'imenu-section (or prefix "*")
- 'imenu-choice item))
- (_ new-prefix))
- pos)))
+ (list (cons new-prefix pos)))
(t
(imenu--flatten-index-alist pos concat-names new-prefix)))))
index-alist))
(if (and imenu-use-popup-menu
(or (eq imenu-use-popup-menu t) mouse-triggered))
(imenu--mouse-menu index-alist last-nonmenu-event)
- (imenu--completion-buffer index-alist prompt)))
- (and (equal result imenu--rescan-item)
- (imenu--cleanup)
- (setq result t imenu--index-alist nil)))
+ (imenu--completion-buffer index-alist prompt))))
result))
(defvar-local imenu--menubar-keymap nil)
(defun imenu--menubar-select (item)
"Use Imenu to select the function or variable named in this menu ITEM."
- (if (equal item imenu--rescan-item)
- (progn
- (imenu--cleanup)
- ;; Make sure imenu-update-menubar redoes everything.
- (setq imenu-menubar-modified-tick -1)
- (setq imenu--index-alist nil)
- (setq imenu--last-menubar-index-alist nil)
- (imenu-update-menubar)
- t)
- (imenu item)
- nil))
+ (imenu item)
+ nil)
(defun imenu-default-goto-function (_name position &rest _rest)
"Move to the given position.
(goto-char position))
(defun imenu-minibuffer-action (string)
- (let ((choice (or
- ;; FIXME: `completion--replace' leaves stale
- ;; `imenu-choice' property on parts of input that it
- ;; keeps unchagned, so we can't use the next line ATM.
- ;; (get-text-property 0 'imenu-choice string)
- (assoc string minibuffer-completion-table))))
- (when (or (imenu--subalist-p choice) (equal choice imenu--rescan-item))
+ (let ((choice (assoc string minibuffer-completion-table)))
+ (when (imenu--subalist-p choice)
(user-error "`%s' is not associated with a specific position" string))
(with-selected-window (minibuffer-selected-window)
(push-mark nil t)