]> code.delx.au - gnu-emacs/blobdiff - lisp/emacs-lisp/edebug.el
merge trunk
[gnu-emacs] / lisp / emacs-lisp / edebug.el
index c2ff81281a13e2542860f524a90e866833769ea6..867f079ce5f609459eb8094348cd9109fe1b9d0c 100644 (file)
@@ -1,6 +1,7 @@
 ;;; edebug.el --- a source-level debugger for Emacs Lisp  -*- lexical-binding: t -*-
 
-;; Copyright (C) 1988-1995, 1997, 1999-2012 Free Software Foundation, Inc.
+;; Copyright (C) 1988-1995, 1997, 1999-2013 Free Software Foundation,
+;; Inc.
 
 ;; Author: Daniel LaLiberte <liberte@holonexus.org>
 ;; Maintainer: FSF
@@ -53,6 +54,7 @@
 
 (require 'macroexp)
 (eval-when-compile (require 'cl-lib))
+(eval-when-compile (require 'pcase))
 
 ;;; Options
 
@@ -460,8 +462,8 @@ STREAM or the value of `standard-input' may be:
 
 This version, from Edebug, maybe instruments the expression.  But the
 STREAM must be the current buffer to do so.  Whether it instruments is
-also dependent on the values of `edebug-all-defs' and
-`edebug-all-forms'."
+also dependent on the values of the option `edebug-all-defs' and
+the option `edebug-all-forms'."
   (or stream (setq stream standard-input))
   (if (eq stream (current-buffer))
       (edebug-read-and-maybe-wrap-form)
@@ -483,8 +485,8 @@ similarly.  Reinitialize the face according to `defface' specification.
 
 With a prefix argument, instrument the code for Edebug.
 
-Setting `edebug-all-defs' to a non-nil value reverses the meaning of
-the prefix argument.  Code is then instrumented when this function is
+Setting option `edebug-all-defs' to a non-nil value reverses the meaning
+of the prefix argument.  Code is then instrumented when this function is
 invoked without a prefix argument
 
 If acting on a `defun' for FUNCTION, and the function was instrumented,
@@ -2071,11 +2073,6 @@ expressions; a `progn' form will be returned enclosing these forms."
 
 (defvar edebug-active nil)  ;; Non-nil when edebug is active
 
-;;; add minor-mode-alist entry
-(or (assq 'edebug-active minor-mode-alist)
-    (setq minor-mode-alist (cons (list 'edebug-active " *Debugging*")
-                                minor-mode-alist)))
-
 (defvar edebug-stack nil)
 ;; Stack of active functions evaluated via edebug.
 ;; Should be nil at the top level.
@@ -2714,8 +2711,7 @@ MSG is printed after `::::} '."
   ;; Start up a recursive edit inside of edebug.
   ;; The current buffer is the edebug-buffer, which is put into edebug-mode.
   ;; Assume that none of the variables below are buffer-local.
-  (let ((edebug-buffer-read-only buffer-read-only)
-       ;; match-data must be done in the outside buffer
+  (let (;; match-data must be done in the outside buffer
        (edebug-outside-match-data
         (with-current-buffer edebug-outside-buffer ; in case match buffer different
           (match-data)))
@@ -2729,8 +2725,6 @@ MSG is printed after `::::} '."
        ;; during a recursive-edit
        edebug-inside-windows
 
-       (edebug-outside-map (current-local-map))
-
         ;; Save the outside value of executing macro.  (here??)
         (edebug-outside-executing-macro executing-kbd-macro)
         (edebug-outside-pre-command-hook
@@ -2803,10 +2797,9 @@ MSG is printed after `::::} '."
                   (not (memq arg-mode '(after error))))
              (message "Break"))
 
-         (setq buffer-read-only t)
          (setq signal-hook-function nil)
 
-         (edebug-mode)
+         (edebug-mode 1)
          (unwind-protect
              (recursive-edit)          ;  <<<<<<<<<< Recursive edit
 
@@ -2827,10 +2820,7 @@ MSG is printed after `::::} '."
                  (set-buffer edebug-buffer)
                  (if (memq edebug-execution-mode '(go Go-nonstop))
                      (edebug-overlay-arrow))
-                 (setq buffer-read-only edebug-buffer-read-only)
-                 (use-local-map edebug-outside-map)
-                 (remove-hook 'kill-buffer-hook 'edebug-kill-buffer t)
-                 )
+                  (edebug-mode -1))
              ;; gotta have a buffer to let its buffer local variables be set
              (get-buffer-create " bogus edebug buffer"))
            ));; inner let
@@ -3772,7 +3762,9 @@ be installed in `emacs-lisp-mode-map'.")
   (interactive)
   (describe-function 'edebug-mode))
 
-(defun edebug-mode ()
+(defvar edebug--mode-saved-vars nil)
+
+(define-minor-mode edebug-mode
   "Mode for Emacs Lisp buffers while in Edebug.
 
 In addition to all Emacs Lisp commands (except those that modify the
@@ -3806,17 +3798,32 @@ Options:
 `edebug-on-signal'
 `edebug-unwrap-results'
 `edebug-global-break-condition'"
+  :lighter " *Debugging*"
+  :keymap edebug-mode-map
   ;; If the user kills the buffer in which edebug is currently active,
   ;; exit to top level, because the edebug command loop can't usefully
   ;; continue running in such a case.
-  (add-hook 'kill-buffer-hook 'edebug-kill-buffer nil t)
-  (use-local-map edebug-mode-map))
+  ;;
+  (if (not edebug-mode)
+      (progn
+        (while edebug--mode-saved-vars
+          (let ((setting (pop edebug--mode-saved-vars)))
+            (if (consp setting)
+                (set (car setting) (cdr setting))
+              (kill-local-variable setting))))
+        (remove-hook 'kill-buffer-hook 'edebug-kill-buffer t))
+    (pcase-dolist (`(,var . ,val) '((buffer-read-only . t)))
+      (push
+       (if (local-variable-p var) (cons var (symbol-value var)) var)
+       edebug--mode-saved-vars)
+      (set (make-local-variable var) val))
+    ;; Append `edebug-kill-buffer' to the hook to avoid interfering with
+    ;; other entries that are unguarded against deleted buffer.
+    (add-hook 'kill-buffer-hook 'edebug-kill-buffer t t)))
 
 (defun edebug-kill-buffer ()
   "Used on `kill-buffer-hook' when Edebug is operating in a buffer of Lisp code."
-  (let (kill-buffer-hook)
-    (kill-buffer (current-buffer)))
-  (top-level))
+  (run-with-timer 0 nil #'top-level))
 
 ;;; edebug eval list mode
 
@@ -4139,7 +4146,7 @@ reinstrument it."
 It is removed when you hit any char."
   ;; This seems not to work with Emacs 18.59. It undoes too far.
   (interactive)
-  (let ((buffer-read-only nil))
+  (let ((inhibit-read-only t))
     (undo-boundary)
     (edebug-display-freq-count)
     (setq unread-command-events
@@ -4293,14 +4300,11 @@ With prefix argument, make it a temporary breakpoint."
 (defun edebug-unload-function ()
   "Unload the Edebug source level debugger."
   (when edebug-active
+    (setq edebug-active nil)
     (unwind-protect
         (abort-recursive-edit)
-      (setq edebug-active nil)
-      (edebug-unload-function)))
-  (save-current-buffer
-    (dolist (buffer (buffer-list))
-      (set-buffer buffer)
-      (when (eq major-mode 'edebug-mode) (emacs-lisp-mode))))
+      ;; We still want to run unload-feature to completion
+      (run-with-idle-timer 0 nil #'(lambda () (unload-feature 'edebug)))))
   (remove-hook 'called-interactively-p-functions
                'edebug--called-interactively-skip)
   (remove-hook 'cl-read-load-hooks 'edebug--require-cl-read)