aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2001-11-20 00:17:25 +0000
committerStefan Monnier2001-11-20 00:17:25 +0000
commit0cdb3baa24e42ddb2fdbc4435ce4f7fc3a3c7c14 (patch)
tree22a1ff602b2e01a851ec8b2be8299f18b953d510
parenta64c7821ce163a728fb227d477f7667483587422 (diff)
downloademacs-0cdb3baa24e42ddb2fdbc4435ce4f7fc3a3c7c14.tar.gz
emacs-0cdb3baa24e42ddb2fdbc4435ce4f7fc3a3c7c14.zip
(imenu--split-menu): Use dolist and copy-sequence.
(imenu--create-keymap-2): Remove. (imenu--create-keymap-1): Simplify, remove third argument. (imenu--generic-function): Use dolist. (imenu-find-default): New function. (imenu--completion-buffer): Use it. (imenu--mouse-menu): Use popup-menu. (imenu--menubar-select): Return t rather than calling imenu.
-rw-r--r--lisp/ChangeLog9
-rw-r--r--lisp/imenu.el256
2 files changed, 112 insertions, 153 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index e37acaccdcf..c5b87637c9b 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,14 @@
12001-11-19 Stefan Monnier <monnier@cs.yale.edu> 12001-11-19 Stefan Monnier <monnier@cs.yale.edu>
2 2
3 * imenu.el (imenu--split-menu): Use dolist and copy-sequence.
4 (imenu--create-keymap-2): Remove.
5 (imenu--create-keymap-1): Simplify, remove third argument.
6 (imenu--generic-function): Use dolist.
7 (imenu-find-default): New function.
8 (imenu--completion-buffer): Use it.
9 (imenu--mouse-menu): Use popup-menu.
10 (imenu--menubar-select): Return t rather than calling imenu.
11
3 * textmodes/fill.el (fill-delete-prefix, fill-delete-newlines): 12 * textmodes/fill.el (fill-delete-prefix, fill-delete-newlines):
4 New functions, extracted from fill-region-as-paragraph. 13 New functions, extracted from fill-region-as-paragraph.
5 (fill-region-as-paragraph): Use them. 14 (fill-region-as-paragraph): Use them.
diff --git a/lisp/imenu.el b/lisp/imenu.el
index 832834afaf8..0dce3a98a6e 100644
--- a/lisp/imenu.el
+++ b/lisp/imenu.el
@@ -207,7 +207,7 @@ The variable `imenu-case-fold-search' determines whether or not the
207regexp matches are case sensitive, and `imenu-syntax-alist' can be 207regexp matches are case sensitive, and `imenu-syntax-alist' can be
208used to alter the syntax table for the search. 208used to alter the syntax table for the search.
209 209
210For example, see the value of `lisp-imenu-generic-expression' used by 210For example, see the value of `fortran-imenu-generic-expression' used by
211`fortran-mode' with `imenu-syntax-alist' set locally to give the 211`fortran-mode' with `imenu-syntax-alist' set locally to give the
212characters which normally have \"symbol\" syntax \"word\" syntax 212characters which normally have \"symbol\" syntax \"word\" syntax
213during matching.") 213during matching.")
@@ -517,20 +517,14 @@ This variable is local in all buffers, once set.")
517 (setq keep-at-top (cons imenu--rescan-item nil) 517 (setq keep-at-top (cons imenu--rescan-item nil)
518 menulist (delq imenu--rescan-item menulist))) 518 menulist (delq imenu--rescan-item menulist)))
519 (setq tail menulist) 519 (setq tail menulist)
520 (while tail 520 (dolist (item tail)
521 (if (imenu--subalist-p (car tail)) 521 (if (imenu--subalist-p item)
522 (setq keep-at-top (cons (car tail) keep-at-top) 522 (setq keep-at-top (cons item keep-at-top)
523 menulist (delq (car tail) menulist))) 523 menulist (delq item menulist))))
524 (setq tail (cdr tail)))
525 (if imenu-sort-function 524 (if imenu-sort-function
526 (setq menulist 525 (setq menulist
527 (sort 526 (sort
528 (let ((res nil) 527 (copy-sequence menulist)
529 (oldlist menulist))
530 ;; Copy list method from the cl package `copy-list'
531 (while (consp oldlist) (push (pop oldlist) res))
532 (if res ; in case, e.g. no functions defined
533 (prog1 (nreverse res) (setcdr res oldlist))))
534 imenu-sort-function))) 528 imenu-sort-function)))
535 (if (> (length menulist) imenu-max-items) 529 (if (> (length menulist) imenu-max-items)
536 (let ((count 0)) 530 (let ((count 0))
@@ -631,35 +625,19 @@ as a way for the user to ask to recalculate the buffer's index alist."
631 alist) 625 alist)
632 t)) 626 t))
633 627
634(defun imenu--create-keymap-2 (alist counter &optional commands) 628(defun imenu--create-keymap-1 (title alist)
635 (let ((map nil)) 629 (let ((counter 0))
636 (mapcar 630 (list* 'keymap title
637 (lambda (item) 631 (mapcar
638 (cond 632 (lambda (item)
639 ((imenu--subalist-p item) 633 (list* (car item) (car item)
640 (nconc (list (setq counter (1+ counter)) 634 (cond
641 (car item) 'keymap (car item)) 635 ((imenu--subalist-p item)
642 (imenu--create-keymap-2 (cdr item) (+ counter 10) commands))) 636 (imenu--create-keymap-1 (car item) (cdr item)))
643 (t 637 (t
644 (let ((end (if commands `(lambda () 638 `(lambda () (interactive)
645 (interactive) 639 (imenu--menubar-select ',item))))))
646 (imenu--menubar-select ',item)) 640 alist))))
647 (cons '(nil) item))))
648 (cons (car item)
649 (cons (car item) end)
650 ;; Fixme: Using this (to speded up menus), instead of
651 ;; the line above, breaks the case where `imenu' is
652 ;; bound to a mouse key. The code in imenu needs
653 ;; fixing somehow to cope.
654 ;; (list 'menu-item (car item) end :key-sequence nil)
655 )))))
656 alist)))
657
658;; If COMMANDS is non-nil, make a real keymap
659;; with a real command used as the definition.
660;; If it is nil, make something suitable for x-popup-menu.
661(defun imenu--create-keymap-1 (title alist &optional commands)
662 (cons 'keymap (cons title (imenu--create-keymap-2 alist 0 commands))))
663 641
664(defun imenu--in-alist (str alist) 642(defun imenu--in-alist (str alist)
665 "Check whether the string STR is contained in multi-level ALIST." 643 "Check whether the string STR is contained in multi-level ALIST."
@@ -686,7 +664,7 @@ as a way for the user to ask to recalculate the buffer's index alist."
686 res)) 664 res))
687 665
688(defvar imenu-syntax-alist nil 666(defvar imenu-syntax-alist nil
689 "Alist of syntax table modifiers to use while executing `imenu--generic-function'. 667 "Alist of syntax table modifiers to use while in `imenu--generic-function'.
690 668
691The car of the assocs may be either a character or a string and the 669The car of the assocs may be either a character or a string and the
692cdr is a syntax description appropriate fo `modify-syntax-entry'. For 670cdr is a syntax description appropriate fo `modify-syntax-entry'. For
@@ -757,7 +735,7 @@ Their results are gathered into an index alist."
757(defvar imenu-case-fold-search t 735(defvar imenu-case-fold-search t
758 "Defines whether `imenu--generic-function' should fold case when matching. 736 "Defines whether `imenu--generic-function' should fold case when matching.
759 737
760This buffer-local variable should be set (only) by initialization code 738This variable should be set (only) by initialization code
761for modes which use `imenu--generic-function'. If it is not set, that 739for modes which use `imenu--generic-function'. If it is not set, that
762function will use the current value of `case-fold-search' to match 740function will use the current value of `case-fold-search' to match
763patterns.") 741patterns.")
@@ -797,14 +775,12 @@ PATTERNS."
797 (table (copy-syntax-table (syntax-table))) 775 (table (copy-syntax-table (syntax-table)))
798 (slist imenu-syntax-alist)) 776 (slist imenu-syntax-alist))
799 ;; Modify the syntax table used while matching regexps. 777 ;; Modify the syntax table used while matching regexps.
800 (while slist 778 (dolist (syn slist)
801 ;; The character(s) to modify may be a single char or a string. 779 ;; The character(s) to modify may be a single char or a string.
802 (if (numberp (caar slist)) 780 (if (numberp (car syn))
803 (modify-syntax-entry (caar slist) (cdar slist) table) 781 (modify-syntax-entry (car syn) (cdr syn) table)
804 (mapc (lambda (c) 782 (dolist (c (car syn))
805 (modify-syntax-entry c (cdar slist) table)) 783 (modify-syntax-entry c (cdr syn) table))))
806 (caar slist)))
807 (setq slist (cdr slist)))
808 (goto-char (point-max)) 784 (goto-char (point-max))
809 (imenu-progress-message prev-pos 0 t) 785 (imenu-progress-message prev-pos 0 t)
810 (unwind-protect ; for syntax table 786 (unwind-protect ; for syntax table
@@ -812,49 +788,44 @@ PATTERNS."
812 (set-syntax-table table) 788 (set-syntax-table table)
813 ;; map over the elements of imenu-generic-expression 789 ;; map over the elements of imenu-generic-expression
814 ;; (typically functions, variables ...) 790 ;; (typically functions, variables ...)
815 (mapc 791 (dolist (pat patterns)
816 (lambda (pat) 792 (let ((menu-title (car pat))
817 (let ((menu-title (car pat)) 793 (regexp (nth 1 pat))
818 (regexp (nth 1 pat)) 794 (index (nth 2 pat))
819 (index (nth 2 pat)) 795 (function (nth 3 pat))
820 (function (nth 3 pat)) 796 (rest (nthcdr 4 pat)))
821 (rest (nthcdr 4 pat))) 797 ;; Go backwards for convenience of adding items in order.
822 ;; Go backwards for convenience of adding items in order. 798 (goto-char (point-max))
823 (goto-char (point-max)) 799 (while (re-search-backward regexp nil t)
824 (while (re-search-backward regexp nil t) 800 (imenu-progress-message prev-pos nil t)
825 (imenu-progress-message prev-pos nil t) 801 (setq beg (match-beginning index))
826 (setq beg (match-beginning index)) 802 ;; Add this sort of submenu only when we've found an
827 ;; Add this sort of submenu only when we've found an 803 ;; item for it, avoiding empty, duff menus.
828 ;; item for it, avoiding empty, duff menus. 804 (unless (assoc menu-title index-alist)
829 (unless (assoc menu-title index-alist) 805 (push (list menu-title) index-alist))
830 (push (list menu-title) index-alist)) 806 (if imenu-use-markers
831 (if imenu-use-markers 807 (setq beg (copy-marker beg)))
832 (setq beg (copy-marker beg))) 808 (let ((item
833 (let ((item 809 (if function
834 (if function 810 (nconc (list (match-string-no-properties index)
835 (nconc (list (match-string-no-properties index) 811 beg function)
836 beg function) 812 rest)
837 rest) 813 (cons (match-string-no-properties index)
838 (cons (match-string-no-properties index) 814 beg)))
839 beg))) 815 ;; This is the desired submenu,
840 ;; This is the desired submenu, 816 ;; starting with its title (or nil).
841 ;; starting with its title (or nil). 817 (menu (assoc menu-title index-alist)))
842 (menu (assoc menu-title index-alist))) 818 ;; Insert the item unless it is already present.
843 ;; Insert the item unless it is already present. 819 (unless (member item (cdr menu))
844 (unless (member item (cdr menu)) 820 (setcdr menu
845 (setcdr menu 821 (cons item (cdr menu))))))))
846 (cons item (cdr menu))))))))
847 patterns)
848 (set-syntax-table old-table))) 822 (set-syntax-table old-table)))
849 (imenu-progress-message prev-pos 100 t) 823 (imenu-progress-message prev-pos 100 t)
850 ;; Sort each submenu by position. 824 ;; Sort each submenu by position.
851 ;; This is in case one submenu gets items from two different regexps. 825 ;; This is in case one submenu gets items from two different regexps.
852 (let ((tail index-alist)) 826 (dolist (item index-alist)
853 (while tail 827 (when (listp item)
854 (if (listp (car tail)) 828 (setcdr item (sort (cdr item) 'imenu--sort-by-position))))
855 (setcdr (car tail)
856 (sort (cdr (car tail)) 'imenu--sort-by-position)))
857 (setq tail (cdr tail))))
858 (let ((main-element (assq nil index-alist))) 829 (let ((main-element (assq nil index-alist)))
859 (nconc (delq main-element (delq 'dummy index-alist)) 830 (nconc (delq main-element (delq 'dummy index-alist))
860 (cdr main-element))))) 831 (cdr main-element)))))
@@ -865,6 +836,19 @@ PATTERNS."
865;;; 836;;;
866;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 837;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
867 838
839;; See also info-lookup-find-item
840(defun imenu-find-default (guess completions)
841 "Fuzzily find an item based on GUESS inside the alist COMPLETIONS."
842 (catch 'found
843 (let ((case-fold-search t))
844 (if (assoc guess completions) guess
845 (dolist (re (list (concat "\\`" (regexp-quote guess) "\\'")
846 (concat "\\`" (regexp-quote guess))
847 (concat (regexp-quote guess) "\\'")
848 (regexp-quote guess)))
849 (dolist (x completions)
850 (if (string-match re (car x)) (throw 'found (car x)))))))))
851
868(defun imenu--completion-buffer (index-alist &optional prompt) 852(defun imenu--completion-buffer (index-alist &optional prompt)
869 "Let the user select from INDEX-ALIST in a completion buffer with PROMPT. 853 "Let the user select from INDEX-ALIST in a completion buffer with PROMPT.
870 854
@@ -879,6 +863,8 @@ Returns t for rescan and otherwise a position number."
879 (car item)) 863 (car item))
880 (cdr item))) 864 (cdr item)))
881 index-alist))) 865 index-alist)))
866 (when (stringp name)
867 (setq name (or (imenu-find-default name prepared-index-alist) name)))
882 (cond (prompt) 868 (cond (prompt)
883 ((and name (imenu--in-alist name prepared-index-alist)) 869 ((and name (imenu--in-alist name prepared-index-alist))
884 (setq prompt (format "Index item (default %s): " name))) 870 (setq prompt (format "Index item (default %s): " name)))
@@ -896,17 +882,14 @@ Returns t for rescan and otherwise a position number."
896 (function 882 (function
897 (lambda () 883 (lambda ()
898 (let ((buffer (current-buffer))) 884 (let ((buffer (current-buffer)))
899 (save-excursion 885 (with-current-buffer "*Completions*"
900 (set-buffer "*Completions*")
901 (setq completion-reference-buffer buffer))))))) 886 (setq completion-reference-buffer buffer)))))))
902 ;; Make a completion question 887 ;; Make a completion question
903 (setq name (completing-read prompt 888 (setq name (completing-read prompt
904 prepared-index-alist 889 prepared-index-alist
905 nil t nil 'imenu--history-list name))))) 890 nil t nil 'imenu--history-list name)))))
906 (cond ((not (stringp name)) 891 (cond ((not (stringp name)) nil)
907 nil) 892 ((string= name (car imenu--rescan-item)) t)
908 ((string= name (car imenu--rescan-item))
909 t)
910 (t 893 (t
911 (setq choice (assoc name prepared-index-alist)) 894 (setq choice (assoc name prepared-index-alist))
912 (if (imenu--subalist-p choice) 895 (if (imenu--subalist-p choice)
@@ -920,43 +903,12 @@ INDEX-ALIST is the buffer index and EVENT is a mouse event.
920 903
921Returns t for rescan and otherwise an element or subelement of INDEX-ALIST." 904Returns t for rescan and otherwise an element or subelement of INDEX-ALIST."
922 (setq index-alist (imenu--split-submenus index-alist)) 905 (setq index-alist (imenu--split-submenus index-alist))
923 (let* ((menu (imenu--split-menu index-alist 906 (let* ((menu (imenu--split-menu index-alist (or title (buffer-name))))
924 (or title (buffer-name)))) 907 (map (imenu--create-keymap-1 (car menu)
925 position) 908 (if (< 1 (length (cdr menu)))
926 (setq menu (imenu--create-keymap-1 (car menu) 909 (cdr menu)
927 (if (< 1 (length (cdr menu))) 910 (cdr (car (cdr menu)))))))
928 (cdr menu) 911 (popup-menu map event)))
929 (cdr (car (cdr menu))))))
930 (setq position (x-popup-menu event menu))
931 (cond ((eq position nil)
932 position)
933 ;; If one call to x-popup-menu handled the nested menus,
934 ;; find the result by looking down the menus here.
935 ((and (listp position)
936 (numberp (car position))
937 (stringp (nth (1- (length position)) position)))
938 (let ((final menu))
939 (while position
940 (setq final (assq (car position) final))
941 (setq position (cdr position)))
942 (or (string= (car final) (car imenu--rescan-item))
943 (nthcdr 3 final))))
944 ;; If x-popup-menu went just one level and found a leaf item,
945 ;; return the INDEX-ALIST element for that.
946 ((and (consp position)
947 (stringp (car position))
948 (null (cdr position)))
949 (or (string= (car position) (car imenu--rescan-item))
950 (assq (car position) index-alist)))
951 ;; If x-popup-menu went just one level
952 ;; and found a non-leaf item (a submenu),
953 ;; recurse to handle the rest.
954 ((listp position)
955 (imenu--mouse-menu position event
956 (if title
957 (concat title imenu-level-separator
958 (car (rassq position index-alist)))
959 (car (rassq position index-alist))))))))
960 912
961(defun imenu-choose-buffer-index (&optional prompt alist) 913(defun imenu-choose-buffer-index (&optional prompt alist)
962 "Let the user select from a buffer index and return the chosen index. 914 "Let the user select from a buffer index and return the chosen index.
@@ -978,7 +930,7 @@ not.
978The returned value is of the form (INDEX-NAME . INDEX-POSITION)." 930The returned value is of the form (INDEX-NAME . INDEX-POSITION)."
979 (let (index-alist 931 (let (index-alist
980 (mouse-triggered (listp last-nonmenu-event)) 932 (mouse-triggered (listp last-nonmenu-event))
981 (result t) ) 933 (result t))
982 ;; If selected by mouse, see to that the window where the mouse is 934 ;; If selected by mouse, see to that the window where the mouse is
983 ;; really is selected. 935 ;; really is selected.
984 (and mouse-triggered 936 (and mouse-triggered
@@ -1040,22 +992,23 @@ A trivial interface to `imenu-add-to-menubar' suitable for use in a hook."
1040 (setq index-alist (imenu--split-submenus index-alist)) 992 (setq index-alist (imenu--split-submenus index-alist))
1041 (setq menu (imenu--split-menu index-alist 993 (setq menu (imenu--split-menu index-alist
1042 (buffer-name))) 994 (buffer-name)))
1043 (setq menu1 (imenu--create-keymap-1 (car menu) 995 (setq menu1 (imenu--create-keymap-1 (car menu)
1044 (if (< 1 (length (cdr menu))) 996 (if (< 1 (length (cdr menu)))
1045 (cdr menu) 997 (cdr menu)
1046 (cdr (car (cdr menu)))) 998 (cdr (car (cdr menu))))))
1047 t))
1048 (setq old (lookup-key (current-local-map) [menu-bar index])) 999 (setq old (lookup-key (current-local-map) [menu-bar index]))
1049 (setcdr old (cdr menu1))))))) 1000 (setcdr old (cdr menu1)))))))
1050 1001
1051(defun imenu--menubar-select (item) 1002(defun imenu--menubar-select (item)
1052 "Use Imenu to select the function or variable named in this menu item." 1003 "Use Imenu to select the function or variable named in this menu ITEM."
1053 (if (equal item imenu--rescan-item) 1004 (if (equal item imenu--rescan-item)
1054 (progn 1005 (progn
1055 (imenu--cleanup) 1006 (imenu--cleanup)
1056 (setq imenu--index-alist nil) 1007 (setq imenu--index-alist nil)
1057 (imenu-update-menubar)) 1008 (imenu-update-menubar)
1058 (imenu item))) 1009 t)
1010 (imenu item)
1011 nil))
1059 1012
1060(defun imenu-default-goto-function (name position &optional rest) 1013(defun imenu-default-goto-function (name position &optional rest)
1061 "Move the point to the given position. 1014 "Move the point to the given position.
@@ -1078,20 +1031,17 @@ for more information."
1078 ;; Convert a string to an alist element. 1031 ;; Convert a string to an alist element.
1079 (if (stringp index-item) 1032 (if (stringp index-item)
1080 (setq index-item (assoc index-item (imenu--make-index-alist)))) 1033 (setq index-item (assoc index-item (imenu--make-index-alist))))
1081 (and index-item 1034 (when index-item
1082 (progn 1035 (push-mark)
1083 (push-mark) 1036 (let* ((is-special-item (listp (cdr index-item)))
1084 ;; Fixme: sort this out so that we can use menu-item with 1037 (function
1085 ;; :key-sequence in imenu--create-keymap-2. 1038 (if is-special-item
1086 (let* ((is-special-item (listp (cdr index-item))) 1039 (nth 2 index-item) imenu-default-goto-function))
1087 (function 1040 (position (if is-special-item
1088 (if is-special-item 1041 (cadr index-item) (cdr index-item)))
1089 (nth 2 index-item) imenu-default-goto-function)) 1042 (rest (if is-special-item (cddr index-item))))
1090 (position (if is-special-item 1043 (apply function (car index-item) position rest))
1091 (cadr index-item) (cdr index-item))) 1044 (run-hooks 'imenu-after-jump-hook)))
1092 (rest (if is-special-item (cddr index-item))))
1093 (apply function (car index-item) position rest))))
1094 (run-hooks 'imenu-after-jump-hook))
1095 1045
1096(dolist (mess 1046(dolist (mess
1097 '("^No items suitable for an index found in this buffer$" 1047 '("^No items suitable for an index found in this buffer$"