0
|
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))
|