Mercurial > hg > xemacs-beta
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)) |