comparison lisp/imenu.el @ 13798:4eac65d000d3

(imenu-update-menubar): New function. (imenu-add-to-menubar): Use an ordinary menu bar submenu. Add imenu-add-to-menubar to menu-bar-update-hook to update the submenu. (imenu--make-index-alist): Add noerror argument. (imenu--menubar-select): New function. (imenu--create-keymap-1, imenu--create-keymap-2): New arg COMMANDS. (imenu): Allow a string as arg.
author Karl Heuer <kwzh@gnu.org>
date Thu, 21 Dec 1995 17:47:08 +0000
parents 9681c6008417
children 187735b53d52
comparison
equal deleted inserted replaced
13797:d00c8f107a39 13798:4eac65d000d3
332 ;; The latest buffer index. 332 ;; The latest buffer index.
333 ;; Buffer local. 333 ;; Buffer local.
334 (defvar imenu--index-alist nil) 334 (defvar imenu--index-alist nil)
335 (make-variable-buffer-local 'imenu--index-alist) 335 (make-variable-buffer-local 'imenu--index-alist)
336 336
337 ;; The latest buffer index used to update the menu bar menu.
338 (defvar imenu--last-menubar-index-alist nil)
339 (make-variable-buffer-local 'imenu--last-menubar-index-alist)
340
337 ;; History list for 'jump-to-function-in-buffer'. 341 ;; History list for 'jump-to-function-in-buffer'.
338 ;; Making this buffer local caused it not to work! 342 ;; Making this buffer local caused it not to work!
339 (defvar imenu--history-list nil) 343 (defvar imenu--history-list nil)
340 344
341 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 345 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
408 ;;; Find all items in this buffer that should be in the index. 412 ;;; Find all items in this buffer that should be in the index.
409 ;;; Returns an alist on the form 413 ;;; Returns an alist on the form
410 ;;; ((NAME . POSITION) (NAME . POSITION) ...) 414 ;;; ((NAME . POSITION) (NAME . POSITION) ...)
411 ;;; 415 ;;;
412 416
413 (defun imenu--make-index-alist () 417 (defun imenu--make-index-alist (&optional noerror)
414 ;; Create a list for this buffer only when needed. 418 ;; Create a list for this buffer only when needed.
415 (or (and imenu--index-alist 419 (or (and imenu--index-alist
416 (or (not imenu-auto-rescan) 420 (or (not imenu-auto-rescan)
417 (and imenu-auto-rescan 421 (and imenu-auto-rescan
418 (> (buffer-size) imenu-auto-rescan-maxout)))) 422 (> (buffer-size) imenu-auto-rescan-maxout))))
419 ;; Get the index 423 ;; Get the index
420 (setq imenu--index-alist 424 (setq imenu--index-alist
421 (save-excursion 425 (save-excursion
422 (funcall imenu-create-index-function)))) 426 (funcall imenu-create-index-function))))
427 (or imenu--index-alist noerror
428 (error "No items suitable for an index found in this buffer"))
423 (or imenu--index-alist 429 (or imenu--index-alist
424 (error "No items suitable for an index found in this buffer")) 430 (setq imenu--index-alist (list nil)))
425 ;; Add a rescan option to the index. 431 ;; Add a rescan option to the index.
426 (cons imenu--rescan-item imenu--index-alist)) 432 (cons imenu--rescan-item imenu--index-alist))
427 ;;; 433 ;;;
428 ;;; Find all markers in alist and makes 434 ;;; Find all markers in alist and makes
429 ;;; them point nowhere. 435 ;;; them point nowhere.
444 ((consp (cdr item)) 450 ((consp (cdr item))
445 (imenu--cleanup (cdr item)))))) 451 (imenu--cleanup (cdr item))))))
446 alist) 452 alist)
447 t)) 453 t))
448 454
449 (defun imenu--create-keymap-2 (alist counter) 455 (defun imenu--create-keymap-2 (alist counter &optional commands)
450 (let ((map nil)) 456 (let ((map nil))
451 (mapcar 457 (mapcar
452 (function 458 (function
453 (lambda (item) 459 (lambda (item)
454 (cond 460 (cond
455 ((listp (cdr item)) 461 ((listp (cdr item))
456 (append (list (incf counter) (car item) 'keymap (car item)) 462 (append (list (incf counter) (car item) 'keymap (car item))
457 (imenu--create-keymap-2 (cdr item) (+ counter 10)))) 463 (imenu--create-keymap-2 (cdr item) (+ counter 10) commands)))
458 (t 464 (t
459 (let ((end (cons '(nil) t))) 465 (let ((end (if commands (list 'lambda 'nil '(interactive)
466 (list 'imenu--menubar-select item))
467 (cons '(nil) t))))
460 (cons (car item) 468 (cons (car item)
461 (cons (car item) end)))) 469 (cons (car item) end))))
462 ))) 470 )))
463 alist))) 471 alist)))
464 472
465 (defun imenu--create-keymap-1 (title alist) 473 ;; If COMMANDS is non-nil, make a real keymap
466 (append (list 'keymap title) (imenu--create-keymap-2 alist 0))) 474 ;; with a real command used as the definition.
475 ;; If it is nil, make something suitable for x-popup-menu.
476 (defun imenu--create-keymap-1 (title alist &optional commands)
477 (append (list 'keymap title) (imenu--create-keymap-2 alist 0 commands)))
467 478
468 479
469 (defun imenu--in-alist (str alist) 480 (defun imenu--in-alist (str alist)
470 "Check whether the string STR is contained in multi-level ALIST." 481 "Check whether the string STR is contained in multi-level ALIST."
471 (let (elt head tail res) 482 (let (elt head tail res)
767 (setq imenu--index-alist nil))) 778 (setq imenu--index-alist nil)))
768 result)) 779 result))
769 780
770 ;;;###autoload 781 ;;;###autoload
771 (defun imenu-add-to-menubar (name) 782 (defun imenu-add-to-menubar (name)
772 "Adds an \"imenu\" entry to the menubar for the current local keymap. 783 "Adds an \"imenu\" entry to the menu bar for the current major mode.
773 NAME is the string naming the menu to be added. 784 NAME is a string used to name the menu bar item.
774 See 'imenu' for more information." 785 See `imenu' for more information."
775 (interactive "sMenu name: ") 786 (interactive "sImenu menu item name: ")
776 (and window-system 787 (define-key (current-local-map) [menu-bar index]
777 (define-key (current-local-map) [menu-bar index] 788 (cons name (nconc (make-sparse-keymap "Imenu") (make-sparse-keymap))))
778 (cons name 'imenu)))) 789 (add-hook 'menu-bar-update-hook 'imenu-update-menubar))
790
791 (defun imenu-update-menubar ()
792 (and (current-local-map)
793 (keymapp (lookup-key (current-local-map) [menu-bar index]))
794 (let ((index-alist (imenu--make-index-alist t)))
795 ;; Don't bother updating if the index-alist has not changed
796 ;; since the last time we did it.
797 (or (equal index-alist imenu--last-menubar-index-alist)
798 (let (menu menu1 old)
799 (setq imenu--last-menubar-index-alist index-alist)
800 (setq menu (imenu--split-menu
801 (if imenu-sort-function
802 (sort
803 (let ((res nil)
804 (oldlist index-alist))
805 ;; Copy list method from the cl package `copy-list'
806 (while (consp oldlist) (push (pop oldlist) res))
807 (prog1 (nreverse res) (setcdr res oldlist)))
808 imenu-sort-function)
809 index-alist)
810 (buffer-name)))
811 (setq menu1 (imenu--create-keymap-1 (car menu)
812 (if (< 1 (length (cdr menu)))
813 (cdr menu)
814 (cdr (car (cdr menu))))
815 t))
816 (setq old (lookup-key (current-local-map) [menu-bar index]))
817 (if (keymapp old)
818 (setcdr (nthcdr 2 old) menu1)))))))
819
820 (defun imenu--menubar-select (item)
821 "Use Imenu to select the function or variable named in this menu item."
822 (interactive)
823 (imenu item))
779 824
780 ;;;###autoload 825 ;;;###autoload
781 (defun imenu (index-item) 826 (defun imenu (index-item)
782 "Jump to a place in the buffer chosen using a buffer menu or mouse menu. 827 "Jump to a place in the buffer chosen using a buffer menu or mouse menu.
783 See `imenu-choose-buffer-index' for more information." 828 See `imenu-choose-buffer-index' for more information."
784 (interactive 829 (interactive
785 (list (save-restriction 830 (list (save-restriction
786 (widen) 831 (widen)
787 (imenu-choose-buffer-index)))) 832 (car (imenu-choose-buffer-index)))))
833 ;; Convert a string to an alist element.
834 (if (stringp index-item)
835 (setq index-item (assoc index-item (imenu--make-index-alist))))
788 (and index-item 836 (and index-item
789 (progn 837 (progn
790 (push-mark) 838 (push-mark)
791 (cond 839 (cond
792 ((markerp (cdr index-item)) 840 ((markerp (cdr index-item))