mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-30 04:10:54 -08:00
(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.
This commit is contained in:
parent
a64c7821ce
commit
0cdb3baa24
2 changed files with 112 additions and 153 deletions
|
|
@ -1,5 +1,14 @@
|
|||
2001-11-19 Stefan Monnier <monnier@cs.yale.edu>
|
||||
|
||||
* imenu.el (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.
|
||||
|
||||
* textmodes/fill.el (fill-delete-prefix, fill-delete-newlines):
|
||||
New functions, extracted from fill-region-as-paragraph.
|
||||
(fill-region-as-paragraph): Use them.
|
||||
|
|
|
|||
256
lisp/imenu.el
256
lisp/imenu.el
|
|
@ -207,7 +207,7 @@ The variable `imenu-case-fold-search' determines whether or not the
|
|||
regexp matches are case sensitive, and `imenu-syntax-alist' can be
|
||||
used to alter the syntax table for the search.
|
||||
|
||||
For example, see the value of `lisp-imenu-generic-expression' used by
|
||||
For example, see the value of `fortran-imenu-generic-expression' used by
|
||||
`fortran-mode' with `imenu-syntax-alist' set locally to give the
|
||||
characters which normally have \"symbol\" syntax \"word\" syntax
|
||||
during matching.")
|
||||
|
|
@ -517,20 +517,14 @@ This variable is local in all buffers, once set.")
|
|||
(setq keep-at-top (cons imenu--rescan-item nil)
|
||||
menulist (delq imenu--rescan-item menulist)))
|
||||
(setq tail menulist)
|
||||
(while tail
|
||||
(if (imenu--subalist-p (car tail))
|
||||
(setq keep-at-top (cons (car tail) keep-at-top)
|
||||
menulist (delq (car tail) menulist)))
|
||||
(setq tail (cdr tail)))
|
||||
(dolist (item tail)
|
||||
(if (imenu--subalist-p item)
|
||||
(setq keep-at-top (cons item keep-at-top)
|
||||
menulist (delq item menulist))))
|
||||
(if imenu-sort-function
|
||||
(setq menulist
|
||||
(sort
|
||||
(let ((res nil)
|
||||
(oldlist menulist))
|
||||
;; Copy list method from the cl package `copy-list'
|
||||
(while (consp oldlist) (push (pop oldlist) res))
|
||||
(if res ; in case, e.g. no functions defined
|
||||
(prog1 (nreverse res) (setcdr res oldlist))))
|
||||
(copy-sequence menulist)
|
||||
imenu-sort-function)))
|
||||
(if (> (length menulist) imenu-max-items)
|
||||
(let ((count 0))
|
||||
|
|
@ -631,35 +625,19 @@ as a way for the user to ask to recalculate the buffer's index alist."
|
|||
alist)
|
||||
t))
|
||||
|
||||
(defun imenu--create-keymap-2 (alist counter &optional commands)
|
||||
(let ((map nil))
|
||||
(mapcar
|
||||
(lambda (item)
|
||||
(cond
|
||||
((imenu--subalist-p item)
|
||||
(nconc (list (setq counter (1+ counter))
|
||||
(car item) 'keymap (car item))
|
||||
(imenu--create-keymap-2 (cdr item) (+ counter 10) commands)))
|
||||
(t
|
||||
(let ((end (if commands `(lambda ()
|
||||
(interactive)
|
||||
(imenu--menubar-select ',item))
|
||||
(cons '(nil) item))))
|
||||
(cons (car item)
|
||||
(cons (car item) end)
|
||||
;; Fixme: Using this (to speded up menus), instead of
|
||||
;; the line above, breaks the case where `imenu' is
|
||||
;; bound to a mouse key. The code in imenu needs
|
||||
;; fixing somehow to cope.
|
||||
;; (list 'menu-item (car item) end :key-sequence nil)
|
||||
)))))
|
||||
alist)))
|
||||
|
||||
;; If COMMANDS is non-nil, make a real keymap
|
||||
;; with a real command used as the definition.
|
||||
;; If it is nil, make something suitable for x-popup-menu.
|
||||
(defun imenu--create-keymap-1 (title alist &optional commands)
|
||||
(cons 'keymap (cons title (imenu--create-keymap-2 alist 0 commands))))
|
||||
(defun imenu--create-keymap-1 (title alist)
|
||||
(let ((counter 0))
|
||||
(list* 'keymap title
|
||||
(mapcar
|
||||
(lambda (item)
|
||||
(list* (car item) (car item)
|
||||
(cond
|
||||
((imenu--subalist-p item)
|
||||
(imenu--create-keymap-1 (car item) (cdr item)))
|
||||
(t
|
||||
`(lambda () (interactive)
|
||||
(imenu--menubar-select ',item))))))
|
||||
alist))))
|
||||
|
||||
(defun imenu--in-alist (str alist)
|
||||
"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."
|
|||
res))
|
||||
|
||||
(defvar imenu-syntax-alist nil
|
||||
"Alist of syntax table modifiers to use while executing `imenu--generic-function'.
|
||||
"Alist of syntax table modifiers to use while in `imenu--generic-function'.
|
||||
|
||||
The car of the assocs may be either a character or a string and the
|
||||
cdr is a syntax description appropriate fo `modify-syntax-entry'. For
|
||||
|
|
@ -757,7 +735,7 @@ Their results are gathered into an index alist."
|
|||
(defvar imenu-case-fold-search t
|
||||
"Defines whether `imenu--generic-function' should fold case when matching.
|
||||
|
||||
This buffer-local variable should be set (only) by initialization code
|
||||
This variable should be set (only) by initialization code
|
||||
for modes which use `imenu--generic-function'. If it is not set, that
|
||||
function will use the current value of `case-fold-search' to match
|
||||
patterns.")
|
||||
|
|
@ -797,14 +775,12 @@ PATTERNS."
|
|||
(table (copy-syntax-table (syntax-table)))
|
||||
(slist imenu-syntax-alist))
|
||||
;; Modify the syntax table used while matching regexps.
|
||||
(while slist
|
||||
(dolist (syn slist)
|
||||
;; The character(s) to modify may be a single char or a string.
|
||||
(if (numberp (caar slist))
|
||||
(modify-syntax-entry (caar slist) (cdar slist) table)
|
||||
(mapc (lambda (c)
|
||||
(modify-syntax-entry c (cdar slist) table))
|
||||
(caar slist)))
|
||||
(setq slist (cdr slist)))
|
||||
(if (numberp (car syn))
|
||||
(modify-syntax-entry (car syn) (cdr syn) table)
|
||||
(dolist (c (car syn))
|
||||
(modify-syntax-entry c (cdr syn) table))))
|
||||
(goto-char (point-max))
|
||||
(imenu-progress-message prev-pos 0 t)
|
||||
(unwind-protect ; for syntax table
|
||||
|
|
@ -812,49 +788,44 @@ PATTERNS."
|
|||
(set-syntax-table table)
|
||||
;; map over the elements of imenu-generic-expression
|
||||
;; (typically functions, variables ...)
|
||||
(mapc
|
||||
(lambda (pat)
|
||||
(let ((menu-title (car pat))
|
||||
(regexp (nth 1 pat))
|
||||
(index (nth 2 pat))
|
||||
(function (nth 3 pat))
|
||||
(rest (nthcdr 4 pat)))
|
||||
;; Go backwards for convenience of adding items in order.
|
||||
(goto-char (point-max))
|
||||
(while (re-search-backward regexp nil t)
|
||||
(imenu-progress-message prev-pos nil t)
|
||||
(setq beg (match-beginning index))
|
||||
;; Add this sort of submenu only when we've found an
|
||||
;; item for it, avoiding empty, duff menus.
|
||||
(unless (assoc menu-title index-alist)
|
||||
(push (list menu-title) index-alist))
|
||||
(if imenu-use-markers
|
||||
(setq beg (copy-marker beg)))
|
||||
(let ((item
|
||||
(if function
|
||||
(nconc (list (match-string-no-properties index)
|
||||
beg function)
|
||||
rest)
|
||||
(cons (match-string-no-properties index)
|
||||
beg)))
|
||||
;; This is the desired submenu,
|
||||
;; starting with its title (or nil).
|
||||
(menu (assoc menu-title index-alist)))
|
||||
;; Insert the item unless it is already present.
|
||||
(unless (member item (cdr menu))
|
||||
(setcdr menu
|
||||
(cons item (cdr menu))))))))
|
||||
patterns)
|
||||
(dolist (pat patterns)
|
||||
(let ((menu-title (car pat))
|
||||
(regexp (nth 1 pat))
|
||||
(index (nth 2 pat))
|
||||
(function (nth 3 pat))
|
||||
(rest (nthcdr 4 pat)))
|
||||
;; Go backwards for convenience of adding items in order.
|
||||
(goto-char (point-max))
|
||||
(while (re-search-backward regexp nil t)
|
||||
(imenu-progress-message prev-pos nil t)
|
||||
(setq beg (match-beginning index))
|
||||
;; Add this sort of submenu only when we've found an
|
||||
;; item for it, avoiding empty, duff menus.
|
||||
(unless (assoc menu-title index-alist)
|
||||
(push (list menu-title) index-alist))
|
||||
(if imenu-use-markers
|
||||
(setq beg (copy-marker beg)))
|
||||
(let ((item
|
||||
(if function
|
||||
(nconc (list (match-string-no-properties index)
|
||||
beg function)
|
||||
rest)
|
||||
(cons (match-string-no-properties index)
|
||||
beg)))
|
||||
;; This is the desired submenu,
|
||||
;; starting with its title (or nil).
|
||||
(menu (assoc menu-title index-alist)))
|
||||
;; Insert the item unless it is already present.
|
||||
(unless (member item (cdr menu))
|
||||
(setcdr menu
|
||||
(cons item (cdr menu))))))))
|
||||
(set-syntax-table old-table)))
|
||||
(imenu-progress-message prev-pos 100 t)
|
||||
;; Sort each submenu by position.
|
||||
;; This is in case one submenu gets items from two different regexps.
|
||||
(let ((tail index-alist))
|
||||
(while tail
|
||||
(if (listp (car tail))
|
||||
(setcdr (car tail)
|
||||
(sort (cdr (car tail)) 'imenu--sort-by-position)))
|
||||
(setq tail (cdr tail))))
|
||||
(dolist (item index-alist)
|
||||
(when (listp item)
|
||||
(setcdr item (sort (cdr item) 'imenu--sort-by-position))))
|
||||
(let ((main-element (assq nil index-alist)))
|
||||
(nconc (delq main-element (delq 'dummy index-alist))
|
||||
(cdr main-element)))))
|
||||
|
|
@ -865,6 +836,19 @@ PATTERNS."
|
|||
;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; See also info-lookup-find-item
|
||||
(defun imenu-find-default (guess completions)
|
||||
"Fuzzily find an item based on GUESS inside the alist COMPLETIONS."
|
||||
(catch 'found
|
||||
(let ((case-fold-search t))
|
||||
(if (assoc guess completions) guess
|
||||
(dolist (re (list (concat "\\`" (regexp-quote guess) "\\'")
|
||||
(concat "\\`" (regexp-quote guess))
|
||||
(concat (regexp-quote guess) "\\'")
|
||||
(regexp-quote guess)))
|
||||
(dolist (x completions)
|
||||
(if (string-match re (car x)) (throw 'found (car x)))))))))
|
||||
|
||||
(defun imenu--completion-buffer (index-alist &optional prompt)
|
||||
"Let the user select from INDEX-ALIST in a completion buffer with PROMPT.
|
||||
|
||||
|
|
@ -879,6 +863,8 @@ Returns t for rescan and otherwise a position number."
|
|||
(car item))
|
||||
(cdr item)))
|
||||
index-alist)))
|
||||
(when (stringp name)
|
||||
(setq name (or (imenu-find-default name prepared-index-alist) name)))
|
||||
(cond (prompt)
|
||||
((and name (imenu--in-alist name prepared-index-alist))
|
||||
(setq prompt (format "Index item (default %s): " name)))
|
||||
|
|
@ -896,17 +882,14 @@ Returns t for rescan and otherwise a position number."
|
|||
(function
|
||||
(lambda ()
|
||||
(let ((buffer (current-buffer)))
|
||||
(save-excursion
|
||||
(set-buffer "*Completions*")
|
||||
(with-current-buffer "*Completions*"
|
||||
(setq completion-reference-buffer buffer)))))))
|
||||
;; Make a completion question
|
||||
(setq name (completing-read prompt
|
||||
prepared-index-alist
|
||||
nil t nil 'imenu--history-list name)))))
|
||||
(cond ((not (stringp name))
|
||||
nil)
|
||||
((string= name (car imenu--rescan-item))
|
||||
t)
|
||||
(cond ((not (stringp name)) nil)
|
||||
((string= name (car imenu--rescan-item)) t)
|
||||
(t
|
||||
(setq choice (assoc name prepared-index-alist))
|
||||
(if (imenu--subalist-p choice)
|
||||
|
|
@ -920,43 +903,12 @@ INDEX-ALIST is the buffer index and EVENT is a mouse event.
|
|||
|
||||
Returns t for rescan and otherwise an element or subelement of INDEX-ALIST."
|
||||
(setq index-alist (imenu--split-submenus index-alist))
|
||||
(let* ((menu (imenu--split-menu index-alist
|
||||
(or title (buffer-name))))
|
||||
position)
|
||||
(setq menu (imenu--create-keymap-1 (car menu)
|
||||
(if (< 1 (length (cdr menu)))
|
||||
(cdr menu)
|
||||
(cdr (car (cdr menu))))))
|
||||
(setq position (x-popup-menu event menu))
|
||||
(cond ((eq position nil)
|
||||
position)
|
||||
;; If one call to x-popup-menu handled the nested menus,
|
||||
;; find the result by looking down the menus here.
|
||||
((and (listp position)
|
||||
(numberp (car position))
|
||||
(stringp (nth (1- (length position)) position)))
|
||||
(let ((final menu))
|
||||
(while position
|
||||
(setq final (assq (car position) final))
|
||||
(setq position (cdr position)))
|
||||
(or (string= (car final) (car imenu--rescan-item))
|
||||
(nthcdr 3 final))))
|
||||
;; If x-popup-menu went just one level and found a leaf item,
|
||||
;; return the INDEX-ALIST element for that.
|
||||
((and (consp position)
|
||||
(stringp (car position))
|
||||
(null (cdr position)))
|
||||
(or (string= (car position) (car imenu--rescan-item))
|
||||
(assq (car position) index-alist)))
|
||||
;; If x-popup-menu went just one level
|
||||
;; and found a non-leaf item (a submenu),
|
||||
;; recurse to handle the rest.
|
||||
((listp position)
|
||||
(imenu--mouse-menu position event
|
||||
(if title
|
||||
(concat title imenu-level-separator
|
||||
(car (rassq position index-alist)))
|
||||
(car (rassq position index-alist))))))))
|
||||
(let* ((menu (imenu--split-menu index-alist (or title (buffer-name))))
|
||||
(map (imenu--create-keymap-1 (car menu)
|
||||
(if (< 1 (length (cdr menu)))
|
||||
(cdr menu)
|
||||
(cdr (car (cdr menu)))))))
|
||||
(popup-menu map event)))
|
||||
|
||||
(defun imenu-choose-buffer-index (&optional prompt alist)
|
||||
"Let the user select from a buffer index and return the chosen index.
|
||||
|
|
@ -978,7 +930,7 @@ not.
|
|||
The returned value is of the form (INDEX-NAME . INDEX-POSITION)."
|
||||
(let (index-alist
|
||||
(mouse-triggered (listp last-nonmenu-event))
|
||||
(result t) )
|
||||
(result t))
|
||||
;; If selected by mouse, see to that the window where the mouse is
|
||||
;; really is selected.
|
||||
(and mouse-triggered
|
||||
|
|
@ -1040,22 +992,23 @@ A trivial interface to `imenu-add-to-menubar' suitable for use in a hook."
|
|||
(setq index-alist (imenu--split-submenus index-alist))
|
||||
(setq menu (imenu--split-menu index-alist
|
||||
(buffer-name)))
|
||||
(setq menu1 (imenu--create-keymap-1 (car menu)
|
||||
(setq menu1 (imenu--create-keymap-1 (car menu)
|
||||
(if (< 1 (length (cdr menu)))
|
||||
(cdr menu)
|
||||
(cdr (car (cdr menu))))
|
||||
t))
|
||||
(cdr (car (cdr menu))))))
|
||||
(setq old (lookup-key (current-local-map) [menu-bar index]))
|
||||
(setcdr old (cdr menu1)))))))
|
||||
|
||||
(defun imenu--menubar-select (item)
|
||||
"Use Imenu to select the function or variable named in this menu item."
|
||||
"Use Imenu to select the function or variable named in this menu ITEM."
|
||||
(if (equal item imenu--rescan-item)
|
||||
(progn
|
||||
(imenu--cleanup)
|
||||
(setq imenu--index-alist nil)
|
||||
(imenu-update-menubar))
|
||||
(imenu item)))
|
||||
(imenu-update-menubar)
|
||||
t)
|
||||
(imenu item)
|
||||
nil))
|
||||
|
||||
(defun imenu-default-goto-function (name position &optional rest)
|
||||
"Move the point to the given position.
|
||||
|
|
@ -1078,20 +1031,17 @@ for more information."
|
|||
;; Convert a string to an alist element.
|
||||
(if (stringp index-item)
|
||||
(setq index-item (assoc index-item (imenu--make-index-alist))))
|
||||
(and index-item
|
||||
(progn
|
||||
(push-mark)
|
||||
;; Fixme: sort this out so that we can use menu-item with
|
||||
;; :key-sequence in imenu--create-keymap-2.
|
||||
(let* ((is-special-item (listp (cdr index-item)))
|
||||
(function
|
||||
(if is-special-item
|
||||
(nth 2 index-item) imenu-default-goto-function))
|
||||
(position (if is-special-item
|
||||
(cadr index-item) (cdr index-item)))
|
||||
(rest (if is-special-item (cddr index-item))))
|
||||
(apply function (car index-item) position rest))))
|
||||
(run-hooks 'imenu-after-jump-hook))
|
||||
(when index-item
|
||||
(push-mark)
|
||||
(let* ((is-special-item (listp (cdr index-item)))
|
||||
(function
|
||||
(if is-special-item
|
||||
(nth 2 index-item) imenu-default-goto-function))
|
||||
(position (if is-special-item
|
||||
(cadr index-item) (cdr index-item)))
|
||||
(rest (if is-special-item (cddr index-item))))
|
||||
(apply function (car index-item) position rest))
|
||||
(run-hooks 'imenu-after-jump-hook)))
|
||||
|
||||
(dolist (mess
|
||||
'("^No items suitable for an index found in this buffer$"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue