diff options
| author | Richard M. Stallman | 1998-04-30 00:05:06 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1998-04-30 00:05:06 +0000 |
| commit | fe2908be7b09f4c765ebdaf16fe07b0a77f78ba8 (patch) | |
| tree | 8c59549201f51f818f427413534486618a5574d4 | |
| parent | 4063eb1c9cdda753fd4d2a2b10456f5df3cfed6e (diff) | |
| download | emacs-fe2908be7b09f4c765ebdaf16fe07b0a77f78ba8.tar.gz emacs-fe2908be7b09f4c765ebdaf16fe07b0a77f78ba8.zip | |
(imenu--generic-function): Doc fix. Rewritten to be faster.
(defgroup imenu): Add :link.
(imenu-use-markers, imenu-auto-rescan-maxout, imenu-generic-expression)
(imenu--make-index-alist, imenu-default-goto-function): Doc fixes.
(imenu-max-item-length, imenu-sort-function)
(imenu-scanning-message): Custom tweak.
(imenu-progress-message): Use real backquote syntax.
(imenu--in-alist): Unused function deleted.
(imenu--flatten-index-alist): Likewise.
(imenu-case-fold-search): Add autoload cookie.
(imenu--completion-buffer): Offer function at point as default.
(imenu--subalist-p): Don't use caadr.
(imenu): Don't use caddr.
(imenu-add-menubar-index): New function.
| -rw-r--r-- | lisp/imenu.el | 405 |
1 files changed, 210 insertions, 195 deletions
diff --git a/lisp/imenu.el b/lisp/imenu.el index 1e276705169..cae7310eed0 100644 --- a/lisp/imenu.el +++ b/lisp/imenu.el | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | ;;; imenu.el --- Framework for mode-specific buffer indexes. | 1 | ;;; imenu.el --- Framework for mode-specific buffer indexes. |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | ;; Author: Ake Stenhoff <etxaksf@aom.ericsson.se> | 5 | ;; Author: Ake Stenhoff <etxaksf@aom.ericsson.se> |
| 6 | ;; Lars Lindberg <lli@sypro.cap.se> | 6 | ;; Lars Lindberg <lli@sypro.cap.se> |
| @@ -32,6 +32,8 @@ | |||
| 32 | ;; A buffer index is an alist of names and buffer positions. | 32 | ;; A buffer index is an alist of names and buffer positions. |
| 33 | ;; For instance all functions in a C-file and their positions. | 33 | ;; For instance all functions in a C-file and their positions. |
| 34 | ;; | 34 | ;; |
| 35 | ;; It is documented in the Emacs Lisp manual. | ||
| 36 | ;; | ||
| 35 | ;; How it works: | 37 | ;; How it works: |
| 36 | 38 | ||
| 37 | ;; A mode-specific function is called to generate the index. It is | 39 | ;; A mode-specific function is called to generate the index. It is |
| @@ -45,10 +47,11 @@ | |||
| 45 | ;; customize for other modes. A function for jumping to the chosen | 47 | ;; customize for other modes. A function for jumping to the chosen |
| 46 | ;; index position is also supplied. | 48 | ;; index position is also supplied. |
| 47 | 49 | ||
| 48 | ;;; Thanks goes to | 50 | ;;; History: |
| 51 | ;; Thanks go to | ||
| 49 | ;; [simon] - Simon Leinen simon@lia.di.epfl.ch | 52 | ;; [simon] - Simon Leinen simon@lia.di.epfl.ch |
| 50 | ;; [dean] - Dean Andrews ada@unison.com | 53 | ;; [dean] - Dean Andrews ada@unison.com |
| 51 | ;; [alon] - Alon Albert al@mercury.co.il | 54 | ;; [alon] - Alon Albert al@mercury.co.il |
| 52 | ;; [greg] - Greg Thompson gregt@porsche.visix.COM | 55 | ;; [greg] - Greg Thompson gregt@porsche.visix.COM |
| 53 | ;; [wolfgang] - Wolfgang Bangerth zcg51122@rpool1.rus.uni-stuttgart.de | 56 | ;; [wolfgang] - Wolfgang Bangerth zcg51122@rpool1.rus.uni-stuttgart.de |
| 54 | ;; [kai] - Kai Grossjohann grossjoh@linus.informatik.uni-dortmund.de | 57 | ;; [kai] - Kai Grossjohann grossjoh@linus.informatik.uni-dortmund.de |
| @@ -69,11 +72,14 @@ | |||
| 69 | (defgroup imenu nil | 72 | (defgroup imenu nil |
| 70 | "Mode-specific buffer indexes." | 73 | "Mode-specific buffer indexes." |
| 71 | :group 'matching | 74 | :group 'matching |
| 72 | :group 'frames) | 75 | :group 'frames |
| 76 | :link '(custom-manual "(elisp)Imenu")) | ||
| 73 | 77 | ||
| 74 | (defcustom imenu-use-markers t | 78 | (defcustom imenu-use-markers t |
| 75 | "*Non-nil means use markers instead of integers for Imenu buffer positions. | 79 | "*Non-nil means use markers instead of integers for Imenu buffer positions. |
| 76 | Setting this to nil makes Imenu work faster. | 80 | |
| 81 | Setting this to nil makes Imenu work a little faster but editing the | ||
| 82 | buffer will make the generated index positions wrong. | ||
| 77 | 83 | ||
| 78 | This might not yet be honored by all index-building functions." | 84 | This might not yet be honored by all index-building functions." |
| 79 | :type 'boolean | 85 | :type 'boolean |
| @@ -82,7 +88,8 @@ This might not yet be honored by all index-building functions." | |||
| 82 | 88 | ||
| 83 | (defcustom imenu-max-item-length 60 | 89 | (defcustom imenu-max-item-length 60 |
| 84 | "*If a number, truncate Imenu entries to that length." | 90 | "*If a number, truncate Imenu entries to that length." |
| 85 | :type 'integer | 91 | :type '(choice integer |
| 92 | (const :tag "Unlimited")) | ||
| 86 | :group 'imenu) | 93 | :group 'imenu) |
| 87 | 94 | ||
| 88 | (defcustom imenu-auto-rescan nil | 95 | (defcustom imenu-auto-rescan nil |
| @@ -90,8 +97,8 @@ This might not yet be honored by all index-building functions." | |||
| 90 | :type 'boolean | 97 | :type 'boolean |
| 91 | :group 'imenu) | 98 | :group 'imenu) |
| 92 | 99 | ||
| 93 | (defcustom imenu-auto-rescan-maxout 60000 | 100 | (defcustom imenu-auto-rescan-maxout 60000 |
| 94 | "*Imenu auto-rescan is disabled in buffers larger than this size. | 101 | "*Imenu auto-rescan is disabled in buffers larger than this size (in bytes). |
| 95 | This variable is buffer-local." | 102 | This variable is buffer-local." |
| 96 | :type 'integer | 103 | :type 'integer |
| 97 | :group 'imenu) | 104 | :group 'imenu) |
| @@ -122,7 +129,9 @@ Set it to `imenu--sort-by-name' if you want alphabetic sorting. | |||
| 122 | The function should take two arguments and return T if the first | 129 | The function should take two arguments and return T if the first |
| 123 | element should come before the second. The arguments are cons cells; | 130 | element should come before the second. The arguments are cons cells; |
| 124 | \(NAME . POSITION). Look at `imenu--sort-by-name' for an example." | 131 | \(NAME . POSITION). Look at `imenu--sort-by-name' for an example." |
| 125 | :type 'function | 132 | :type '(choice (const :tag "No sorting" nil) |
| 133 | (const :tag "Sort by name" 'imenu--sort-by-name) | ||
| 134 | (function :tag "Another function")) | ||
| 126 | :group 'imenu) | 135 | :group 'imenu) |
| 127 | 136 | ||
| 128 | (defcustom imenu-max-items 25 | 137 | (defcustom imenu-max-items 25 |
| @@ -135,8 +144,10 @@ element should come before the second. The arguments are cons cells; | |||
| 135 | If non-nil, user gets a message during the scanning of the buffer. | 144 | If non-nil, user gets a message during the scanning of the buffer. |
| 136 | 145 | ||
| 137 | Relevant only if the mode-specific function that creates the buffer | 146 | Relevant only if the mode-specific function that creates the buffer |
| 138 | index use `imenu-progress-message'." | 147 | index use `imenu-progress-message', and not useful if that is fast, in |
| 139 | :type 'string | 148 | which case you might as well set this to nil." |
| 149 | :type '(choice string | ||
| 150 | (const :tag "None" nil)) | ||
| 140 | :group 'imenu) | 151 | :group 'imenu) |
| 141 | 152 | ||
| 142 | (defcustom imenu-space-replacement "^" | 153 | (defcustom imenu-space-replacement "^" |
| @@ -180,16 +191,16 @@ menu. See the info section on Regexps for more information. | |||
| 180 | INDEX points to the substring in REGEXP that contains the name (of the | 191 | INDEX points to the substring in REGEXP that contains the name (of the |
| 181 | function, variable or type) that is to appear in the menu. | 192 | function, variable or type) that is to appear in the menu. |
| 182 | 193 | ||
| 183 | For emacs-lisp-mode for example PATTERN would look like: | ||
| 184 | |||
| 185 | '((nil \"^\\\\s-*(def\\\\(un\\\\|subst\\\\|macro\\\\|advice\\\\)\\\\s-+\\\\([-A-Za-z0-9+]+\\\\)\" 2) | ||
| 186 | (\"*Vars*\" \"^\\\\s-*(def\\\\(var\\\\|const\\\\)\\\\s-+\\\\([-A-Za-z0-9+]+\\\\)\" 2) | ||
| 187 | (\"*Types*\" \"^\\\\s-*(def\\\\(type\\\\|struct\\\\|class\\\\|ine-condition\\\\)\\\\s-+\\\\([-A-Za-z0-9+]+\\\\)\" 2)) | ||
| 188 | |||
| 189 | The variable is buffer-local. | 194 | The variable is buffer-local. |
| 190 | 195 | ||
| 191 | The variable `imenu-case-fold-search' determines whether or not the | 196 | The variable `imenu-case-fold-search' determines whether or not the |
| 192 | regexp matches are case sensitive.") | 197 | regexp matches are case sensitive. and `imenu-syntax-alist' can be |
| 198 | used to alter the syntax table for the search. | ||
| 199 | |||
| 200 | For example, see the value of `lisp-imenu-generic-expression' used by | ||
| 201 | `lisp-mode' and `emacs-lisp-mode' with `imenu-syntax-alist' set | ||
| 202 | locally to give the characters which normally have \"punctuation\" | ||
| 203 | syntax \"word\" syntax during matching.") | ||
| 193 | 204 | ||
| 194 | ;;;###autoload | 205 | ;;;###autoload |
| 195 | (make-variable-buffer-local 'imenu-generic-expression) | 206 | (make-variable-buffer-local 'imenu-generic-expression) |
| @@ -206,11 +217,12 @@ Simple elements in the alist look like (INDEX-NAME . INDEX-POSITION). | |||
| 206 | Special elements look like (INDEX-NAME INDEX-POSITION FUNCTION ARGUMENTS...). | 217 | Special elements look like (INDEX-NAME INDEX-POSITION FUNCTION ARGUMENTS...). |
| 207 | A nested sub-alist element looks like (INDEX-NAME SUB-ALIST). | 218 | A nested sub-alist element looks like (INDEX-NAME SUB-ALIST). |
| 208 | The function `imenu--subalist-p' tests an element and returns t | 219 | The function `imenu--subalist-p' tests an element and returns t |
| 209 | if it is a sub-alist. | 220 | if it is a sub-alist. |
| 210 | 221 | ||
| 211 | This function is called within a `save-excursion'. | 222 | This function is called within a `save-excursion'. |
| 212 | 223 | ||
| 213 | The variable is buffer-local.") | 224 | The variable is buffer-local.") |
| 225 | ;;;###autoload | ||
| 214 | (make-variable-buffer-local 'imenu-create-index-function) | 226 | (make-variable-buffer-local 'imenu-create-index-function) |
| 215 | 227 | ||
| 216 | (defvar imenu-prev-index-position-function 'beginning-of-defun | 228 | (defvar imenu-prev-index-position-function 'beginning-of-defun |
| @@ -229,7 +241,7 @@ This variable is local in all buffers.") | |||
| 229 | (make-variable-buffer-local 'imenu-prev-index-position-function) | 241 | (make-variable-buffer-local 'imenu-prev-index-position-function) |
| 230 | 242 | ||
| 231 | (defvar imenu-extract-index-name-function nil | 243 | (defvar imenu-extract-index-name-function nil |
| 232 | "Function for extracting the index item nam, given a position. | 244 | "Function for extracting the index item name, given a position. |
| 233 | 245 | ||
| 234 | This function is called after `imenu-prev-index-position-function' | 246 | This function is called after `imenu-prev-index-position-function' |
| 235 | finds a position for an index item, with point at that position. | 247 | finds a position for an index item, with point at that position. |
| @@ -247,25 +259,24 @@ The function in this variable is called when selecting a normal index-item.") | |||
| 247 | 259 | ||
| 248 | (defun imenu--subalist-p (item) | 260 | (defun imenu--subalist-p (item) |
| 249 | (and (consp (cdr item)) (listp (cadr item)) | 261 | (and (consp (cdr item)) (listp (cadr item)) |
| 250 | (not (eq (caadr item) 'lambda)))) | 262 | (not (eq (car (cadr item)) 'lambda)))) |
| 251 | 263 | ||
| 252 | ;;; | 264 | ;; Macro to display a progress message. |
| 253 | ;;; Macro to display a progress message. | 265 | ;; RELPOS is the relative position to display. |
| 254 | ;;; RELPOS is the relative position to display. | 266 | ;; If RELPOS is nil, then the relative position in the buffer |
| 255 | ;;; If RELPOS is nil, then the relative position in the buffer | 267 | ;; is calculated. |
| 256 | ;;; is calculated. | 268 | ;; PREVPOS is the variable in which we store the last position displayed. |
| 257 | ;;; PREVPOS is the variable in which we store the last position displayed. | ||
| 258 | (defmacro imenu-progress-message (prevpos &optional relpos reverse) | 269 | (defmacro imenu-progress-message (prevpos &optional relpos reverse) |
| 259 | (` (and | 270 | `(and |
| 260 | imenu-scanning-message | 271 | imenu-scanning-message |
| 261 | (let ((pos (, (if relpos | 272 | (let ((pos ,(if relpos |
| 262 | relpos | 273 | relpos |
| 263 | (` (imenu--relative-position (, reverse))))))) | 274 | `(imenu--relative-position ,reverse)))) |
| 264 | (if (, (if relpos t | 275 | (if ,(if relpos t |
| 265 | (` (> pos (+ 5 (, prevpos)))))) | 276 | `(> pos (+ 5 ,prevpos))) |
| 266 | (progn | 277 | (progn |
| 267 | (message imenu-scanning-message pos) | 278 | (message imenu-scanning-message pos) |
| 268 | (setq (, prevpos) pos))))))) | 279 | (setq ,prevpos pos)))))) |
| 269 | 280 | ||
| 270 | 281 | ||
| 271 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 282 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| @@ -288,7 +299,7 @@ The function in this variable is called when selecting a normal index-item.") | |||
| 288 | 299 | ||
| 289 | ;;; | 300 | ;;; |
| 290 | ;;; Lisp | 301 | ;;; Lisp |
| 291 | ;;; | 302 | ;;; |
| 292 | 303 | ||
| 293 | (defun imenu-example--lisp-extract-index-name () | 304 | (defun imenu-example--lisp-extract-index-name () |
| 294 | ;; Example of a candidate for `imenu-extract-index-name-function'. | 305 | ;; Example of a candidate for `imenu-extract-index-name-function'. |
| @@ -317,31 +328,31 @@ The function in this variable is called when selecting a normal index-item.") | |||
| 317 | ;; Search for the function | 328 | ;; Search for the function |
| 318 | (while (beginning-of-defun) | 329 | (while (beginning-of-defun) |
| 319 | (imenu-progress-message prev-pos nil t) | 330 | (imenu-progress-message prev-pos nil t) |
| 320 | (save-match-data | 331 | (save-match-data |
| 321 | (and (looking-at "(def") | 332 | (and (looking-at "(def") |
| 322 | (save-excursion | 333 | (save-excursion |
| 323 | (down-list 1) | 334 | (down-list 1) |
| 324 | (cond | 335 | (cond |
| 325 | ((looking-at "def\\(var\\|const\\)") | 336 | ((looking-at "def\\(var\\|const\\)") |
| 326 | (forward-sexp 2) | 337 | (forward-sexp 2) |
| 327 | (push (imenu-example--name-and-position) | 338 | (push (imenu-example--name-and-position) |
| 328 | index-var-alist)) | 339 | index-var-alist)) |
| 329 | ((looking-at "def\\(un\\|subst\\|macro\\|advice\\)") | 340 | ((looking-at "def\\(un\\|subst\\|macro\\|advice\\)") |
| 330 | (forward-sexp 2) | 341 | (forward-sexp 2) |
| 331 | (push (imenu-example--name-and-position) | 342 | (push (imenu-example--name-and-position) |
| 332 | index-alist)) | 343 | index-alist)) |
| 333 | ((looking-at "def\\(type\\|struct\\|class\\|ine-condition\\)") | 344 | ((looking-at "def\\(type\\|struct\\|class\\|ine-condition\\)") |
| 334 | (forward-sexp 2) | 345 | (forward-sexp 2) |
| 335 | (if (= (char-after (1- (point))) ?\)) | 346 | (if (= (char-after (1- (point))) ?\)) |
| 336 | (progn | 347 | (progn |
| 337 | (forward-sexp -1) | 348 | (forward-sexp -1) |
| 338 | (down-list 1) | 349 | (down-list 1) |
| 339 | (forward-sexp 1))) | 350 | (forward-sexp 1))) |
| 340 | (push (imenu-example--name-and-position) | 351 | (push (imenu-example--name-and-position) |
| 341 | index-type-alist)) | 352 | index-type-alist)) |
| 342 | (t | 353 | (t |
| 343 | (forward-sexp 2) | 354 | (forward-sexp 2) |
| 344 | (push (imenu-example--name-and-position) | 355 | (push (imenu-example--name-and-position) |
| 345 | index-unknown-alist))))))) | 356 | index-unknown-alist))))))) |
| 346 | (imenu-progress-message prev-pos 100) | 357 | (imenu-progress-message prev-pos 100) |
| 347 | (and index-var-alist | 358 | (and index-var-alist |
| @@ -357,7 +368,7 @@ The function in this variable is called when selecting a normal index-item.") | |||
| 357 | 368 | ||
| 358 | ;; Regular expression to find C functions | 369 | ;; Regular expression to find C functions |
| 359 | (defvar imenu-example--function-name-regexp-c | 370 | (defvar imenu-example--function-name-regexp-c |
| 360 | (concat | 371 | (concat |
| 361 | "^[a-zA-Z0-9]+[ \t]?" ; type specs; there can be no | 372 | "^[a-zA-Z0-9]+[ \t]?" ; type specs; there can be no |
| 362 | "\\([a-zA-Z0-9_*]+[ \t]+\\)?" ; more than 3 tokens, right? | 373 | "\\([a-zA-Z0-9_*]+[ \t]+\\)?" ; more than 3 tokens, right? |
| 363 | "\\([a-zA-Z0-9_*]+[ \t]+\\)?" | 374 | "\\([a-zA-Z0-9_*]+[ \t]+\\)?" |
| @@ -500,12 +511,13 @@ This variable is local in all buffers, once set.") | |||
| 500 | ;;; Split up each long alist that are nested within ALIST | 511 | ;;; Split up each long alist that are nested within ALIST |
| 501 | ;;; into nested alists. | 512 | ;;; into nested alists. |
| 502 | (defun imenu--split-submenus (alist) | 513 | (defun imenu--split-submenus (alist) |
| 503 | (mapcar (function (lambda (elt) | 514 | (mapcar (function |
| 504 | (if (and (consp elt) | 515 | (lambda (elt) |
| 505 | (stringp (car elt)) | 516 | (if (and (consp elt) |
| 506 | (listp (cdr elt))) | 517 | (stringp (car elt)) |
| 507 | (imenu--split-menu (cdr elt) (car elt)) | 518 | (listp (cdr elt))) |
| 508 | elt))) | 519 | (imenu--split-menu (cdr elt) (car elt)) |
| 520 | elt))) | ||
| 509 | alist)) | 521 | alist)) |
| 510 | 522 | ||
| 511 | ;;; Truncate all strings in MENULIST to imenu-max-item-length | 523 | ;;; Truncate all strings in MENULIST to imenu-max-item-length |
| @@ -526,11 +538,14 @@ This variable is local in all buffers, once set.") | |||
| 526 | (defun imenu--make-index-alist (&optional noerror) | 538 | (defun imenu--make-index-alist (&optional noerror) |
| 527 | "Create an index-alist for the definitions in the current buffer. | 539 | "Create an index-alist for the definitions in the current buffer. |
| 528 | 540 | ||
| 541 | Report an error if the list is empty unless NOERROR is supplied and | ||
| 542 | non-nil. | ||
| 543 | |||
| 529 | Simple elements in the alist look like (INDEX-NAME . INDEX-POSITION). | 544 | Simple elements in the alist look like (INDEX-NAME . INDEX-POSITION). |
| 530 | Special elements look like (INDEX-NAME FUNCTION ARGUMENTS...). | 545 | Special elements look like (INDEX-NAME FUNCTION ARGUMENTS...). |
| 531 | A nested sub-alist element looks like (INDEX-NAME SUB-ALIST). | 546 | A nested sub-alist element looks like (INDEX-NAME SUB-ALIST). |
| 532 | The function `imenu--subalist-p' tests an element and returns t | 547 | The function `imenu--subalist-p' tests an element and returns t |
| 533 | if it is a sub-alist. | 548 | if it is a sub-alist. |
| 534 | 549 | ||
| 535 | There is one simple element with negative POSITION; that's intended | 550 | There is one simple element with negative POSITION; that's intended |
| 536 | as a way for the user to ask to recalculate the buffer's index alist." | 551 | as a way for the user to ask to recalculate the buffer's index alist." |
| @@ -560,7 +575,7 @@ as a way for the user to ask to recalculate the buffer's index alist." | |||
| 560 | (defvar imenu--cleanup-seen) | 575 | (defvar imenu--cleanup-seen) |
| 561 | 576 | ||
| 562 | (defun imenu--cleanup (&optional alist) | 577 | (defun imenu--cleanup (&optional alist) |
| 563 | ;; If alist is provided use that list. | 578 | ;; If alist is provided use that list. |
| 564 | ;; If not, empty the table of lists already seen | 579 | ;; If not, empty the table of lists already seen |
| 565 | ;; and use imenu--index-alist. | 580 | ;; and use imenu--index-alist. |
| 566 | (if alist | 581 | (if alist |
| @@ -596,8 +611,7 @@ as a way for the user to ask to recalculate the buffer's index alist." | |||
| 596 | (imenu--menubar-select ',item)) | 611 | (imenu--menubar-select ',item)) |
| 597 | (cons '(nil) item)))) | 612 | (cons '(nil) item)))) |
| 598 | (cons (car item) | 613 | (cons (car item) |
| 599 | (cons (car item) end)))) | 614 | (cons (car item) end))))))) |
| 600 | ))) | ||
| 601 | alist))) | 615 | alist))) |
| 602 | 616 | ||
| 603 | ;; If COMMANDS is non-nil, make a real keymap | 617 | ;; If COMMANDS is non-nil, make a real keymap |
| @@ -606,16 +620,15 @@ as a way for the user to ask to recalculate the buffer's index alist." | |||
| 606 | (defun imenu--create-keymap-1 (title alist &optional commands) | 620 | (defun imenu--create-keymap-1 (title alist &optional commands) |
| 607 | (append (list 'keymap title) (imenu--create-keymap-2 alist 0 commands))) | 621 | (append (list 'keymap title) (imenu--create-keymap-2 alist 0 commands))) |
| 608 | 622 | ||
| 609 | |||
| 610 | (defun imenu--in-alist (str alist) | 623 | (defun imenu--in-alist (str alist) |
| 611 | "Check whether the string STR is contained in multi-level ALIST." | 624 | "Check whether the string STR is contained in multi-level ALIST." |
| 612 | (let (elt head tail res) | 625 | (let (elt head tail res) |
| 613 | (setq res nil) | 626 | (setq res nil) |
| 614 | (while alist | 627 | (while alist |
| 615 | (setq elt (car alist) | 628 | (setq elt (car alist) |
| 616 | tail (cdr elt) | 629 | tail (cdr elt) |
| 617 | alist (cdr alist) | 630 | alist (cdr alist) |
| 618 | head (car elt)) | 631 | head (car elt)) |
| 619 | ;; A nested ALIST element looks like | 632 | ;; A nested ALIST element looks like |
| 620 | ;; (INDEX-NAME (INDEX-NAME . INDEX-POSITION) ...) | 633 | ;; (INDEX-NAME (INDEX-NAME . INDEX-POSITION) ...) |
| 621 | ;; while a bottom-level element looks like | 634 | ;; while a bottom-level element looks like |
| @@ -656,7 +669,7 @@ Their results are gathered into an index alist." | |||
| 656 | (goto-char (point-max)) | 669 | (goto-char (point-max)) |
| 657 | (imenu-progress-message prev-pos 0 t) | 670 | (imenu-progress-message prev-pos 0 t) |
| 658 | ;; Search for the function | 671 | ;; Search for the function |
| 659 | (while (funcall imenu-prev-index-position-function) | 672 | (while (funcall imenu-prev-index-position-function) |
| 660 | (imenu-progress-message prev-pos nil t) | 673 | (imenu-progress-message prev-pos nil t) |
| 661 | (save-excursion | 674 | (save-excursion |
| 662 | (setq name (funcall imenu-extract-index-name-function))) | 675 | (setq name (funcall imenu-extract-index-name-function))) |
| @@ -668,7 +681,7 @@ Their results are gathered into an index alist." | |||
| 668 | index-alist)) | 681 | index-alist)) |
| 669 | ;; Use generic expression if possible. | 682 | ;; Use generic expression if possible. |
| 670 | ((and imenu-generic-expression) | 683 | ((and imenu-generic-expression) |
| 671 | (imenu--generic-function imenu-generic-expression)) | 684 | (imenu--generic-function imenu-generic-expression)) |
| 672 | (t | 685 | (t |
| 673 | (error "This buffer cannot use `imenu-default-create-index-function'")))) | 686 | (error "This buffer cannot use `imenu-default-create-index-function'")))) |
| 674 | 687 | ||
| @@ -684,26 +697,26 @@ Their results are gathered into an index alist." | |||
| 684 | name | 697 | name |
| 685 | "")) | 698 | "")) |
| 686 | 699 | ||
| 687 | (defun imenu--flatten-index-alist (index-alist &optional concat-names prefix) | 700 | ;; Not used and would require cl at run time |
| 688 | ;; Takes a nested INDEX-ALIST and returns a flat index alist. | 701 | ;;; (defun imenu--flatten-index-alist (index-alist &optional concat-names prefix) |
| 689 | ;; If optional CONCAT-NAMES is non-nil, then a nested index has its | 702 | ;;; ;; Takes a nested INDEX-ALIST and returns a flat index alist. |
| 690 | ;; name and a space concatenated to the names of the children. | 703 | ;;; ;; If optional CONCAT-NAMES is non-nil, then a nested index has its |
| 691 | ;; Third argument PREFIX is for internal use only. | 704 | ;;; ;; name and a space concatenated to the names of the children. |
| 692 | (mapcan | 705 | ;;; ;; Third argument PREFIX is for internal use only. |
| 693 | (function | 706 | ;;; (mapcan |
| 694 | (lambda (item) | 707 | ;;; (lambda (item) |
| 695 | (let* ((name (car item)) | 708 | ;;; (let* ((name (car item)) |
| 696 | (pos (cdr item)) | 709 | ;;; (pos (cdr item)) |
| 697 | (new-prefix (and concat-names | 710 | ;;; (new-prefix (and concat-names |
| 698 | (if prefix | 711 | ;;; (if prefix |
| 699 | (concat prefix imenu-level-separator name) | 712 | ;;; (concat prefix imenu-level-separator name) |
| 700 | name)))) | 713 | ;;; name)))) |
| 701 | (cond | 714 | ;;; (cond |
| 702 | ((or (markerp pos) (numberp pos)) | 715 | ;;; ((or (markerp pos) (numberp pos)) |
| 703 | (list (cons new-prefix pos))) | 716 | ;;; (list (cons new-prefix pos))) |
| 704 | (t | 717 | ;;; (t |
| 705 | (imenu--flatten-index-alist pos new-prefix)))))) | 718 | ;;; (imenu--flatten-index-alist pos new-prefix))))) |
| 706 | index-alist)) | 719 | ;;; index-alist)) |
| 707 | 720 | ||
| 708 | ;;; | 721 | ;;; |
| 709 | ;;; Generic index gathering function. | 722 | ;;; Generic index gathering function. |
| @@ -716,15 +729,16 @@ This buffer-local variable should be set (only) by initialization code | |||
| 716 | for modes which use `imenu--generic-function'. If it is not set, that | 729 | for modes which use `imenu--generic-function'. If it is not set, that |
| 717 | function will use the current value of `case-fold-search' to match | 730 | function will use the current value of `case-fold-search' to match |
| 718 | patterns.") | 731 | patterns.") |
| 732 | ;;;###autoload | ||
| 719 | (make-variable-buffer-local 'imenu-case-fold-search) | 733 | (make-variable-buffer-local 'imenu-case-fold-search) |
| 720 | 734 | ||
| 735 | ;; Originally "Built on some ideas that Erik Naggum <erik@naggum.no> | ||
| 736 | ;; once posted to comp.emacs" but since substantially re-written. | ||
| 721 | (defun imenu--generic-function (patterns) | 737 | (defun imenu--generic-function (patterns) |
| 722 | ;; Built on some ideas that Erik Naggum <erik@naggum.no> once posted | ||
| 723 | ;; to comp.emacs | ||
| 724 | "Return an index of the current buffer as an alist. | 738 | "Return an index of the current buffer as an alist. |
| 725 | 739 | ||
| 726 | PATTERN is an alist with elements that look like this: (MENU-TITLE | 740 | PATTERNS is an alist with elements that look like this: |
| 727 | REGEXP INDEX). | 741 | (MENU-TITLE REGEXP INDEX). |
| 728 | 742 | ||
| 729 | MENU-TITLE is a string used as the title for the submenu or nil if the | 743 | MENU-TITLE is a string used as the title for the submenu or nil if the |
| 730 | entries are not nested. | 744 | entries are not nested. |
| @@ -737,85 +751,70 @@ menu. See the info section on Regexps for more information. | |||
| 737 | INDEX points to the substring in REGEXP that contains the name (of the | 751 | INDEX points to the substring in REGEXP that contains the name (of the |
| 738 | function, variable or type) that is to appear in the menu. | 752 | function, variable or type) that is to appear in the menu. |
| 739 | 753 | ||
| 740 | For emacs-lisp-mode for example PATTERN would look like: | 754 | See `lisp-imenu-generic-expression' for an example of PATTERNS. |
| 741 | |||
| 742 | '((nil \"^\\\\s-*(def\\\\(un\\\\|subst\\\\|macro\\\\|advice\\\\)\\\\s-+\\\\([-A-Za-z0-9]+\\\\)\" 2) | ||
| 743 | (\"*Vars*\" \"^\\\\s-*(def\\\\(var\\\\|const\\\\)\\\\s-+\\\\([-A-Za-z0-9]+\\\\)\" 2) | ||
| 744 | (\"*Types*\" \"^\\\\s-*(def\\\\(type\\\\|struct\\\\|class\\\\|ine-condition\\\\)\\\\s-+\\\\([-A-Za-z0-9]+\\\\)\" 2))' | ||
| 745 | 755 | ||
| 746 | Returns an index of the current buffer as an alist. The elements in | 756 | Returns an index of the current buffer as an alist. The elements in |
| 747 | the alist look like: (INDEX-NAME . INDEX-POSITION). They may also be | 757 | the alist look like: (INDEX-NAME . INDEX-POSITION). They may also be |
| 748 | nested index lists like (INDEX-NAME . INDEX-ALIST) depending on | 758 | nested index lists like (INDEX-NAME . INDEX-ALIST) depending on |
| 749 | pattern. | 759 | PATTERNS." |
| 750 | |||
| 751 | \(imenu--generic-function PATTERN\)." | ||
| 752 | 760 | ||
| 753 | (let ((index-alist (list 'dummy)) | 761 | (let ((index-alist (list 'dummy)) |
| 754 | (found nil) | 762 | prev-pos beg |
| 755 | (global-regexp | ||
| 756 | (concat "\\(" | ||
| 757 | (mapconcat | ||
| 758 | (function (lambda (pattern) (identity (cadr pattern)))) | ||
| 759 | patterns "\\)\\|\\(") | ||
| 760 | "\\)")) | ||
| 761 | prev-pos | ||
| 762 | |||
| 763 | (case-fold-search imenu-case-fold-search) | 763 | (case-fold-search imenu-case-fold-search) |
| 764 | (old-table (syntax-table)) | 764 | (old-table (syntax-table)) |
| 765 | (table (copy-syntax-table (syntax-table))) | 765 | (table (copy-syntax-table (syntax-table))) |
| 766 | (slist imenu-syntax-alist)) | 766 | (slist imenu-syntax-alist)) |
| 767 | ;; Modify the syntax table used while matching regexps. | 767 | ;; Modify the syntax table used while matching regexps. |
| 768 | (while slist | 768 | (while slist |
| 769 | ;; The character to modify may be a single CHAR or a STRING. | 769 | ;; The character(s) to modify may be a single char or a string. |
| 770 | (let ((chars (if (numberp (car (car slist))) | 770 | (if (numberp (caar slist)) |
| 771 | (list (car (car slist))) | 771 | (modify-syntax-entry (caar slist) (cdar slist) table) |
| 772 | (mapcar 'identity (car (car slist))))) | 772 | (mapcar (function |
| 773 | (syntax (cdr (car slist)))) | 773 | (lambda (c) |
| 774 | (while chars | 774 | (modify-syntax-entry c (cdar slist) table))) |
| 775 | (modify-syntax-entry (car chars) syntax table) | 775 | (caar slist))) |
| 776 | (setq chars (cdr chars))) | 776 | (setq slist (cdr slist))) |
| 777 | (setq slist (cdr slist)))) | ||
| 778 | (goto-char (point-max)) | 777 | (goto-char (point-max)) |
| 779 | (imenu-progress-message prev-pos 0 t) | 778 | (imenu-progress-message prev-pos 0 t) |
| 780 | (unwind-protect | 779 | (unwind-protect ; for syntax table |
| 781 | (progn | 780 | (save-match-data |
| 782 | (set-syntax-table table) | 781 | (set-syntax-table table) |
| 783 | (save-match-data | 782 | ;; map over the elements of imenu-generic-expression |
| 784 | (while (re-search-backward global-regexp nil t) | 783 | ;; (typically functions, variables ...) |
| 785 | (imenu-progress-message prev-pos nil t) | 784 | (mapcar |
| 786 | (setq found nil) | 785 | (function |
| 787 | (save-excursion | 786 | (lambda (pat) |
| 788 | (goto-char (match-beginning 0)) | 787 | (let ((menu-title (car pat)) |
| 789 | (mapcar | 788 | (regexp (nth 1 pat)) |
| 790 | (function | 789 | (index (nth 2 pat)) |
| 791 | (lambda (pat) | 790 | (function (nth 3 pat)) |
| 792 | (let ((menu-title (car pat)) | 791 | (rest (nthcdr 4 pat))) |
| 793 | (regexp (cadr pat)) | 792 | ;; Go backwards for convenience of adding items in order. |
| 794 | (index (caddr pat)) | 793 | (goto-char (point-max)) |
| 795 | (function (cadddr pat)) | 794 | (while (re-search-backward regexp nil t) |
| 796 | (rest (cddddr pat))) | 795 | (imenu-progress-message prev-pos nil t) |
| 797 | (if (and (not found) ; Only allow one entry; | 796 | (setq beg (match-beginning index)) |
| 798 | (looking-at regexp)) | 797 | ;; Add this sort of submenu only when we've found an |
| 799 | (let ((beg (match-beginning index)) | 798 | ;; item for it, avoiding empty, duff menus. |
| 800 | (end (match-end index))) | 799 | (unless (assoc menu-title index-alist) |
| 801 | (setq found t) | 800 | (push (list menu-title) index-alist)) |
| 802 | (push | 801 | (if imenu-use-markers |
| 803 | (let ((name | 802 | (setq beg (set-marker (make-marker) beg))) |
| 804 | (buffer-substring-no-properties beg end))) | 803 | (let ((item |
| 805 | ;; [ydi] updated for imenu-use-markers | 804 | (if function |
| 806 | (if imenu-use-markers | 805 | (nconc (list (match-string-no-properties index) |
| 807 | (setq beg (set-marker (make-marker) beg))) | 806 | beg function) |
| 808 | (if function | 807 | rest) |
| 809 | (nconc (list name beg function) | 808 | (cons (match-string-no-properties index) |
| 810 | rest) | 809 | beg))) |
| 811 | (cons name beg))) | 810 | (menu (cdr (assoc menu-title index-alist)))) |
| 812 | (cdr | 811 | ;; avoid duplicates from, e.g. cc-mode patterns |
| 813 | (or (assoc menu-title index-alist) | 812 | (unless (member item menu) |
| 814 | (car (push | 813 | ;; insert the item after the (sub-)menu title |
| 815 | (cons menu-title '()) | 814 | (setcdr (assoc menu-title index-alist) |
| 816 | index-alist)))))))))) | 815 | (cons item menu)))))))) |
| 817 | patterns))) | 816 | patterns) |
| 818 | (set-syntax-table old-table)))) | 817 | (set-syntax-table old-table))) |
| 819 | (imenu-progress-message prev-pos 100 t) | 818 | (imenu-progress-message prev-pos 100 t) |
| 820 | (let ((main-element (assq nil index-alist))) | 819 | (let ((main-element (assq nil index-alist))) |
| 821 | (nconc (delq main-element (delq 'dummy index-alist)) | 820 | (nconc (delq main-element (delq 'dummy index-alist)) |
| @@ -832,33 +831,39 @@ pattern. | |||
| 832 | 831 | ||
| 833 | Returns t for rescan and otherwise a position number." | 832 | Returns t for rescan and otherwise a position number." |
| 834 | ;; Create a list for this buffer only when needed. | 833 | ;; Create a list for this buffer only when needed. |
| 835 | (let (name choice | 834 | (let ((name (thing-at-point 'symbol)) |
| 836 | (prepared-index-alist | 835 | choice |
| 837 | (mapcar | 836 | (prepared-index-alist |
| 838 | (function | 837 | (mapcar |
| 839 | (lambda (item) | 838 | (function |
| 840 | (cons (imenu--replace-spaces (car item) imenu-space-replacement) | 839 | (lambda (item) |
| 841 | (cdr item)))) | 840 | (cons (imenu--replace-spaces (car item) imenu-space-replacement) |
| 842 | index-alist))) | 841 | (cdr item)))) |
| 842 | index-alist))) | ||
| 843 | (cond (prompt) | ||
| 844 | ((and name (imenu--in-alist name prepared-index-alist)) | ||
| 845 | (setq prompt (format "Index item (default %s): " name))) | ||
| 846 | (t (setq prompt "Index item: "))) | ||
| 843 | (if (eq imenu-always-use-completion-buffer-p 'never) | 847 | (if (eq imenu-always-use-completion-buffer-p 'never) |
| 844 | (setq name (completing-read (or prompt "Index item: ") | 848 | (setq name (completing-read prompt |
| 845 | prepared-index-alist | 849 | prepared-index-alist |
| 846 | nil t nil 'imenu--history-list)) | 850 | nil t nil 'imenu--history-list name)) |
| 847 | (save-window-excursion | 851 | (save-window-excursion |
| 848 | ;; Display the completion buffer | 852 | ;; Display the completion buffer |
| 849 | (with-output-to-temp-buffer "*Completions*" | 853 | (with-output-to-temp-buffer "*Completions*" |
| 850 | (display-completion-list | 854 | (display-completion-list |
| 851 | (all-completions "" prepared-index-alist ))) | 855 | (all-completions "" prepared-index-alist ))) |
| 852 | (let ((minibuffer-setup-hook | 856 | (let ((minibuffer-setup-hook |
| 853 | (function (lambda () | 857 | (function |
| 854 | (let ((buffer (current-buffer))) | 858 | (lambda () |
| 855 | (save-excursion | 859 | (let ((buffer (current-buffer))) |
| 856 | (set-buffer "*Completions*") | 860 | (save-excursion |
| 857 | (setq completion-reference-buffer buffer))))))) | 861 | (set-buffer "*Completions*") |
| 862 | (setq completion-reference-buffer buffer))))))) | ||
| 858 | ;; Make a completion question | 863 | ;; Make a completion question |
| 859 | (setq name (completing-read (or prompt "Index item: ") | 864 | (setq name (completing-read prompt |
| 860 | prepared-index-alist | 865 | prepared-index-alist |
| 861 | nil t nil 'imenu--history-list))))) | 866 | nil t nil 'imenu--history-list name))))) |
| 862 | (cond ((not (stringp name)) | 867 | (cond ((not (stringp name)) |
| 863 | nil) | 868 | nil) |
| 864 | ((string= name (car imenu--rescan-item)) | 869 | ((string= name (car imenu--rescan-item)) |
| @@ -877,9 +882,9 @@ INDEX-ALIST is the buffer index and EVENT is a mouse event. | |||
| 877 | Returns t for rescan and otherwise an element or subelement of INDEX-ALIST." | 882 | Returns t for rescan and otherwise an element or subelement of INDEX-ALIST." |
| 878 | (setq index-alist (imenu--split-submenus index-alist)) | 883 | (setq index-alist (imenu--split-submenus index-alist)) |
| 879 | (let* ((menu (imenu--split-menu index-alist | 884 | (let* ((menu (imenu--split-menu index-alist |
| 880 | (or title (buffer-name)))) | 885 | (or title (buffer-name)))) |
| 881 | position) | 886 | position) |
| 882 | (setq menu (imenu--create-keymap-1 (car menu) | 887 | (setq menu (imenu--create-keymap-1 (car menu) |
| 883 | (if (< 1 (length (cdr menu))) | 888 | (if (< 1 (length (cdr menu))) |
| 884 | (cdr menu) | 889 | (cdr menu) |
| 885 | (cdr (car (cdr menu)))))) | 890 | (cdr (car (cdr menu)))))) |
| @@ -896,7 +901,7 @@ Returns t for rescan and otherwise an element or subelement of INDEX-ALIST." | |||
| 896 | (setq final (assoc (car position) final)) | 901 | (setq final (assoc (car position) final)) |
| 897 | (setq position (cdr position))) | 902 | (setq position (cdr position))) |
| 898 | (or (string= (car final) (car imenu--rescan-item)) | 903 | (or (string= (car final) (car imenu--rescan-item)) |
| 899 | (cdr (cdr (cdr final)))))) | 904 | (nthcdr 3 final)))) |
| 900 | ;; If x-popup-menu went just one level and found a leaf item, | 905 | ;; If x-popup-menu went just one level and found a leaf item, |
| 901 | ;; return the INDEX-ALIST element for that. | 906 | ;; return the INDEX-ALIST element for that. |
| 902 | ((and (consp position) | 907 | ((and (consp position) |
| @@ -956,7 +961,7 @@ The returned value is of the form (INDEX-NAME . INDEX-POSITION)." | |||
| 956 | 961 | ||
| 957 | ;;;###autoload | 962 | ;;;###autoload |
| 958 | (defun imenu-add-to-menubar (name) | 963 | (defun imenu-add-to-menubar (name) |
| 959 | "Adds an `imenu' entry to the menu bar for the current buffer. | 964 | "Add an `imenu' entry to the menu bar for the current buffer. |
| 960 | NAME is a string used to name the menu bar item. | 965 | NAME is a string used to name the menu bar item. |
| 961 | See the command `imenu' for more information." | 966 | See the command `imenu' for more information." |
| 962 | (interactive "sImenu menu item name: ") | 967 | (interactive "sImenu menu item name: ") |
| @@ -976,6 +981,14 @@ See the command `imenu' for more information." | |||
| 976 | (add-hook 'menu-bar-update-hook 'imenu-update-menubar)) | 981 | (add-hook 'menu-bar-update-hook 'imenu-update-menubar)) |
| 977 | (error "The mode `%s' does not support Imenu" mode-name))) | 982 | (error "The mode `%s' does not support Imenu" mode-name))) |
| 978 | 983 | ||
| 984 | ;;;###autoload | ||
| 985 | (defun imenu-add-menubar-index () | ||
| 986 | "Add an Imenu \"Index\" entry on the menu bar for the current buffer. | ||
| 987 | |||
| 988 | A trivial interface to `imenu-add-to-menubar' suitable for use in a hook." | ||
| 989 | (interactive) | ||
| 990 | (imenu-add-to-menubar "Index")) | ||
| 991 | |||
| 979 | (defvar imenu-buffer-menubar nil) | 992 | (defvar imenu-buffer-menubar nil) |
| 980 | 993 | ||
| 981 | (defun imenu-update-menubar () | 994 | (defun imenu-update-menubar () |
| @@ -989,12 +1002,12 @@ See the command `imenu' for more information." | |||
| 989 | (setq imenu--last-menubar-index-alist index-alist) | 1002 | (setq imenu--last-menubar-index-alist index-alist) |
| 990 | (setq index-alist (imenu--split-submenus index-alist)) | 1003 | (setq index-alist (imenu--split-submenus index-alist)) |
| 991 | (setq menu (imenu--split-menu index-alist | 1004 | (setq menu (imenu--split-menu index-alist |
| 992 | (buffer-name))) | 1005 | (buffer-name))) |
| 993 | (setq menu1 (imenu--create-keymap-1 (car menu) | 1006 | (setq menu1 (imenu--create-keymap-1 (car menu) |
| 994 | (if (< 1 (length (cdr menu))) | 1007 | (if (< 1 (length (cdr menu))) |
| 995 | (cdr menu) | 1008 | (cdr menu) |
| 996 | (cdr (car (cdr menu)))) | 1009 | (cdr (car (cdr menu)))) |
| 997 | t)) | 1010 | t)) |
| 998 | (setq old (lookup-key (current-local-map) [menu-bar index])) | 1011 | (setq old (lookup-key (current-local-map) [menu-bar index])) |
| 999 | (setcdr old (cdr menu1))))))) | 1012 | (setcdr old (cdr menu1))))))) |
| 1000 | 1013 | ||
| @@ -1008,10 +1021,11 @@ See the command `imenu' for more information." | |||
| 1008 | (imenu item))) | 1021 | (imenu item))) |
| 1009 | 1022 | ||
| 1010 | (defun imenu-default-goto-function (name position &optional rest) | 1023 | (defun imenu-default-goto-function (name position &optional rest) |
| 1011 | "This function is used for moving the point to POSITION. | 1024 | "Move the point to the given position. |
| 1012 | The NAME and REST parameters are not used, they are here just to make | 1025 | |
| 1013 | this function have the same interface as a function placed in a special | 1026 | NAME is ignored. POSITION is where to move. REST is also ignored. |
| 1014 | index-item." | 1027 | The ignored args just make this function have the same interface as a |
| 1028 | function placed in a special index-item." | ||
| 1015 | (if (or (< position (point-min)) | 1029 | (if (or (< position (point-min)) |
| 1016 | (> position (point-max))) | 1030 | (> position (point-max))) |
| 1017 | ;; widen if outside narrowing | 1031 | ;; widen if outside narrowing |
| @@ -1021,7 +1035,8 @@ index-item." | |||
| 1021 | ;;;###autoload | 1035 | ;;;###autoload |
| 1022 | (defun imenu (index-item) | 1036 | (defun imenu (index-item) |
| 1023 | "Jump to a place in the buffer chosen using a buffer menu or mouse menu. | 1037 | "Jump to a place in the buffer chosen using a buffer menu or mouse menu. |
| 1024 | See `imenu-choose-buffer-index' for more information." | 1038 | INDEX-ITEM specifies the position. See `imenu-choose-buffer-index' |
| 1039 | for more information." | ||
| 1025 | (interactive (list (imenu-choose-buffer-index))) | 1040 | (interactive (list (imenu-choose-buffer-index))) |
| 1026 | ;; Convert a string to an alist element. | 1041 | ;; Convert a string to an alist element. |
| 1027 | (if (stringp index-item) | 1042 | (if (stringp index-item) |
| @@ -1030,9 +1045,9 @@ See `imenu-choose-buffer-index' for more information." | |||
| 1030 | (progn | 1045 | (progn |
| 1031 | (push-mark) | 1046 | (push-mark) |
| 1032 | (let* ((is-special-item (listp (cdr index-item))) | 1047 | (let* ((is-special-item (listp (cdr index-item))) |
| 1033 | (function | 1048 | (function |
| 1034 | (if is-special-item | 1049 | (if is-special-item |
| 1035 | (caddr index-item) imenu-default-goto-function)) | 1050 | (nth 2 index-item) imenu-default-goto-function)) |
| 1036 | (position (if is-special-item | 1051 | (position (if is-special-item |
| 1037 | (cadr index-item) (cdr index-item))) | 1052 | (cadr index-item) (cdr index-item))) |
| 1038 | (rest (if is-special-item (cddr index-item)))) | 1053 | (rest (if is-special-item (cddr index-item)))) |