aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorStefan Monnier2013-07-26 03:38:18 -0400
committerStefan Monnier2013-07-26 03:38:18 -0400
commit56ea72917a7a700e29cf6c115fd1cd75ad782e9e (patch)
tree1a9220717c6333b376d45ebc044ad8ed71cfda37 /lisp
parentf6b1502430653fac080f76a08edd2eb690f92146 (diff)
downloademacs-56ea72917a7a700e29cf6c115fd1cd75ad782e9e.tar.gz
emacs-56ea72917a7a700e29cf6c115fd1cd75ad782e9e.zip
Add support for lexical variables to the debugger's `e' command.
* lisp/emacs-lisp/debug.el (debug): Don't let-bind the debugger-outer-* vars, except for debugger-outer-match-data. (debugger-frame-number): Move check for "on a function call" from callers into it. Add `skip-base' argument. (debugger-frame, debugger-frame-clear): Simplify accordingly. (debugger-env-macro): Only reset the state stored in non-variables, i.e. current-buffer and match-data. (debugger-eval-expression): Rewrite using backtrace-eval. * lisp/subr.el (internal--called-interactively-p--get-frame): Remove. (called-interactively-p): * lisp/emacs-lisp/edebug.el (edebug--called-interactively-skip): Use the new `base' arg of backtrace-frame instead. * src/eval.c (set_specpdl_old_value): New function. (unbind_to): Minor simplification. (get_backtrace_frame): New function. (Fbacktrace_frame): Use it. Add `base' argument. (backtrace_eval_unrewind, Fbacktrace_eval): New functions. (syms_of_eval): Export backtrace-eval. * src/xterm.c (x_focus_changed): Simplify.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog16
-rw-r--r--lisp/emacs-lisp/debug.el145
-rw-r--r--lisp/emacs-lisp/edebug.el2
-rw-r--r--lisp/subr.el18
4 files changed, 48 insertions, 133 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 79582ea560a..84919e634be 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,19 @@
12013-07-26 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 Add support for lexical variables to the debugger's `e' command.
4 * emacs-lisp/debug.el (debug): Don't let-bind the debugger-outer-*
5 vars, except for debugger-outer-match-data.
6 (debugger-frame-number): Move check for "on a function call" from
7 callers into it. Add `skip-base' argument.
8 (debugger-frame, debugger-frame-clear): Simplify accordingly.
9 (debugger-env-macro): Only reset the state stored in non-variables,
10 i.e. current-buffer and match-data.
11 (debugger-eval-expression): Rewrite using backtrace-eval.
12 * subr.el (internal--called-interactively-p--get-frame): Remove.
13 (called-interactively-p):
14 * emacs-lisp/edebug.el (edebug--called-interactively-skip): Use the new
15 `base' arg of backtrace-frame instead.
16
12013-07-26 Glenn Morris <rgm@gnu.org> 172013-07-26 Glenn Morris <rgm@gnu.org>
2 18
3 * align.el (align-regexp): Doc fix. (Bug#14857) 19 * align.el (align-regexp): Doc fix. (Bug#14857)
diff --git a/lisp/emacs-lisp/debug.el b/lisp/emacs-lisp/debug.el
index 0728e86d072..aee48eef668 100644
--- a/lisp/emacs-lisp/debug.el
+++ b/lisp/emacs-lisp/debug.el
@@ -102,22 +102,6 @@ The value used here is passed to `quit-restore-window'."
102This is to optimize `debugger-make-xrefs'.") 102This is to optimize `debugger-make-xrefs'.")
103 103
104(defvar debugger-outer-match-data) 104(defvar debugger-outer-match-data)
105(defvar debugger-outer-load-read-function)
106(defvar debugger-outer-overriding-local-map)
107(defvar debugger-outer-overriding-terminal-local-map)
108(defvar debugger-outer-track-mouse)
109(defvar debugger-outer-last-command)
110(defvar debugger-outer-this-command)
111(defvar debugger-outer-unread-command-events)
112(defvar debugger-outer-unread-post-input-method-events)
113(defvar debugger-outer-last-input-event)
114(defvar debugger-outer-last-command-event)
115(defvar debugger-outer-last-nonmenu-event)
116(defvar debugger-outer-last-event-frame)
117(defvar debugger-outer-standard-input)
118(defvar debugger-outer-standard-output)
119(defvar debugger-outer-inhibit-redisplay)
120(defvar debugger-outer-cursor-in-echo-area)
121(defvar debugger-will-be-back nil 105(defvar debugger-will-be-back nil
122 "Non-nil if we expect to get back in the debugger soon.") 106 "Non-nil if we expect to get back in the debugger soon.")
123 107
@@ -174,24 +158,6 @@ first will be printed into the backtrace buffer."
174 ;; Save the outer values of these vars for the `e' command 158 ;; Save the outer values of these vars for the `e' command
175 ;; before we replace the values. 159 ;; before we replace the values.
176 (debugger-outer-match-data (match-data)) 160 (debugger-outer-match-data (match-data))
177 (debugger-outer-load-read-function load-read-function)
178 (debugger-outer-overriding-local-map overriding-local-map)
179 (debugger-outer-overriding-terminal-local-map
180 overriding-terminal-local-map)
181 (debugger-outer-track-mouse track-mouse)
182 (debugger-outer-last-command last-command)
183 (debugger-outer-this-command this-command)
184 (debugger-outer-unread-command-events unread-command-events)
185 (debugger-outer-unread-post-input-method-events
186 unread-post-input-method-events)
187 (debugger-outer-last-input-event last-input-event)
188 (debugger-outer-last-command-event last-command-event)
189 (debugger-outer-last-nonmenu-event last-nonmenu-event)
190 (debugger-outer-last-event-frame last-event-frame)
191 (debugger-outer-standard-input standard-input)
192 (debugger-outer-standard-output standard-output)
193 (debugger-outer-inhibit-redisplay inhibit-redisplay)
194 (debugger-outer-cursor-in-echo-area cursor-in-echo-area)
195 (debugger-with-timeout-suspend (with-timeout-suspend))) 161 (debugger-with-timeout-suspend (with-timeout-suspend)))
196 ;; Set this instead of binding it, so that `q' 162 ;; Set this instead of binding it, so that `q'
197 ;; will not restore it. 163 ;; will not restore it.
@@ -294,26 +260,6 @@ first will be printed into the backtrace buffer."
294 (funcall (nth 0 debugger-previous-state)))))) 260 (funcall (nth 0 debugger-previous-state))))))
295 (with-timeout-unsuspend debugger-with-timeout-suspend) 261 (with-timeout-unsuspend debugger-with-timeout-suspend)
296 (set-match-data debugger-outer-match-data))) 262 (set-match-data debugger-outer-match-data)))
297 ;; Put into effect the modified values of these variables
298 ;; in case the user set them with the `e' command.
299 (setq load-read-function debugger-outer-load-read-function)
300 (setq overriding-local-map debugger-outer-overriding-local-map)
301 (setq overriding-terminal-local-map
302 debugger-outer-overriding-terminal-local-map)
303 (setq track-mouse debugger-outer-track-mouse)
304 (setq last-command debugger-outer-last-command)
305 (setq this-command debugger-outer-this-command)
306 (setq unread-command-events debugger-outer-unread-command-events)
307 (setq unread-post-input-method-events
308 debugger-outer-unread-post-input-method-events)
309 (setq last-input-event debugger-outer-last-input-event)
310 (setq last-command-event debugger-outer-last-command-event)
311 (setq last-nonmenu-event debugger-outer-last-nonmenu-event)
312 (setq last-event-frame debugger-outer-last-event-frame)
313 (setq standard-input debugger-outer-standard-input)
314 (setq standard-output debugger-outer-standard-output)
315 (setq inhibit-redisplay debugger-outer-inhibit-redisplay)
316 (setq cursor-in-echo-area debugger-outer-cursor-in-echo-area)
317 (setq debug-on-next-call debugger-step-after-exit) 263 (setq debug-on-next-call debugger-step-after-exit)
318 debugger-value))) 264 debugger-value)))
319 265
@@ -518,18 +464,21 @@ removes itself from that hook."
518 (setq debugger-jumping-flag nil) 464 (setq debugger-jumping-flag nil)
519 (remove-hook 'post-command-hook 'debugger-reenable)) 465 (remove-hook 'post-command-hook 'debugger-reenable))
520 466
521(defun debugger-frame-number () 467(defun debugger-frame-number (&optional skip-base)
522 "Return number of frames in backtrace before the one point points at." 468 "Return number of frames in backtrace before the one point points at."
523 (save-excursion 469 (save-excursion
524 (beginning-of-line) 470 (beginning-of-line)
471 (if (looking-at " *;;;\\|[a-z]")
472 (error "This line is not a function call"))
525 (let ((opoint (point)) 473 (let ((opoint (point))
526 (count 0)) 474 (count 0))
527 (while (not (eq (cadr (backtrace-frame count)) 'debug)) 475 (unless skip-base
528 (setq count (1+ count))) 476 (while (not (eq (cadr (backtrace-frame count)) 'debug))
529 ;; Skip debug--implement-debug-on-entry frame. 477 (setq count (1+ count)))
530 (when (eq 'debug--implement-debug-on-entry 478 ;; Skip debug--implement-debug-on-entry frame.
531 (cadr (backtrace-frame (1+ count)))) 479 (when (eq 'debug--implement-debug-on-entry
532 (setq count (+ 2 count))) 480 (cadr (backtrace-frame (1+ count))))
481 (setq count (+ 2 count))))
533 (goto-char (point-min)) 482 (goto-char (point-min))
534 (when (looking-at "Debugger entered--\\(Lisp error\\|returning value\\):") 483 (when (looking-at "Debugger entered--\\(Lisp error\\|returning value\\):")
535 (goto-char (match-end 0)) 484 (goto-char (match-end 0))
@@ -551,12 +500,8 @@ removes itself from that hook."
551 "Request entry to debugger when this frame exits. 500 "Request entry to debugger when this frame exits.
552Applies to the frame whose line point is on in the backtrace." 501Applies to the frame whose line point is on in the backtrace."
553 (interactive) 502 (interactive)
554 (save-excursion
555 (beginning-of-line)
556 (if (looking-at " *;;;\\|[a-z]")
557 (error "This line is not a function call")))
558 (beginning-of-line)
559 (backtrace-debug (debugger-frame-number) t) 503 (backtrace-debug (debugger-frame-number) t)
504 (beginning-of-line)
560 (if (= (following-char) ? ) 505 (if (= (following-char) ? )
561 (let ((inhibit-read-only t)) 506 (let ((inhibit-read-only t))
562 (delete-char 1) 507 (delete-char 1)
@@ -567,12 +512,8 @@ Applies to the frame whose line point is on in the backtrace."
567 "Do not enter debugger when this frame exits. 512 "Do not enter debugger when this frame exits.
568Applies to the frame whose line point is on in the backtrace." 513Applies to the frame whose line point is on in the backtrace."
569 (interactive) 514 (interactive)
570 (save-excursion
571 (beginning-of-line)
572 (if (looking-at " *;;;\\|[a-z]")
573 (error "This line is not a function call")))
574 (beginning-of-line)
575 (backtrace-debug (debugger-frame-number) nil) 515 (backtrace-debug (debugger-frame-number) nil)
516 (beginning-of-line)
576 (if (= (following-char) ?*) 517 (if (= (following-char) ?*)
577 (let ((inhibit-read-only t)) 518 (let ((inhibit-read-only t))
578 (delete-char 1) 519 (delete-char 1)
@@ -583,59 +524,33 @@ Applies to the frame whose line point is on in the backtrace."
583 "Run BODY in original environment." 524 "Run BODY in original environment."
584 (declare (indent 0)) 525 (declare (indent 0))
585 `(save-excursion 526 `(save-excursion
586 (if (null (buffer-name debugger-old-buffer)) 527 (if (null (buffer-live-p debugger-old-buffer))
587 ;; old buffer deleted 528 ;; old buffer deleted
588 (setq debugger-old-buffer (current-buffer))) 529 (setq debugger-old-buffer (current-buffer)))
589 (set-buffer debugger-old-buffer) 530 (set-buffer debugger-old-buffer)
590 (let ((load-read-function debugger-outer-load-read-function) 531 (set-match-data debugger-outer-match-data)
591 (overriding-terminal-local-map 532 (prog1
592 debugger-outer-overriding-terminal-local-map) 533 (progn ,@body)
593 (overriding-local-map debugger-outer-overriding-local-map) 534 (setq debugger-outer-match-data (match-data)))))
594 (track-mouse debugger-outer-track-mouse)
595 (last-command debugger-outer-last-command)
596 (this-command debugger-outer-this-command)
597 (unread-command-events debugger-outer-unread-command-events)
598 (unread-post-input-method-events
599 debugger-outer-unread-post-input-method-events)
600 (last-input-event debugger-outer-last-input-event)
601 (last-command-event debugger-outer-last-command-event)
602 (last-nonmenu-event debugger-outer-last-nonmenu-event)
603 (last-event-frame debugger-outer-last-event-frame)
604 (standard-input debugger-outer-standard-input)
605 (standard-output debugger-outer-standard-output)
606 (inhibit-redisplay debugger-outer-inhibit-redisplay)
607 (cursor-in-echo-area debugger-outer-cursor-in-echo-area))
608 (set-match-data debugger-outer-match-data)
609 (prog1
610 (progn ,@body)
611 (setq debugger-outer-match-data (match-data))
612 (setq debugger-outer-load-read-function load-read-function)
613 (setq debugger-outer-overriding-terminal-local-map
614 overriding-terminal-local-map)
615 (setq debugger-outer-overriding-local-map overriding-local-map)
616 (setq debugger-outer-track-mouse track-mouse)
617 (setq debugger-outer-last-command last-command)
618 (setq debugger-outer-this-command this-command)
619 (setq debugger-outer-unread-command-events unread-command-events)
620 (setq debugger-outer-unread-post-input-method-events
621 unread-post-input-method-events)
622 (setq debugger-outer-last-input-event last-input-event)
623 (setq debugger-outer-last-command-event last-command-event)
624 (setq debugger-outer-last-nonmenu-event last-nonmenu-event)
625 (setq debugger-outer-last-event-frame last-event-frame)
626 (setq debugger-outer-standard-input standard-input)
627 (setq debugger-outer-standard-output standard-output)
628 (setq debugger-outer-inhibit-redisplay inhibit-redisplay)
629 (setq debugger-outer-cursor-in-echo-area cursor-in-echo-area)
630 ))))
631 535
632(defun debugger-eval-expression (exp) 536(defun debugger-eval-expression (exp)
633 "Eval an expression, in an environment like that outside the debugger." 537 "Eval an expression, in an environment like that outside the debugger.
538The environment used is the one when entering the activation frame at point."
634 (interactive 539 (interactive
635 (list (read-from-minibuffer "Eval: " 540 (list (read-from-minibuffer "Eval: "
636 nil read-expression-map t 541 nil read-expression-map t
637 'read-expression-history))) 542 'read-expression-history)))
638 (debugger-env-macro (eval-expression exp))) 543 (let ((nframe (condition-case nil (1+ (debugger-frame-number 'skip-base))
544 (error 0))) ;; If on first line.
545 (base (if (eq 'debug--implement-debug-on-entry
546 (cadr (backtrace-frame 1 'debug)))
547 'debug--implement-debug-on-entry 'debug)))
548 (debugger-env-macro
549 (let ((val (backtrace-eval exp nframe base)))
550 (prog1
551 (prin1 val t)
552 (let ((str (eval-expression-print-format val)))
553 (if str (princ str t))))))))
639 554
640(defvar debugger-mode-map 555(defvar debugger-mode-map
641 (let ((map (make-keymap)) 556 (let ((map (make-keymap))
diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el
index 36c72f3a3bd..7771c3adaa4 100644
--- a/lisp/emacs-lisp/edebug.el
+++ b/lisp/emacs-lisp/edebug.el
@@ -4268,7 +4268,7 @@ With prefix argument, make it a temporary breakpoint."
4268 (eq (nth 1 (nth 1 frame1)) '()) 4268 (eq (nth 1 (nth 1 frame1)) '())
4269 (eq (nth 1 frame2) 'edebug-enter)) 4269 (eq (nth 1 frame2) 'edebug-enter))
4270 ;; `edebug-enter' calls itself on its first invocation. 4270 ;; `edebug-enter' calls itself on its first invocation.
4271 (if (eq (nth 1 (internal--called-interactively-p--get-frame i)) 4271 (if (eq (nth 1 (backtrace-frame i 'called-interactively-p))
4272 'edebug-enter) 4272 'edebug-enter)
4273 2 1))) 4273 2 1)))
4274 4274
diff --git a/lisp/subr.el b/lisp/subr.el
index 7130639dbe5..3b85a9bedb0 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -4191,22 +4191,6 @@ I is the index of the frame after FRAME2. It should return nil
4191if those frames don't seem special and otherwise, it should return 4191if those frames don't seem special and otherwise, it should return
4192the number of frames to skip (minus 1).") 4192the number of frames to skip (minus 1).")
4193 4193
4194(defmacro internal--called-interactively-p--get-frame (n)
4195 ;; `sym' will hold a global variable, which will be used kind of like C's
4196 ;; "static" variables.
4197 (let ((sym (make-symbol "base-index")))
4198 `(progn
4199 (defvar ,sym)
4200 (unless (boundp ',sym)
4201 (let ((i 1))
4202 (while (not (eq (indirect-function (nth 1 (backtrace-frame i)) t)
4203 (indirect-function 'called-interactively-p)))
4204 (setq i (1+ i)))
4205 (setq ,sym i)))
4206 ;; (unless (eq (nth 1 (backtrace-frame ,sym)) 'called-interactively-p)
4207 ;; (error "called-interactively-p: %s is out-of-sync!" ,sym))
4208 (backtrace-frame (+ ,sym ,n)))))
4209
4210(defun called-interactively-p (&optional kind) 4194(defun called-interactively-p (&optional kind)
4211 "Return t if the containing function was called by `call-interactively'. 4195 "Return t if the containing function was called by `call-interactively'.
4212If KIND is `interactive', then only return t if the call was made 4196If KIND is `interactive', then only return t if the call was made
@@ -4241,7 +4225,7 @@ command is called from a keyboard macro?"
4241 (get-next-frame 4225 (get-next-frame
4242 (lambda () 4226 (lambda ()
4243 (setq frame nextframe) 4227 (setq frame nextframe)
4244 (setq nextframe (internal--called-interactively-p--get-frame i)) 4228 (setq nextframe (backtrace-frame i 'called-interactively-p))
4245 ;; (message "Frame %d = %S" i nextframe) 4229 ;; (message "Frame %d = %S" i nextframe)
4246 (setq i (1+ i))))) 4230 (setq i (1+ i)))))
4247 (funcall get-next-frame) ;; Get the first frame. 4231 (funcall get-next-frame) ;; Get the first frame.