Mercurial > emacs
annotate lisp/imenu.el @ 7327:1e2d4da6b5c4
Comment change.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Thu, 05 May 1994 03:58:49 +0000 |
parents | cd73ba498964 |
children | 542ab48d0f18 |
rev | line source |
---|---|
6230 | 1 ;;; imenu.el --- Framework for mode-specific buffer indexes. |
2 | |
3 ;; Copyright (C) 1994 Free Software Foundation, Inc. | |
4 | |
5 ;; Author: Ake Stenhoff <etxaksf@aom.ericsson.se> | |
6 ;; Lars Lindberg <lli@sypro.cap.se> | |
7 ;; Created: 8 Feb 1994 | |
6909
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
8 ;; Version: 1.7 |
6230 | 9 ;; Keywords: tools |
10 ;; | |
11 ;; This program is free software; you can redistribute it and/or modify | |
12 ;; it under the terms of the GNU General Public License as published by | |
13 ;; the Free Software Foundation; either version 2, or (at your option) | |
14 ;; any later version. | |
15 ;; | |
16 ;; This program is distributed in the hope that it will be useful, | |
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 ;; GNU General Public License for more details. | |
20 ;; | |
21 ;; You should have received a copy of the GNU General Public License | |
22 ;; along with this program; if not, write to the Free Software | |
23 ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
24 | |
25 ;;; Commentary: | |
26 ;; | |
27 ;; Purpose of this package: | |
28 ;; To present a framework for mode-specific buffer indexes. | |
29 ;; A buffer index is an alist of names and buffer positions. | |
30 ;; For instance all functions in a C-file and their positions. | |
31 ;; | |
32 ;; How it works: | |
33 | |
34 ;; A mode-specific function is called to generate the index. It is | |
35 ;; then presented to the user, who can choose from this index. | |
36 ;; | |
37 ;; The package comes with a set of example functions for how to | |
38 ;; utilize this package. | |
39 | |
40 ;; There are *examples* for index gathering functions for C/C++ and | |
41 ;; Lisp/Emacs Lisp but it is easy to customize for other modes. A | |
42 ;; function for jumping to the chosen index position is also | |
43 ;; supplied. | |
44 | |
45 ;;; Change Log: | |
6909
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
46 ;; v1.7 Apr 12 1994 Ake Stenhoff |
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
47 ;; Changed doc strings refering to symbols. |
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
48 ;; Require 'cl' when compiling only. |
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
49 ;; Only uses 'cl' macros. |
6241 | 50 ;; v1.6 Feb 28 1994 Ake Stenhoff |
51 ;; Added alist as an optional argument to | |
52 ;; 'imenu-choose-buffer-index'. | |
53 ;; Thanks [dean]. | |
54 ;; v1.5 Feb 25 1994 Ake Stenhoff | |
55 ;; Added code to parse DEFSTRUCT, DEFCLASS, DEFTYPE, | |
56 ;; DEFINE-CONDITION in the lisp example function. | |
57 ;; Thanks [simon]. | |
6230 | 58 ;; v1.4 Feb 18 1994 Ake Stenhoff |
59 ;; Added 'imenu-create-submenu-name' for creating a submenu name. | |
60 ;; This is for getting a general look of submenu names. | |
61 ;; Added variable 'imenu-submenu-name-format' used by | |
62 ;; 'imenu-create-submenu-name'. | |
63 ;; v1.3 Feb 17 1994 Lars Lindberg | |
64 ;; Added 'imenu--flatten-index-alist' for flatten nexted index | |
65 ;; alists. | |
66 ;; New examples for lisp mode that utilizes the features better. | |
67 ;; Added the variable 'imenu-space-replacement'. | |
68 ;; The completion-buffer version of the index menu now replaces | |
69 ;; spaces in the index-names to make tokens of them. | |
70 ;; v1.2 Feb 14 1994 Ake Stenhoff & Lars Lindberg | |
71 ;; Now handles nested index lists. | |
72 ;; v1.1 Feb 9 1994 Ake Stenhoff & Lars Lindberg | |
73 ;; Better comments (?). | |
74 ;; v1.0 Feb 8 1994 Ake Stenhoff & Lars Lindberg | |
75 ;; Based on func-menu.el 3.5. | |
76 | |
6241 | 77 ;;; Thanks goes to |
78 ;; [simon] - Simon Leinen simon@lia.di.epfl.ch | |
79 ;; [dean] - Dean Andrews ada@unison.com | |
80 ;; | |
81 | |
6230 | 82 ;;; Code |
6909
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
83 (eval-when-compile (require 'cl)) |
6230 | 84 |
85 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
86 ;;; | |
87 ;;; Customizable variables | |
88 ;;; | |
89 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
90 | |
91 (defvar imenu-always-use-completion-buffer-p nil | |
92 "*Set this to non-nil for displaying the index in a completion buffer. | |
93 | |
94 Non-nil means always display the index in a completion buffer. | |
95 Nil means display the index as a mouse menu when the mouse was | |
7319
cd73ba498964
(imenu): Renamed from goto-index-pos.
Richard M. Stallman <rms@gnu.org>
parents:
6909
diff
changeset
|
96 used to invoke `imenu'.") |
6230 | 97 |
98 (defvar imenu-sort-function nil | |
99 "*The function to use for sorting the index mouse-menu. | |
100 | |
101 Affects only the mouse index menu. | |
102 | |
103 Set this to nil if you don't want any sorting (faster). | |
104 The items in the menu are then presented in the order they were found | |
105 in the buffer. | |
106 | |
6909
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
107 Set it to `imenu--sort-by-name' if you want alphabetic sorting. |
6230 | 108 |
109 The function should take two arguments and return T if the first | |
110 element should come before the second. The arguments are cons cells; | |
6909
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
111 (NAME . POSITION). Look at `imenu--sort-by-name' for an example.") |
6230 | 112 |
113 (defvar imenu-max-items 25 | |
114 "*Maximum number of elements in an index mouse-menu.") | |
115 | |
116 (defvar imenu-scanning-message "Scanning buffer for index. (%3d%%)" | |
117 "*Progress message during the index scanning of the buffer. | |
118 If non NIL, user gets a message during the scanning of the buffer | |
119 | |
120 Relevant only if the mode-specific function that creates the buffer | |
6909
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
121 index use `imenu-progress-message'.") |
6230 | 122 |
123 (defvar imenu-space-replacement "^" | |
124 "*The replacement string for spaces in index names. | |
125 Used when presenting the index in a completion-buffer to make the | |
126 names work as tokens.") | |
127 | |
128 (defvar imenu-level-separator ":" | |
129 "*The separator between index names of different levels. | |
130 Used for making mouse-menu titles and for flattening nested indexes | |
131 with name concatenation.") | |
132 | |
133 (defvar imenu-submenu-name-format "%s..." | |
134 "*The format for making a submenu name.") | |
135 | |
136 ;;;; Hooks | |
137 | |
138 (defvar imenu-create-index-function 'imenu-default-create-index-function | |
139 "The function to use for creating a buffer index. | |
140 | |
141 It should be a function that takes no arguments and returns an index | |
142 of the current buffer as an alist. The elements in the alist look | |
143 like: (INDEX-NAME . INDEX-POSITION). You may also nest index list like | |
144 (INDEX-NAME . INDEX-ALIST). | |
145 | |
6909
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
146 This function is called within a `save-excursion'. |
6230 | 147 |
148 The variable is buffer-local.") | |
149 (make-variable-buffer-local 'imenu-create-index-function) | |
150 | |
7319
cd73ba498964
(imenu): Renamed from goto-index-pos.
Richard M. Stallman <rms@gnu.org>
parents:
6909
diff
changeset
|
151 (defvar imenu-prev-index-position-function 'beginning-of-defun |
6230 | 152 "Function for finding the next index position. |
153 | |
6909
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
154 If `imenu-create-index-function' is set to |
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
155 `imenu-default-create-index-function', then you must set this variable |
6230 | 156 to a function that will find the next index, looking backwards in the |
157 file. | |
158 | |
159 The function should leave point at the place to be connected to the | |
160 index and it should return nil when it doesn't find another index. ") | |
7319
cd73ba498964
(imenu): Renamed from goto-index-pos.
Richard M. Stallman <rms@gnu.org>
parents:
6909
diff
changeset
|
161 (make-variable-buffer-local 'imenu-prev-index-position-function) |
6230 | 162 |
7319
cd73ba498964
(imenu): Renamed from goto-index-pos.
Richard M. Stallman <rms@gnu.org>
parents:
6909
diff
changeset
|
163 (defvar imenu-extract-index-name-function nil |
6230 | 164 "Function for extracting the index name. |
165 | |
166 This function is called after the function pointed out by | |
7319
cd73ba498964
(imenu): Renamed from goto-index-pos.
Richard M. Stallman <rms@gnu.org>
parents:
6909
diff
changeset
|
167 `imenu-prev-index-position-function'.") |
cd73ba498964
(imenu): Renamed from goto-index-pos.
Richard M. Stallman <rms@gnu.org>
parents:
6909
diff
changeset
|
168 (make-variable-buffer-local 'imenu-extract-index-name-function) |
6230 | 169 |
170 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
171 ;;; | |
172 ;;; Internal variables | |
173 ;;; | |
174 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
175 | |
176 ;; The item to use in the index for rescanning the buffer. | |
177 (defconst imenu--rescan-item '("*Rescan*" . -99)) | |
178 | |
179 ;; The latest buffer index. | |
180 ;; Buffer local. | |
181 (defvar imenu--index-alist nil) | |
182 (make-variable-buffer-local 'imenu--index-alist) | |
183 | |
184 ;; History list for 'jump-to-function-in-buffer'. | |
185 ;; Buffer local. | |
186 (defvar imenu--history-list nil) | |
187 (make-variable-buffer-local 'imenu--history-list) | |
188 | |
189 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
190 ;;; | |
191 ;;; Internal support functions | |
192 ;;; | |
193 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
194 | |
195 ;;; | |
196 ;;; Sort function | |
197 ;;; Sorts the items depending on their index name. | |
198 ;;; An item look like (NAME . POSITION). | |
199 ;;; | |
200 (defun imenu--sort-by-name (item1 item2) | |
201 (string-lessp (car item1) (car item2))) | |
202 | |
203 (defun imenu--relative-position (&optional reverse) | |
204 ;; Support function to calculate relative position in buffer | |
205 ;; Beginning of buffer is 0 and end of buffer is 100 | |
206 ;; If REVERSE is non-nil then the beginning is 100 and the end is 0. | |
207 (let ((pos (point)) | |
208 (total (buffer-size))) | |
209 (and reverse (setq pos (- total pos))) | |
210 (if (> total 50000) | |
211 ;; Avoid overflow from multiplying by 100! | |
212 (/ (1- pos) (max (/ total 100) 1)) | |
213 (/ (* 100 (1- pos)) (max total 1))))) | |
214 | |
215 ;;; | |
216 ;;; Macro to display a progress message. This will probably be used | |
217 ;;; in a tight loop, that is why we use a macro. | |
218 ;;; RELPOS is the relative position to display. | |
219 ;;; If RELPOS is nil, then the relative position in the buffer | |
220 ;;; is calculated. | |
221 (defmacro imenu-progress-message (&optional relpos reverse) | |
222 (` (and | |
223 imenu-scanning-message | |
224 (message imenu-scanning-message | |
225 (, (if relpos | |
226 relpos | |
227 (` (imenu--relative-position (, reverse))))))))) | |
228 | |
229 ;;; | |
230 ;;; Function for suporting general looking submenu names. | |
6909
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
231 ;;; Uses `imenu-submenu-name-format' for creating the name. |
6230 | 232 ;;; NAME is the base of the new submenu name. |
233 ;;; | |
234 (defun imenu-create-submenu-name (name) | |
235 (format imenu-submenu-name-format name)) | |
236 | |
237 ;; Split LIST into sublists of max length N. | |
238 ;; Example (imenu--split '(1 2 3 4 5 6 7 8) 3)-> '((1 2 3) (4 5 6) (7 8)) | |
239 (defun imenu--split (list n) | |
240 (let ((remain list) | |
241 (result '()) | |
242 (sublist '()) | |
243 (i 0)) | |
244 (while remain | |
245 (push (pop remain) sublist) | |
246 (incf i) | |
247 (and (= i n) | |
248 ;; We have finished a sublist | |
249 (progn (push (nreverse sublist) result) | |
250 (setq i 0) | |
251 (setq sublist '())))) | |
252 ;; There might be a sublist (if the length of LIST mod n is != 0) | |
253 ;; that has to be added to the result list. | |
254 (and sublist | |
255 (push (nreverse sublist) result)) | |
256 (nreverse result))) | |
257 | |
258 ;;; | |
259 ;;; Split a menu in to several menus. | |
260 ;;; | |
261 (defun imenu--split-menu (menulist title) | |
262 (cons "Function menus" | |
263 (mapcar | |
264 (function | |
265 (lambda (menu) | |
266 (cons (format "(%s)" title) menu))) | |
267 (imenu--split menulist imenu-max-items)))) | |
268 | |
269 ;;; | |
270 ;;; Find all items in this buffer that should be in the index. | |
271 ;;; Returns an alist on the form | |
272 ;;; ((NAME . POSITION) (NAME . POSITION) ...) | |
273 ;;; | |
274 | |
275 (defun imenu--make-index-alist () | |
276 ;; Create a list for this buffer only when needed. | |
277 (or imenu--index-alist | |
278 ;; Get the index | |
279 (setq imenu--index-alist | |
280 (save-excursion | |
281 (funcall imenu-create-index-function)))) | |
282 (or imenu--index-alist | |
283 (error "No items suitable for an index found in this buffer.")) | |
284 ;; Add a rescan option to the index. | |
285 (cons imenu--rescan-item imenu--index-alist)) | |
286 | |
287 (defun imenu-default-create-index-function () | |
288 "*Wrapper for index searching functions. | |
289 | |
290 Moves point to end of buffer and then repeatedly calls | |
7319
cd73ba498964
(imenu): Renamed from goto-index-pos.
Richard M. Stallman <rms@gnu.org>
parents:
6909
diff
changeset
|
291 `imenu-prev-index-position-function' and `imenu-extract-index-name-function'. |
6230 | 292 Their results are gathered into an index alist." |
293 | |
7319
cd73ba498964
(imenu): Renamed from goto-index-pos.
Richard M. Stallman <rms@gnu.org>
parents:
6909
diff
changeset
|
294 (or (and (fboundp imenu-prev-index-position-function) |
cd73ba498964
(imenu): Renamed from goto-index-pos.
Richard M. Stallman <rms@gnu.org>
parents:
6909
diff
changeset
|
295 (fboundp imenu-extract-index-name-function)) |
6230 | 296 (error "The mode \"%s\" does not take full advantage of imenu.el yet." |
297 mode-name)) | |
298 (let ((index-alist '()) | |
299 name) | |
300 (goto-char (point-max)) | |
301 (imenu-progress-message 0 t) | |
302 ;; Search for the function | |
7319
cd73ba498964
(imenu): Renamed from goto-index-pos.
Richard M. Stallman <rms@gnu.org>
parents:
6909
diff
changeset
|
303 (while (funcall imenu-prev-index-position-function) |
6230 | 304 (imenu-progress-message nil t) |
305 (save-excursion | |
7319
cd73ba498964
(imenu): Renamed from goto-index-pos.
Richard M. Stallman <rms@gnu.org>
parents:
6909
diff
changeset
|
306 (setq name (funcall imenu-extract-index-name-function))) |
6230 | 307 (and (stringp name) |
308 (push (cons name (point)) index-alist))) | |
309 (imenu-progress-message 100 t) | |
310 index-alist)) | |
311 | |
312 (defun imenu--replace-spaces (name replacement) | |
313 ;; Replace all spaces in NAME with REPLACEMENT. | |
314 ;; That second argument should be a string. | |
315 (mapconcat | |
316 (function | |
317 (lambda (ch) | |
318 (if (char-equal ch ?\ ) | |
319 replacement | |
320 (char-to-string ch)))) | |
321 name | |
322 "")) | |
323 | |
324 (defun imenu--flatten-index-alist (index-alist &optional concat-names prefix) | |
325 ;; Takes a nested INDEX-ALIST and returns a flat index alist. | |
326 ;; If optional CONCAT-NAMES is non-nil, then a nested index has its | |
327 ;; name and a space concatenated to the names of the children. | |
328 ;; Third argument PREFIX is for internal use only. | |
329 (mapcan | |
330 (function | |
331 (lambda (item) | |
332 (let* ((name (car item)) | |
333 (pos (cdr item)) | |
334 (new-prefix (and concat-names | |
335 (if prefix | |
336 (concat prefix imenu-level-separator name) | |
337 name)))) | |
338 (cond | |
339 ((numberp pos) | |
340 (list (cons new-prefix pos))) | |
341 (t | |
342 (imenu--flatten-index-alist pos new-prefix)))))) | |
343 index-alist)) | |
344 | |
345 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
346 ;;; | |
347 ;;; The main functions for this package! | |
348 ;;; | |
349 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
350 | |
351 (defun imenu--completion-buffer (index-alist &optional prompt) | |
352 "Let the user select from INDEX-ALIST in a completion buffer with PROMPT. | |
353 | |
354 Returns t for rescan and otherwise a position number." | |
355 ;; Create a list for this buffer only when needed. | |
356 (let (name choice | |
357 (prepared-index-alist | |
358 (mapcar | |
359 (function | |
360 (lambda (item) | |
361 (cons (imenu--replace-spaces (car item) imenu-space-replacement) | |
362 (cdr item)))) | |
363 index-alist))) | |
364 (save-window-excursion | |
365 ;; Display the completion buffer | |
366 (with-output-to-temp-buffer "*Completions*" | |
367 (display-completion-list | |
368 (all-completions "" prepared-index-alist ))) | |
369 ;; Make a completion question | |
370 (setq name (completing-read (or prompt "Index item: ") | |
371 prepared-index-alist | |
372 nil t nil 'imenu--history-list))) | |
373 (cond | |
374 ((not (stringp name)) | |
375 nil) | |
376 ((string= name (car imenu--rescan-item)) | |
377 t) | |
378 (t | |
379 (setq choice (assoc name prepared-index-alist)) | |
380 (cond | |
381 ((listp (cdr choice)) | |
382 (imenu--completion-buffer (cdr choice) prompt)) | |
383 (t | |
384 choice)))))) | |
7319
cd73ba498964
(imenu): Renamed from goto-index-pos.
Richard M. Stallman <rms@gnu.org>
parents:
6909
diff
changeset
|
385 |
6230 | 386 (defun imenu--mouse-menu (index-alist event &optional title) |
387 "Let the user select from a buffer index from a mouse menu. | |
388 | |
389 INDEX-ALIST is the buffer index and EVENT is a mouse event. | |
390 | |
391 Returns t for rescan and otherwise a position number." | |
392 (let* ((menu (imenu--split-menu | |
393 (if imenu-sort-function | |
6909
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
394 (sort |
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
395 (let ((res nil) |
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
396 (oldlist index-alist)) |
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
397 ;; Copy list method from the cl package `copy-list' |
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
398 (while (consp oldlist) (push (pop oldlist) res)) |
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
399 (prog1 (nreverse res) (setcdr res oldlist))) |
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
400 imenu-sort-function) |
6230 | 401 index-alist) |
402 (or title (buffer-name)))) | |
403 position) | |
404 (setq position (x-popup-menu event menu)) | |
405 (cond | |
406 ((eq position nil) | |
407 position) | |
6241 | 408 ((listp position) |
6230 | 409 (imenu--mouse-menu position event |
410 (if title | |
411 (concat title imenu-level-separator | |
412 (car (rassq position index-alist))) | |
413 (car (rassq position index-alist))))) | |
414 ((= position (cdr imenu--rescan-item)) | |
415 t) | |
416 (t | |
417 (rassq position index-alist))))) | |
418 | |
6241 | 419 (defun imenu-choose-buffer-index (&optional prompt alist) |
6230 | 420 "Let the user select from a buffer index and return the chosen index. |
421 | |
422 If the user originally activated this function with the mouse, a mouse | |
423 menu is used. Otherwise a completion buffer is used and the user is | |
424 prompted with PROMPT. | |
425 | |
6241 | 426 If you call this function with index alist ALIST, then it lets the user |
427 select from ALIST. | |
428 | |
6909
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
429 With no index alist ALIST, it calls `imenu--make-index-alist' to |
6241 | 430 create the index alist. |
431 | |
6909
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
432 If `imenu-always-use-completion-buffer-p' is non-nil, then the |
6230 | 433 completion buffer is always used, no matter if the mouse was used or |
434 not. | |
435 | |
436 The returned value is on the form (INDEX-NAME . INDEX-POSITION)." | |
437 (let (index-alist | |
438 (mouse-triggered (listp last-command-event)) | |
439 (result t) ) | |
440 ;; If selected by mouse, see to that the window where the mouse is | |
441 ;; really is selected. | |
442 (and mouse-triggered | |
443 (let ((window (posn-window (event-start last-command-event)))) | |
444 (or (framep window) (select-window window)))) | |
445 ;; Create a list for this buffer only when needed. | |
446 (while (eq result t) | |
6241 | 447 (setq index-alist (if alist alist (imenu--make-index-alist))) |
6230 | 448 (setq result |
449 (if (and mouse-triggered | |
450 (not imenu-always-use-completion-buffer-p)) | |
451 (imenu--mouse-menu index-alist last-command-event) | |
452 (imenu--completion-buffer index-alist prompt))) | |
453 (and (eq result t) | |
454 (setq imenu--index-alist nil))) | |
455 result)) | |
456 | |
7319
cd73ba498964
(imenu): Renamed from goto-index-pos.
Richard M. Stallman <rms@gnu.org>
parents:
6909
diff
changeset
|
457 ;;;###autoload |
cd73ba498964
(imenu): Renamed from goto-index-pos.
Richard M. Stallman <rms@gnu.org>
parents:
6909
diff
changeset
|
458 (defun imenu () |
cd73ba498964
(imenu): Renamed from goto-index-pos.
Richard M. Stallman <rms@gnu.org>
parents:
6909
diff
changeset
|
459 "Jump to a place in the buffer chosen using a buffer menu or mouse menu. |
6909
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
460 See `imenu-choose-buffer-index' for more information." |
6230 | 461 (interactive) |
462 (let ((index-item (imenu-choose-buffer-index))) | |
463 (and index-item | |
464 (progn | |
465 (push-mark) | |
466 (goto-char (cdr index-item)))))) | |
467 | |
468 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
469 ;;;; | |
470 ;;;; Some examples of functions utilizing the framework of this | |
471 ;;;; package. | |
472 ;;;; | |
473 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
474 | |
475 ;; Return the current/previous sexp and the location of the sexp (it's | |
476 ;; beginning) without moving the point. | |
477 (defun imenu-example--name-and-position () | |
478 (save-excursion | |
479 (forward-sexp -1) | |
480 (let ((beg (point)) | |
481 (end (progn (forward-sexp) (point)))) | |
482 (cons (buffer-substring beg end) | |
483 beg)))) | |
484 | |
485 ;;; | |
486 ;;; Lisp | |
487 ;;; | |
488 | |
489 (defun imenu-example--lisp-extract-index-name () | |
6909
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
490 ;; Example of a candidate for `imenu-extract-index-name-function'. |
6230 | 491 ;; This will generate a flat index of definitions in a lisp file. |
492 (save-match-data | |
493 (and (looking-at "(def") | |
494 (condition-case nil | |
495 (progn | |
496 (down-list 1) | |
497 (forward-sexp 2) | |
498 (let ((beg (point)) | |
499 (end (progn (forward-sexp -1) (point)))) | |
500 (buffer-substring beg end))) | |
501 (error nil))))) | |
502 | |
503 (defun imenu-example--create-lisp-index () | |
6909
9e59751db725
Require cl only at compile time.
Richard M. Stallman <rms@gnu.org>
parents:
6241
diff
changeset
|
504 ;; Example of a candidate for `imenu-create-index-function'. |
6230 | 505 ;; It will generate a nested index of definitions. |
506 (let ((index-alist '()) | |
507 (index-var-alist '()) | |
6241 | 508 (index-type-alist '()) |
6230 | 509 (index-unknown-alist '())) |
510 (goto-char (point-max)) | |
511 (imenu-progress-message 0) | |
512 ;; Search for the function | |
513 (while (beginning-of-defun) | |
514 (imenu-progress-message nil t) | |
515 (save-match-data | |
516 (and (looking-at "(def") | |
517 (save-excursion | |
518 (down-list 1) | |
519 (cond | |
520 ((looking-at "def\\(var\\|const\\)") | |
521 (forward-sexp 2) | |
522 (push (imenu-example--name-and-position) | |
523 index-var-alist)) | |
524 ((looking-at "def\\(un\\|subst\\|macro\\|advice\\)") | |
525 (forward-sexp 2) | |
526 (push (imenu-example--name-and-position) | |
527 index-alist)) | |
6241 | 528 ((looking-at "def\\(type\\|struct\\|class\\|ine-condition\\)") |
529 (forward-sexp 2) | |
530 (if (= (char-after (1- (point))) ?\)) | |
531 (progn | |
532 (forward-sexp -1) | |
533 (down-list 1) | |
534 (forward-sexp 1))) | |
535 (push (imenu-example--name-and-position) | |
536 index-type-alist)) | |
6230 | 537 (t |
538 (forward-sexp 2) | |
539 (push (imenu-example--name-and-position) | |
540 index-unknown-alist))))))) | |
541 (imenu-progress-message 100) | |
542 (and index-var-alist | |
543 (push (cons (imenu-create-submenu-name "Variables") index-var-alist) | |
544 index-alist)) | |
6241 | 545 (and index-type-alist |
546 (push (cons (imenu-create-submenu-name "Types") index-type-alist) | |
547 index-alist)) | |
6230 | 548 (and index-unknown-alist |
549 (push (cons (imenu-create-submenu-name "Syntax-unknown") index-unknown-alist) | |
550 index-alist)) | |
551 index-alist)) | |
552 | |
553 | |
554 ;;; | |
555 ;;; C | |
556 ;;; | |
557 ;; Regular expression to find C functions | |
558 (defvar imenu-example--function-name-regexp-c | |
559 (concat | |
560 "^[a-zA-Z0-9]+[ \t]?" ; type specs; there can be no | |
561 "\\([a-zA-Z0-9_*]+[ \t]+\\)?" ; more than 3 tokens, right? | |
562 "\\([a-zA-Z0-9_*]+[ \t]+\\)?" | |
563 "\\([*&]+[ \t]*\\)?" ; pointer | |
564 "\\([a-zA-Z0-9_*]+\\)[ \t]*(" ; name | |
565 )) | |
566 | |
567 (defun imenu-example--create-c-index (&optional regexp) | |
568 (let ((index-alist '()) | |
569 (char)) | |
570 (goto-char (point-min)) | |
571 (imenu-progress-message 0) | |
572 ;; Search for the function | |
573 (save-match-data | |
574 (while (re-search-forward | |
575 (or regexp imenu-example--function-name-regexp-c) | |
576 nil t) | |
577 (imenu-progress-message) | |
578 (backward-up-list 1) | |
579 (save-excursion | |
580 (goto-char (scan-sexps (point) 1)) | |
581 (setq char (following-char))) | |
582 ;; Skip this function name if it is a prototype declaration. | |
583 (if (not (eq char ?\;)) | |
584 (push (imenu-example--name-and-position) index-alist)))) | |
585 (imenu-progress-message 100) | |
586 (nreverse index-alist))) | |
587 | |
588 ;;; | |
589 ;;; C++ | |
590 ;;; | |
591 ;; Regular expression to find C++ functions | |
592 (defvar imenu-example--function-name-regexp-c++ | |
593 (concat | |
594 "^[a-zA-Z0-9:]+[ \t]?" ; type specs; there can be no | |
595 "\\([a-zA-Z0-9_:~*]+[ \t]+\\)?" ; more than 3 tokens, right? | |
596 "\\([a-zA-Z0-9_:~*]+[ \t]+\\)?" | |
597 "\\([*&]+[ \t]*\\)?" ; pointer | |
598 "\\([a-zA-Z0-9_:*]+\\)[ \t]*(" ; name | |
599 )) | |
600 (defun imenu-example--create-c++-index () | |
601 (imenu-example--create-c-index imenu-example--function-name-regexp-c++)) | |
602 | |
603 | |
604 ;;; | |
605 ;;; Example of hooks for the examples above | |
606 ;;; Put this in your .emacs. | |
607 ;;; | |
608 ;; (add-hook 'emacs-lisp-mode-hook | |
609 ;; (function | |
610 ;; (lambda () | |
611 ;; (setq imenu-create-index-function | |
612 ;; (function imenu-example--create-lisp-index))))) | |
613 | |
614 ;; (add-hook 'lisp-mode-hook | |
615 ;; (function | |
616 ;; (lambda () | |
617 ;; (setq imenu-create-index-function | |
618 ;; (function imenu-example--create-lisp-index))))) | |
619 | |
620 ;; (add-hook 'c++-mode-hook | |
621 ;; (function | |
622 ;; (lambda () | |
623 ;; (setq imenu-create-index-function | |
624 ;; (function imenu-example--create-c++-index))))) | |
625 | |
626 ;; (add-hook 'c-mode-hook | |
627 ;; (function | |
628 ;; (lambda () | |
629 ;; (setq imenu-create-index-function | |
630 ;; (function imenu-example--create-c-index))))) | |
631 | |
632 (provide 'imenu) | |
633 | |
634 ;;; imenu.el ends here |