- offset elem pair mark)
- (while alist
- (setq elem (car-safe alist)
- alist (cdr-safe alist))
- ;; Elements of alist are either ("name" . marker), or
- ;; ("submenu" ("name" . marker) ... ).
- (unless (listp (cdr elem))
- (setq elem (list elem)))
- (while elem
- (setq pair (car elem)
- elem (cdr elem))
- (and (consp pair)
- (number-or-marker-p (setq mark (cdr pair)))
- (if (>= (setq offset (- (point) mark)) 0)
- (if (< offset minoffset) ; find the closest item
- (setq minoffset offset
- name (car pair)))
- ;; Entries in order, so can skip all those after point.
- (setq elem nil)))))))
+ offset pair mark imstack namestack)
+ ;; Elements of alist are either ("name" . marker), or
+ ;; ("submenu" ("name" . marker) ... ). The list can be
+ ;; arbitrarily nested.
+ (while (or alist imstack)
+ (if alist
+ (progn
+ (setq pair (car-safe alist)
+ alist (cdr-safe alist))
+
+ (cond ((atom pair)) ; skip anything not a cons
+
+ ((imenu--subalist-p pair)
+ (setq imstack (cons alist imstack)
+ namestack (cons (car pair) namestack)
+ alist (cdr pair)))
+
+ ((number-or-marker-p (setq mark (cdr pair)))
+ (if (>= (setq offset (- (point) mark)) 0)
+ (if (< offset minoffset) ; find the closest item
+ (setq minoffset offset
+ name (funcall
+ which-func-imenu-joiner-function
+ (reverse (cons (car pair) namestack)))))
+ ;; Entries in order, so can skip all those after point.
+ (setq alist nil
+ imstack nil)))))
+
+ (setq alist (car imstack)
+ namestack (cdr namestack)
+ imstack (cdr imstack))))))
+