Mercurial > emacs
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)) |