Support resizing frames and windows pixelwise.
[bpt/emacs.git] / lisp / emacs-lisp / debug.el
index 0728e86..aa5b25b 100644 (file)
@@ -102,22 +102,6 @@ The value used here is passed to `quit-restore-window'."
 This is to optimize `debugger-make-xrefs'.")
 
 (defvar debugger-outer-match-data)
-(defvar debugger-outer-load-read-function)
-(defvar debugger-outer-overriding-local-map)
-(defvar debugger-outer-overriding-terminal-local-map)
-(defvar debugger-outer-track-mouse)
-(defvar debugger-outer-last-command)
-(defvar debugger-outer-this-command)
-(defvar debugger-outer-unread-command-events)
-(defvar debugger-outer-unread-post-input-method-events)
-(defvar debugger-outer-last-input-event)
-(defvar debugger-outer-last-command-event)
-(defvar debugger-outer-last-nonmenu-event)
-(defvar debugger-outer-last-event-frame)
-(defvar debugger-outer-standard-input)
-(defvar debugger-outer-standard-output)
-(defvar debugger-outer-inhibit-redisplay)
-(defvar debugger-outer-cursor-in-echo-area)
 (defvar debugger-will-be-back nil
   "Non-nil if we expect to get back in the debugger soon.")
 
@@ -174,24 +158,6 @@ first will be printed into the backtrace buffer."
          ;; Save the outer values of these vars for the `e' command
          ;; before we replace the values.
          (debugger-outer-match-data (match-data))
-         (debugger-outer-load-read-function load-read-function)
-         (debugger-outer-overriding-local-map overriding-local-map)
-         (debugger-outer-overriding-terminal-local-map
-          overriding-terminal-local-map)
-         (debugger-outer-track-mouse track-mouse)
-         (debugger-outer-last-command last-command)
-         (debugger-outer-this-command this-command)
-         (debugger-outer-unread-command-events unread-command-events)
-         (debugger-outer-unread-post-input-method-events
-          unread-post-input-method-events)
-         (debugger-outer-last-input-event last-input-event)
-         (debugger-outer-last-command-event last-command-event)
-         (debugger-outer-last-nonmenu-event last-nonmenu-event)
-         (debugger-outer-last-event-frame last-event-frame)
-         (debugger-outer-standard-input standard-input)
-         (debugger-outer-standard-output standard-output)
-         (debugger-outer-inhibit-redisplay inhibit-redisplay)
-         (debugger-outer-cursor-in-echo-area cursor-in-echo-area)
          (debugger-with-timeout-suspend (with-timeout-suspend)))
       ;; Set this instead of binding it, so that `q'
       ;; will not restore it.
@@ -238,7 +204,7 @@ first will be printed into the backtrace buffer."
                        (window-resize
                         debugger-window
                         (- debugger-previous-window-height
-                           (window-total-size debugger-window)))
+                           (window-total-height debugger-window)))
                      (error nil)))
                (setq debugger-previous-window debugger-window))
              (debugger-mode)
@@ -270,7 +236,7 @@ first will be printed into the backtrace buffer."
                     (eq (window-buffer debugger-window) debugger-buffer))
            ;; Record height of debugger window.
            (setq debugger-previous-window-height
-                 (window-total-size debugger-window)))
+                 (window-total-height debugger-window)))
          (if debugger-will-be-back
              ;; Restore previous window configuration (Bug#12623).
              (set-window-configuration window-configuration)
@@ -294,26 +260,6 @@ first will be printed into the backtrace buffer."
                  (funcall (nth 0 debugger-previous-state))))))
          (with-timeout-unsuspend debugger-with-timeout-suspend)
          (set-match-data debugger-outer-match-data)))
