;;; imenu.el --- framework for mode-specific buffer indexes
-;; Copyright (C) 1994, 1995, 1996, 1997, 1998, 2002, 2003, 2004,
-;; 2005, 2006 Free Software Foundation, Inc.
+;; Copyright (C) 1994, 1995, 1996, 1997, 1998, 2001, 2002, 2003, 2004,
+;; 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
;; Author: Ake Stenhoff <etxaksf@aom.ericsson.se>
;; Lars Lindberg <lli@sypro.cap.se>
;; This file is part of GNU Emacs.
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
:link '(custom-manual "(elisp)Imenu"))
(defcustom imenu-use-markers t
- "*Non-nil means use markers instead of integers for Imenu buffer positions.
+ "Non-nil means use markers instead of integers for Imenu buffer positions.
Setting this to nil makes Imenu work a little faster but editing the
buffer will make the generated index positions wrong.
(defcustom imenu-max-item-length 60
- "*If a number, truncate Imenu entries to that length."
+ "If a number, truncate Imenu entries to that length."
:type '(choice integer
(const :tag "Unlimited"))
:group 'imenu)
(defcustom imenu-auto-rescan nil
- "*Non-nil means Imenu should always rescan the buffers."
+ "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 (in bytes).
+ "Imenu auto-rescan is disabled in buffers larger than this size (in bytes).
This variable is buffer-local."
:type 'integer
:group 'imenu)
:version "22.1")
(defcustom imenu-after-jump-hook nil
- "*Hooks called after jumping to a place in the buffer.
+ "Hooks called after jumping to a place in the buffer.
Useful things to use here include `reposition-window', `recenter', and
\(lambda () (recenter 0)) to show at top of screen."
;;;###autoload
(defcustom imenu-sort-function nil
- "*The function to use for sorting the index mouse-menu.
+ "The function to use for sorting the index mouse-menu.
Affects only the mouse index menu.
:group 'imenu)
(defcustom imenu-max-items 25
- "*Maximum number of elements in a mouse menu for Imenu."
+ "Maximum number of elements in a mouse menu for Imenu."
:type 'integer
:group 'imenu)
;; :group 'imenu)
(defcustom imenu-space-replacement "."
- "*The replacement string for spaces in index names.
+ "The replacement string for spaces in index names.
Used when presenting the index in a completion buffer to make the
names work as tokens."
:type '(choice string (const nil))
:group 'imenu)
(defcustom imenu-level-separator ":"
- "*The separator between index names of different levels.
+ "The separator between index names of different levels.
Used for making mouse-menu titles and for flattening nested indexes
with name concatenation."
:type 'string
;; Split LIST into sublists of max length N.
;; Example (imenu--split '(1 2 3 4 5 6 7 8) 3)-> '((1 2 3) (4 5 6) (7 8))
+;;
+;; The returned list DOES NOT share structure with LIST.
(defun imenu--split (list n)
(let ((remain list)
(result '())
;;; Split the alist MENULIST into a nested alist, if it is long enough.
;;; In any case, add TITLE to the front of the alist.
+;;; If IMENU--RESCAN-ITEM is present in MENULIST, it is moved to the
+;;; beginning of the returned alist.
+;;;
+;;; The returned alist DOES NOT share structure with MENULIST.
(defun imenu--split-menu (menulist title)
- (let (keep-at-top tail)
+ (let ((menulist (copy-sequence menulist))
+ keep-at-top tail)
(if (memq imenu--rescan-item menulist)
- (setq keep-at-top (cons imenu--rescan-item nil)
+ (setq keep-at-top (list imenu--rescan-item)
menulist (delq imenu--rescan-item menulist)))
(setq tail menulist)
(dolist (item tail)
(push item keep-at-top)
(setq menulist (delq item menulist))))
(if imenu-sort-function
- (setq menulist (sort (copy-sequence menulist) imenu-sort-function)))
+ (setq menulist (sort menulist imenu-sort-function)))
(if (> (length menulist) imenu-max-items)
(setq menulist
(mapcar
;;; Split up each long alist that are nested within ALIST
;;; into nested alists.
+;;;
+;;; Return a split and sorted copy of ALIST. The returned alist DOES
+;;; NOT share structure with ALIST.
(defun imenu--split-submenus (alist)
(mapcar (function
(lambda (elt)
(make-variable-buffer-local 'imenu-syntax-alist)
(defun imenu-default-create-index-function ()
- "*Default function to create an index alist of the current buffer.
+ "Default function to create an index alist of the current buffer.
The most general method is to move point to end of buffer, then repeatedly call
`imenu-prev-index-position-function' and `imenu-extract-index-name-function'.
appear in the menu. See the info section on Regexps for more
information. REGEXP may also be a function, called without
arguments. It is expected to search backwards. It shall return
-true and set `match-data' iff it finds another element.
+true and set `match-data' if it finds another element.
INDEX points to the substring in REGEXP that contains the
name (of the function, variable or type) that is to appear in the
With no index alist ALIST, it calls `imenu--make-index-alist' to
create the index alist.
-If `imenu-use-popup-menu' is non-nil, then the
-completion buffer is always used, no matter if the mouse was used or
-not.
+If `imenu-use-popup-menu' is nil, then the completion buffer
+is always used, no matter if the mouse was used or not.
The returned value is of the form (INDEX-NAME . INDEX-POSITION)."
(let (index-alist
`(menu-item ,name ,(make-sparse-keymap "Imenu")))
(use-local-map newmap)
(add-hook 'menu-bar-update-hook 'imenu-update-menubar))
- (error "The mode `%s' does not support Imenu" mode-name)))
+ (error "The mode `%s' does not support Imenu"
+ (format-mode-line mode-name))))
;;;###autoload
(defun imenu-add-menubar-index ()
(defvar imenu-buffer-menubar nil)
(defvar imenu-menubar-modified-tick 0
- "The value of (buffer-modified-tick) as of last call to `imenu-update-menubar'.")
+ "The value of (buffer-chars-modified-tick) as of the last call
+to `imenu-update-menubar'.")
(make-variable-buffer-local 'imenu-menubar-modified-tick)
(defun imenu-update-menubar ()
(when (and (current-local-map)
(keymapp (lookup-key (current-local-map) [menu-bar index]))
- (not (eq (buffer-modified-tick)
- imenu-menubar-modified-tick)))
- (setq imenu-menubar-modified-tick (buffer-modified-tick))
+ (/= (buffer-chars-modified-tick) imenu-menubar-modified-tick))
+ (setq imenu-menubar-modified-tick (buffer-chars-modified-tick))
(let ((index-alist (imenu--make-index-alist t)))
;; Don't bother updating if the index-alist has not changed
;; since the last time we did it.