comparison lisp/energize/energize-visit-use.el @ 0:376386a54a3c r19-14

Import from CVS: tag r19-14
author cvs
date Mon, 13 Aug 2007 08:45:50 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:376386a54a3c
1 ;;; -*- Mode:Emacs-Lisp -*-
2 ;;; Copyright © 1992-1993 by Lucid, Inc. All Rights Reserved.
3
4 ;; Load this file and ^X-\ (back-slash) gets bound to a
5 ;; command that visit all the places where a language element is used.
6 ;; It can be started from the Le-Browser buffer of that language element
7 ;; or from a toplevel from defining the element.
8 ;;
9 ;; The visit happens as follows:
10 ;; - the 1st ^X-\ jumps to the beginning of the definition of the 1sr user.
11 ;; - then search-forward inside the first user for the name of the
12 ;; language element that was in the le-browser buffer.
13 ;; - the 2rd one searches again etc.. until no more match is found inside
14 ;; the body of the 1 user.
15 ;; - after the last match is seen the next user of the LE is visited
16 ;; the same way.
17 ;;
18 ;; If you want to start revisiting while a previous visit is not terminated do
19 ;; ^U-^X-\ in another (or the same) le-browser buffer.
20 ;;
21 ;; If you position the point on a User in the LE Browser buffer before doing
22 ;; ^X-\, that use will become the next one shown.
23 ;;
24 ;; energize-next-use-previous, ^U-1-^X-\, backs up one use
25 ;;
26 ;; It's quite crude and the UI could be improved in different ways.
27 ;; What about:
28 ;; - Allow for stacking of visits so that you can recursively
29 ;; visit another LE while one is being visited.
30 ;; - Highlight all the occurences of the LE-name inside the body of the user.
31 ;; - Deal with *alternatives*
32
33 (defvar energize-next-use-show-le-browser t
34 "*If t energize-next-use-command will show both the next use and the le-browser buffer")
35
36 (defvar energize-next-use-search-by-file nil ;; default is off cause on is slow
37 "*If t energize-next-use-command will show all uses in a file before going to
38 the next file")
39
40 (defvar energize-next-use-command-name ())
41 (defvar energize-next-use-label ())
42 (defvar energize-next-use-name ())
43 (defvar energize-next-use-from-mark ())
44 (defvar energize-next-use-source-start-mark ())
45 (defvar energize-next-use-source-end-mark ())
46 (defvar energize-next-use-source-current-mark ())
47 (defvar energize-next-use-current-file ())
48 (defvar energize-next-use-file-began-mark ())
49 (defvar energize-next-use-from-extent-cache ())
50 (defvar energize-next-use-history ())
51 (defvar energize-next-use-history-pointer ())
52 (defvar energize-next-use-marker-heap ())
53
54 ;; remember markers we allocate so we can clean them up
55 (defun energize-next-use-make-a-marker ()
56 (let ((m (make-marker)))
57 (setq energize-next-use-marker-heap
58 (cons m energize-next-use-marker-heap))
59 m))
60
61 (defun energize-next-use-copy-a-marker (mark)
62 (let ((m (copy-marker mark)))
63 (setq energize-next-use-marker-heap
64 (cons m energize-next-use-marker-heap))
65 m))
66
67 (defun energize-next-use-cleanup-markers ()
68 (while energize-next-use-marker-heap
69 (set-marker (car energize-next-use-marker-heap) nil)
70 (setq energize-next-use-marker-heap (cdr energize-next-use-marker-heap))))
71
72 (defun extent-after (pos)
73 (let ((extent (next-extent (current-buffer))))
74 (while (and extent (< (extent-start-position extent) pos))
75 (setq extent (next-extent extent)))
76 extent))
77
78 (defun energize-next-use-start-pos ()
79 (save-excursion
80 (goto-char (point-min))
81 (if (search-forward energize-next-use-label () t)
82 (point)
83 ())))
84
85 ;; see if we are in the LE Browser buffer of the object we are looking at
86 ;; uses of. If so, capture the position as a possible place to find the
87 ;; next user, rather than take the first or next in sequence.
88 (defun energize-next-use-start-pos-offset ()
89 ;; energize-next-use-from-mark is NULL iff this is called from
90 ;; energize-next-use-init - in that case assume that if we are in a LEB
91 ;; it is the one we will be using
92 (if (if (and energize-next-use-from-mark
93 (marker-buffer energize-next-use-from-mark))
94 (eq (current-buffer) (marker-buffer energize-next-use-from-mark))
95 (eq major-mode 'energize-browser-mode))
96 (save-excursion
97 (beginning-of-line)
98 (point))))
99
100 (defun energize-next-use-get-name (name)
101 (let ((colon (- (length name) 1)))
102 (while (and (> colon 0) (not (eq (aref name colon) ?:)))
103 (setq colon (- colon 1)))
104 (if (= (aref name colon) ?:)
105 (substring name (+ colon 1))
106 name)))
107
108 ;; cache the extents (and later the results of following them to the
109 ;; source buffer) to avoid calling the server too many times
110 ;; returns nil if the extent does not have a "source" menu option
111 ;; returns the cache entry otherwise
112 (defun energize-next-use-valid-from-extent-p (buff extent)
113 (let ((cache-entry (assoc extent energize-next-use-from-extent-cache)))
114 (if (not cache-entry)
115 (if (energize-list-menu buff extent ()
116 energize-next-use-command-name)
117 (setq energize-next-use-from-extent-cache
118 (cons (setq cache-entry (list extent))
119 energize-next-use-from-extent-cache))))
120 cache-entry))
121
122 ;; decide what use to look at next. current is nil if called from
123 ;; energize-next-use-next, else it is the presumed first extent for
124 ;; energize-next-use-from-mark passed from energize-next-use-init
125 ;; wanted-pos is the position of the cursor in the LE Browser of the
126 ;; object being looked for, or nil if the cursor is not in that buffer
127 ;; if wanted-pos is non-nil it means we will consider restarting the
128 ;; search at the user indicated by that position. Otherwise, we just
129 ;; return current. If this is nil too, it means just continue searching
130 ;; as before. If not, it means continue initializing as before.
131 ;;
132 ;; returns an extent to be used to set energize-next-use-from-mark or nil
133 (defun energize-next-use-adjust-for-start-offset (current wanted-pos)
134 ;; assumes we're in the LE browser buffer (we may not have been when
135 ;; the value of wanted-pos was determined)
136 (if wanted-pos
137 (let ((end-pos (energize-next-use-end-pos))
138 ;; ok will be set to the first extent found that is actually
139 ;; a user
140 (ok nil)
141 (try (or current (extent-after (energize-next-use-start-pos)))))
142 ;; loop will exit if an actual user extent is found that follows
143 ;; the wanted-pos - if we go out of bounds, try is set to nil
144 ;; else it is the desired extent on exit from the loop
145 (while (and try
146 (or (< (extent-start-position try) end-pos)
147 (setq try nil))
148 (not
149 (and
150 ;; try is a valid user extent if this menu exists
151 (energize-next-use-valid-from-extent-p
152 (current-buffer) try)
153 ;; but it might be before wanted-pos,
154 (or (> (extent-end-position try) wanted-pos)
155 ;; in which case remember it as ok unless
156 ;; ok was already set
157 (and (setq ok (or ok try)) nil)))))
158 (setq try (next-extent try)))
159 ;; return try or if we were called from init, return ok
160 ;; else return nil to mean continue searching in current sequence
161 (or try (and current ok)))
162 current))
163
164 (defun energize-next-use-set-marks (extent buffer)
165 (if (not energize-next-use-from-mark)
166 (setq energize-next-use-from-mark (make-marker)))
167 (set-marker energize-next-use-from-mark
168 (extent-start-position extent) buffer))
169
170 (defun energize-next-use-init (command label)
171 ;; start-offset is the position of point if it is in the LEB buffer
172 (let ((start-offset (energize-next-use-start-pos-offset)))
173 (if (not (eq major-mode 'energize-browser-mode))
174 (if (energize-list-menu (current-buffer)
175 (energize-extent-at (point)) ()
176 "browse_le")
177 (energize-execute-command "browse_le"
178 (energize-extent-at (point)) () t)
179 (error
180 "command undefined unless in a LE buffer or at a LE definition form")))
181 (setq energize-next-use-command-name command)
182 (setq energize-next-use-label label)
183 (setq energize-next-use-current-file nil)
184 (setq energize-next-use-from-extent-cache nil)
185 (setq energize-next-use-history nil)
186 (setq energize-next-use-history-pointer nil)
187 (let* ((pos (energize-next-use-start-pos))
188 (extent (and pos
189 ;; start at the beginning, unless start-pos says
190 ;; to start further along
191 (energize-next-use-adjust-for-start-offset
192 (extent-after pos) start-offset))))
193 (if (null extent)
194 (error "no uses")
195 (energize-next-use-set-marks extent (current-buffer))
196 (setq energize-next-use-name
197 (save-excursion
198 (let ((s (energize-next-use-get-name (buffer-name))))
199 (if (let ((l (length s)))
200 (while (not
201 (and (> l 0)
202 (progn
203 (beginning-of-buffer)
204 (search-forward
205 (substring s 0 l) nil t))))
206 (setq l (- l 1)))
207 (> l 0))
208 (let (pos)
209 (backward-sexp)
210 (setq pos (point))
211 (forward-sexp)
212 (buffer-substring pos (point)))
213 s))))))
214 (energize-next-use-show-both)))
215
216 (defun energize-next-use-end-pos ()
217 (save-excursion
218 (goto-char (point-min))
219 (search-forward energize-next-use-label)
220 (re-search-forward "^ *[A-Za-z ]*: " () 'end)
221 (point)))
222
223 ;; return the source-entry portion of the extent cache, looking it up
224 ;; if necessary by doing energize-execute-command "source" on the extent
225 ;; source-entry portion is list of
226 ;; a) point marker after executing the "source" command
227 ;; b) a flag saying we've actually visited this use, not just looked it up
228 ;; c) marker for the window-start after executing the "source" command
229 (defun energize-next-use-from-extent-source-info (from-extent-entry)
230 (let ((extent (car from-extent-entry))
231 (source-entry (cdr from-extent-entry)))
232 (if (not source-entry)
233 (save-window-excursion
234 (save-excursion
235 (let ((pre-display-buffer-function nil)) ;; hack for multi-frame
236 (energize-execute-command
237 energize-next-use-command-name extent () t))
238 (setcdr from-extent-entry
239 (setq source-entry
240 (list (energize-next-use-copy-a-marker
241 (point-marker))
242 nil
243 (set-marker
244 (energize-next-use-make-a-marker)
245 (window-start))))))))
246 source-entry))
247
248 (defun energize-next-use-from-extent-source-mark (source-entry)
249 (car source-entry))
250
251 (defun energize-next-use-from-extent-source-start-mark (source-entry)
252 (car (cdr (cdr source-entry))))
253
254 (defun energize-next-use-from-extent-source-seen-p (source-entry)
255 (car (cdr source-entry)))
256
257 (defun energize-next-use-from-extent-set-source-seen-p (source-entry)
258 (setcar (cdr source-entry) t))
259
260 ;; goto the next user - or if advance is nil try to re-establish the
261 ;; extent for the current one
262 (defun energize-next-use-next-to-extent (advance)
263 (let ((buff (marker-buffer energize-next-use-from-mark))
264 (from-pos (marker-position energize-next-use-from-mark)))
265 (and buff from-pos
266 (let ((result nil))
267 (set-buffer buff)
268 (let ((end-pos (energize-next-use-end-pos))
269 (extent (or (energize-extent-at from-pos)
270 (setq advance nil)
271 (extent-after from-pos))))
272 (if (and advance energize-next-use-search-by-file)
273 (if (not energize-next-use-current-file)
274 ;; if searching by file but dont have a current file,
275 ;; set current file to current source buffer
276 (if (setq energize-next-use-current-file
277 (and energize-next-use-source-start-mark
278 (marker-buffer
279 energize-next-use-source-start-mark)))
280 (progn
281 (if (not energize-next-use-file-began-mark)
282 (setq energize-next-use-file-began-mark
283 (make-marker)))
284 (set-marker energize-next-use-file-began-mark
285 from-pos buff))))
286 (setq energize-next-use-current-file nil))
287 (if advance
288 (setq extent (next-extent extent)))
289 (if energize-next-use-search-by-file
290 (message "Searching for next use in current file...")
291 (message "Searching for next use..."))
292 ;; validate the extent
293 (while extent
294 (while
295 (and
296 extent
297 ;; if extent is beyond the end of the "used by" zone
298 ;; set it to nil to terminate loop
299 (or (< (extent-start-position extent) end-pos)
300 (setq extent nil))
301 (not
302 (let ((from-extent-entry
303 (energize-next-use-valid-from-extent-p
304 buff extent)))
305 (and
306 ;; true if the extent has a "source" menu option
307 from-extent-entry
308 (or
309 (not energize-next-use-search-by-file)
310 ;; see if this is extent points to the current file
311 ;; or a file we haven't looked at yet, if not current
312 ;; file is set now
313 (let* ((source-entry
314 (energize-next-use-from-extent-source-info
315 from-extent-entry))
316 (source-marker
317 (energize-next-use-from-extent-source-mark
318 source-entry))
319 (buff (marker-buffer source-marker)))
320 (if energize-next-use-current-file
321 (eq buff energize-next-use-current-file)
322 (not
323 (energize-next-use-from-extent-source-seen-p
324 source-entry)))))))))
325 (setq extent (next-extent extent)))
326 (if extent
327 ;; we found one we can use - remember it but set extent
328 ;; to nil to terminate the loop
329 (progn
330 ;; convert the extent to a mark for future reference
331 (energize-next-use-set-marks extent buff)
332 ;; terminate the loop
333 (setq extent nil)
334 ;; saw we succeeded in finding something
335 (setq result t))
336 ;; we didn't find anything valid - if we were looking in
337 ;; the current file, restart the loop now looking for
338 ;; anything we haven't used yet, to make it the current file
339 ;; if we weren't looking in the current file then we really
340 ;; have failed to find anything left, so return nil
341 (if energize-next-use-current-file
342 (progn
343 (setq energize-next-use-current-file nil)
344 (setq extent
345 ;; restart loop from were we started looking at
346 ;; the current file
347 (let ((pos (marker-position
348 energize-next-use-file-began-mark)))
349 (and pos
350 (or (energize-extent-at pos)
351 (extent-after pos)))))))))
352 (if energize-next-use-search-by-file
353 (message "Searching for next use in current file...done")
354 (message "Searching for next use...done"))
355 result)))))
356
357 (defun energize-next-use-show-from (&optional mark)
358 (setq mark (or mark energize-next-use-from-mark))
359 (if energize-next-use-show-le-browser
360 ;; position the browser to the line of the current user
361 (let ((buff (marker-buffer mark))
362 (from-pos (marker-position mark)))
363 (and buff from-pos
364 (progn
365 ;; don't worry about pre-display-buffer-function here;
366 ;; we actually want a new frame to be created when
367 ;; displaying the Browser buffer.
368 (pop-to-buffer buff)
369 (goto-char from-pos)
370 (beginning-of-line)
371 (set-window-start (selected-window) (point)))))
372 (message "next use of %s" energize-next-use-name)))
373
374 (defun energize-next-use-show-to ()
375 (let* ((buff (marker-buffer energize-next-use-from-mark))
376 (from-pos (marker-position energize-next-use-from-mark))
377 (from-extent (and buff from-pos (energize-extent-at from-pos buff)))
378 (from-extent-entry
379 ;; get the cache entry for the current user extent in the browser
380 (energize-next-use-valid-from-extent-p buff from-extent))
381 (source-extent nil))
382 (and
383 from-extent-entry
384 (let* ((source-entry
385 (energize-next-use-from-extent-source-info
386 from-extent-entry))
387 (source-marker
388 (energize-next-use-from-extent-source-mark
389 source-entry))
390 (source-buffer (marker-buffer source-marker))
391 (source-pos (marker-position source-marker))
392 ;; if we're allowed to split frames, call pop-to-buffer
393 ;; with no pre-display-buffer-function, so that the current
394 ;; frame (the frame of the Browser buffer) is used. If
395 ;; we don't split frames, then use the p-d-b-f, so that a
396 ;; new frame can be created for this file.
397 (pre-display-buffer-function
398 (if energize-split-screens-p
399 nil
400 pre-display-buffer-function)))
401 (if source-pos
402 (progn
403 ;; position the source window as if we had just executed the
404 ;; command "source" on the from-extent in the browser
405 (pop-to-buffer source-buffer)
406 (set-window-start
407 (selected-window)
408 (marker-position
409 (energize-next-use-from-extent-source-start-mark source-entry))
410 t)
411 (goto-char source-marker)
412 ;; note that we have actually visited this use
413 (energize-next-use-from-extent-set-source-seen-p source-entry)
414 (setq source-extent (energize-extent-at (point))))))
415 (let ((start-pos (extent-start-position source-extent)))
416 ;; convert positions to markers
417 (if (not energize-next-use-source-start-mark)
418 (setq energize-next-use-source-start-mark (make-marker)))
419 (if (not energize-next-use-source-end-mark)
420 (setq energize-next-use-source-end-mark (make-marker)))
421 (if (not energize-next-use-source-current-mark)
422 (setq energize-next-use-source-current-mark (make-marker)))
423 (set-marker energize-next-use-source-start-mark start-pos)
424 (set-marker energize-next-use-source-current-mark start-pos)
425 (set-marker energize-next-use-source-end-mark
426 (extent-end-position source-extent))))))
427
428 (defun energize-next-use-search-for-name ()
429 (if (let ((case-fold-search nil)
430 (found nil)
431 (end-pos (marker-position energize-next-use-source-end-mark)))
432 (if end-pos
433 (progn
434 (buffer-syntactic-context-flush-cache)
435 ;; case sensitive exact search for token not in comment or string
436 (while
437 (and
438 (setq found
439 (re-search-forward
440 (concat "[^A-Za-z0-9_]"
441 (regexp-quote energize-next-use-name)
442 "[^A-Za-z0-9_]")
443 end-pos t))
444 (save-excursion (buffer-syntactic-context))))))
445 found)
446 (progn
447 ;; allow for the delimiter
448 (backward-char 1)
449 t)
450 nil))
451
452
453 ;; say this if search can't find the thing that is being used
454 (defun energize-next-use-not-lexically-apparent ()
455 (message "next use of %s is here, but not lexically apparent"
456 energize-next-use-name))
457
458 ;; called when visiting a new users, not a new use within that user
459 (defun energize-next-use-show-both ()
460 ;; reposition the browser to the line showing the user
461 (energize-next-use-show-from)
462 ;; position the source to the user definition form
463 (energize-next-use-show-to)
464 ;; instead of stopping at the beginning of the user form,
465 ;; go immediately to the first use found if it is lexically apparent
466 (if (and
467 energize-next-use-source-start-mark
468 (let ((buff (marker-buffer energize-next-use-source-start-mark))
469 (current-pos
470 (marker-position energize-next-use-source-current-mark))
471 (end-pos (marker-position energize-next-use-source-end-mark)))
472 (if (and buff current-pos end-pos)
473 (save-excursion
474 (set-buffer buff)
475 (and (< current-pos end-pos)
476 (progn
477 (goto-char current-pos)
478 (energize-next-use-search-for-name)))))))
479 ;; an apparent use is there, so proceed as if going to the next use
480 ;; within the user
481 (energize-next-use-next)
482 ;; no use is apparent, so print a message
483 (energize-next-use-not-lexically-apparent)
484 ;; record the history entry for a non-apparent use - it is distinguished
485 ;; by having no point position from which to make a region to highlight
486 (setq energize-next-use-history
487 (cons (list (energize-next-use-copy-a-marker
488 energize-next-use-from-mark)
489 (energize-next-use-copy-a-marker
490 energize-next-use-source-current-mark)
491 (set-marker (energize-next-use-make-a-marker)
492 (window-start)))
493 energize-next-use-history))
494 (setq energize-next-use-history-pointer
495 energize-next-use-history)))
496
497 ;; show the next use within the current user - if no more are found
498 ;; go to the next user
499 (defun energize-next-use-next ()
500 ;; new-start will get set to an extent for a user at which to
501 ;; reposition the visit, iff the cursor is in the LEB buffer
502 ;; of the usee at a valid position in the list of users.
503 (let ((new-start (energize-next-use-adjust-for-start-offset
504 nil (energize-next-use-start-pos-offset)))
505 (buff (marker-buffer energize-next-use-source-start-mark))
506 (current-pos (marker-position energize-next-use-source-current-mark))
507 (end-pos (marker-position energize-next-use-source-end-mark)))
508 (if (and buff (not (eq buff (current-buffer))))
509 (set-buffer buff))
510 ;; new-start means we are repositioning due to the point being in the
511 ;; user list in the browser. In this case we will act as if we are
512 ;; at the end of the old user
513 (if new-start
514 (energize-next-use-set-marks
515 new-start
516 (marker-buffer energize-next-use-from-mark)))
517 (cond ((and buff current-pos end-pos
518 (not new-start) ;; don't stay in current user if repositioning
519 (< current-pos end-pos)
520 (progn
521 (goto-char current-pos)
522 (energize-next-use-search-for-name)))
523 ;; the 'still in the same user' case
524 (set-marker energize-next-use-source-current-mark (point))
525 ;; redisplay the browser in case it got covered up
526 (energize-next-use-show-from)
527 ;; We know that we're not changing files, so there won't be any
528 ;; need to create a new frame; it would be nice if we reselected
529 ;; the appropriate frame instead of just using the current frame,
530 ;; but that's more work, and this will very rarely do the wrong
531 ;; thing.
532 (let ((pre-display-buffer-function
533 (if energize-split-screens-p
534 nil
535 pre-display-buffer-function)))
536 ;; display the source buffer
537 (pop-to-buffer buff)
538 ;; had to do this because window-start overrides point
539 ;; in terms of deciding what part of the window to show
540 ;; this seems like a possible bug
541 (set-window-buffer (selected-window) buff)
542 (push-mark (point) t)
543 (backward-char (length energize-next-use-name))
544 (if zmacs-regions
545 (zmacs-activate-region))
546 ;; record the visit in the history - this entry has a point
547 ;; marker, distinguishing it from a non-lexically apparent one
548 (setq energize-next-use-history
549 (cons (list
550 (energize-next-use-copy-a-marker
551 energize-next-use-from-mark)
552 (energize-next-use-copy-a-marker
553 energize-next-use-source-current-mark)
554 (set-marker (energize-next-use-make-a-marker)
555 (window-start))
556 (set-marker (energize-next-use-make-a-marker)
557 (point)))
558 energize-next-use-history))
559 (setq energize-next-use-history-pointer
560 energize-next-use-history)))
561 ((or new-start
562 (energize-next-use-next-to-extent
563 (and buff current-pos end-pos)))
564 ;; the 'moved to a new user or repositioned to one' case
565 (energize-next-use-show-both))
566 (t
567 ;; no more users
568 (energize-next-use-terminate)
569 (error "no more")))))
570
571
572 (defun energize-next-use-terminate ()
573 (setq energize-next-use-command-name ())
574 (setq energize-next-use-label ())
575 (setq energize-next-use-name ())
576 (if energize-next-use-from-mark
577 (set-marker energize-next-use-from-mark nil))
578 (if energize-next-use-source-start-mark
579 (set-marker energize-next-use-source-start-mark nil))
580 (if energize-next-use-source-current-mark
581 (set-marker energize-next-use-source-current-mark nil))
582 (if energize-next-use-source-end-mark
583 (set-marker energize-next-use-source-end-mark nil))
584 (if energize-next-use-file-began-mark
585 (set-marker energize-next-use-file-began-mark nil))
586 (energize-next-use-cleanup-markers))
587
588 ;; get next use from history list if we have regressed or are regressing
589 ;; if history-pointer == history then we are in the present
590 ;; to go back set history-pointer to cdr history-pointer
591 ;; to go forward set history-pointer to the last cell on history prior to
592 ;; the current value of history-pointer
593 ;; a history entry is just redisplay info for the browser and source buffers
594 (defun energize-next-use-from-history (backward)
595 (if backward
596 (setq energize-next-use-history-pointer
597 (cdr energize-next-use-history-pointer))
598 (let ((temp energize-next-use-history-pointer))
599 (setq energize-next-use-history-pointer
600 energize-next-use-history)
601 (while (not (eq (cdr energize-next-use-history-pointer) temp))
602 (setq energize-next-use-history-pointer
603 (cdr energize-next-use-history-pointer)))))
604 (let* ((history-entry (car energize-next-use-history-pointer))
605 (from-mark (car history-entry))
606 (source-mark (car (cdr history-entry)))
607 (source-start-mark (car (cdr (cdr history-entry))))
608 (source-point-mark (car (cdr (cdr (cdr history-entry))))))
609 (energize-next-use-show-from from-mark)
610 (if (and (marker-position source-mark)
611 (marker-position source-start-mark))
612 (progn
613 (pop-to-buffer (marker-buffer source-mark))
614 (set-window-start
615 (selected-window) (marker-position source-start-mark) t)
616 (goto-char source-mark)
617 (if (and source-point-mark (marker-position source-point-mark))
618 (progn
619 (push-mark (point) t)
620 (goto-char source-point-mark)
621 (if zmacs-regions
622 (zmacs-activate-region)))
623 (energize-next-use-not-lexically-apparent))))))
624
625 (defun energize-next-use-go (label command)
626 (if (and energize-next-use-from-mark
627 (marker-position energize-next-use-from-mark))
628 (if (eq energize-next-use-history-pointer
629 energize-next-use-history)
630 ;; normal case
631 (energize-next-use-next)
632 ;; in the depths of history but going forward
633 (energize-next-use-from-history nil))
634 ;; beginning of time
635 (energize-next-use-init label command)))
636
637 (defun energize-next-use-previous ()
638 (if (cdr energize-next-use-history-pointer)
639 ;; going back in time
640 (energize-next-use-from-history t)
641 ;; trying to go beyond the pale
642 (error "no prior use")))
643
644 (defun energize-next-use-command (arg)
645 "Show the next place where the current language element is used.
646 The current language element is the one that point is on for source buffers
647 or the element displayed in a language element browser buffer.
648 Repeated calls to this functions visit all the callers in sequence.
649
650 With prefix arg = 1, back up to the last use.
651
652 With prefix arg > 1, start a visit from scratch on the current language
653 element.
654
655 If the point is on a particular user in the language element browser, the
656 search will be (re)started in that user.
657
658 The variable energize-next-use-show-le-browser controls if this command should
659 display both the language element browser buffer and the next user or just the
660 next user of the current language element.
661
662 The variable energize-next-use-search-by-file controls whether all uses within
663 a given file should be shown in sequence. If the value is nil, the uses
664 are shown in the order in which they appear in the LE Browser. If the
665 value is non-nil, the all uses in a given file are shown before proceeding to
666 the next use in another file."
667 (interactive "P")
668 (if (eq arg 1)
669 (energize-next-use-previous)
670 (if arg
671 (energize-next-use-terminate))
672 (energize-next-use-go "source" "Used By:")))
673
674 (define-key global-map '[(control x) \\] 'energize-next-use-command)
675
676 (defun energize-next-use-start ()
677 "Start visiting the uses of a language element.
678 If executed in a LE Browser buffer visit the uses of the language element
679 in the buffer. In a source buffer visit the uses of the language element
680 at (point)"
681 (interactive)
682 (energize-next-use-command 4))