Mercurial > emacs
annotate lisp/emacs-lisp/edebug.el @ 6404:639d046c8b28
(lisp): Include version.el, not version.elc.
author | Roland McGrath <roland@gnu.org> |
---|---|
date | Fri, 18 Mar 1994 06:42:03 +0000 |
parents | d90fbaccf96a |
children | c79a6bf75daa |
rev | line source |
---|---|
846
20674ae6bf52
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
1 ;;; edebug.el --- a source-level debugger for emacs lisp |
661 | 2 |
3 ;; Copyright (C) 1988, 1989, 1990, 1991 Free Software Foundation, Inc | |
4 | |
846
20674ae6bf52
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
5 ;; Author: Daniel LaLiberte <liberte@cs.uiuc.edu> |
2247
2c7997f249eb
Add or correct keywords
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
1821
diff
changeset
|
6 ;; Keywords: lisp, tools, maint |
846
20674ae6bf52
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
7 |
2307
10e417efb12a
Added or corrected Commentary sections
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2247
diff
changeset
|
8 ;; This is Dan's 2.5 version with some header comments rearranged to separate |
10e417efb12a
Added or corrected Commentary sections
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2247
diff
changeset
|
9 ;; the Change Log from the Commentary (so the package-finder code can browse |
10e417efb12a
Added or corrected Commentary sections
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2247
diff
changeset
|
10 ;; the Commentary). |
10e417efb12a
Added or corrected Commentary sections
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2247
diff
changeset
|
11 |
661 | 12 ;; This file is part of GNU Emacs. |
13 | |
14 ;; GNU Emacs is distributed in the hope that it will be useful, | |
15 ;; but WITHOUT ANY WARRANTY. No author or distributor | |
16 ;; accepts responsibility to anyone for the consequences of using it | |
17 ;; or for whether it serves any particular purpose or works at all, | |
18 ;; unless he says so in writing. Refer to the GNU Emacs General Public | |
19 ;; License for full details. | |
20 | |
21 ;; Everyone is granted permission to copy, modify and redistribute | |
22 ;; GNU Emacs, but only under the conditions described in the | |
23 ;; GNU Emacs General Public License. A copy of this license is | |
24 ;; supposed to have been given to you along with GNU Emacs so you | |
25 ;; can know your rights and responsibilities. It should be in a | |
26 ;; file named COPYING. Among other things, the copyright notice | |
27 ;; and this notice must be preserved on all copies. | |
28 | |
846
20674ae6bf52
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
29 ;;;; Commentary: |
20674ae6bf52
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
30 |
20674ae6bf52
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
31 ;;; This minor mode allows programmers to step through Emacs Lisp source |
661 | 32 ;;; code while executing, set breakpoints, etc. See the texinfo |
33 ;;; document (being constructed...) for more detailed instructions | |
34 ;;; than contained here. Send me your enhancement, ideas, bugs, or | |
35 ;;; fixes. | |
36 | |
37 ;;; Daniel LaLiberte 217-244-0785 | |
38 ;;; University of Illinois, Urbana-Champaign | |
39 ;;; Department of Computer Science | |
40 ;;; 1304 W Springfield | |
41 ;;; Urbana, IL 61801 | |
42 | |
43 ;;; uiucdcs!liberte | |
44 ;;; liberte@cs.uiuc.edu | |
45 | |
46 ;;; Contents: | |
47 ;;; ========= | |
2307
10e417efb12a
Added or corrected Commentary sections
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2247
diff
changeset
|
48 ;;; Installation |
661 | 49 ;;; Change list |
50 ;;; Utilities | |
51 ;;; Parser | |
52 ;;; Debugger | |
53 | |
54 | |
2307
10e417efb12a
Added or corrected Commentary sections
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2247
diff
changeset
|
55 ;;; Installation |
10e417efb12a
Added or corrected Commentary sections
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2247
diff
changeset
|
56 ;;; ------------ |
10e417efb12a
Added or corrected Commentary sections
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2247
diff
changeset
|
57 ;; Put edebug.el in some directory in your load-path and byte-compile it. |
10e417efb12a
Added or corrected Commentary sections
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2247
diff
changeset
|
58 |
10e417efb12a
Added or corrected Commentary sections
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2247
diff
changeset
|
59 ;; Put the following forms in your .emacs file. |
10e417efb12a
Added or corrected Commentary sections
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2247
diff
changeset
|
60 ;; (define-key emacs-lisp-mode-map "\^Xx" 'edebug-defun) |
10e417efb12a
Added or corrected Commentary sections
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2247
diff
changeset
|
61 ;; (autoload 'edebug-defun "edebug") |
10e417efb12a
Added or corrected Commentary sections
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2247
diff
changeset
|
62 ;; (autoload 'edebug-debug "edebug") |
10e417efb12a
Added or corrected Commentary sections
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2247
diff
changeset
|
63 ;; (setq debugger 'edebug-debug) |
10e417efb12a
Added or corrected Commentary sections
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2247
diff
changeset
|
64 ;; ... other options, described in the next section. |
10e417efb12a
Added or corrected Commentary sections
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2247
diff
changeset
|
65 |
10e417efb12a
Added or corrected Commentary sections
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2247
diff
changeset
|
66 ;; Evaluate a defun for edebug with edebug-defun. |
10e417efb12a
Added or corrected Commentary sections
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2247
diff
changeset
|
67 ;; Evaluate your function normally. |
10e417efb12a
Added or corrected Commentary sections
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2247
diff
changeset
|
68 ;; Use the "?" command in edebug to describe other commands. |
10e417efb12a
Added or corrected Commentary sections
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2247
diff
changeset
|
69 ;; See edebug.texinfo for more instructions. |
10e417efb12a
Added or corrected Commentary sections
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2247
diff
changeset
|
70 |
10e417efb12a
Added or corrected Commentary sections
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
2247
diff
changeset
|
71 ;;; Change Log: |
661 | 72 |
73 ;;; Revision 2.5 91/07/25 13:32:53 liberte | |
74 ;;; Doc string cleanup. | |
75 ;;; If edebug-form-hook is t, evaluate all arguments. | |
76 ;;; If edebug-form-hook is 0, evaluate no arguments. | |
77 ;;; If edebug-form-hook is nil, evaluate macro args according | |
78 ;;; to edebug-eval-macro-args. | |
79 ;;; Save the outside value of executing macro. | |
80 ;;; Save and restore the outside restriction. | |
81 ;;; Dont force update for go and Go-nonstop. | |
82 ;;; Save and restore last-command-char, last-command, | |
83 ;;; this-command, last-input-char. | |
84 ;;; For epoch, do epoch::dispatch-events before sit-for | |
85 ;;; and input-pending-p since X events could interfere. | |
86 ;;; Warn about unsetting non-existent breakpoint. | |
87 ;;; Fix edebug-forward-sexp with prefix arg. | |
88 ;;; Add edebug-step-out to exit from current sexp. | |
89 ;;; | |
90 ;;; Revision 2.4 91/03/18 12:35:44 liberte | |
91 ;;; Force update after go or Go-nonstop modes, so overlay arrow is correct. | |
92 ;;; Support debug-on-quit. Remove edebug-on-error. | |
93 ;;; Fix edebug-anonymous. Bug found by jackr@wpd.sgi.com (Jack Repenning). | |
94 ;;; Don't discard-input anymore. Easier to change modes this way. | |
95 ;;; Fix max-lisp-eval-depth and max-specpdl-size incrementing. | |
96 ;;; Save and restore points in all buffers, if | |
97 ;;; edebug-save-buffer-points is non-nil. Expensive! | |
98 ;;; Bug caught by wolfgang@wsrcc.com (Wolfgang S. Rupprecht) | |
99 ;;; Save standard-output and standard-input in edebug-recursive-edit | |
100 ;;; so that edebug-outside-excursion can restore them. | |
101 ;;; Call set-buffer in edebug-pop-to-buffer since | |
102 ;;; select-window does not do that. | |
103 ;;; Fix edebug's eval-defun to remember current buffer inside evaluations | |
104 ;;; and to evaluate top-level forms. Found by Jamie Zawinski. | |
105 ;;; Add edebug-interactive-entry to support interactive forms with | |
106 ;;; non-string arg. Bug found by Jack Repenning. | |
107 ;;; Simplify edebug-restore-match-data to just store-match-data. | |
108 ;;; Motivated by linus@lysator.liu.se. | |
109 ;;; Move the match-data call to before the outside | |
110 ;;; buffer is changed, since it assumes that. | |
111 ;;; | |
112 ;;; Revision 2.3 91/01/17 20:55:14 liberte | |
113 ;;; Fix bug found by hollen@megatek.uucp. | |
114 ;;; Current buffer was not being restored. | |
115 ;;; Call edebug with (edebug begin end 'exp) | |
116 ;;; and add additional wrapper around body of functions: | |
117 ;;; (edebug-enter function body). | |
118 ;;; Make &optional only apply to immediate next arg | |
119 ;;; in edebug-form-parser (was edebug-macro-parser). | |
120 ;;; Catch debug errors with edebug. Yeah! | |
121 ;;; Reset edebug-mode on first function entry. Yeah! | |
122 ;;; Motivated by Dion Hollenbeck. | |
123 ;;; Add the missing bindings to the global-edebug-map. | |
124 ;;; eval-current-buffer now uses eval-region. | |
125 ;;; eval-region now does not narrow region. | |
126 ;;; Narrowing was the cause of the window-start being set wrong. | |
127 ;;; Reset edebug-mode only on | |
128 ;;; first entry of any function at each recursive-edit level. | |
129 ;;; Add edebug-backtrace, to generate cleaned up | |
3591
507f64624555
Apply typo patches from Paul Eggert.
Jim Blandy <jimb@redhat.com>
parents:
3350
diff
changeset
|
130 ;;; backtrace. It doesn't "work" like the debug backtrace, however. |
661 | 131 ;;; Require reselecting outside window even if |
132 ;;; quit occurs, otherwise save-excursions may restore | |
133 ;;; buffer to the wrong window. | |
134 ;;; | |
135 ;;; Revision 2.2 90/11/26 21:14:22 liberte | |
136 ;;; Shadow eval-defun and eval-region. Toggle | |
137 ;;; edebugging with edebug-all-defuns. | |
138 ;;; Call edebug with (edebug 'function begin end 'exp) | |
139 ;;; Suggested by Jamie Zawinski <jwz@lucid.com>. | |
140 ;;; Add edebug-form-parser to process macro args. | |
141 ;;; Motivated by Darryl Okahata darrylo@hpnmxx.hp.com. | |
142 ;;; Fix by Roland McGrath <roland@ai.mit.edu> | |
143 ;;; to wrap body of edebug-save-restriction in progn. | |
144 ;;; Fix by Darryl Okahata <darrylo%hpnmd@hpcea.hp.com> | |
145 ;;; to add (set-window-hscroll (selected-window) 0) to | |
146 ;;; edebug-pop-to-buffer. | |
147 ;;; | |
148 ;;; Revision 2.1 90/11/16 21:55:35 liberte | |
149 ;;; Clean up. | |
150 ;;; Add edebug-form-hook to edebug macro calls. Thanks to Joe Wells. | |
151 ;;; edebug-forward-sexp uses step mode if no forward-sexp. | |
152 ;;; | |
153 ;;; Revision 2.0 90/11/14 22:30:54 liberte | |
154 ;;; Handle lambda forms, function, interactive evals, defmacro. | |
155 ;;; Clean up display for Epoch - save and restore screen configurations. | |
156 ;;; Note: epoch 3.2 broke set-window-configuration. | |
157 ;;; Also, sit-for pauses do not always work in epoch. | |
158 ;;; Display evaluations window. | |
159 ;;; Display result after expression evaluation. | |
160 ;;; Thanks to discussions with Shinichirou Sugou. | |
161 ;;; Conditional and temporary breakpoints. | |
162 ;;; Change "continue" to "go" mode and add different "continue" mode. | |
163 ;;; Option to stop before symbols. | |
164 ;;; | |
165 ;;; Fix by: Glen Ditchfield gjditchfield@violet.uwaterloo.ca | |
166 ;;; to handle ?# type chars. | |
167 ;;; | |
168 ;;; Revision 1.5 89/05/10 02:39:27 liberte | |
169 ;;; Fix condition-case expression lists. | |
170 ;;; Reorganize edebug. | |
171 ;;; | |
172 ;;; Revision 1.4 89/02/14 22:58:34 liberte | |
173 ;;; Fix broken breakpointing. | |
846
20674ae6bf52
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
174 ;;; Temporarily widen Emacs Lisp buffer during edebug. |
661 | 175 ;;; |
176 ;;; Revision 1.3 89/01/30 00:26:09 liberte | |
177 ;;; More bug fixes for cond and let. | |
178 ;;; Another parsing fix backquote. | |
179 ;;; Fix for lambda forms inside defuns. | |
180 ;;; Leave point at syntax error, mark at starting position. | |
181 ;;; | |
182 ;;; Revision 1.2 88/11/28 12:14:15 liberte | |
3591
507f64624555
Apply typo patches from Paul Eggert.
Jim Blandy <jimb@redhat.com>
parents:
3350
diff
changeset
|
183 ;;; Bug fixes: cond construct didn't execute. |
507f64624555
Apply typo patches from Paul Eggert.
Jim Blandy <jimb@redhat.com>
parents:
3350
diff
changeset
|
184 ;;; () in sexp list didn't parse |
507f64624555
Apply typo patches from Paul Eggert.
Jim Blandy <jimb@redhat.com>
parents:
3350
diff
changeset
|
185 ;;; () as variable in condition-case didn't parse. |
661 | 186 ;;; |
187 ;;; Revision 1.1 88/11/28 12:11:27 liberte | |
188 ;;; Initial revision | |
189 ;;; | |
190 | |
846
20674ae6bf52
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
191 ;;; Code: |
20674ae6bf52
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
192 |
661 | 193 |
194 ;;; Options | |
195 ;;; ------- | |
196 | |
197 (defvar edebug-all-defuns nil | |
198 "*If non-nil, all defuns and defmacros evaluated will use edebug. | |
199 eval-defun without prefix arg and eval-region will use edebug-defun. | |
200 | |
201 If nil, eval-region evaluates normally, but eval-defun with prefix arg | |
202 uses edebug-defun. eval-region is called by eval-defun, eval-last-sexp, | |
203 and eval-print-last-sexp. | |
204 | |
846
20674ae6bf52
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
205 You may wish to make this variable local to each Emacs Lisp buffer by calling |
661 | 206 (make-local-variable 'edebug-all-defuns) in your emacs-lisp-mode-hook. |
207 You can use the function edebug-all-defuns to toggle its value.") | |
208 | |
209 | |
210 (defvar edebug-eval-macro-args nil | |
211 "*If non-nil, edebug will assume that all macro call arguments for | |
212 macros that have no edebug-form-hook may be evaluated, otherwise it | |
213 will not. To specify exceptions for macros that have some arguments | |
214 evaluated and some not, you should specify an edebug-form-hook") | |
215 | |
216 (defvar edebug-stop-before-symbols nil | |
217 "*Non-nil causes edebug to stop before symbols as well as after. | |
218 In any case, it is possible to stop before a symbol with a breakpoint or | |
219 interrupt.") | |
220 | |
221 (defvar edebug-save-windows t | |
222 "*If non-nil, save and restore window configuration on edebug calls. | |
223 It takes some time to save and restore, so if your program does not care | |
224 what happens to the window configurations, it is better to set this | |
225 variable to nil.") | |
226 | |
227 (defvar edebug-save-point t | |
228 "*If non-nil, save and restore the point and mark in source code buffers.") | |
229 | |
230 (defvar edebug-save-buffer-points nil | |
231 "*If non-nil, save and restore the points of all buffers, displayed or not. | |
232 | |
233 Saving and restoring buffer points is necessary if you are debugging | |
234 code that changes the point of a buffer which is displayed in a | |
235 non-selected window. If edebug or the user then selects the | |
236 window, the buffer's point will be changed to the window's point. | |
237 | |
238 Saving and restoring all the points is an expensive operation since it | |
239 visits each buffer twice for each edebug call, so it is best to avoid | |
240 it if you can.") | |
241 | |
242 (defvar edebug-initial-mode 'step | |
243 "*Global initial mode for edebug, if non-nil. | |
244 This is used when edebug is first entered for each recursive-edit level. | |
245 Possible values are nil (meaning keep using edebug-mode), step, go, | |
246 Go-nonstop, trace, Trace-fast, continue, and Continue-fast.") | |
247 | |
248 (defvar edebug-trace nil | |
249 "*Non-nil if edebug should show a trace of function entry and exit. | |
250 Tracing output is displayed in a buffer named *edebug-trace*, one | |
251 function entry or exit per line, indented by the recursion level. You | |
252 can customize by replacing functions edebug-print-trace-entry and | |
253 edebug-print-trace-exit.") | |
254 | |
255 | |
256 | |
257 ;;;======================================================================== | |
258 ;;; Utilities | |
259 ;;; --------- | |
260 | |
261 (defun edebug-which-function () | |
262 "Return the symbol of the function we are in" | |
263 (save-excursion | |
264 (end-of-defun) | |
265 (beginning-of-defun) | |
266 (down-list 1) | |
267 (if (not (memq (read (current-buffer)) '(defun defmacro))) | |
5126
30682388c4cf
Delete periods from error messages.
Richard M. Stallman <rms@gnu.org>
parents:
5125
diff
changeset
|
268 (error "Not in defun or defmacro")) |
661 | 269 (read (current-buffer)))) |
270 | |
271 (defun edebug-last-sexp () | |
272 "Return the last sexp before point in current buffer. | |
846
20674ae6bf52
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
273 Assumes Emacs Lisp syntax is active." |
661 | 274 (car |
275 (read-from-string | |
276 (buffer-substring | |
277 (save-excursion | |
278 (forward-sexp -1) | |
279 (point)) | |
280 (point))))) | |
281 | |
282 (defun edebug-window-list () | |
283 "Return a list of windows, in order of next-window." | |
3591
507f64624555
Apply typo patches from Paul Eggert.
Jim Blandy <jimb@redhat.com>
parents:
3350
diff
changeset
|
284 ;; This doesn't work for epoch. |
661 | 285 (let* ((first-window (selected-window)) |
286 (window-list (list first-window)) | |
287 (next (next-window first-window))) | |
288 (while (not (eq next first-window)) | |
289 (setq window-list (cons next window-list)) | |
290 (setq next (next-window next))) | |
291 (nreverse window-list))) | |
292 | |
293 (defun edebug-get-buffer-points () | |
294 "Return a list of buffer point pairs, for all buffers." | |
295 (save-excursion | |
296 (mapcar (function (lambda (buf) | |
297 (set-buffer buf) | |
298 (cons buf (point)))) | |
299 (buffer-list)))) | |
300 | |
301 (defun edebug-set-buffer-points () | |
302 "Restore the buffer-points given by edebug-get-buffer-points." | |
303 (mapcar (function (lambda (buf-point) | |
304 (if (buffer-name (car buf-point)) ; still exists | |
305 (progn | |
306 (set-buffer (car buf-point)) | |
307 (goto-char (cdr buf-point)))))) | |
308 edebug-buffer-points)) | |
309 | |
310 (defun edebug-two-window-p () | |
311 "Return t if there are two windows." | |
312 (and (not (one-window-p)) | |
313 (eq (selected-window) | |
314 (next-window (next-window (selected-window)))))) | |
315 | |
316 (defun edebug-macrop (object) | |
317 "Return the macro named by OBJECT, or nil if it is not a macro." | |
318 (while (and (symbolp object) (fboundp object)) | |
319 (setq object (symbol-function object))) | |
320 (if (and (listp object) | |
321 (eq 'macro (car object)) | |
322 (edebug-functionp (cdr object))) | |
323 object)) | |
324 | |
325 (defun edebug-functionp (object) | |
326 "Returns the function named by OBJECT, or nil if it is not a function." | |
327 (while (and (symbolp object) (fboundp object)) | |
328 (setq object (symbol-function object))) | |
329 (if (or (subrp object) | |
5125
127a513c13b2
(edebug-functionp): Recognize compiled functions.
Richard M. Stallman <rms@gnu.org>
parents:
4761
diff
changeset
|
330 (byte-code-function-p object) |
661 | 331 (and (listp object) |
332 (eq (car object) 'lambda) | |
333 (listp (car (cdr object))))) | |
334 object)) | |
335 | |
336 (defun edebug-sort-alist (alist function) | |
337 "Return the ALIST sorted with comparison function FUNCTION. | |
338 This uses 'sort so the sorting is destructive." | |
339 (sort alist (function | |
340 (lambda (e1 e2) | |
341 (funcall function (car e1) (car e2)))))) | |
342 | |
343 (put 'edebug-save-restriction 'edebug-form-hook | |
344 '(&rest form)) | |
345 | |
346 (defmacro edebug-save-restriction (&rest body) | |
347 "Evaluate BODY while saving the current buffers restriction. | |
348 BODY may change buffer outside of current restriction, unlike | |
349 save-restriction. BODY may change the current buffer, | |
350 and the restriction will be restored to the original buffer, | |
351 and the current buffer remains current. | |
352 Return the result of the last expression in BODY." | |
353 (` (let ((edebug:s-r-beg (point-min-marker)) | |
354 (edebug:s-r-end (point-max-marker))) | |
355 (unwind-protect | |
356 (progn (,@ body)) | |
357 (save-excursion | |
358 (set-buffer (marker-buffer edebug:s-r-beg)) | |
359 (narrow-to-region edebug:s-r-beg edebug:s-r-end)))))) | |
360 | |
361 | |
362 ;;;============================================================= | |
363 ;;; Redefine eval-defun, eval-region, and eval-current-buffer. | |
364 ;;; ----------------------------------------------------------- | |
365 | |
366 (defun edebug-all-defuns () | |
367 "Toggle edebugging of all defuns and defmacros, | |
368 not including those evaluated in the minibuffer, or during load." | |
369 (interactive) | |
370 (setq edebug-all-defuns (not edebug-all-defuns)) | |
371 (message "Edebugging is %s." (if edebug-all-defuns "on" "off"))) | |
372 | |
373 | |
374 (if (not (fboundp 'edebug-emacs-eval-defun)) | |
375 (fset 'edebug-emacs-eval-defun (symbol-function 'eval-defun))) | |
376 ;;(fset 'eval-defun (symbol-function 'edebug-emacs-eval-defun)) | |
377 | |
378 (defun eval-defun (edebug-debug) | |
379 "Edebug replacement for eval-defun. Print value in the minibuffer. | |
380 Evaluate the top-level form that point is in or before. Note: | |
381 eval-defun normally evaluates any top-level form, not just defuns. | |
382 | |
383 Here are the differences from the standard eval-defun. If the prefix | |
384 argument is the same as edebug-all-defuns (nil or non-nil), evaluate | |
385 normally; otherwise edebug-defun is called to wrap edebug calls around | |
386 evaluatable expressions in the defun or defmacro body. Also, the | |
387 value printed by edebug-defun is not just the function name." | |
388 (interactive "P") | |
389 (let ((edebug-all-defuns | |
390 (not (eq (not edebug-debug) (not edebug-all-defuns))))) | |
391 (edebug-emacs-eval-defun nil) | |
392 )) | |
393 | |
394 | |
395 (if (not (fboundp 'edebug-emacs-eval-region)) | |
396 (fset 'edebug-emacs-eval-region (symbol-function 'eval-region))) | |
397 ;; (fset 'eval-region (symbol-function 'edebug-emacs-eval-region)) | |
398 | |
399 (defun eval-region (edebug-e-r-start edebug-e-r-end | |
400 &optional edebug-e-r-output) | |
5388
95ef89411635
(eval-current-buffer): Old definition deleted.
Richard M. Stallman <rms@gnu.org>
parents:
5126
diff
changeset
|
401 "Edebug replacement for eval-region. |
661 | 402 Like eval-region, but call edebug-defun for defuns or defmacros. |
403 Also, this eval-region does not narrow to the region and | |
404 if an error occurs, point is left at the error." | |
405 ;; One other piddling difference concerns whitespace after the expression. | |
406 (interactive "r") | |
407 (let ((standard-output (or edebug-e-r-output 'symbolp)) | |
408 (edebug-e-r-pnt (point)) | |
409 (edebug-e-r-buf (current-buffer)) | |
410 (edebug-e-r-inside-buf (current-buffer)) | |
411 ;; Mark the end because it may move. | |
412 (edebug-e-r-end-marker (set-marker (make-marker) edebug-e-r-end)) | |
413 edebug-e-r-val | |
414 ) | |
415 (goto-char edebug-e-r-start) | |
416 (edebug-skip-whitespace) | |
417 (while (< (point) edebug-e-r-end-marker) | |
418 (if (and edebug-all-defuns | |
419 (eq 'lparen (edebug-next-token-class)) | |
420 (save-excursion | |
421 (forward-char 1) ; skip \( | |
422 (memq (edebug-read-sexp) '(defun defmacro)))) | |
423 (progn | |
424 (edebug-defun) | |
425 ;; Potential problem: edebug-defun always prints name. | |
426 (forward-sexp 1) ; skip the defun | |
427 ) | |
428 (if (and (eq 'lparen (edebug-next-token-class)) | |
429 (save-excursion | |
430 (forward-char 1) ; skip \( | |
431 (memq (edebug-read-sexp) '(defun defmacro)))) | |
432 ;; If it's a defun or defmacro, but not edebug-all-defuns | |
433 ;; reset the symbols edebug property to be just a marker at | |
434 ;; the definitions source code. | |
435 (put (edebug-which-function) 'edebug (point-marker))) | |
436 | |
437 ;; Evaluate normally - after restoring the current-buffer. | |
438 (setq edebug-e-r-val (edebug-read-sexp)) | |
439 (save-excursion | |
440 (set-buffer edebug-e-r-inside-buf) | |
441 (setq edebug-e-r-val (eval edebug-e-r-val)) | |
442 ;; Remember current buffer for next time. | |
443 (setq edebug-e-r-inside-buf (current-buffer))) | |
444 | |
445 (if edebug-e-r-output | |
446 (progn | |
447 (setq values (cons edebug-e-r-val values)) | |
448 (if (eq standard-output t) | |
449 (prin1 edebug-e-r-val) | |
450 (print edebug-e-r-val)))) | |
451 ) | |
452 (goto-char | |
453 (min (max edebug-e-r-end-marker (point)) | |
454 (progn (edebug-skip-whitespace) (point)))) | |
455 ) ; while | |
456 (if (null edebug-e-r-output) | |
457 ;; do the save-excursion recovery | |
458 (progn | |
459 ;; but mark is not restored | |
460 (set-buffer edebug-e-r-buf) | |
461 (goto-char edebug-e-r-pnt))) | |
462 nil | |
463 )) | |
464 | |
465 | |
5388
95ef89411635
(eval-current-buffer): Old definition deleted.
Richard M. Stallman <rms@gnu.org>
parents:
5126
diff
changeset
|
466 (defun edebug-eval-buffer (&optional buffer edebug-e-c-b-output) |
95ef89411635
(eval-current-buffer): Old definition deleted.
Richard M. Stallman <rms@gnu.org>
parents:
5126
diff
changeset
|
467 "Edebug replacement for eval-buffer. |
95ef89411635
(eval-current-buffer): Old definition deleted.
Richard M. Stallman <rms@gnu.org>
parents:
5126
diff
changeset
|
468 Execute the current buffer as Lisp code using eval-region. See |
95ef89411635
(eval-current-buffer): Old definition deleted.
Richard M. Stallman <rms@gnu.org>
parents:
5126
diff
changeset
|
469 eval-region for reasons why this function is redefined by edebug." |
661 | 470 (interactive) |
5388
95ef89411635
(eval-current-buffer): Old definition deleted.
Richard M. Stallman <rms@gnu.org>
parents:
5126
diff
changeset
|
471 (or buffer |
95ef89411635
(eval-current-buffer): Old definition deleted.
Richard M. Stallman <rms@gnu.org>
parents:
5126
diff
changeset
|
472 (setq buffer (current-buffer))) |
727 | 473 (save-excursion |
474 (set-buffer buffer) | |
475 (eval-region (point-min) (point-max) edebug-e-c-b-output))) | |
476 | |
5388
95ef89411635
(eval-current-buffer): Old definition deleted.
Richard M. Stallman <rms@gnu.org>
parents:
5126
diff
changeset
|
477 ;; The standard eval-buffer doesn't use eval-region. |
727 | 478 (if (and (fboundp 'eval-buffer) |
479 (not (fboundp 'edebug-emacs-eval-buffer))) | |
480 (progn | |
481 (fset 'edebug-emacs-eval-buffer | |
482 (symbol-function 'eval-buffer)) | |
483 (fset 'eval-buffer 'edebug-eval-buffer))) | |
484 | |
661 | 485 |
486 | |
487 ;;;====================================================================== | |
488 ;;; The Parser | |
489 ;;; ---------- | |
490 | |
491 ;;; The top level function for parsing defuns is edebug-defun; it | |
492 ;;; calls all the rest. It checks the syntax a bit and leaves point | |
493 ;;; at any error it finds, but otherwise should appear to work like | |
494 ;;; eval-defun. | |
495 | |
496 ;;; The basic plan is to surround each expression with a call to the | |
497 ;;; function edebug together with indexes into a table of positions of | |
498 ;;; all expressions. Thus an expression "exp" in function foo | |
499 ;;; becomes: | |
500 | |
501 ;;; (edebug 1 2 'exp) | |
502 | |
503 ;;; First point moved to to the beginning of exp (offset 1 of the | |
504 ;;; current function). Then the expression is evaluated and point is | |
505 ;;; moved to offset 2, at the end of exp. | |
506 | |
507 ;;; The top level expressions of the function are wrapped in a call to | |
508 ;;; edebug-enter, which supplies the function name and the actual | |
509 ;;; arguments to the function. See functions edebug and edebug-enter | |
510 ;;; for more details. | |
511 | |
512 | |
727 | 513 ;;;###autoload |
661 | 514 (defun edebug-defun () |
515 "Evaluate defun or defmacro, like eval-defun, but with edebug calls. | |
516 Print its name in the minibuffer and leave point after any error it finds, | |
517 with mark at the original point." | |
518 (interactive) | |
519 (let (def-kind ; whether defmacro or defun | |
520 def-name | |
521 def-args | |
522 def-docstring | |
523 defun-interactive | |
524 (edebug-offset-index 0) | |
525 edebug-offset-list | |
526 edebug-func-mark | |
527 (starting-point (point)) | |
528 tmp-point | |
529 (parse-sexp-ignore-comments t)) | |
530 | |
531 (condition-case err | |
532 (progn | |
533 (end-of-defun) | |
534 (beginning-of-defun) | |
535 (down-list 1) | |
536 | |
537 (setq edebug-func-mark (point-marker)) | |
538 (if (not (eq 'defun (setq def-kind (edebug-read-sexp)))) | |
539 (if (not (eq 'defmacro def-kind)) | |
540 (edebug-syntax-error "%s is not a defun or defmacro." | |
541 def-kind))) | |
542 (setq def-name (edebug-read-sexp)) | |
543 (if (not (symbolp def-name)) | |
544 (edebug-syntax-error "Bad defun name: %s" def-name)) | |
545 (setq def-args (edebug-read-sexp)) | |
546 (if (not (listp def-args)) | |
547 (edebug-syntax-error "Bad defun arg list: %s" def-args)) | |
548 | |
549 ;; look for doc string | |
550 (setq tmp-point (point)) | |
551 (if (eq 'string (edebug-next-token-class)) | |
552 (progn | |
553 (setq def-docstring (edebug-read-sexp)) | |
554 (setq tmp-point (point)))) | |
555 | |
556 ;; look for interactive form | |
557 (if (eq 'lparen (edebug-next-token-class)) | |
558 (progn | |
559 (forward-char 1) ; skip \( | |
560 (if (eq 'interactive (edebug-read-sexp)) | |
561 (progn | |
562 (setq defun-interactive | |
563 (cons 'interactive (edebug-interactive))) | |
564 (forward-char 1) ; skip \) | |
565 (setq tmp-point (point)) | |
566 )))) | |
567 | |
568 (goto-char tmp-point) | |
569 | |
570 ;; build the new definition | |
571 (fset def-name (` (lambda | |
572 (, def-args) | |
573 (, def-docstring) | |
574 (, defun-interactive) | |
575 ;; the remainder is a list of sexps | |
576 (edebug-enter | |
577 (quote (, def-name)) | |
578 (quote (, def-args)) | |
579 (quote (progn | |
580 (,@ (edebug-sexp-list t))))) | |
581 ))) | |
582 ;; if it is a defmacro, prepend 'macro | |
583 (if (eq 'defmacro def-kind) | |
584 (fset def-name (cons 'macro (symbol-function def-name)))) | |
585 | |
586 ;; recover point, like save-excursion but only if no error occurs | |
587 (goto-char starting-point) | |
588 | |
589 ;; store the offset list in functions property list | |
590 (put def-name 'edebug | |
591 (list edebug-func-mark | |
592 nil ; clear breakpoints | |
593 (vconcat (nreverse edebug-offset-list)))) | |
594 (message "edebug: %s" def-name) | |
595 ) ; progn | |
596 | |
597 (invalid-read-syntax | |
598 ;; Set mark at starting-point so user can return. | |
599 ;; Leave point at error. | |
600 (save-excursion | |
601 (goto-char starting-point) | |
602 (set-mark-command nil)) | |
603 (message "Syntax error: %s" (cdr err)) | |
604 ;; (signal 'invalid-read-syntax (cdr err)) ; pass it on, to who? | |
605 ) | |
606 ) ; condition-case | |
607 def-name | |
608 )) | |
609 | |
610 | |
611 (defun edebug-sexp-list (debuggable) | |
612 "Return an edebug form built from the sexp list following point in the | |
613 current buffer. If DEBUGGABLE then wrap edebug calls around each sexp. | |
614 The sexp list does not start with a left paren; we are already in the list. | |
615 Leave point at (before) the trailing right paren." | |
616 (let (sexp-list) | |
617 (while (not (eq 'rparen (edebug-next-token-class))) | |
618 (setq sexp-list (cons (if debuggable | |
619 (edebug-form) | |
620 (edebug-read-sexp)) | |
621 sexp-list))) | |
622 (nreverse sexp-list))) | |
623 | |
624 | |
625 (defun edebug-increment-offset () | |
626 ;; accesses edebug-offset-index and edebug-offset-list | |
627 (setq edebug-offset-index (1+ edebug-offset-index)) | |
628 (setq edebug-offset-list (cons (- (point) edebug-func-mark) | |
629 edebug-offset-list))) | |
630 | |
631 | |
632 (defun edebug-make-edebug-form (index form) | |
633 "Return the edebug form for the current function at offset INDEX given FORM. | |
634 Looks like: (edebug def-name INDEX edebug-offset-index 'FORM). | |
635 Also increment the offset index." | |
636 (prog1 | |
637 (list 'edebug | |
638 index | |
639 edebug-offset-index | |
640 (list 'quote form)) | |
641 (edebug-increment-offset) | |
642 )) | |
643 | |
644 | |
645 (defun edebug-form () | |
646 "Return the debug form for the following form. Add the point offset | |
647 to the edebug-offset-list for the function and move point to | |
648 immediately after the form." | |
649 (let* ((index edebug-offset-index) | |
650 form class) | |
651 ;; The point must be added to the offset list now | |
652 ;; because edebug-list will add more offsets indirectly. | |
653 (edebug-skip-whitespace) | |
654 (edebug-increment-offset) | |
655 (setq class (edebug-next-token-class)) | |
656 (cond | |
657 ((eq 'lparen class) | |
658 (edebug-make-edebug-form index (edebug-list))) | |
659 | |
660 ((eq 'symbol class) | |
661 (if (and (not (memq (setq form (edebug-read-sexp)) '(nil t))) | |
662 ;; note: symbol includes numbers, see parsing utilities | |
663 (not (numberp form))) | |
664 (edebug-make-edebug-form index form) | |
665 form)) | |
666 (t (edebug-read-sexp))))) | |
667 | |
668 | |
669 (defun edebug-list () | |
670 "Return an edebug form built from the list form that follows point. | |
671 Insert debug calls as appropriate to the form. Start with point at | |
672 the left paren. Leave point after the right paren." | |
673 (let ((beginning (point)) | |
674 class | |
675 head) | |
676 | |
677 (forward-char 1) ; skip \( | |
678 (setq class (edebug-next-token-class)) | |
679 (cond | |
680 ((eq 'symbol class) | |
681 (setq head (edebug-read-sexp))) | |
682 ((eq 'lparen class) | |
683 (setq head (edebug-anonymous))) | |
684 ((eq 'rparen class) | |
685 (setq head nil)) | |
686 (t (edebug-syntax-error | |
687 "Head of list must be a symbol or lambda expression."))) | |
688 | |
689 (prog1 | |
690 (if head | |
691 (cons head | |
692 (cond | |
693 | |
694 ;; None of the edebug-form-hooks defined below are used, for speed. | |
695 ;; They are included for documentation, though the hook would not | |
696 ;; necessarily behave the same as the function it is replacing. | |
697 | |
698 ;;; Using the edebug-form-hooks should work, but would take more time. | |
699 ;;; ((symbolp head) | |
700 ;;; (let ((form (get head 'edebug-form-hook))) | |
701 ;;; (if form | |
702 ;;; (edebug-form-parser form) | |
703 ;;; (if (edebug-macrop head) | |
704 ;;; (if edebug-eval-macro-args | |
705 ;;; (edebug-sexp-list t) | |
706 ;;; (edebug-sexp-list nil)) | |
707 ;;; ;; assume it is a function | |
708 ;;; (edebug-sexp-list t))))) | |
709 | |
710 ;; handle all special-forms with unevaluated arguments | |
711 ((memq head '(let let*)) (edebug-let)) | |
712 ((memq head '(setq setq-default)) (edebug-setq)) | |
713 ((eq head 'cond) (edebug-cond)) | |
714 ((eq head 'condition-case) (edebug-condition-case)) | |
715 | |
716 ((memq head '(quote ; permits more than one arg | |
717 defun defvar defconst defmacro)) | |
718 (edebug-sexp-list nil)) | |
719 ((eq head 'function) | |
720 (list | |
721 (if (eq 'lparen (edebug-next-token-class)) | |
722 (edebug-anonymous) | |
723 (edebug-read-sexp) ; should be just a symbol | |
724 ))) | |
725 | |
726 ;; is it a lisp macro? | |
727 ((edebug-macrop head) | |
728 (or (and (symbolp head) | |
729 (let ((form (get head 'edebug-form-hook))) | |
730 (if form | |
731 (if (eq form t) | |
732 (edebug-sexp-list t) | |
733 (if (eq form 0) | |
734 (edebug-sexp-list nil) | |
735 (edebug-form-parser form)))))) | |
736 (edebug-sexp-list edebug-eval-macro-args))) | |
737 | |
738 ((eq head 'interactive) | |
739 (edebug-syntax-error "interactive not expected here.")) | |
740 | |
741 ;; otherwise it is a function call | |
742 (t (edebug-sexp-list t)) | |
743 ))) | |
744 | |
745 (if (eq 'rparen (edebug-next-token-class)) | |
746 (forward-char 1) ; skip \) | |
747 (edebug-syntax-error "Too many arguments.")) | |
748 ))) | |
749 | |
750 | |
751 (defun edebug-form-parser (args) | |
752 "Parse the macro arguments that follow based on ARGS. | |
753 ARGS describes the types of the arguments of a list form. Each of the ARGS | |
754 is processed left to right, in the same order as the arguments of the | |
755 list form. See the edebug documentation for more details. The ARGS | |
756 may be one of the following: | |
757 | |
758 symbolp - an unevaluated symbol | |
759 integerp - an unevaluated number | |
760 stringp - an unevaluated string | |
761 vectorp - an unevaluated vector | |
762 atom - an unevaluated number, string, symbol, or vector | |
763 | |
764 sexp - an unevaluated sexp (atom or list); may not be empty | |
765 form - an evaluated sexp; may not be empty | |
766 | |
767 foo - any other symbol should be the name of a function; this | |
768 function is called on the argument as a predicate and an error | |
769 is signaled if the predicate fails. | |
770 | |
771 &optional - one following arg in the list may or may not appear. | |
772 &rest - all following args are repeated zero or more times as a group. | |
773 This is an extension of the normal meaning of &rest. | |
774 &or - each of the following args are alternatives, processed left to | |
775 right until one succeeds. There is no way to group | |
776 more than one list element as one alternative. | |
777 | |
778 (...) - a sublist, of the same format as the top level, processed recursively. | |
779 Special case: if the car of the list is quote, the argument must match | |
780 the quoted sexp (see example below of 'for macro). | |
781 " | |
782 | |
783 (let ((arglist args) | |
784 arg form form-list class | |
785 &optional &rest &or) | |
786 (while (and arglist | |
787 (not (eq 'rparen (setq class (edebug-next-token-class))))) | |
788 (catch 'no-match | |
789 (setq arg (car arglist)) | |
790 (setq arglist (cdr arglist)) | |
791 (if (and &rest (null arglist)) | |
792 (setq arglist &rest)) | |
793 | |
794 (cond | |
795 ((memq arg '(&optional &rest &or)) | |
796 ;; remember arglist at this point | |
797 (set arg arglist) | |
798 (throw 'no-match nil)) | |
799 | |
800 ((eq arg 'form) | |
801 (setq form (edebug-form))) | |
802 | |
803 ((eq arg 'sexp) | |
804 (setq form (edebug-read-sexp))) | |
805 | |
806 ((listp arg) | |
807 (if (eq 'quote (car arg)) | |
808 ;; special case, match the quoted symbol | |
809 (let ((pnt (point))) | |
810 (setq arg (car (cdr arg))) | |
811 (if (not (eq arg (setq form (edebug-read-sexp)))) | |
812 (edebug-form-parser-error) | |
813 )) | |
814 (if (eq class 'lparen) | |
815 (progn | |
816 (forward-char 1) ; skip \( | |
817 (setq form (edebug-form-parser arg)) | |
818 (forward-char 1) ; skip \) | |
819 )))) | |
820 ((symbolp arg) | |
821 (let ((pnt (point)) | |
822 (pred (if (fboundp arg) (symbol-function arg)))) | |
823 (and pred | |
824 (not (funcall pred (setq form (edebug-read-sexp)))) | |
825 (edebug-form-parser-error) | |
826 ))) | |
827 (t (throw 'no-match nil)) | |
828 ) ; cond | |
829 (setq &optional nil) ; only lasts for one match | |
830 (setq form-list (cons form form-list)) ; skipped by no-match throw | |
831 )) ; while | |
832 | |
833 (if (and arglist (not (or &optional &rest | |
834 (memq (car arglist) '(&optional &rest))))) | |
835 (edebug-syntax-error "Not enough arguments.")) | |
836 (if (not (eq 'rparen (edebug-next-token-class))) | |
837 (if &or | |
838 (edebug-syntax-error "Unrecognized argument.") | |
839 (edebug-syntax-error "Too many arguments."))) | |
840 (nreverse form-list))) | |
841 | |
842 | |
843 (defun edebug-form-parser-error () | |
844 (goto-char pnt) | |
845 (if &or | |
846 (throw 'no-match nil) | |
847 (if &optional | |
848 (progn | |
849 (setq &optional nil) ; only lasts for one failed match not in &or | |
850 (throw 'no-match nil)) | |
851 (edebug-syntax-error "%s is not %s" form arg)))) | |
852 | |
846
20674ae6bf52
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
853 ;; for loop defined in Emacs Lisp manual |
661 | 854 (put 'for 'edebug-form-hook |
855 '(symbolp 'from form 'to form 'do &rest form)) | |
856 | |
857 ;; case and do defined in cl.el | |
858 (put 'case 'edebug-form-hook | |
859 '(form &rest (sexp form))) | |
860 | |
861 (put 'do 'edebug-form-hook | |
862 '((&rest | |
863 &or symbolp | |
864 (symbolp &optional form | |
865 &optional form)) | |
866 (form &rest form) | |
867 &rest body)) | |
868 | |
869 (put 'defvar 'edebug-form-hook | |
870 (put 'defconst 'edebug-form-hook | |
871 '(symbolp &optional form &optional stringp))) | |
872 | |
873 (put 'defun 'edebug-form-hook | |
874 (put 'defmacro 'edebug-form-hook | |
875 '(symbolp (&rest symbolp) | |
876 &optional stringp | |
877 &optional ('interactive &or stringp form) | |
878 &rest form))) | |
879 | |
880 (put 'anonymous 'edebug-form-hook | |
881 '(&optional 'macro 'lambda (&rest symbolp) &rest form)) | |
882 | |
883 (defun edebug-anonymous () | |
884 "Return the edebug form for an anonymous lambda or macro. | |
885 Point starts before the left paren and ends after it." | |
886 (forward-char 1) ; skip \( | |
887 (prog1 | |
888 (let ((head (edebug-read-sexp))) | |
889 (cond | |
890 ((eq head 'lambda) | |
891 (edebug-lambda)) | |
892 ((eq head 'macro) | |
893 (if (not (eq 'lambda (edebug-read-sexp))) | |
894 (edebug-syntax-error "lambda expected.")) | |
895 (cons 'macro (edebug-lambda))) | |
896 (t (edebug-syntax-error "Anonymous lambda or macro expected.")))) | |
897 (forward-char 1) ; skip \) | |
898 )) | |
899 | |
900 | |
901 (defun edebug-lambda () | |
902 "Return the edebug form for the lambda form that follows. | |
903 Point starts after the lambda symbol and is moved to before the right paren." | |
904 (append | |
905 (list 'lambda (edebug-read-sexp)) ; the args | |
906 (edebug-sexp-list t))) ; the body | |
907 | |
908 | |
909 | |
910 (put 'let 'edebug-form-hook | |
911 (put 'let* 'edebug-form-hook | |
912 '((&rest | |
913 &or (symbolp &optional form) | |
914 symbolp) | |
915 &rest form))) | |
916 | |
917 (defun edebug-let () | |
918 "Return the edebug form of the let or let* form. | |
919 Leave point before the right paren." | |
920 (let (var-value-list | |
921 token | |
922 class) | |
923 (cons | |
924 ;; first process the var/value list | |
925 (if (not (eq 'lparen (edebug-next-token-class))) | |
926 (if (setq token (edebug-read-sexp)) | |
927 (edebug-syntax-error "Bad var list in let.") ; should be nil | |
928 token ; == nil | |
929 ) | |
930 | |
931 (forward-char 1) ; lparen | |
932 (while (not (eq 'rparen (setq class (edebug-next-token-class)))) | |
933 (setq var-value-list | |
934 (cons | |
935 (if (not (eq 'lparen class)) | |
936 (edebug-read-sexp) | |
937 (forward-char 1) ; lparen | |
938 (prog1 | |
939 (edebug-var-value) | |
940 (if (not (eq 'rparen (edebug-next-token-class))) | |
941 (edebug-syntax-error "Right paren expected in let.") | |
942 (forward-char 1) ; rparen | |
943 ))) | |
944 var-value-list))) | |
945 (forward-char 1) ; rparen | |
946 (nreverse var-value-list)) | |
947 | |
948 ;; now process the expression list | |
949 (edebug-sexp-list t)))) | |
950 | |
951 | |
952 (defun edebug-var-value () | |
953 "Return the edebug form of the var and optional value that follow point. | |
954 Leave point after the value, if there is one." | |
955 (list | |
956 (edebug-read-sexp) ; the variable | |
957 (and (not (eq 'rparen (edebug-next-token-class))) | |
958 (edebug-form)))) | |
959 | |
960 | |
961 (put 'setq 'edebug-form-hook | |
962 (put 'setq-default 'edebug-form-hook | |
963 '(&rest symbolp form))) | |
964 | |
965 (defun edebug-setq () | |
966 "Return the edebug form of the setq or setq-default var-value list." | |
967 (let (var-value-list) | |
968 (while (not (eq 'rparen (edebug-next-token-class))) | |
969 (setq var-value-list | |
970 (append var-value-list | |
971 (edebug-var-value)))) | |
972 var-value-list)) | |
973 | |
974 | |
975 (put 'interactive 'edebug-form-hook | |
976 '(&optional &or stringp form)) | |
977 | |
978 (defun edebug-interactive () | |
979 "Return the edebug form of the interactive form." | |
980 (list | |
981 (if (not (eq 'rparen (edebug-next-token-class))) | |
982 (if (eq 'string (edebug-next-token-class)) | |
983 (edebug-read-sexp) | |
984 (prog1 | |
985 (` (edebug-interactive-entry | |
986 (quote (, def-name)) | |
987 (quote ((,@ (edebug-form)))))) | |
988 (if (not (eq 'rparen (edebug-next-token-class))) | |
989 (edebug-syntax-error | |
990 "Only first expression used in interactive form."))))))) | |
991 | |
992 | |
993 (put 'cond 'edebug-form-hook | |
994 '(&rest (form &rest form))) | |
995 | |
996 (defun edebug-cond () | |
997 "Return the edebug form of the cond form." | |
998 (let (value-value-list | |
999 class) | |
1000 (while (not (eq 'rparen (setq class (edebug-next-token-class)))) | |
1001 (setq value-value-list | |
1002 (cons | |
1003 (if (not (eq 'lparen class)) | |
1004 (let ((thing (edebug-read-sexp))) | |
1005 (if thing | |
1006 (edebug-syntax-error "Condition expected in cond") | |
1007 nil)) | |
1008 (forward-char 1) ; \( | |
1009 (prog1 | |
1010 (cons | |
1011 (edebug-form) | |
1012 (if (eq 'rparen (edebug-next-token-class)) | |
1013 nil | |
1014 (edebug-sexp-list t))) | |
1015 (if (not (eq 'rparen (edebug-next-token-class))) | |
1016 (edebug-syntax-error "Right paren expected in cond")) | |
1017 (forward-char 1) ; \) | |
1018 )) | |
1019 value-value-list))) | |
1020 (nreverse value-value-list))) | |
1021 | |
1022 | |
3591
507f64624555
Apply typo patches from Paul Eggert.
Jim Blandy <jimb@redhat.com>
parents:
3350
diff
changeset
|
1023 ;; Bug: this doesn't support condition name lists |
661 | 1024 (put 'condition-case 'edebug-form-hook |
1025 '(symbolp | |
1026 form | |
1027 &rest (symbolp &optional form))) | |
1028 | |
1029 (defun edebug-condition-case () | |
1030 "Return the edebug form of the condition-case form." | |
1031 (cons | |
1032 (let (token) | |
1033 ;; read the variable or nil | |
1034 (setq token (edebug-read-sexp)) | |
1035 (if (not (symbolp token)) | |
1036 (edebug-syntax-error | |
1037 "Variable or nil required for condition-case; found: %s" token)) | |
1038 token) | |
1039 | |
1040 (cons | |
1041 (edebug-form) ; the form | |
1042 | |
1043 ;; process handlers | |
1044 (let (symb-sexp-list | |
1045 class) | |
1046 (while (not (eq 'rparen (setq class (edebug-next-token-class)))) | |
1047 (setq symb-sexp-list | |
1048 (cons | |
1049 (if (not (eq 'lparen class)) | |
1050 (edebug-syntax-error "Bad handler in condition-case.") | |
1051 (forward-char 1) ; \( | |
1052 (prog1 | |
1053 (cons | |
1054 (edebug-read-sexp) ; the error-condition | |
1055 (and (not (eq 'rparen (edebug-next-token-class))) | |
1056 (edebug-sexp-list t))) | |
1057 (forward-char 1) ; \) | |
1058 )) | |
1059 symb-sexp-list))) | |
1060 (nreverse symb-sexp-list))))) | |
1061 | |
1062 | |
1063 | |
1064 ;;------------------------------------------------ | |
1065 ;; Parser utilities | |
1066 | |
1067 (defun edebug-syntax-error (msg &rest args) | |
1068 "Signal an invalid-read-syntax with MSG and ARGS. | |
1069 This is caught by edebug-defun." | |
1070 (signal 'invalid-read-syntax (apply 'format msg args))) | |
1071 | |
1072 | |
1073 (defun edebug-skip-whitespace () | |
1074 "Leave point before the next token, skipping white space and comments." | |
1075 (skip-chars-forward " \t\r\n\f") | |
1076 (while (= (following-char) ?\;) | |
6226
d90fbaccf96a
(edebug-skip-whitespace): Only \n, not \r, ends a comment.
Richard M. Stallman <rms@gnu.org>
parents:
5388
diff
changeset
|
1077 (skip-chars-forward "^\n") ; skip the comment |
661 | 1078 (skip-chars-forward " \t\r\n\f"))) |
1079 | |
1080 (defun edebug-read-sexp () | |
1081 "Read one sexp from the current buffer starting at point. | |
1082 Leave point immediately after it. A sexp can be a list or atom. | |
1083 An atom is a symbol (or number), character, string, or vector." | |
1084 ;; This is gummed up by parser inconsistencies (bugs?) | |
1085 (let (token) | |
1086 (edebug-skip-whitespace) | |
1087 (if (or (= (following-char) ?\[) (= (following-char) ??)) | |
1088 ;; scan-sexps doesn't read vectors or character literals correctly, | |
1089 ;; but read does. | |
1090 (setq token (read (current-buffer))) | |
1091 (goto-char | |
1092 (min ; use the lesser of the read and scan-sexps motion | |
1093 ;; read goes one too far if (quoted) string or symbol | |
1094 ;; is immediately followed by non-whitespace | |
1095 (save-excursion | |
1096 (setq token (read (current-buffer))) | |
1097 (point)) | |
1098 ;; scan-sexps reads too far if a quoting character is read | |
1099 (scan-sexps (point) 1)))) | |
1100 token)) | |
1101 | |
1102 (defconst edebug-syntax-table | |
1103 (let ((table (make-vector 256 'symbol))) | |
1104 ;; Treat numbers as symbols, because of confusion with -, -1, and 1-. | |
1105 (aset table ?\( 'lparen) | |
1106 (aset table ?\) 'rparen) | |
1107 (aset table ?\' 'quote) | |
1108 (aset table ?\" 'string) | |
1109 (aset table ?\? 'char) | |
1110 (aset table ?\[ 'vector) | |
1111 (aset table ?\. 'dot) | |
1112 ;; We dont care about any other chars since they wont be seen. | |
1113 table) | |
1114 "Lookup table for the token class of each character.") | |
1115 | |
1116 (defun edebug-next-token-class () | |
1117 "Move to the next token and return its class. We only care about | |
1118 lparen, rparen, dot, quote, string, char, vector, or symbol." | |
1119 (edebug-skip-whitespace) | |
1120 (aref edebug-syntax-table (following-char))) | |
1121 | |
1122 | |
1123 ;;;================================================================= | |
1124 ;;; The debugger itself | |
1125 ;;; ------------------- | |
1126 | |
1127 | |
1128 (defvar edebug-active nil | |
1129 "Non-nil when edebug is active") | |
1130 | |
1131 | |
1132 ;;; add minor-mode-alist entry | |
1133 (or (assq 'edebug-active minor-mode-alist) | |
1134 (setq minor-mode-alist (cons (list 'edebug-active " *Debugging*") | |
1135 minor-mode-alist))) | |
1136 | |
1137 (defvar edebug-backtrace nil | |
1138 "Stack of active functions evaluated via edebug. | |
1139 Should be nil at the top level.") | |
1140 | |
1141 (defvar edebug-offset-indices nil ; not used yet. | |
1142 "Stack of offset indices of visited edebug sexps. | |
1143 Should be nil at the top level.") | |
1144 | |
1145 (defvar edebug-entered nil | |
1146 "Non-nil if edebug has already been entered at this recursive edit level.") | |
1147 | |
1148 | |
1149 (defun edebug-enter (edebug-func edebug-args edebug-body) | |
1150 "Entering FUNC. The arguments are ARGS, and the body is BODY. | |
1151 Setup edebug variables and evaluate BODY. This function is called | |
1152 when a function evaluated with edebug-defun is entered. Return the | |
1153 result of BODY." | |
1154 | |
1155 ;; Is this the first time we are entering edebug since | |
1156 ;; lower-level recursive-edit command? | |
1157 (if (and (not edebug-entered) | |
1158 edebug-initial-mode) | |
1159 ;; Reset edebug-mode to the initial mode. | |
1160 (setq edebug-mode edebug-initial-mode)) | |
1161 (let* ((edebug-entered t) | |
4761
fd03ee47c0b2
(edebug-enter): Don't call the current function being debugged in
Brian Fox <bfox@gnu.org>
parents:
3591
diff
changeset
|
1162 (pre-command-hook (if (memq edebug-func pre-command-hook) |
fd03ee47c0b2
(edebug-enter): Don't call the current function being debugged in
Brian Fox <bfox@gnu.org>
parents:
3591
diff
changeset
|
1163 nil pre-command-hook)) |
fd03ee47c0b2
(edebug-enter): Don't call the current function being debugged in
Brian Fox <bfox@gnu.org>
parents:
3591
diff
changeset
|
1164 (post-command-hook (if (memq edebug-func post-command-hook) |
fd03ee47c0b2
(edebug-enter): Don't call the current function being debugged in
Brian Fox <bfox@gnu.org>
parents:
3591
diff
changeset
|
1165 nil post-command-hook)) |
661 | 1166 (edebug-data (get edebug-func 'edebug)) |
1167 ;; pull out parts of the edebug-data | |
1168 (edebug-func-mark (car edebug-data)) ; mark at function start | |
1169 | |
1170 (edebug-buffer (marker-buffer edebug-func-mark)) | |
1171 (edebug-backtrace (cons edebug-func edebug-backtrace)) | |
1172 (max-lisp-eval-depth (+ 6 max-lisp-eval-depth)) ; too much?? | |
1173 (max-specpdl-size (+ 10 max-specpdl-size)) ; the args and these vars | |
1174 ) | |
1175 (if edebug-trace | |
1176 (let ((edebug-stack-depth (1- (length edebug-backtrace))) | |
1177 edebug-result) | |
1178 (edebug-print-trace-entry | |
1179 "*edebug-trace*" edebug-func edebug-args edebug-stack-depth) | |
1180 (setq edebug-result (eval edebug-body)) | |
1181 (edebug-print-trace-exit | |
1182 "*edebug-trace*" edebug-func edebug-result edebug-stack-depth) | |
1183 edebug-result) | |
1184 (eval edebug-body) | |
1185 ))) | |
1186 | |
1187 (defun edebug-interactive-entry (edebug-func edebug-args) | |
1188 "Evaluating FUNCs non-string argument of interactive form ARGS." | |
1189 (if (and (not edebug-entered) | |
1190 edebug-initial-mode) | |
1191 ;; Reset edebug-mode to the initial mode. | |
1192 (setq edebug-mode edebug-initial-mode)) | |
1193 (let* ((edebug-entered t) | |
1194 (edebug-data (get edebug-func 'edebug)) | |
1195 ;; pull out parts of the edebug-data | |
1196 (edebug-func-mark (car edebug-data)) ; mark at function start | |
1197 | |
1198 (edebug-buffer (marker-buffer edebug-func-mark)) | |
1199 ;; (edebug-backtrace (cons edebug-func edebug-backtrace)) | |
1200 ) | |
1201 (eval edebug-args))) | |
1202 | |
1203 | |
1204 (defun edebug-print-trace-entry | |
1205 (edebug-stream edebug-function edebug-args edebug-stack-depth) | |
1206 (edebug-trace-display | |
1207 edebug-stream | |
1208 "%sEnter: %s\n" (make-string edebug-stack-depth ?\ ) edebug-function) | |
1209 ) | |
1210 | |
1211 (defun edebug-print-trace-exit | |
1212 (edebug-stream edebug-function edebug-result edebug-stack-depth) | |
1213 (edebug-trace-display | |
1214 edebug-stream | |
1215 "%sExit: %s\n" (make-string edebug-stack-depth ?\ ) edebug-function) | |
1216 ) | |
1217 | |
1218 | |
1219 (defun edebug (edebug-before-index edebug-after-index edebug-exp) | |
1220 "Debug current function given BEFORE and AFTER positions around EXP. | |
1221 BEFORE and AFTER are indexes into the position offset vector in the | |
1222 functions 'edebug property. edebug is called from functions compiled | |
1223 with edebug-defun." | |
1224 (let ((max-lisp-eval-depth (+ 5 max-lisp-eval-depth)) ; enough?? | |
1225 (max-specpdl-size (+ 7 max-specpdl-size)) ; the args and these vars | |
1226 (edebug-offset-indices | |
1227 (cons edebug-before-index edebug-offset-indices)) | |
1228 ;; Save the outside value of executing macro. | |
1229 (edebug-outside-executing-macro executing-macro) | |
1230 ;; Don't keep reading from an executing kbd macro within edebug! | |
1231 (executing-macro nil) | |
1232 ) | |
1233 (if (and (eq edebug-mode 'Go-nonstop) | |
1234 (not (edebug-input-pending-p))) | |
1235 ;; Just return evalled expression. | |
1236 (eval edebug-exp) | |
1237 (edebug-debugger edebug-before-index 'enter edebug-exp) | |
1238 (edebug-debugger edebug-after-index 'exit (eval edebug-exp)) | |
1239 ))) | |
1240 | |
1241 | |
1242 (defun edebug-debugger (edebug-offset-index edebug-arg-mode edebug-exp) | |
1243 "Determine if edebug display should be updated." | |
1244 (let* ( | |
1245 ;; This needs to be here since breakpoints may be changed. | |
1246 (edebug-breakpoints (car (cdr edebug-data))) ; list of breakpoints | |
1247 (edebug-break-data (assq edebug-offset-index edebug-breakpoints)) | |
1248 (edebug-break | |
1249 (if edebug-break-data | |
1250 (let ((edebug-break-condition | |
1251 (car (cdr edebug-break-data)))) | |
1252 (or (not edebug-break-condition) | |
1253 (eval edebug-break-condition))))) | |
1254 ) | |
1255 (if (and edebug-break | |
1256 (car (cdr (cdr edebug-break-data)))) ; is it temporary? | |
1257 ;; Delete the breakpoint. | |
1258 (setcdr edebug-data | |
1259 (cons (delq edebug-break-data edebug-breakpoints) | |
1260 (cdr (cdr edebug-data))))) | |
1261 | |
1262 ;; Dont do anything if mode is go, continue, or Continue-fast | |
1263 ;; and no break, and no input. | |
1264 (if (or (and (not (memq edebug-mode '(go continue Continue-fast))) | |
1265 (or edebug-stop-before-symbols | |
1266 (not (and (eq edebug-arg-mode 'enter) | |
1267 (symbolp edebug-exp))))) | |
1268 (edebug-input-pending-p) | |
1269 edebug-break) | |
1270 (edebug-display)) | |
1271 | |
1272 edebug-exp | |
1273 )) | |
1274 | |
1275 | |
1276 (defvar edebug-window-start 0 | |
1277 "Remember where each buffers' window starts between edebug calls. | |
1278 This is to avoid spurious recentering.") | |
1279 | |
1280 (setq-default edebug-window-start 0) | |
1281 (make-variable-buffer-local 'edebug-window-start) | |
1282 | |
1283 (defun edebug-display () | |
1284 "Setup windows for edebug, determine mode, maybe enter recursive-edit." | |
1285 ;; uses local variables of edebug-enter, edebug, and edebug-debugger. | |
1286 (let ((edebug-active t) ; for minor mode alist | |
1287 edebug-stop ; should we enter recursive-edit | |
1288 (edebug-point (+ edebug-func-mark | |
1289 (aref (car (cdr (cdr edebug-data))) | |
1290 edebug-offset-index))) | |
1291 (edebug-buffer-points | |
1292 (if edebug-save-buffer-points (edebug-get-buffer-points))) | |
1293 edebug-window ; window displaying edebug-buffer | |
1294 edebug-inside-window ; window displayed after recursive edit | |
1295 (edebug-outside-window (selected-window)) | |
1296 (edebug-outside-buffer (current-buffer)) | |
1297 (edebug-outside-point (point)) | |
2629
137117f5c44c
* edebug.el (edebug-display): Call the `mark' function with the
Jim Blandy <jimb@redhat.com>
parents:
2307
diff
changeset
|
1298 (edebug-outside-mark (mark t)) |
661 | 1299 edebug-outside-windows ; window or screen configuration |
1300 edebug-outside-edebug-point ; old point in edebug buffer | |
1301 edebug-outside-edebug-mark | |
1302 | |
1303 edebug-eval-buffer ; declared here so we can kill it below | |
1304 (edebug-eval-result-list (and edebug-eval-list | |
1305 (edebug-eval-result-list))) | |
1306 (edebug-outside-o-a-p overlay-arrow-position) | |
1307 (edebug-outside-o-a-s overlay-arrow-string) | |
1308 (edebug-outside-c-i-e-a cursor-in-echo-area) | |
1309 | |
1310 edebug-outside-point-min | |
1311 edebug-outside-point-max | |
1312 | |
1313 overlay-arrow-position | |
1314 overlay-arrow-string | |
1315 (cursor-in-echo-area nil) | |
1316 ;; any others?? | |
1317 ) | |
1318 (if (not (buffer-name edebug-buffer)) | |
5126
30682388c4cf
Delete periods from error messages.
Richard M. Stallman <rms@gnu.org>
parents:
5125
diff
changeset
|
1319 (let ((debug-on-error nil)) |
30682388c4cf
Delete periods from error messages.
Richard M. Stallman <rms@gnu.org>
parents:
5125
diff
changeset
|
1320 (error "Buffer defining %s not found" edebug-func))) |
661 | 1321 |
1322 ;; Save windows now before we modify them. | |
1323 (if edebug-save-windows | |
1324 (setq edebug-outside-windows | |
1325 (edebug-current-window-configuration))) | |
1326 | |
1327 ;; If edebug-buffer is not currently displayed, | |
1328 ;; first find a window for it. | |
1329 (edebug-pop-to-buffer edebug-buffer) | |
1330 (setq edebug-window (selected-window)) | |
1331 | |
1332 ;; Now display eval list, if any. | |
1333 ;; This is done after the pop to edebug-buffer | |
1334 ;; so that buffer-window correspondence is correct after quit. | |
1335 (edebug-eval-display edebug-eval-result-list) | |
1336 (select-window edebug-window) | |
1337 | |
1338 (if edebug-save-point | |
1339 (progn | |
1340 (setq edebug-outside-edebug-point (point)) | |
2629
137117f5c44c
* edebug.el (edebug-display): Call the `mark' function with the
Jim Blandy <jimb@redhat.com>
parents:
2307
diff
changeset
|
1341 (setq edebug-outside-edebug-mark (mark t)))) |
661 | 1342 |
1343 (edebug-save-restriction | |
1344 (setq edebug-outside-point-min (point-min)) | |
1345 (setq edebug-outside-point-max (point-max)) | |
1346 (widen) | |
1347 (goto-char edebug-point) | |
1348 | |
1349 (setq edebug-window-start | |
1350 (edebug-adjust-window edebug-window-start)) | |
1351 | |
1352 (if (edebug-input-pending-p) ; not including keyboard macros | |
1353 (progn | |
1354 (setq edebug-mode 'step) | |
1355 (setq edebug-stop t) | |
1356 (edebug-stop) | |
1357 ;; (discard-input) ; is this unfriendly?? | |
1358 )) | |
1359 (edebug-overlay-arrow) | |
1360 | |
1361 (cond | |
1362 ((eq 'exit edebug-arg-mode) | |
1363 ;; Display result of previous evaluation. | |
1364 (setq edebug-previous-result edebug-exp) | |
1365 (edebug-previous-result)) | |
1366 | |
1367 ((eq 'error edebug-arg-mode) | |
1368 ;; Display error message | |
1369 (beep) | |
1370 (if (eq 'quit (car edebug-exp)) | |
1371 (message "Quit") | |
1372 (message "%s: %s" | |
1373 (get (car edebug-exp) 'error-message) | |
1374 (car (cdr edebug-exp))))) | |
1375 | |
1376 (edebug-break | |
1377 (message "Break")) | |
1378 (t (message ""))) | |
1379 | |
1380 (if edebug-break | |
1381 (if (not (memq edebug-mode '(continue Continue-fast))) | |
1382 (setq edebug-stop t) | |
1383 (if (eq edebug-mode 'continue) | |
1384 (edebug-sit-for 1) | |
1385 (edebug-sit-for 0))) | |
1386 ;; not edebug-break | |
1387 (if (eq edebug-mode 'trace) | |
1388 (edebug-sit-for 1) ; Force update and pause. | |
1389 (if (eq edebug-mode 'Trace-fast) | |
1390 (edebug-sit-for 0) ; Force update and continue. | |
1391 ))) | |
1392 | |
1393 (unwind-protect | |
1394 (if (or edebug-stop | |
1395 (eq edebug-mode 'step) | |
1396 (eq edebug-arg-mode 'error)) | |
1397 (progn | |
1398 (setq edebug-mode 'step) | |
3591
507f64624555
Apply typo patches from Paul Eggert.
Jim Blandy <jimb@redhat.com>
parents:
3350
diff
changeset
|
1399 (edebug-overlay-arrow) ; this doesn't always show up. |
661 | 1400 (edebug-recursive-edit));; <<<<<< Recursive edit |
1401 ) | |
1402 | |
1403 (if edebug-save-buffer-points | |
1404 (edebug-set-buffer-points)) | |
1405 ;; Since we may be in a save-excursion, in case of quit | |
1406 ;; restore the outside window only. | |
1407 (select-window edebug-outside-window) | |
1408 ) ; unwind-protect | |
1409 | |
1410 ;; None of the following is done if quit or signal occurs. | |
1411 (if edebug-save-point | |
1412 ;; Restore point and mark in edebug-buffer. | |
1413 ;; This does the save-excursion recovery only if no quit. | |
1414 ;; If edebug-buffer == edebug-outside-buffer, | |
1415 ;; then this is redundant with outside save-excursion. | |
1416 (progn | |
1417 (set-buffer edebug-buffer) | |
1418 (goto-char edebug-outside-edebug-point) | |
1419 (if (mark-marker) | |
1420 (set-marker (mark-marker) edebug-outside-edebug-mark)) | |
1421 )) | |
1422 ) ; edebug-save-restriction | |
1423 | |
1424 ;; Restore windows, buffer, point, and mark. | |
1425 (if edebug-save-windows | |
1426 ;; Restore windows before continuing. | |
1427 (edebug-set-window-configuration edebug-outside-windows)) | |
1428 (set-buffer edebug-outside-buffer) | |
1429 (goto-char edebug-outside-point) | |
1430 (if (mark-marker) | |
1431 (set-marker (mark-marker) edebug-outside-mark)) | |
1432 ;; The following is not sufficient, and sometimes annoying. | |
1433 ;; (if (memq edebug-mode '(go Go-nonstop)) | |
1434 ;; (edebug-sit-for 0)) | |
1435 )) | |
1436 | |
1437 | |
1438 (defvar edebug-depth 0 | |
1439 "Number of recursive edits started by edebug. | |
1440 Should be 0 at the top level.") | |
1441 | |
1442 (defvar edebug-recursion-depth 0 | |
1443 "Value of recursion-depth when edebug was called.") | |
1444 | |
1445 | |
1446 (defun edebug-recursive-edit () | |
1447 "Start up a recursive edit inside of edebug." | |
1448 ;; The current buffer is the edebug-buffer, which is put into edebug-mode. | |
1449 (let ((edebug-buffer-read-only buffer-read-only) | |
1450 ;; match-data must be done in the outside buffer | |
1451 (edebug-outside-match-data | |
1452 (save-excursion | |
1453 (set-buffer edebug-outside-buffer) | |
1454 (match-data))) | |
1455 | |
1456 (edebug-depth (1+ edebug-depth)) | |
1457 (edebug-recursion-depth (recursion-depth)) | |
1458 edebug-entered ; bind locally to nil | |
1459 edebug-backtrace-buffer ; each recursive edit gets its own | |
1460 ;; The window configuration may be saved and restored | |
1461 ;; during a recursive-edit | |
1462 edebug-inside-windows | |
1463 | |
1464 (edebug-outside-map (current-local-map)) | |
1465 (edebug-outside-standard-output standard-output) | |
1466 (edebug-outside-standard-input standard-input) | |
1467 | |
1468 (edebug-outside-last-command-char last-command-char) | |
1469 (edebug-outside-last-command last-command) | |
1470 (edebug-outside-this-command this-command) | |
1471 (edebug-outside-last-input-char last-input-char) | |
1472 ;; (edebug-outside-unread-command-char unread-command-char) | |
1473 | |
1474 ;; Declare the following local variables to protect global values. | |
1475 ;; We could set these to the values for previous edebug call. | |
1476 ;; But instead make it local, but use global value. | |
1477 (last-command-char last-command-char) | |
1478 (last-command last-command) | |
1479 (this-command this-command) | |
1480 (last-input-char last-input-char) | |
1821
04fb1d3d6992
JimB's changes since January 18th
Jim Blandy <jimb@redhat.com>
parents:
851
diff
changeset
|
1481 ;; Assume no edebug command sets unread-command-events. |
661 | 1482 ;; (unread-command-char -1) |
1483 | |
1484 (debug-on-error debug-on-error) | |
1485 | |
1486 ;; others?? | |
1487 ) | |
1488 | |
1489 (if (and (eq edebug-mode 'go) | |
1490 (not (memq edebug-arg-mode '(exit error)))) | |
1491 (message "Break")) | |
1492 (edebug-mode) | |
1493 (if (boundp 'edebug-outside-debug-on-error) | |
1494 (setq debug-on-error edebug-outside-debug-on-error)) | |
1495 | |
1496 (setq buffer-read-only t) | |
1497 (unwind-protect | |
1498 (recursive-edit) ; <<<<<<<<<< Recursive edit | |
1499 | |
1500 ;; Do the following, even if quit occurs. | |
1501 (if edebug-backtrace-buffer | |
1502 (kill-buffer edebug-backtrace-buffer)) | |
1503 ;; Could be an option to keep eval display up. | |
1504 (if edebug-eval-buffer (kill-buffer edebug-eval-buffer)) | |
1505 | |
1506 ;; Remember selected-window after recursive-edit. | |
1507 (setq edebug-inside-window (selected-window)) | |
1508 | |
1509 (store-match-data edebug-outside-match-data) | |
1510 | |
1511 ;; Recursive edit may have changed buffers, | |
1512 ;; so set it back before exiting let. | |
1513 (if (buffer-name edebug-buffer) ; if it still exists | |
1514 (progn | |
1515 (set-buffer edebug-buffer) | |
1516 (if (memq edebug-mode '(go Go-nonstop)) | |
1517 (edebug-overlay-arrow)) | |
1518 (setq buffer-read-only edebug-buffer-read-only) | |
1519 (use-local-map edebug-outside-map) | |
1520 ;; Remember current window-start for next visit. | |
1521 (select-window edebug-window) | |
1522 (if (eq edebug-buffer (window-buffer edebug-window)) | |
1523 (setq edebug-window-start (window-start))) | |
1524 (select-window edebug-inside-window) | |
1525 )) | |
1526 ))) | |
1527 | |
1528 | |
1529 ;;-------------------------- | |
1530 ;; Display related functions | |
1531 | |
1532 (defun edebug-adjust-window (old-start) | |
1533 "Adjust window to fit as much as possible following point. | |
1534 The display should prefer to start at OLD-START if point is not visible. | |
1535 Return the new window-start." | |
1536 (if (not (pos-visible-in-window-p)) | |
1537 (progn | |
1538 (set-window-start (selected-window) old-start) | |
1539 (if (not (pos-visible-in-window-p)) | |
1540 (let ((start (window-start)) | |
1541 (pnt (point))) | |
1542 (set-window-start | |
1543 (selected-window) | |
1544 (save-excursion | |
1545 (forward-line | |
1546 (if (< pnt start) -1 ; one line before | |
1547 (- (/ (window-height) 2)) ; center the line | |
1548 )) | |
1549 (beginning-of-line) | |
1550 (point))))))) | |
1551 (window-start)) | |
1552 | |
1553 | |
1554 (defconst edebug-arrow-alist | |
1555 '((Continue-fast . ">") | |
1556 (Trace-fast . ">") | |
1557 (continue . ">") | |
1558 (trace . "->") | |
1559 (step . "=>") | |
1560 (go . "<>") | |
1561 (Go-nonstop . "..") ; not used | |
1562 ) | |
1563 "Association list of arrows for each edebug mode. | |
1564 If you come up with arrows that make more sense, let me know.") | |
1565 | |
1566 (defun edebug-overlay-arrow () | |
1567 "Set up the overlay arrow at beginning-of-line in current buffer. | |
1568 The arrow string is derived from edebug-arrow-alist and edebug-mode." | |
1569 (let* ((pos)) | |
1570 (save-excursion | |
1571 (beginning-of-line) | |
1572 (setq pos (point))) | |
1573 (setq overlay-arrow-string | |
1574 (cdr (assq edebug-mode edebug-arrow-alist))) | |
1575 (setq overlay-arrow-position (make-marker)) | |
1576 (set-marker overlay-arrow-position pos (current-buffer)))) | |
1577 | |
1578 | |
1579 (put 'edebug-outside-excursion 'edebug-form-hook | |
1580 '(&rest form)) | |
1581 | |
1582 (defmacro edebug-outside-excursion (&rest body) | |
1583 "Evaluate an expression list in the outside context. | |
1584 Return the result of the last expression." | |
1585 (` (save-excursion ; of current-buffer | |
1586 (if edebug-save-windows | |
1587 (progn | |
1588 ;; After excursion, we will | |
1589 ;; restore to current window configuration. | |
1590 (setq edebug-inside-windows | |
1591 (edebug-current-window-configuration)) | |
1592 ;; Restore outside windows. | |
1593 (edebug-set-window-configuration edebug-outside-windows))) | |
1594 | |
1595 (set-buffer edebug-buffer) | |
1596 ;; Restore outside context. | |
1597 (let ((edebug-inside-map (current-local-map)) | |
1598 (last-command-char edebug-outside-last-command-char) | |
1599 (last-command edebug-outside-last-command) | |
1600 (this-command edebug-outside-this-command) | |
1601 ;; (unread-command-char edebug-outside-unread-command-char) | |
1602 (last-input-char edebug-outside-last-input-char) | |
1603 (overlay-arrow-position edebug-outside-o-a-p) | |
1604 (overlay-arrow-string edebug-outside-o-a-s) | |
1605 (cursor-in-echo-area edebug-outside-c-i-e-a) | |
1606 (standard-output edebug-outside-standard-output) | |
1607 (standard-input edebug-outside-standard-input) | |
1608 (executing-macro edebug-outside-executing-macro) | |
1609 ) | |
1610 (unwind-protect | |
1611 (save-restriction | |
1612 (narrow-to-region edebug-outside-point-min | |
1613 edebug-outside-point-max) | |
1614 (save-excursion ; of edebug-buffer | |
1615 (if edebug-save-point | |
1616 (progn | |
1617 (goto-char edebug-outside-edebug-point) | |
1618 (if (mark-marker) | |
1619 (set-marker (mark-marker) | |
1620 edebug-outside-edebug-mark)) | |
1621 )) | |
1622 (use-local-map edebug-outside-map) | |
1623 (store-match-data edebug-outside-match-data) | |
1624 (select-window edebug-outside-window) | |
1625 (set-buffer edebug-outside-buffer) | |
1626 (goto-char edebug-outside-point) | |
1627 (,@ body) | |
1628 ) ; save-excursion | |
1629 ) ; save-restriction | |
1630 ;; Back to edebug-buffer. Restore rest of inside context. | |
1631 (use-local-map edebug-inside-map) | |
1632 (if edebug-save-windows | |
1633 ;; Restore inside windows. | |
1634 (edebug-set-window-configuration edebug-inside-windows)) | |
1635 )) ; let | |
1636 ))) | |
1637 | |
1638 | |
1639 (defun edebug-toggle-save-windows () | |
1640 "Toggle the edebug-save-windows variable. | |
1641 Each time you toggle it, the inside and outside window configurations | |
1642 become the same as the current configuration." | |
1643 (interactive) | |
1644 (if (setq edebug-save-windows (not edebug-save-windows)) | |
1645 (setq edebug-inside-windows | |
1646 (setq edebug-outside-windows | |
1647 (edebug-current-window-configuration)))) | |
1648 (message "Window saving is %s." | |
1649 (if edebug-save-windows "on" "off"))) | |
1650 | |
1651 | |
1652 (defun edebug-where () | |
1653 "Show the debug windows and where we stopped in the program." | |
1654 (interactive) | |
1655 (if (not edebug-active) | |
5126
30682388c4cf
Delete periods from error messages.
Richard M. Stallman <rms@gnu.org>
parents:
5125
diff
changeset
|
1656 (error "edebug is not active")) |
661 | 1657 (edebug-pop-to-buffer edebug-buffer) |
1658 (goto-char edebug-point) ; from edebug | |
1659 ) | |
1660 | |
1661 (defun edebug-view-outside () | |
1662 "Change to the outside window configuration." | |
1663 (interactive) | |
1664 (if (not edebug-active) | |
5126
30682388c4cf
Delete periods from error messages.
Richard M. Stallman <rms@gnu.org>
parents:
5125
diff
changeset
|
1665 (error "edebug is not active")) |
661 | 1666 (setq edebug-inside-windows (edebug-current-window-configuration)) |
1667 (edebug-set-window-configuration edebug-outside-windows) | |
1668 (goto-char edebug-outside-point) | |
1669 (message "Window configuration outside of edebug. Return with %s" | |
1670 (substitute-command-keys "\\<global-map>\\[edebug-where]"))) | |
1671 | |
1672 | |
1673 (defun edebug-bounce-point () | |
1674 "Bounce the point in the outside current buffer." | |
1675 (interactive) | |
1676 (if (not edebug-active) | |
5126
30682388c4cf
Delete periods from error messages.
Richard M. Stallman <rms@gnu.org>
parents:
5125
diff
changeset
|
1677 (error "edebug is not active")) |
661 | 1678 (save-excursion |
1679 ;; If the buffer's currently displayed, avoid the set-window-configuration. | |
1680 (save-window-excursion | |
1681 (edebug-pop-to-buffer edebug-outside-buffer) | |
1682 ;; (edebug-sit-for 1) ; this shouldnt be necessary | |
1683 (goto-char edebug-outside-point) | |
1684 ;; (message "current buffer: %s" (current-buffer)) | |
1685 (edebug-sit-for 1) | |
1686 (edebug-pop-to-buffer edebug-buffer)))) | |
1687 | |
1688 | |
1689 | |
1690 ;;-------------------------- | |
1691 ;; epoch related things | |
1692 | |
1693 (defvar edebug-epoch-running (and (boundp 'epoch::version) epoch::version) | |
1694 "non-nil if epoch is running. | |
1695 Windows are handled a little differently under epoch.") | |
1696 | |
1697 | |
1698 (defun edebug-current-window-configuration () | |
778 | 1699 "Return the current window or frame configuration." |
661 | 1700 (if edebug-epoch-running |
1701 (edebug-current-screen-configuration) | |
1702 (current-window-configuration))) | |
1703 | |
1704 | |
1705 (defun edebug-set-window-configuration (conf) | |
778 | 1706 "Set the window or frame configuration to CONF." |
661 | 1707 (if edebug-epoch-running |
1708 (edebug-set-screen-configuration conf) | |
1709 (set-window-configuration conf))) | |
1710 | |
1711 | |
1712 (defun edebug-get-buffer-window (buffer) | |
1713 (if edebug-epoch-running | |
1714 (epoch::get-buffer-window buffer) | |
1715 (get-buffer-window buffer))) | |
1716 | |
1717 | |
1718 (defun edebug-pop-to-buffer (buffer) | |
778 | 1719 "Like pop-to-buffer, but select a frame that buffer was shown in." |
661 | 1720 (let ((edebug-window (edebug-get-buffer-window buffer))) |
1721 (if edebug-window | |
1722 (select-window edebug-window) | |
1723 ;; It is not currently displayed, so find some place to display it. | |
1724 (if edebug-epoch-running | |
1725 ;; Select a screen that the buffer has been displayed in before | |
1726 ;; or the current screen otherwise. | |
1727 (select-screen | |
1728 ;; allowed-screens in epoch 3.2, was called screens before that | |
1729 (or (car (symbol-buffer-value 'allowed-screens buffer)) | |
1730 (epoch::current-screen)))) | |
1731 (if (one-window-p) | |
1732 (split-window)) | |
1733 (select-window (next-window)) | |
1734 (set-window-buffer (selected-window) buffer) | |
1735 (set-window-hscroll (selected-window) 0) | |
1736 )) | |
1737 ;; Selecting the window does not set the buffer. | |
1738 (set-buffer buffer) | |
1739 ) | |
1740 | |
1741 | |
1742 (defun edebug-current-screen-configuration () | |
1743 "Return an object recording the current configuration of Epoch screen-list. | |
1744 The object is a list of pairs of the form (SCREEN . CONFIGURATION) | |
1745 where SCREEN has window-configuration CONFIGURATION. The current | |
1746 screen is the head of the list." | |
1747 (let ((screen-list (epoch::screen-list 'unmapped)) | |
1748 (current-screen (epoch::get-screen)) | |
1749 (current-buffer (current-buffer)) | |
1750 ) | |
1751 ;; put current screen first | |
1752 (setq screen-list (cons current-screen (delq current-screen screen-list))) | |
1753 (prog1 | |
1754 (mapcar (function | |
1755 (lambda (screen) | |
1756 (cons screen | |
1757 (progn | |
1758 (epoch::select-screen screen) | |
1759 (current-window-configuration))))) | |
1760 screen-list) | |
1761 (epoch::select-screen current-screen) | |
1762 (set-buffer current-buffer) | |
1763 ))) | |
1764 | |
1765 (defun edebug-set-screen-configuration (sc) | |
1766 "Set the window-configuration for all the screens in SC. | |
1767 Set the current screen to be the head of SC." | |
1768 (mapcar (function | |
1769 (lambda (screen-conf) | |
1770 (if (epoch::screen-p (car screen-conf)) ; still exist? | |
1771 (progn | |
1772 (epoch::select-screen (car screen-conf)) | |
1773 (set-window-configuration (cdr screen-conf)))))) | |
1774 sc) | |
1775 (if (epoch::screen-p (car (car sc))) | |
1776 (epoch::select-screen (car (car sc)))) | |
1777 ) | |
1778 | |
1779 | |
1780 (defun edebug-sit-for (arg) | |
1781 (if edebug-epoch-running | |
1782 (epoch::dispatch-events)) | |
1783 (sit-for arg) | |
1784 ) | |
1785 | |
1786 (defun edebug-input-pending-p () | |
1787 (if edebug-epoch-running | |
1788 (epoch::dispatch-events)) | |
1789 (input-pending-p) | |
1790 ) | |
1791 | |
1792 | |
1793 | |
1794 ;;-------------------------- | |
1795 ;; breakpoint related functions | |
1796 | |
1797 (defun edebug-find-stop-point () | |
1798 "Return (function . index) of the nearest edebug stop point." | |
1799 (let* ((def-name (edebug-which-function)) | |
1800 (edebug-data | |
1801 (or (get def-name 'edebug) | |
1802 (error | |
5126
30682388c4cf
Delete periods from error messages.
Richard M. Stallman <rms@gnu.org>
parents:
5125
diff
changeset
|
1803 "%s must first be evaluated with edebug-defun" def-name))) |
661 | 1804 ;; pull out parts of edebug-data. |
1805 (edebug-func-mark (car edebug-data)) | |
1806 (edebug-breakpoints (car (cdr edebug-data))) | |
1807 | |
1808 (offset-vector (car (cdr (cdr edebug-data)))) | |
1809 (offset (- (save-excursion | |
1810 (if (looking-at "[ \t]") | |
1811 ;; skip backwards until non-whitespace, or bol | |
1812 (skip-chars-backward " \t")) | |
1813 (point)) | |
1814 edebug-func-mark)) | |
1815 len i) | |
1816 ;; the offsets are in order so we can do a linear search | |
1817 (setq len (length offset-vector)) | |
1818 (setq i 0) | |
1819 (while (and (< i len) (> offset (aref offset-vector i))) | |
1820 (setq i (1+ i))) | |
1821 (if (and (< i len) | |
1822 (<= offset (aref offset-vector i))) | |
1823 ;; return the relevant info | |
1824 (cons def-name i) | |
1825 (message "Point is not on an expression in %s." | |
1826 def-name) | |
1827 ))) | |
1828 | |
1829 | |
1830 (defun edebug-next-breakpoint () | |
1831 "Move point to the next breakpoint, or first if none past point." | |
1832 (interactive) | |
1833 (let ((edebug-stop-point (edebug-find-stop-point))) | |
1834 (if edebug-stop-point | |
1835 (let* ((def-name (car edebug-stop-point)) | |
1836 (index (cdr edebug-stop-point)) | |
1837 (edebug-data (get def-name 'edebug)) | |
1838 | |
1839 ;; pull out parts of edebug-data | |
1840 (edebug-func-mark (car edebug-data)) | |
1841 (edebug-breakpoints (car (cdr edebug-data))) | |
1842 (offset-vector (car (cdr (cdr edebug-data)))) | |
1843 breakpoint) | |
1844 (if (not edebug-breakpoints) | |
1845 (message "No breakpoints in this function.") | |
1846 (let ((breaks edebug-breakpoints)) | |
1847 (while (and breaks | |
1848 (<= (car (car breaks)) index)) | |
1849 (setq breaks (cdr breaks))) | |
1850 (setq breakpoint | |
1851 (if breaks | |
1852 (car breaks) | |
1853 ;; goto the first breakpoint | |
1854 (car edebug-breakpoints))) | |
1855 (goto-char (+ edebug-func-mark | |
1856 (aref offset-vector (car breakpoint)))) | |
1857 | |
1858 (message (concat (if (car (cdr (cdr breakpoint))) | |
1859 "Temporary " "") | |
1860 (if (car (cdr breakpoint)) | |
1861 (format "Condition: %s" | |
1862 (prin1-to-string | |
1863 (car (cdr breakpoint)))) | |
1864 ""))) | |
1865 )))))) | |
1866 | |
1867 | |
1868 (defun edebug-modify-breakpoint (flag &optional condition temporary) | |
1869 "Modify the breakpoint for the form at point or after it according | |
1870 to FLAG: set if t, clear if nil. Then move to that point. | |
1871 If CONDITION or TEMPORARY are non-nil, add those attributes to | |
1872 the breakpoint. " | |
1873 (let ((edebug-stop-point (edebug-find-stop-point))) | |
1874 (if edebug-stop-point | |
1875 (let* ((def-name (car edebug-stop-point)) | |
1876 (index (cdr edebug-stop-point)) | |
1877 (edebug-data (get def-name 'edebug)) | |
1878 | |
1879 ;; pull out parts of edebug-data | |
1880 (edebug-func-mark (car edebug-data)) | |
1881 (edebug-breakpoints (car (cdr edebug-data))) | |
1882 (offset-vector (car (cdr (cdr edebug-data)))) | |
1883 present) | |
1884 ;; delete it either way | |
1885 (setq present (assq index edebug-breakpoints)) | |
1886 (setq edebug-breakpoints (delq present edebug-breakpoints)) | |
1887 (if flag | |
1888 (progn | |
1889 ;; add it to the list and resort | |
1890 (setq edebug-breakpoints | |
1891 (edebug-sort-alist | |
1892 (cons | |
1893 (list index condition temporary) | |
1894 edebug-breakpoints) '<)) | |
1895 (message "Breakpoint set in %s." def-name)) | |
1896 (if present | |
1897 (message "Breakpoint unset in %s." def-name) | |
1898 (message "No breakpoint here."))) | |
1899 | |
1900 (setcdr edebug-data | |
1901 (cons edebug-breakpoints (cdr (cdr edebug-data)))) | |
1902 (goto-char (+ edebug-func-mark (aref offset-vector index))) | |
1903 )))) | |
1904 | |
1905 (defun edebug-set-breakpoint (arg) | |
1906 "Set the breakpoint of nearest sexp. | |
1907 With prefix argument, make it a temporary breakpoint." | |
1908 (interactive "P") | |
1909 (edebug-modify-breakpoint t nil arg)) | |
1910 | |
1911 (defun edebug-unset-breakpoint () | |
1912 "Clear the breakpoint of nearest sexp." | |
1913 (interactive) | |
1914 (edebug-modify-breakpoint nil)) | |
1915 | |
1916 (defun edebug-set-conditional-breakpoint (arg condition) | |
1917 "Set a conditional breakpoint at nearest sexp. | |
1918 The condition is evaluated in the outside context. | |
1919 With prefix argument, make it a temporary breakpoint." | |
1920 (interactive "P\nxCondition: ") | |
1921 (edebug-modify-breakpoint t condition arg)) | |
1922 | |
1923 | |
1924 ;;-------------------------- | |
1925 ;; Mode switching functions | |
1926 | |
1927 (defun edebug-set-mode (mode shortmsg msg) | |
1928 "Set the edebug mode to MODE. | |
1929 Display SHORTMSG, or MSG if not within edebug." | |
1930 (interactive) | |
1931 (setq edebug-mode mode) | |
1932 (if (< 0 edebug-depth) | |
1933 (if (eq (current-buffer) edebug-buffer) | |
1934 (progn | |
1935 (message shortmsg) | |
1936 (exit-recursive-edit))) | |
1937 (message msg))) | |
1938 | |
1939 | |
1940 (defun edebug-step-through () | |
1941 "Proceed to next debug step." | |
1942 (interactive) | |
1943 (edebug-set-mode 'step "" "edebug will stop before next eval.")) | |
1944 | |
1945 (defun edebug-go (arg) | |
1946 "Go, evaluating until break. | |
1947 With ARG set temporary break at stop point and go." | |
1948 (interactive "P") | |
1949 (if arg | |
1950 (edebug-set-breakpoint t)) | |
1951 (edebug-set-mode 'go "Go..." "edebug will go until break.")) | |
1952 | |
1953 (defun edebug-Go-nonstop () | |
1954 "Go, evaluating without debugging." | |
1955 (interactive) | |
1956 (edebug-set-mode 'Go-nonstop "Go-Nonstop..." | |
1957 "edebug will not stop at breaks.")) | |
1958 | |
1959 (defun edebug-forward-sexp (arg) | |
1960 "Proceed from the current point to the end of the ARGth sexp ahead. | |
1961 If there are not ARG sexps ahead, then do edebug-step-out." | |
1962 (interactive "p") | |
1963 (condition-case err | |
1964 (let ((parse-sexp-ignore-comments t)) | |
1965 ;; Call forward-sexp repeatedly until done or failure. | |
1966 (forward-sexp arg) | |
1967 (edebug-go t)) | |
1968 (error | |
1969 (edebug-step-out) | |
1970 ))) | |
1971 | |
1972 (defun edebug-step-out () | |
1973 "Proceed from the current point to the end of the containing sexp. | |
1974 If there is no containing sexp that is not the top level defun, | |
1975 go to the end of the last sexp, or if that is the same point, then step." | |
1976 (interactive) | |
1977 (condition-case err | |
1978 (let ((parse-sexp-ignore-comments t)) | |
1979 (up-list 1) | |
1980 (save-excursion | |
1981 ;; Is there still a containing expression? | |
1982 (up-list 1)) | |
1983 (edebug-go t)) | |
1984 (error | |
1985 ;; At top level - 1, so first check if there are more sexps at this level. | |
1986 (let ((start-point (point))) | |
1987 ;; (up-list 1) | |
1988 (down-list -1) | |
1989 (if (= (point) start-point) | |
1990 (edebug-step-through) ; No more at this level, so step. | |
1991 (edebug-go t) | |
1992 ))))) | |
1993 | |
1994 | |
1995 (defun edebug-goto-here () | |
1996 "Proceed to this stop point." | |
1997 (interactive) | |
1998 (edebug-go t) | |
1999 ) | |
2000 | |
2001 (defun edebug-trace () | |
2002 "Begin trace mode." | |
2003 (interactive) | |
2004 (edebug-set-mode 'trace "Tracing..." "edebug will trace with pause.")) | |
2005 | |
2006 (defun edebug-Trace-fast () | |
2007 "Trace with no wait at each step." | |
2008 (interactive) | |
2009 (edebug-set-mode 'Trace-fast | |
2010 "Trace fast..." "edebug will trace without pause.")) | |
2011 | |
2012 (defun edebug-continue () | |
2013 "Begin continue mode." | |
2014 (interactive) | |
2015 (edebug-set-mode 'continue "Continue..." | |
2016 "edebug will pause at breakpoints.")) | |
2017 | |
2018 (defun edebug-Continue-fast () | |
2019 "Trace with no wait at each step." | |
2020 (interactive) | |
2021 (edebug-set-mode 'Continue-fast "Continue fast..." | |
2022 "edebug will stop and go at breakpoints.")) | |
2023 | |
2024 | |
2025 (defun edebug-step-in () | |
2026 "Step into the function about to be called. | |
2027 Do this before the arguments are evaluated since otherwise it will be | |
2028 too late. One side effect of using edebug-step-in is that the next | |
2029 time the function is called, edebug will be called there as well." | |
2030 (interactive) | |
2031 (if (not (eq 'enter edebug-arg-mode)) | |
5126
30682388c4cf
Delete periods from error messages.
Richard M. Stallman <rms@gnu.org>
parents:
5125
diff
changeset
|
2032 (error "You must be in front of a function or macro call")) |
661 | 2033 (let* ((func (car edebug-exp)) |
2034 (func-marker (get func 'edebug))) | |
2035 (cond | |
2036 ((markerp func-marker) | |
2037 (save-excursion | |
2038 (set-buffer (marker-buffer func-marker)) | |
2039 (goto-char func-marker) | |
2040 (edebug-defun))) | |
2041 ((listp func-marker) | |
2042 ;; its already been evaluated for edebug | |
2043 nil) | |
5126
30682388c4cf
Delete periods from error messages.
Richard M. Stallman <rms@gnu.org>
parents:
5125
diff
changeset
|
2044 (t (error "You must first evaluate %s in a buffer" func)))) |
661 | 2045 (exit-recursive-edit)) |
2046 | |
2047 | |
2048 ;;(defun edebug-exit-out () | |
2049 ;; "Go until the current function exits." | |
2050 ;; (interactive) | |
2051 ;; (edebug-set-mode 'exiting "Exit...")) | |
2052 | |
2053 | |
2054 (defun edebug-stop () | |
2055 "Useful for exiting from trace loop." | |
2056 (interactive) | |
2057 (message "Stop")) | |
2058 | |
2059 | |
2060 ;;; The following initial mode setting definitions are not used yet. | |
2061 | |
2062 (defconst edebug-initial-mode-alist | |
2063 '((edebug-Continue-fast . Continue-fast) | |
2064 (edebug-Trace-fast . Trace-fast) | |
2065 (edebug-continue . continue) | |
2066 (edebug-trace . trace) | |
2067 (edebug-go . go) | |
2068 (edebug-step-through . step) | |
2069 (edebug-Go-nonstop . Go-nonstop) | |
2070 ) | |
2071 "Association list between commands and the modes they set.") | |
2072 | |
2073 | |
2074 (defun edebug-set-initial-mode () | |
2075 "Ask for the initial mode of the enclosing function. | |
2076 The mode is requested via the key that would be used to set the mode in | |
2077 edebug-mode." | |
2078 (interactive) | |
2079 (let* ((this-function (edebug-which-function)) | |
2080 (keymap (if (eq edebug-mode-map (current-local-map)) | |
2081 edebug-mode-map)) | |
2082 (old-mode (or (get this-function 'edebug-initial-mode) | |
2083 edebug-initial-mode)) | |
2084 (key (read-key-sequence | |
2085 (format | |
2086 "Change initial edebug mode for %s from %s (%s) to (enter key): " | |
2087 this-function | |
2088 old-mode | |
2089 (where-is-internal | |
2090 (car (rassq old-mode edebug-initial-mode-alist)) | |
2091 keymap 'firstonly | |
2092 )))) | |
2093 (mode (cdr (assq (key-binding key) edebug-initial-mode-alist))) | |
2094 ) | |
2095 (if (and mode | |
2096 (or (get this-function 'edebug-initial-mode) | |
2097 (not (eq mode edebug-initial-mode)))) | |
2098 (progn | |
2099 (put this-function 'edebug-initial-mode mode) | |
2100 (message "Initial mode for %s is now: %s" | |
2101 this-function mode)) | |
5126
30682388c4cf
Delete periods from error messages.
Richard M. Stallman <rms@gnu.org>
parents:
5125
diff
changeset
|
2102 (error "Key must map to one of the mode changing commands") |
661 | 2103 ))) |
2104 | |
2105 | |
2106 | |
2107 ;;-------------------------- | |
2108 ;; Evaluation of expressions | |
2109 | |
2110 (defvar edebug-previous-result nil | |
2111 "Last result returned from an expression.") | |
2112 | |
2113 (defun edebug-previous-result () | |
2114 "Return the previous result." | |
2115 (interactive) | |
2116 (let ((print-escape-newlines t) | |
2117 (print-length 20)) | |
2118 (message "Result: %s" (prin1-to-string edebug-previous-result)))) | |
2119 | |
2120 | |
2121 (defun edebug-eval (expr) | |
2122 "Evaluate EXPR in the outside environment." | |
2123 (if (not edebug-active) | |
5126
30682388c4cf
Delete periods from error messages.
Richard M. Stallman <rms@gnu.org>
parents:
5125
diff
changeset
|
2124 (error "edebug is not active")) |
661 | 2125 (edebug-outside-excursion |
2126 (eval expr))) | |
2127 | |
2128 (defun edebug-eval-expression (expr) | |
2129 "Prompt and evaluate an expression in the outside environment. | |
2130 Print result in minibuffer." | |
2131 (interactive "xEval: ") | |
2132 (prin1 (edebug-eval expr))) | |
2133 | |
2134 (defun edebug-eval-last-sexp () | |
2135 "Evaluate sexp before point in the outside environment; | |
2136 print value in minibuffer." | |
2137 (interactive) | |
2138 (prin1 (edebug-eval (edebug-last-sexp)))) | |
2139 | |
2140 (defun edebug-eval-print-last-sexp () | |
2141 "Evaluate sexp before point in the outside environment; | |
2142 print value into current buffer." | |
2143 (interactive) | |
2144 (let ((standard-output (current-buffer))) | |
2145 (print | |
2146 (condition-case err | |
2147 (edebug-eval (edebug-last-sexp)) | |
2148 (error (format "%s: %s" | |
2149 (get (car err) 'error-message) | |
2150 (car (cdr err)))))))) | |
2151 | |
2152 ;;;--------------------------------- | |
2153 ;;; edebug minor mode initialization | |
2154 | |
2155 (defvar edebug-mode 'step | |
2156 "Current edebug mode set by user.") | |
2157 | |
2158 (defvar edebug-mode-map nil) | |
2159 (if edebug-mode-map | |
2160 nil | |
2161 (progn | |
2162 (setq edebug-mode-map (copy-keymap emacs-lisp-mode-map)) | |
2163 ;; control | |
2164 (define-key edebug-mode-map " " 'edebug-step-through) | |
2165 (define-key edebug-mode-map "g" 'edebug-go) | |
2166 (define-key edebug-mode-map "G" 'edebug-Go-nonstop) | |
2167 (define-key edebug-mode-map "t" 'edebug-trace) | |
2168 (define-key edebug-mode-map "T" 'edebug-Trace-fast) | |
2169 (define-key edebug-mode-map "c" 'edebug-continue) | |
2170 (define-key edebug-mode-map "C" 'edebug-Continue-fast) | |
2171 | |
2172 (define-key edebug-mode-map "f" 'edebug-forward-sexp) | |
2173 (define-key edebug-mode-map "h" 'edebug-goto-here) | |
2174 | |
2175 (define-key edebug-mode-map "r" 'edebug-previous-result) | |
2176 | |
2177 (define-key edebug-mode-map "i" 'edebug-step-in) | |
2178 (define-key edebug-mode-map "o" 'edebug-step-out) | |
2179 | |
2180 ;; (define-key edebug-mode-map "m" 'edebug-set-initial-mode) | |
2181 | |
2182 (define-key edebug-mode-map "q" 'top-level) | |
2183 (define-key edebug-mode-map "a" 'abort-recursive-edit) | |
2184 (define-key edebug-mode-map "S" 'edebug-stop) | |
2185 | |
2186 ;; breakpoints | |
2187 (define-key edebug-mode-map "b" 'edebug-set-breakpoint) | |
2188 (define-key edebug-mode-map "u" 'edebug-unset-breakpoint) | |
2189 (define-key edebug-mode-map "B" 'edebug-next-breakpoint) | |
2190 (define-key edebug-mode-map "x" 'edebug-set-conditional-breakpoint) | |
2191 | |
2192 ;; evaluation | |
2193 (define-key edebug-mode-map "e" 'edebug-eval-expression) | |
2194 (define-key edebug-mode-map "\C-x\C-e" 'edebug-eval-last-sexp) | |
2195 (define-key edebug-mode-map "E" 'edebug-visit-eval-list) | |
2196 | |
2197 ;; views | |
2198 (define-key edebug-mode-map "w" 'edebug-where) | |
2199 (define-key edebug-mode-map "v" 'edebug-view-outside) | |
2200 (define-key edebug-mode-map "p" 'edebug-bounce-point) | |
2201 (define-key edebug-mode-map "W" 'edebug-toggle-save-windows) | |
2202 | |
2203 ;; misc | |
2204 (define-key edebug-mode-map "?" 'edebug-help) | |
2205 (define-key edebug-mode-map "d" 'edebug-backtrace) | |
2206 | |
2207 (define-key edebug-mode-map "-" 'negative-argument) | |
2208 )) | |
2209 | |
2629
137117f5c44c
* edebug.el (edebug-display): Call the `mark' function with the
Jim Blandy <jimb@redhat.com>
parents:
2307
diff
changeset
|
2210 ;;;###autoload |
661 | 2211 (defvar global-edebug-prefix "\^XX" |
2212 "Prefix key for global edebug commands, available from any buffer.") | |
2213 | |
2629
137117f5c44c
* edebug.el (edebug-display): Call the `mark' function with the
Jim Blandy <jimb@redhat.com>
parents:
2307
diff
changeset
|
2214 ;;;###autoload |
661 | 2215 (defvar global-edebug-map nil |
2216 "Global map of edebug commands, available from any buffer.") | |
2217 | |
2629
137117f5c44c
* edebug.el (edebug-display): Call the `mark' function with the
Jim Blandy <jimb@redhat.com>
parents:
2307
diff
changeset
|
2218 ;;;###autoload |
661 | 2219 (if global-edebug-map |
2220 nil | |
2221 (setq global-edebug-map (make-sparse-keymap)) | |
2222 | |
2223 (global-unset-key global-edebug-prefix) | |
2224 (global-set-key global-edebug-prefix global-edebug-map) | |
2225 | |
2226 ;; (define-key global-edebug-map "X" 'edebug-step-through) | |
2629
137117f5c44c
* edebug.el (edebug-display): Call the `mark' function with the
Jim Blandy <jimb@redhat.com>
parents:
2307
diff
changeset
|
2227 (define-key global-edebug-map "d" 'edebug-defun) |
661 | 2228 (define-key global-edebug-map " " 'edebug-step-through) |
2229 (define-key global-edebug-map "g" 'edebug-go) | |
2230 (define-key global-edebug-map "G" 'edebug-Go-nonstop) | |
2231 (define-key global-edebug-map "t" 'edebug-trace) | |
2232 (define-key global-edebug-map "T" 'edebug-Trace-fast) | |
2233 (define-key global-edebug-map "c" 'edebug-continue) | |
2234 (define-key global-edebug-map "C" 'edebug-Continue-fast) | |
2235 | |
2236 ;; (define-key global-edebug-map "m" 'edebug-set-initial-mode) | |
2237 (define-key global-edebug-map "b" 'edebug-set-breakpoint) | |
2238 (define-key global-edebug-map "x" 'edebug-set-conditional-breakpoint) | |
2239 (define-key global-edebug-map "u" 'edebug-unset-breakpoint) | |
2240 (define-key global-edebug-map "w" 'edebug-where) | |
2241 (define-key global-edebug-map "q" 'top-level) | |
2242 ) | |
2243 | |
2244 | |
2245 (defun edebug-help () | |
2246 (interactive) | |
2247 (describe-function 'edebug-mode)) | |
2248 | |
2249 | |
2250 (defun edebug-mode () | |
846
20674ae6bf52
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
2251 "Mode for Emacs Lisp buffers while in edebug. Under construction. |
661 | 2252 |
2253 There are both buffer local and global key bindings to several | |
2254 functions. E.g. edebug-step-through is bound to | |
2255 \\[edebug-step-through] in the debug buffer and | |
2256 \\<global-map>\\[edebug-step-through] in any buffer. | |
2257 | |
2258 edebug buffer commands: | |
2259 \\{edebug-mode-map} | |
2260 | |
2261 Global commands prefixed by global-edbug-prefix: | |
2262 \\{global-edebug-map} | |
2263 | |
2264 Options: | |
2265 edebug-all-defuns | |
2266 edebug-eval-macro-args | |
2267 edebug-stop-before-symbols | |
2268 edebug-save-windows | |
2269 edebug-save-point | |
2270 edebug-save-buffer-points | |
2271 edebug-initial-mode | |
2272 edebug-trace | |
2273 " | |
2274 (use-local-map edebug-mode-map)) | |
2275 | |
2276 | |
2277 | |
2278 ;;=============================================== | |
2279 ;; edebug eval list mode | |
2280 ;; A list of expressions and their evaluations is displayed | |
2281 ;; in edebug-eval-buffer | |
2282 | |
2283 (defvar edebug-eval-list nil | |
2284 "List of expressions to evaluate.") | |
2285 | |
2286 ;;(defvar edebug-eval-buffer "*edebug*" | |
2287 ;; "*Declared globally so edebug-eval-display can be called independent | |
2288 ;;of edebug (not implemented yet).") | |
2289 | |
2290 | |
2291 (defun edebug-eval-result-list () | |
2292 "Return a list of evaluations of edebug-eval-list" | |
2293 ;; Assumes in outside environment. | |
2294 (mapcar (function | |
2295 (lambda (expr) | |
2296 (condition-case err | |
2297 (eval expr) | |
2298 (error (format "%s: %s" | |
2299 (get (car err) 'error-message) | |
2300 (car (cdr err)))) | |
2301 ))) | |
2302 edebug-eval-list)) | |
2303 | |
2304 (defun edebug-eval-display-list (edebug-eval-result-list) | |
2305 ;; Assumes edebug-eval-buffer exists. | |
2306 (let ((edebug-eval-list-temp edebug-eval-list) | |
2307 (standard-output edebug-eval-buffer) | |
2308 (edebug-display-line | |
2309 (format ";%s\n" (make-string (- (window-width) 2) ?-)))) | |
2310 (edebug-pop-to-buffer edebug-eval-buffer) | |
2311 (erase-buffer) | |
2312 (while edebug-eval-list-temp | |
2313 (prin1 (car edebug-eval-list-temp)) (terpri) | |
2314 (prin1 (car edebug-eval-result-list)) (terpri) | |
2315 (princ edebug-display-line) | |
2316 (setq edebug-eval-list-temp (cdr edebug-eval-list-temp)) | |
2317 (setq edebug-eval-result-list (cdr edebug-eval-result-list))) | |
2318 )) | |
2319 | |
2320 (defun edebug-create-eval-buffer () | |
2321 (if (not (and edebug-eval-buffer (buffer-name edebug-eval-buffer))) | |
2322 (progn | |
2323 (set-buffer (setq edebug-eval-buffer (get-buffer-create "*edebug*"))) | |
2324 (edebug-eval-mode)))) | |
2325 | |
2326 ;; Should generalize this to be callable outside of edebug | |
2327 ;; with calls in user functions, e.g. (edebug-eval-display) | |
2328 | |
2329 (defun edebug-eval-display (edebug-eval-result-list) | |
2330 "Display expressions and evaluations in EVAL-LIST. | |
2331 It modifies the context by popping up the eval display." | |
2332 (if edebug-eval-result-list | |
2333 (progn | |
2334 (edebug-create-eval-buffer) | |
2335 (edebug-pop-to-buffer edebug-eval-buffer) | |
2336 (edebug-eval-display-list edebug-eval-result-list) | |
2337 ))) | |
2338 | |
2339 (defun edebug-eval-redisplay () | |
2340 "Redisplay eval list in outside environment. | |
2341 May only be called from within edebug-recursive-edit." | |
2342 (edebug-create-eval-buffer) | |
2343 (edebug-pop-to-buffer edebug-eval-buffer) | |
2344 (edebug-outside-excursion | |
2345 (edebug-eval-display-list (edebug-eval-result-list)) | |
2346 )) | |
2347 | |
2348 (defun edebug-visit-eval-list () | |
2349 (interactive) | |
2350 (edebug-eval-redisplay) | |
2351 (edebug-pop-to-buffer edebug-eval-buffer)) | |
2352 | |
2353 | |
2354 (defun edebug-update-eval-list () | |
2355 "Replace the evaluation list with the sexps now in the eval buffer." | |
2356 (interactive) | |
2357 (let ((starting-point (point)) | |
2358 new-list) | |
2359 (goto-char (point-min)) | |
2360 ;; get the first expression | |
2361 (edebug-skip-whitespace) | |
2362 (if (not (eobp)) | |
2363 (progn | |
2364 (forward-sexp 1) | |
2365 (setq new-list (cons (edebug-last-sexp) new-list)))) | |
2366 | |
2367 (while (re-search-forward "^;" nil t) | |
2368 (forward-line 1) | |
2369 (skip-chars-forward " \t\n\r") | |
2370 (if (and (/= ?\; (following-char)) | |
2371 (not (eobp))) | |
2372 (progn | |
2373 (forward-sexp 1) | |
2374 (setq new-list (cons (edebug-last-sexp) new-list))))) | |
2375 | |
2376 (setq edebug-eval-list (nreverse new-list)) | |
2377 (edebug-eval-redisplay) | |
2378 (goto-char starting-point))) | |
2379 | |
2380 | |
2381 (defun edebug-delete-eval-item () | |
2382 "Delete the item under point and redisplay." | |
2383 ;; could add arg to do repeatedly | |
2384 (interactive) | |
2385 (if (re-search-backward "^;" nil 'nofail) | |
2386 (forward-line 1)) | |
2387 (delete-region | |
2388 (point) (progn (re-search-forward "^;" nil 'nofail) | |
2389 (beginning-of-line) | |
2390 (point))) | |
2391 (edebug-update-eval-list)) | |
2392 | |
2393 | |
2394 | |
2395 (defvar edebug-eval-mode-map nil | |
2396 "Keymap for edebug-eval-mode. Superset of lisp-interaction-mode.") | |
2397 | |
2398 (if edebug-eval-mode-map | |
2399 nil | |
2400 (setq edebug-eval-mode-map (copy-keymap lisp-interaction-mode-map)) | |
2401 | |
2402 (define-key edebug-eval-mode-map "\C-c\C-w" 'edebug-where) | |
2403 (define-key edebug-eval-mode-map "\C-c\C-d" 'edebug-delete-eval-item) | |
2404 (define-key edebug-eval-mode-map "\C-c\C-u" 'edebug-update-eval-list) | |
2405 (define-key edebug-eval-mode-map "\C-x\C-e" 'edebug-eval-last-sexp) | |
2406 (define-key edebug-eval-mode-map "\C-j" 'edebug-eval-print-last-sexp) | |
2407 ) | |
2408 | |
2409 | |
2410 (defun edebug-eval-mode () | |
2411 "Mode for data display buffer while in edebug. Under construction. | |
2412 ... ignore the following... | |
2413 There are both buffer local and global key bindings to several | |
2414 functions. E.g. edebug-step-through is bound to | |
2415 \\[edebug-step-through] in the debug buffer and | |
2416 \\<global-map>\\[edebug-step-through] in any buffer. | |
2417 | |
2418 Eval list buffer commands: | |
2419 \\{edebug-eval-mode-map} | |
2420 | |
2421 Global commands prefixed by global-edbug-prefix: | |
2422 \\{global-edebug-map} | |
2423 " | |
2424 (lisp-interaction-mode) | |
2425 (setq major-mode 'edebug-eval-mode) | |
2426 (setq mode-name "Edebug-Eval") | |
2427 (use-local-map edebug-eval-mode-map)) | |
2428 | |
2429 | |
2430 ;;======================================== | |
2431 ;; Interface with standard debugger. | |
2432 | |
2433 (setq debugger 'edebug-debug) | |
2434 ;; (setq debugger 'debug) ; use the default | |
2435 | |
2436 ;; Note that debug and its utilities must be byte-compiled to work, since | |
2437 ;; they depend on the backtrace looking a certain way. | |
2438 | |
727 | 2439 ;;;###autoload |
661 | 2440 (defun edebug-debug (&rest debugger-args) |
2441 "Replacement for debug. | |
2442 If an error or quit occurred and we are running an edebugged function, | |
2443 show where we last were. Otherwise call debug normally." | |
2444 (if (and edebug-backtrace ; anything active? | |
2445 (eq (recursion-depth) edebug-recursion-depth) | |
2446 ) | |
2447 | |
2448 ;; Where were we before the error occurred? | |
2449 (let ((edebug-offset-index (car edebug-offset-indices)) | |
2450 (edebug-arg-mode (car debugger-args)) | |
2451 (edebug-exp (car (cdr debugger-args))) | |
2452 edebug-break-data | |
2453 edebug-break | |
2454 (edebug-outside-debug-on-eror debug-on-error) | |
2455 (debug-on-error nil)) | |
2456 (edebug-display) | |
2457 ) | |
2458 | |
2459 ;; Otherwise call debug normally. | |
2460 ;; Still need to remove extraneous edebug calls from stack. | |
2461 (apply 'debug debugger-args) | |
2462 )) | |
2463 | |
2464 | |
2465 (defun edebug-backtrace () | |
2466 "Display a non-working backtrace. Better than nothing..." | |
2467 (interactive) | |
2468 (let ((old-buf (current-buffer))) | |
2469 (if (not edebug-backtrace-buffer) | |
2470 (setq edebug-backtrace-buffer | |
2471 (let ((default-major-mode 'fundamental-mode)) | |
2472 (generate-new-buffer "*Backtrace*")))) | |
2473 (edebug-pop-to-buffer edebug-backtrace-buffer) | |
2474 (erase-buffer) | |
2475 (let ((standard-output (current-buffer)) | |
2476 (print-escape-newlines t) | |
2477 (print-length 50) | |
2478 last-ok-point | |
2479 ) | |
2480 (setq truncate-lines t) | |
2481 (backtrace) | |
2482 | |
2483 ;; Clean up the backtrace. | |
2484 (goto-char (point-min)) | |
2485 (delete-region | |
2486 (point) | |
2487 (progn | |
2488 ;; Everything up to the first edebug is internal. | |
2489 (re-search-forward "^ edebug(") | |
2490 (forward-line 1) | |
2491 (point))) | |
2492 (forward-line 1) | |
2493 (setq last-ok-point (point)) | |
2494 | |
2495 ;; Delete interspersed edebug internals. | |
2496 (while (re-search-forward "^ edebug" nil t) | |
2497 (if (looking-at "-enter") | |
2498 ;; delete extraneous progn at top level of function body | |
2499 (save-excursion | |
2500 (goto-char last-ok-point) | |
2501 (forward-line -1) | |
2502 (setq last-ok-point (point)))) | |
2503 (forward-line 1) | |
2504 (delete-region last-ok-point (point)) | |
2505 (forward-line 1) ; skip past the good line | |
2506 (setq last-ok-point (point)) | |
2507 ) | |
2508 ) | |
2509 (edebug-pop-to-buffer old-buf) | |
2510 )) | |
2511 | |
2512 | |
2513 ;;======================================================================== | |
2514 ;; Trace display - append text to a buffer, and update display. | |
2515 ;;; e.g. | |
2516 ;;; (edebug-trace-display | |
2517 ;;; "*trace-point*" | |
2518 ;;; "saving: point = %s window-start = %s\n" | |
2519 ;;; (point) (window-start)) | |
2520 | |
2521 (defun edebug-trace-display (buf-name fmt &rest args) | |
2522 "In buffer BUF-NAME, display FMT and ARGS at the end and make it visible. | |
2523 The buffer is created if it does not exist. | |
2524 You must include newlines in FMT to break lines." | |
2525 (let* ((selected-window (selected-window)) | |
2526 (buffer (get-buffer-create buf-name)) | |
2527 (buf-window)) | |
2528 (edebug-pop-to-buffer buffer) | |
2529 (save-excursion | |
2530 (setq buf-window (selected-window)) | |
2531 (set-buffer buffer) | |
2532 (goto-char (point-max)) | |
2533 (insert (apply 'format fmt args)) | |
2534 (set-window-point buf-window (point)) | |
2535 (forward-line (- 1 (window-height buf-window))) | |
2536 (set-window-start buf-window (point)) | |
2537 ;; (edebug-sit-for 1) | |
2538 (bury-buffer buffer) | |
2539 ) | |
2540 (select-window selected-window))) | |
2541 | |
3350 | 2542 (provide 'edebug) |
2543 | |
661 | 2544 ;;; edebug.el ends here |