-      ;; Put into effect the modified values of these variables
-      ;; in case the user set them with the `e' command.
-      (setq load-read-function debugger-outer-load-read-function)
-      (setq overriding-local-map debugger-outer-overriding-local-map)
-      (setq overriding-terminal-local-map
-           debugger-outer-overriding-terminal-local-map)
-      (setq track-mouse debugger-outer-track-mouse)
-      (setq last-command debugger-outer-last-command)
-      (setq this-command debugger-outer-this-command)
-      (setq unread-command-events debugger-outer-unread-command-events)
-      (setq unread-post-input-method-events
-           debugger-outer-unread-post-input-method-events)
-      (setq last-input-event debugger-outer-last-input-event)
-      (setq last-command-event debugger-outer-last-command-event)
-      (setq last-nonmenu-event debugger-outer-last-nonmenu-event)
-      (setq last-event-frame debugger-outer-last-event-frame)
-      (setq standard-input debugger-outer-standard-input)
-      (setq standard-output debugger-outer-standard-output)
-      (setq inhibit-redisplay debugger-outer-inhibit-redisplay)
-      (setq cursor-in-echo-area debugger-outer-cursor-in-echo-area)
       (setq debug-on-next-call debugger-step-after-exit)
       debugger-value)))
 \f
@@ -342,33 +288,41 @@ That buffer should be current already."
   (insert "Debugger entered")
   ;; lambda is for debug-on-call when a function call is next.
   ;; debug is for debug-on-entry function called.
-  (pcase (car args)
-    ((or `lambda `debug)
-     (insert "--entering a function:\n"))
-    ;; Exiting a function.
-    (`exit
-     (insert "--returning value: ")
-     (setq debugger-value (nth 1 args))
-     (prin1 debugger-value (current-buffer))
-     (insert ?\n)
-     (delete-char 1)
-     (insert ? )
-     (beginning-of-line))
-    ;; Debugger entered for an error.
-    (`error
-     (insert "--Lisp error: ")
-     (prin1 (nth 1 args) (current-buffer))
-     (insert ?\n))
-    ;; debug-on-call, when the next thing is an eval.
-    (`t
-     (insert "--beginning evaluation of function call form:\n"))
-    ;; User calls debug directly.
-    (_
-     (insert ": ")
-     (prin1 (if (eq (car args) 'nil)
-                (cdr args) args)
-            (current-buffer))
-     (insert ?\n)))
+  (let ((pos (point)))
+    (pcase (car args)
+      ((or `lambda `debug)
+       (insert "--entering a function:\n")
+       (setq pos (1- (point))))
+      ;; Exiting a function.
+      (`exit
+       (insert "--returning value: ")
+       (setq pos (point))
+       (setq debugger-value (nth 1 args))
+       (prin1 debugger-value (current-buffer))
+       (insert ?\n)
+       (delete-char 1)
+       (insert ? )
+       (beginning-of-line))
+      ;; Debugger entered for an error.
+      (`error
+       (insert "--Lisp error: ")
+       (setq pos (point))
+       (prin1 (nth 1 args) (current-buffer))
+       (insert ?\n))
+      ;; debug-on-call, when the next thing is an eval.
+      (`t
+       (insert "--beginning evaluation of function call form:\n")
+       (setq pos (1- (point))))
+      ;; User calls debug directly.
+      (_
+       (insert ": ")
+       (setq pos (point))
+       (prin1 (if (eq (car args) 'nil)
+                  (cdr args) args)
+              (current-buffer))
+       (insert ?\n)))
+    ;; Place point on "stack frame 0" (bug#15101).
+    (goto-char pos))
   ;; After any frame that uses eval-buffer,
   ;; insert a line that states the buffer position it's reading at.
   (save-excursion
@@ -518,18 +472,21 @@ removes itself from that hook."
   (setq debugger-jumping-flag nil)
   (remove-hook 'post-command-hook 'debugger-reenable))
 
-(defun debugger-frame-number ()
+(defun debugger-frame-number (&optional skip-base)
   "Return number of frames in backtrace before the one point points at."
   (save-excursion
     (beginning-of-line)
+    (if (looking-at " *;;;\\|[a-z]")
+       (error "This line is not a function call"))
     (let ((opoint (point))
          (count 0))
-      (while (not (eq (cadr (backtrace-frame count)) 'debug))
-       (setq count (1+ count)))
-      ;; Skip debug--implement-debug-on-entry frame.
-      (when (eq 'debug--implement-debug-on-entry
-                (cadr (backtrace-frame (1+ count))))
-       (setq count (+ 2 count)))
+      (unless skip-base
+        (while (not (eq (cadr (backtrace-frame count)) 'debug))
+          (setq count (1+ count)))
+        ;; Skip debug--implement-debug-on-entry frame.
+        (when (eq 'debug--implement-debug-on-entry
+                  (cadr (backtrace-frame (1+ count))))
+          (setq count (+ 2 count))))
       (goto-char (point-min))
       (when (looking-at "Debugger entered--\\(Lisp error\\|returning value\\):")
        (goto-char (match-end 0))
@@ -551,12 +508,8 @@ removes itself from that hook."
   "Request entry to debugger when this frame exits.
 Applies to the frame whose line point is on in the backtrace."
   (interactive)
-  (save-excursion
-    (beginning-of-line)
-    (if (looking-at " *;;;\\|[a-z]")
-       (error "This line is not a function call")))
-  (beginning-of-line)
   (backtrace-debug (debugger-frame-number) t)
+  (beginning-of-line)
   (if (= (following-char) ? )
       (let ((inhibit-read-only t))
        (delete-char 1)
@@ -567,12 +520,8 @@ Applies to the frame whose line point is on in the backtrace."
   "Do not enter debugger when this frame exits.
 Applies to the frame whose line point is on in the backtrace."
   (interactive)
-  (save-excursion
-    (beginning-of-line)
-    (if (looking-at " *;;;\\|[a-z]")
-       (error "This line is not a function call")))
-  (beginning-of-line)
   (backtrace-debug (debugger-frame-number) nil)
+  (beginning-of-line)
   (if (= (following-char) ?*)
       (let ((inhibit-read-only t))
        (delete-char 1)
@@ -583,59 +532,32 @@ Applies to the frame whose line point is on in the backtrace."
   "Run BODY in original environment."
   (declare (indent 0))
   `(save-excursion
-    (if (null (buffer-name debugger-old-buffer))
+    (if (null (buffer-live-p debugger-old-buffer))
         ;; old buffer deleted
         (setq debugger-old-buffer (current-buffer)))
     (set-buffer debugger-old-buffer)
-    (let ((load-read-function debugger-outer-load-read-function)
-          (overriding-terminal-local-map
-           debugger-outer-overriding-terminal-local-map)
-          (overriding-local-map debugger-outer-overriding-local-map)
-          (track-mouse debugger-outer-track-mouse)
-          (last-command debugger-outer-last-command)
-          (this-command debugger-outer-this-command)
-          (unread-command-events debugger-outer-unread-command-events)
-          (unread-post-input-method-events
-           debugger-outer-unread-post-input-method-events)
-          (last-input-event debugger-outer-last-input-event)
-          (last-command-event debugger-outer-last-command-event)
-          (last-nonmenu-event debugger-outer-last-nonmenu-event)
-          (last-event-frame debugger-outer-last-event-frame)
-          (standard-input debugger-outer-standard-input)
-          (standard-output debugger-outer-standard-output)
-          (inhibit-redisplay debugger-outer-inhibit-redisplay)
-          (cursor-in-echo-area debugger-outer-cursor-in-echo-area))
-      (set-match-data debugger-outer-match-data)
-      (prog1
-          (progn ,@body)
-        (setq debugger-outer-match-data (match-data))
-        (setq debugger-outer-load-read-function load-read-function)
-        (setq debugger-outer-overriding-terminal-local-map
-              overriding-terminal-local-map)
-        (setq debugger-outer-overriding-local-map overriding-local-map)
-        (setq debugger-outer-track-mouse track-mouse)
-        (setq debugger-outer-last-command last-command)
-        (setq debugger-outer-this-command this-command)
-        (setq debugger-outer-unread-command-events unread-command-events)
-        (setq debugger-outer-unread-post-input-method-events
-              unread-post-input-method-events)
-        (setq debugger-outer-last-input-event last-input-event)
-        (setq debugger-outer-last-command-event last-command-event)
-        (setq debugger-outer-last-nonmenu-event last-nonmenu-event)
-        (setq debugger-outer-last-event-frame last-event-frame)
-        (setq debugger-outer-standard-input standard-input)
-        (setq debugger-outer-standard-output standard-output)
-        (setq debugger-outer-inhibit-redisplay inhibit-redisplay)
-        (setq debugger-outer-cursor-in-echo-area cursor-in-echo-area)
-        ))))
-
-(defun debugger-eval-expression (exp)
-  "Eval an expression, in an environment like that outside the debugger."
+    (set-match-data debugger-outer-match-data)
+    (prog1
+        (progn ,@body)
+      (setq debugger-outer-match-data (match-data)))))
+
+(defun debugger-eval-expression (exp &optional nframe)
+  "Eval an expression, in an environment like that outside the debugger.
+The environment used is the one when entering the activation frame at point."
   (interactive
-   (list (read-from-minibuffer "Eval: "
-                              nil read-expression-map t
-                              'read-expression-history)))
-  (debugger-env-macro (eval-expression exp)))
+   (list (read--expression "Eval in stack frame: ")))
+  (let ((nframe (or nframe
+                    (condition-case nil (1+ (debugger-frame-number 'skip-base))
+                      (error 0)))) ;; If on first line.
+         (base (if (eq 'debug--implement-debug-on-entry
+                      (cadr (backtrace-frame 1 'debug)))
+                  'debug--implement-debug-on-entry 'debug)))
+    (debugger-env-macro
+      (let ((val (backtrace-eval exp nframe base)))
+        (prog1
+            (prin1 val t)
+          (let ((str (eval-expression-print-format val)))
+            (if str (princ str t))))))))
 \f
 (defvar debugger-mode-map
   (let ((map (make-keymap))
@@ -704,7 +626,7 @@ Applies to the frame whose line point is on in the backtrace."
 
 (put 'debugger-mode 'mode-class 'special)
 
-(defun debugger-mode ()
+(define-derived-mode debugger-mode fundamental-mode "Debugger"
   "Mode for backtrace buffers, selected in debugger.
 \\<debugger-mode-map>
 A line starts with `*' if exiting that frame will call the debugger.
@@ -719,13 +641,9 @@ which functions will enter the debugger when called.
 
 Complete list of commands:
 \\{debugger-mode-map}"
-  (kill-all-local-variables)
-  (setq major-mode 'debugger-mode)
-  (setq mode-name "Debugger")
   (setq truncate-lines t)
   (set-syntax-table emacs-lisp-mode-syntax-table)
-  (use-local-map debugger-mode-map)
-  (run-mode-hooks 'debugger-mode-hook))
+  (use-local-map debugger-mode-map))
 \f
 (defcustom debugger-record-buffer "*Debugger-record*"
   "Buffer name for expression values, for \\[debugger-record-expression]."
@@ -736,11 +654,7 @@ Complete list of commands:
 (defun debugger-record-expression  (exp)
   "Display a variable's value and record it in `*Backtrace-record*' buffer."
   (interactive
-   (list (read-from-minibuffer
-         "Record Eval: "
-         nil
-         read-expression-map t
-         'read-expression-history)))
+   (list (read--expression "Record Eval: ")))
   (let* ((buffer (get-buffer-create debugger-record-buffer))
         (standard-output buffer))
     (princ (format "Debugger Eval (%s): " exp))