X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/6d7d9efad3111b3145d6cf46b45f1cebf5faf2ca..96439b6aabaca49a1fb43bf5d526e82f12b0924b:/lisp/imenu.el diff --git a/lisp/imenu.el b/lisp/imenu.el index c35f963e99..dc5241420b 100644 --- a/lisp/imenu.el +++ b/lisp/imenu.el @@ -1,6 +1,6 @@ ;;; imenu.el --- Framework for mode-specific buffer indexes. -;; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. +;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc. ;; Author: Ake Stenhoff ;; Lars Lindberg @@ -65,22 +65,49 @@ ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defvar imenu-auto-rescan nil - "*Non-nil means Imenu should always rescan the buffers.") +(defgroup imenu nil + "Mode-specific buffer indexes." + :group 'matching + :group 'frames) -(defvar imenu-auto-rescan-maxout 60000 - "* auto-rescan is disabled in buffers larger than this. -This variable is buffer-local.") +(defcustom imenu-use-markers t + "*Non-nil means use markers instead of integers for Imenu buffer positions. +Setting this to nil makes Imenu work faster. -(defvar imenu-always-use-completion-buffer-p nil +This might not yet be honored by all index-building functions." + :type 'boolean + :group 'imenu) + + +(defcustom imenu-max-item-length 60 + "*If a number, truncate Imenu entries to that length." + :type 'integer + :group 'imenu) + +(defcustom imenu-auto-rescan nil + "*Non-nil means Imenu should always rescan the buffers." + :type 'boolean + :group 'imenu) + +(defcustom imenu-auto-rescan-maxout 60000 + "*Imenu auto-rescan is disabled in buffers larger than this size. +This variable is buffer-local." + :type 'integer + :group 'imenu) + +(defcustom imenu-always-use-completion-buffer-p nil "*Set this to non-nil for displaying the index in a completion buffer. -Non-nil means always display the index in a completion buffer. -Nil means display the index as a mouse menu when the mouse was -used to invoke `imenu'. -`never' means never automatically display a listing of any kind.") +`never' means never automatically display a listing of any kind. +A value of nil (the default) means display the index as a mouse menu +if the mouse was used to invoke `imenu'. +Another non-nil value means always display the index in a completion buffer." + :type '(choice (const :tag "On Mouse" nil) + (const :tag "Never" never) + (sexp :tag "Always" :format "%t\n" t)) + :group 'imenu) -(defvar imenu-sort-function nil +(defcustom imenu-sort-function nil "*The function to use for sorting the index mouse-menu. Affects only the mouse index menu. @@ -93,33 +120,43 @@ Set it to `imenu--sort-by-name' if you want alphabetic sorting. The function should take two arguments and return T if the first element should come before the second. The arguments are cons cells; -\(NAME . POSITION). Look at `imenu--sort-by-name' for an example.") +\(NAME . POSITION). Look at `imenu--sort-by-name' for an example." + :type 'function + :group 'imenu) -(defvar imenu-max-items 25 - "*Maximum number of elements in an mouse menu for Imenu.") +(defcustom imenu-max-items 25 + "*Maximum number of elements in a mouse menu for Imenu." + :type 'integer + :group 'imenu) -(defvar imenu-scanning-message "Scanning buffer for index (%3d%%)" +(defcustom imenu-scanning-message "Scanning buffer for index (%3d%%)" "*Progress message during the index scanning of the buffer. -If non-nil, user gets a message during the scanning of the buffer +If non-nil, user gets a message during the scanning of the buffer. Relevant only if the mode-specific function that creates the buffer -index use `imenu-progress-message'.") +index use `imenu-progress-message'." + :type 'string + :group 'imenu) -(defvar imenu-space-replacement "^" +(defcustom imenu-space-replacement "^" "*The replacement string for spaces in index names. Used when presenting the index in a completion-buffer to make the -names work as tokens.") +names work as tokens." + :type 'string + :group 'imenu) -(defvar imenu-level-separator ":" +(defcustom imenu-level-separator ":" "*The separator between index names of different levels. Used for making mouse-menu titles and for flattening nested indexes -with name concatenation.") +with name concatenation." + :type 'string + :group 'imenu) ;;;###autoload (defvar imenu-generic-expression nil "The regex pattern to use for creating a buffer index. -If non-nil this pattern is passed to `imenu-create-index-with-pattern' +If non-nil this pattern is passed to `imenu--generic-function' to create a buffer index. The value should be an alist with elements that look like this: @@ -191,6 +228,12 @@ This function is called after the function pointed out by `imenu-prev-index-position-function'.") (make-variable-buffer-local 'imenu-extract-index-name-function) +(defvar imenu-default-goto-function 'imenu-default-goto-function + "The default function called when selecting an Imenu item. +The function in this variable is called when selecting a normal index-item.") +(make-variable-buffer-local 'imenu-default-goto-function) + + (defun imenu--subalist-p (item) (and (consp (cdr item)) (listp (cadr item)) (not (eq (caadr item) 'lambda)))) @@ -226,12 +269,11 @@ This function is called after the function pointed out by (defun imenu-example--name-and-position () (save-excursion (forward-sexp -1) - (let ((beg (point)) - (end (progn (forward-sexp) (point))) - (marker (make-marker))) - (set-marker marker beg) + ;; [ydi] modified for imenu-use-markers + (let ((beg (if imenu-use-markers (point-marker) (point))) + (end (progn (forward-sexp) (point)))) (cons (buffer-substring beg end) - marker)))) + beg)))) ;;; ;;; Lisp @@ -447,6 +489,21 @@ This function is called after the function pointed out by elt))) alist)) +;;; Truncate all strings in MENULIST to imenu-max-item-length +(defun imenu--truncate-items (menulist) + (mapcar (function + (lambda (item) + (cond + ((consp (cdr item)) + (imenu--truncate-items (cdr item))) + (t + ;; truncate if necessary + (if (and (numberp imenu-max-item-length) + (> (length (car item)) imenu-max-item-length)) + (setcar item (substring (car item) 0 imenu-max-item-length))))))) + menulist)) + + (defun imenu--make-index-alist (&optional noerror) "Create an index-alist for the definitions in the current buffer. @@ -462,10 +519,14 @@ as a way for the user to ask to recalculate the buffer's index alist." (or (not imenu-auto-rescan) (and imenu-auto-rescan (> (buffer-size) imenu-auto-rescan-maxout)))) - ;; Get the index - (setq imenu--index-alist - (save-excursion - (funcall imenu-create-index-function)))) + ;; Get the index; truncate if necessary + (progn + (setq imenu--index-alist + (save-excursion + (save-restriction + (widen) + (funcall imenu-create-index-function)))) + (imenu--truncate-items imenu--index-alist))) (or imenu--index-alist noerror (error "No items suitable for an index found in this buffer")) (or imenu--index-alist @@ -569,14 +630,16 @@ Their results are gathered into an index alist." (save-excursion (setq name (funcall imenu-extract-index-name-function))) (and (stringp name) - (push (cons name (point)) index-alist))) + ;; [ydi] updated for imenu-use-markers + (push (cons name (if imenu-use-markers (point-marker) (point))) + index-alist))) (imenu-progress-message prev-pos 100 t) index-alist)) ;; Use generic expression if possible. ((and imenu-generic-expression) (imenu--generic-function imenu-generic-expression)) (t - (error "The mode `%s' does not support Imenu" mode-name)))) + (error "This buffer cannot use `imenu-default-create-index-function'")))) (defun imenu--replace-spaces (name replacement) ;; Replace all spaces in NAME with REPLACEMENT. @@ -675,15 +738,17 @@ pattern. (rest (cddddr pat))) (if (and (not found) ; Only allow one entry; (looking-at regexp)) - (let ((beg (make-marker)) + (let ((beg (match-beginning index)) (end (match-end index))) - (set-marker beg (match-beginning index)) (setq found t) (push (let ((name (buffer-substring-no-properties beg end))) + ;; [ydi] updated for imenu-use-markers + (if imenu-use-markers + (setq beg (set-marker (make-marker) beg))) (if function - (nconc (list name function name beg) + (nconc (list name beg function) rest) (cons name beg))) (cdr @@ -836,15 +901,19 @@ The returned value is of the form (INDEX-NAME . INDEX-POSITION)." NAME is a string used to name the menu bar item. See the command `imenu' for more information." (interactive "sImenu menu item name: ") - (let ((newmap (make-sparse-keymap)) - (menu-bar (lookup-key (current-local-map) [menu-bar]))) - (define-key newmap [menu-bar] - (append (make-sparse-keymap) menu-bar)) - (define-key newmap [menu-bar index] - (cons name (nconc (make-sparse-keymap "Imenu") - (make-sparse-keymap)))) - (use-local-map (append newmap (current-local-map)))) - (add-hook 'menu-bar-update-hook 'imenu-update-menubar)) + (if (or (and (fboundp imenu-prev-index-position-function) + (fboundp imenu-extract-index-name-function)) + (and imenu-generic-expression)) + (let ((newmap (make-sparse-keymap)) + (menu-bar (lookup-key (current-local-map) [menu-bar]))) + (define-key newmap [menu-bar] + (append (make-sparse-keymap) menu-bar)) + (define-key newmap [menu-bar index] + (cons name (nconc (make-sparse-keymap "Imenu") + (make-sparse-keymap)))) + (use-local-map (append newmap (current-local-map))) + (add-hook 'menu-bar-update-hook 'imenu-update-menubar)) + (error "The mode `%s' does not support Imenu" mode-name))) (defvar imenu-buffer-menubar nil) @@ -870,45 +939,43 @@ See the command `imenu' for more information." (defun imenu--menubar-select (item) "Use Imenu to select the function or variable named in this menu item." - (if (equal item '("*Rescan*" . -99)) + (if (equal item imenu--rescan-item) (progn (imenu--cleanup) (setq imenu--index-alist nil) (imenu-update-menubar)) (imenu item))) +(defun imenu-default-goto-function (name position &optional rest) + "This function is used for moving the point to POSITION. +The NAME and REST parameters are not used, they are here just to make +this function have the same interface as a function placed in a special +index-item." + (if (or (< position (point-min)) + (> position (point-max))) + ;; widen if outside narrowing + (widen)) + (goto-char position)) + ;;;###autoload (defun imenu (index-item) "Jump to a place in the buffer chosen using a buffer menu or mouse menu. See `imenu-choose-buffer-index' for more information." - (interactive - (list (save-restriction - (widen) - (imenu-choose-buffer-index)))) + (interactive (list (imenu-choose-buffer-index))) ;; 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) - (cond - ((markerp (cdr index-item)) - (if (or (< (marker-position (cdr index-item)) (point-min)) - (> (marker-position (cdr index-item)) (point-max))) - ;; widen if outside narrowing - (widen)) - (goto-char (marker-position (cdr index-item)))) - ((imenu--subalist-p index-item) - (if (or (< (cdr index-item) (point-min)) - (> (cdr index-item) (point-max))) - ;; widen if outside narrowing - (widen)) - (goto-char (cdr index-item))) - (t - ;; A special item with a function. - (let ((function (cadr index-item)) - (rest (cddr index-item))) - (apply function (car index-item) rest))))))) + (let* ((is-special-item (listp (cdr index-item))) + (function + (if is-special-item + (caddr 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))))) (provide 'imenu)