;;; edebug.el --- a source-level debugger for Emacs Lisp
-;; Copyright (C) 1988, 89, 90, 91, 92, 93, 94, 95, 97, 1999, 2000, 2001
+;; Copyright (C) 1988,89,90,91,92,93,94,95,97,1999,2000,01,03,2004
;; Free Software Foundation, Inc.
;; Author: Daniel LaLiberte <liberte@holonexus.org>
;;;###autoload
(defcustom edebug-all-defs nil
- "*If non-nil, evaluation of any defining forms will instrument for Edebug.
+ "*If non-nil, evaluating defining forms instruments for Edebug.
This applies to `eval-defun', `eval-region', `eval-buffer', and
`eval-current-buffer'. `eval-region' is also called by
`eval-last-sexp', and `eval-print-last-sexp'.
:group 'edebug)
(defcustom edebug-initial-mode 'step
- "*Initial execution mode for Edebug, if non-nil. If this variable
-is non-@code{nil}, it specifies the initial execution mode for Edebug
-when it is first activated. Possible values are step, next, go,
-Go-nonstop, trace, Trace-fast, continue, and Continue-fast."
+ "*Initial execution mode for Edebug, if non-nil.
+If this variable is non-nil, it specifies the initial execution mode
+for Edebug when it is first activated. Possible values are step, next,
+go, Go-nonstop, trace, Trace-fast, continue, and Continue-fast."
:type '(choice (const step) (const next) (const go)
(const Go-nonstop) (const trace)
(const Trace-fast) (const continue)
(defcustom edebug-print-length 50
- "*Default value of `print-length' to use while printing results in Edebug."
+ "*Default value of `print-length' for printing results in Edebug."
:type 'integer
:group 'edebug)
(defcustom edebug-print-level 50
- "*Default value of `print-level' to use while printing results in Edebug."
+ "*Default value of `print-level' for printing results in Edebug."
:type 'integer
:group 'edebug)
(defcustom edebug-print-circle t
- "*Default value of `print-circle' to use while printing results in Edebug."
+ "*Default value of `print-circle' for printing results in Edebug."
:type 'boolean
:group 'edebug)
"Return a list of windows, in order of `next-window'."
;; This doesn't work for epoch.
(let (window-list)
- (walk-windows (lambda (w) (setq window-list (cons w window-list))))
+ (walk-windows (lambda (w) (push w window-list)))
(nreverse window-list)))
;; Not used.
(setq object (edebug-lookup-function object))
(if (and (listp object)
(eq 'macro (car object))
- (edebug-functionp (cdr object)))
- object))
-
-(defun edebug-functionp (object)
- "Returns the function named by OBJECT, or nil if it is not a function."
- (setq object (edebug-lookup-function object))
- (if (or (subrp object)
- (byte-code-function-p object)
- (and (listp object)
- (eq (car object) 'lambda)
- (listp (car (cdr object)))))
+ (functionp (cdr object)))
object))
(defun edebug-sort-alist (alist function)
(let (list)
(walk-windows (lambda (w)
(unless (eq w (selected-window))
- (setq list (cons (cons (window-buffer w)
- (window-point w))
- list)))))
+ (push (cons (window-buffer w)
+ (window-point w))
+ list))))
list))
(defun edebug-set-buffer-points (buffer-points)
;; Restore the buffer-points created by edebug-get-displayed-buffer-points.
- (let ((current-buffer (current-buffer)))
- (mapcar (function (lambda (buf-point)
- (if (buffer-name (car buf-point)) ; still exists
- (progn
- (set-buffer (car buf-point))
- (goto-char (cdr buf-point))))))
- buffer-points)
- (set-buffer current-buffer)))
+ (save-current-buffer
+ (mapcar (lambda (buf-point)
+ (when (buffer-live-p (car buf-point))
+ (set-buffer (car buf-point))
+ (goto-char (cdr buf-point))))
+ buffer-points)))
(defun edebug-current-windows (which-windows)
;; Get either a full window configuration or some window information.
If the current defun is actually a call to `defvar', then reset the
variable using its initial value expression even if the variable
already has some other value. (Normally `defvar' does not change the
-variable's value if it already has a value.)
+variable's value if it already has a value.) Treat `defcustom'
+similarly. Reinitialize the face according to `defface' specification.
With a prefix argument, instrument the code for Edebug.
((and (eq (car form) 'defcustom)
(default-boundp (nth 1 form)))
;; Force variable to be bound.
- (set-default (nth 1 form) (eval (nth 2 form)))))
+ (set-default (nth 1 form) (eval (nth 2 form))))
+ ((eq (car form) 'defface)
+ ;; Reset the face.
+ (setq face-new-frame-defaults
+ (assq-delete-all (nth 1 form) face-new-frame-defaults))
+ (put (nth 1 form) 'face-defface-spec nil)
+ ;; See comments in `eval-defun-1' for purpose of code below
+ (setq form (prog1 `(prog1 ,form
+ (put ',(nth 1 form) 'saved-face
+ ',(get (nth 1 form) 'saved-face))
+ (put ',(nth 1 form) 'customized-face
+ ,(nth 2 form)))
+ (put (nth 1 form) 'saved-face nil)))))
(setq edebug-result (eval form))
(if (not edebugging)
(princ edebug-result)
(if (and (eq (following-char) ?.)
(save-excursion
(forward-char 1)
- (and (>= (following-char) ?0)
- (<= (following-char) ?9))))
+ (or (and (eq (aref edebug-read-syntax-table (following-char))
+ 'symbol)
+ (not (= (following-char) ?\;)))
+ (memq (following-char) '(?\, ?\.)))))
'symbol
(aref edebug-read-syntax-table (following-char))))
;; Ignore the last created offset pair.
(setcdr edebug-current-offset (cdr (cdr edebug-current-offset))))
-(def-edebug-spec edebug-storing-offsets (form body))
-(put 'edebug-storing-offsets 'lisp-indent-hook 1)
-
(defmacro edebug-storing-offsets (point &rest body)
+ (declare (debug (form body)) (indent 1))
`(unwind-protect
(progn
(edebug-store-before-offset ,point)
))
(defun edebug-read-storing-offsets (stream)
- (let ((class (edebug-next-token-class))
- func
- edebug-read-dotted-list) ; see edebug-store-after-offset
+ (let (edebug-read-dotted-list) ; see edebug-store-after-offset
(edebug-storing-offsets (point)
- (if (setq func (assq class edebug-read-alist))
- (funcall (cdr func) stream)
- ;; anything else, just read it.
- (edebug-original-read stream))
- )))
+ (funcall
+ (or (cdr (assq (edebug-next-token-class) edebug-read-alist))
+ ;; anything else, just read it.
+ 'edebug-original-read)
+ stream))))
(defun edebug-read-symbol (stream)
(edebug-original-read stream))
;; Turn 'thing into (quote thing)
(forward-char 1)
(list
- (edebug-storing-offsets (point) 'quote)
+ (edebug-storing-offsets (1- (point)) 'quote)
(edebug-read-storing-offsets stream)))
+(defvar edebug-read-backquote-level 0
+ "If non-zero, we're in a new-style backquote.
+It should never be negative. This controls how we read comma constructs.")
+
(defun edebug-read-backquote (stream)
;; Turn `thing into (\` thing)
- (let ((opoint (point)))
- (forward-char 1)
- ;; Generate the same structure of offsets we would have
- ;; if the resulting list appeared verbatim in the input text.
- (edebug-storing-offsets opoint
- (list
- (edebug-storing-offsets opoint '\`)
- (edebug-read-storing-offsets stream)))))
-
-(defvar edebug-read-backquote-new nil
- "Non-nil if reading the inside of a new-style backquote with no parens around it.
-Value of nil means reading the inside of an old-style backquote construct
-which is surrounded by an extra set of parentheses.
-This controls how we read comma constructs.")
+ (forward-char 1)
+ (list
+ (edebug-storing-offsets (1- (point)) '\`)
+ (let ((edebug-read-backquote-level (1+ edebug-read-backquote-level)))
+ (edebug-read-storing-offsets stream))))
(defun edebug-read-comma (stream)
;; Turn ,thing into (\, thing). Handle ,@ and ,. also.
(forward-char 1)))
;; Generate the same structure of offsets we would have
;; if the resulting list appeared verbatim in the input text.
- (if edebug-read-backquote-new
- (list
- (edebug-storing-offsets opoint symbol)
- (edebug-read-storing-offsets stream))
- (edebug-storing-offsets opoint symbol)))))
+ (if (zerop edebug-read-backquote-level)
+ (edebug-storing-offsets opoint symbol)
+ (list
+ (edebug-storing-offsets opoint symbol)
+ (let ((edebug-read-backquote-level (1- edebug-read-backquote-level)))
+ (edebug-read-storing-offsets stream)))))))
(defun edebug-read-function (stream)
;; Turn #'thing into (function thing)
(cond ((eq ?\' (following-char))
(forward-char 1)
(list
- (edebug-storing-offsets (point)
+ (edebug-storing-offsets (- (point) 2)
(if (featurep 'cl) 'function* 'function))
(edebug-read-storing-offsets stream)))
((memq (following-char) '(?: ?B ?O ?X ?b ?o ?x ?1 ?2 ?3 ?4 ?5 ?6
- ?7 ?8 ?9 ?0))
+ ?7 ?8 ?9 ?0))
(backward-char 1)
(edebug-original-read stream))
(t (edebug-syntax-error "Bad char after #"))))
(prog1
(let ((elements))
(while (not (memq (edebug-next-token-class) '(rparen dot)))
- (if (eq (edebug-next-token-class) 'backquote)
- (let ((edebug-read-backquote-new (not (null elements)))
- (opoint (point)))
- (if edebug-read-backquote-new
- (setq elements (cons (edebug-read-backquote stream) elements))
- (forward-char 1) ; Skip backquote.
- ;; Call edebug-storing-offsets here so that we
- ;; produce the same offsets we would have had
- ;; if the backquote were an ordinary symbol.
- (setq elements (cons (edebug-storing-offsets opoint '\`)
- elements))))
- (setq elements (cons (edebug-read-storing-offsets stream) elements))))
+ (if (and (eq (edebug-next-token-class) 'backquote)
+ (null elements)
+ (zerop edebug-read-backquote-level))
+ (progn
+ ;; Old style backquote.
+ (forward-char 1) ; Skip backquote.
+ ;; Call edebug-storing-offsets here so that we
+ ;; produce the same offsets we would have had
+ ;; if the backquote were an ordinary symbol.
+ (push (edebug-storing-offsets (1- (point)) '\`) elements))
+ (push (edebug-read-storing-offsets stream) elements)))
(setq elements (nreverse elements))
(if (eq 'dot (edebug-next-token-class))
(let (dotted-form)
(prog1
(let ((elements))
(while (not (eq 'rbracket (edebug-next-token-class)))
- (setq elements (cons (edebug-read-storing-offsets stream) elements)))
+ (push (edebug-read-storing-offsets stream) elements))
(apply 'vector (nreverse elements)))
(forward-char 1) ; skip \]
))
(setcdr cursor offsets)
cursor)
-'(defun edebug-copy-cursor (cursor)
+(defun edebug-copy-cursor (cursor)
;; Copy the cursor using the same object and offsets.
(cons (car cursor) (cdr cursor)))
(edebug-set-cursor cursor (edebug-cursor-expressions cursor)
(cdr (edebug-cursor-offsets cursor)))
(cond
- ((null head) nil) ; () is legal.
-
((symbolp head)
(cond
- ((null head)
- (edebug-syntax-error "nil head"))
+ ((null head) nil) ; () is legal.
((eq head 'interactive-p)
;; Special case: replace (interactive-p) with variable
(setq edebug-def-interactive 'check-it)
head (edebug-move-cursor cursor))))))
((consp head)
- (if (and (listp head) (eq (car head) ',))
+ (if (eq (car head) ',)
+ ;; The head of a form should normally be a symbol or a lambda
+ ;; expression but it can also be an unquote form to be filled
+ ;; before evaluation. We evaluate the arguments anyway, on the
+ ;; assumption that the unquote form will place a proper function
+ ;; name (rather than a macro name).
(edebug-match cursor '(("," def-form) body))
;; Process anonymous function and args.
;; This assumes no anonymous macros.
(edebug-match-specs cursor '(lambda-expr body) 'edebug-match-specs)))
(t (edebug-syntax-error
- "Head of list form must be a symbol or lambda expression.")))
+ "Head of list form must be a symbol or lambda expression")))
))
;;; Matching of specs.
[&optional ("interactive" interactive)]
def-body))
(def-edebug-spec defmacro
- (&define name lambda-list def-body))
-(def-edebug-spec define-derived-mode
- (&define name symbolp stringp [&optional stringp] def-body))
-(def-edebug-spec define-minor-mode
- (&define name stringp
- [&optional sexp sexp &or consp symbolp]
- [&rest [keywordp sexp]]
- def-body))
-;; This plain doesn't work ;-( -sm
-;; (def-edebug-spec define-skeleton
-;; (&define name stringp def-body))
+ (&define name lambda-list [&optional ("declare" &rest sexp)] def-body))
(def-edebug-spec arglist lambda-list) ;; deprecated - use lambda-list.
(def-edebug-spec backquote-form
(&or
([&or "," ",@"] &or ("quote" backquote-form) form)
- (backquote-form &rest backquote-form)
+ ;; The simple version:
+ ;; (backquote-form &rest backquote-form)
+ ;; doesn't handle (a . ,b). The straightforward fix:
+ ;; (backquote-form . [&or nil backquote-form])
+ ;; uses up too much stack space.
+ ;; Note that `(foo . ,@bar) is not legal, so we don't need to handle it.
+ (backquote-form [&rest [¬ ","] backquote-form]
+ . [&or nil backquote-form])
;; If you use dotted forms in backquotes, replace the previous line
;; with the following. This takes quite a bit more stack space, however.
;; (backquote-form . [&or nil backquote-form])
(def-edebug-spec edebug-\` (def-form))
;; Assume immediate quote in unquotes mean backquote at next higher level.
-(def-edebug-spec , (&or ("quote" edebug-`) def-form))
+(def-edebug-spec , (&or ("quote" edebug-\`) def-form))
(def-edebug-spec ,@ (&define ;; so (,@ form) is never wrapped.
- &or ("quote" edebug-`) def-form))
+ &or ("quote" edebug-\`) def-form))
;; New byte compiler.
(def-edebug-spec defsubst defun)
(def-edebug-spec save-selected-window t)
(def-edebug-spec save-current-buffer t)
-(def-edebug-spec save-match-data t)
-(def-edebug-spec with-output-to-string t)
-(def-edebug-spec with-current-buffer t)
-(def-edebug-spec combine-after-change-calls t)
(def-edebug-spec delay-mode-hooks t)
(def-edebug-spec with-temp-file t)
-(def-edebug-spec with-temp-buffer t)
(def-edebug-spec with-temp-message t)
(def-edebug-spec with-syntax-table t)
-(def-edebug-spec dolist ((symbolp form &rest form) &rest form))
-(def-edebug-spec dotimes ((symbolp form &rest form) &rest form))
(def-edebug-spec push (form sexp))
(def-edebug-spec pop (sexp))
-(def-edebug-spec unless t)
-(def-edebug-spec when t)
+
+(def-edebug-spec 1value (form))
+(def-edebug-spec noreturn (form))
+
;; Anything else?
;; Save the outside value of executing macro. (here??)
(edebug-outside-executing-macro executing-kbd-macro)
- (edebug-outside-pre-command-hook pre-command-hook)
- (edebug-outside-post-command-hook post-command-hook))
+ (edebug-outside-pre-command-hook
+ (edebug-var-status 'pre-command-hook))
+ (edebug-outside-post-command-hook
+ (edebug-var-status 'post-command-hook)))
(unwind-protect
(let (;; Don't keep reading from an executing kbd macro
;; within edebug unless edebug-continue-kbd-macro is
edebug-next-execution-mode nil)
(edebug-enter edebug-function edebug-args edebug-body))
;; Reset global variables in case outside value was changed.
- (setq executing-kbd-macro edebug-outside-executing-macro
- pre-command-hook edebug-outside-pre-command-hook
- post-command-hook edebug-outside-post-command-hook
- )))
+ (setq executing-kbd-macro edebug-outside-executing-macro)
+ (edebug-restore-status
+ 'post-command-hook edebug-outside-post-command-hook)
+ (edebug-restore-status
+ 'pre-command-hook edebug-outside-pre-command-hook)))
(let* ((edebug-data (get edebug-function 'edebug))
(edebug-def-mark (car edebug-data)) ; mark at def start
(funcall edebug-body))
)))
+(defun edebug-var-status (var)
+ "Return a cons cell describing the status of VAR's current binding.
+The purpose of this function is so you can properly undo
+subsequent changes to the same binding, by passing the status
+cons cell to `edebug-restore-status'. The status cons cell
+has the form (LOCUS . VALUE), where LOCUS can be a buffer
+\(for a buffer-local binding), a frame (for a frame-local binding),
+or nil (if the default binding is current)."
+ (cons (variable-binding-locus var)
+ (symbol-value var)))
+
+(defun edebug-restore-status (var status)
+ "Reset VAR based on STATUS.
+STATUS should be a list you got from `edebug-var-status'."
+ (let ((locus (car status))
+ (value (cdr status)))
+ (cond ((bufferp locus)
+ (if (buffer-live-p locus)
+ (with-current-buffer locus
+ (set var value))))
+ ((framep locus)
+ (modify-frame-parameters locus (list (cons var value))))
+ (t
+ (set var value)))))
(defun edebug-enter-trace (edebug-body)
(let ((edebug-stack-depth (1+ edebug-stack-depth))
(defun edebug-display ()
+ (unless (marker-position edebug-def-mark)
+ ;; The buffer holding the source has been killed.
+ ;; Let's at least show a backtrace so the user can figure out
+ ;; which function we're talking about.
+ (debug))
;; Setup windows for edebug, determine mode, maybe enter recursive-edit.
;; Uses local variables of edebug-enter, edebug-before, edebug-after
;; and edebug-debugger.
(defun edebug-modify-breakpoint (flag &optional condition temporary)
- "Modify the breakpoint for the form at point or after it according
-to FLAG: set if t, clear if nil. Then move to that point.
+ "Modify the breakpoint for the form at point or after it.
+Set it if FLAG is non-nil, clear it otherwise. Then move to that point.
If CONDITION or TEMPORARY are non-nil, add those attributes to
the breakpoint. "
(let ((edebug-stop-point (edebug-find-stop-point)))
(defun edebug-set-global-break-condition (expression)
- (interactive (list (read-minibuffer
- "Global Condition: "
- (format "%s" edebug-global-break-condition))))
+ (interactive
+ (list
+ (let ((initial (and edebug-global-break-condition
+ (format "%s" edebug-global-break-condition))))
+ (read-from-minibuffer
+ "Global Condition: " initial read-expression-map t
+ (if (equal (car read-expression-history) initial)
+ '(read-expression-history . 1)
+ 'read-expression-history)))))
(setq edebug-global-break-condition expression))
(defun edebug-goto-here ()
- "Proceed to this stop point."
+ "Proceed to first stop-point at or after current position of point."
(interactive)
(edebug-go-mode t))
(executing-kbd-macro edebug-outside-executing-macro)
(defining-kbd-macro edebug-outside-defining-kbd-macro)
- (pre-command-hook edebug-outside-pre-command-hook)
- (post-command-hook edebug-outside-post-command-hook)
+ ;; Get the values out of the saved statuses.
+ (pre-command-hook (cdr edebug-outside-pre-command-hook))
+ (post-command-hook (cdr edebug-outside-post-command-hook))
;; See edebug-display
(overlay-arrow-position edebug-outside-o-a-p)
edebug-outside-executing-macro executing-kbd-macro
edebug-outside-defining-kbd-macro defining-kbd-macro
- edebug-outside-pre-command-hook pre-command-hook
- edebug-outside-post-command-hook post-command-hook
edebug-outside-o-a-p overlay-arrow-position
edebug-outside-o-a-s overlay-arrow-string
edebug-outside-c-i-e-a cursor-in-echo-area
- ))) ; let
+ )
+
+ ;; Restore the outside saved values; don't alter
+ ;; the outside binding loci.
+ (setcdr edebug-outside-pre-command-hook pre-command-hook)
+ (setcdr edebug-outside-post-command-hook post-command-hook)
+
+ )) ; let
))
(defvar cl-debug-env nil) ;; defined in cl; non-nil when lexical env used.
(edebug-prin1-to-string value)))
(defun edebug-compute-previous-result (edebug-previous-value)
+ (if edebug-unwrap-results
+ (setq edebug-previous-value
+ (edebug-unwrap* edebug-previous-value)))
(setq edebug-previous-result
- (if (and (integerp edebug-previous-value)
- (< edebug-previous-value 256)
- (>= edebug-previous-value 0))
- (format "Result: %s = %s" edebug-previous-value
- (single-key-description edebug-previous-value))
- (if edebug-unwrap-results
- (setq edebug-previous-value
- (edebug-unwrap* edebug-previous-value)))
- (concat "Result: "
- (edebug-safe-prin1-to-string edebug-previous-value)))))
+ (concat "Result: "
+ (edebug-safe-prin1-to-string edebug-previous-value)
+ (eval-expression-print-format edebug-previous-value))))
(defun edebug-previous-result ()
"Print the previous result."
(princ
(edebug-outside-excursion
(setq values (cons (edebug-eval edebug-expr) values))
- (edebug-safe-prin1-to-string (car values)))))
+ (concat (edebug-safe-prin1-to-string (car values))
+ (eval-expression-print-format (car values))))))
(defun edebug-eval-last-sexp ()
- "Evaluate sexp before point in the outside environment;
-print value in minibuffer."
+ "Evaluate sexp before point in the outside environment.
+Print value in minibuffer."
(interactive)
(edebug-eval-expression (edebug-last-sexp)))
(defun edebug-eval-print-last-sexp ()
- "Evaluate sexp before point in the outside environment;
-print value into current buffer."
+ "Evaluate sexp before point in outside environment; insert value.
+This prints the value into current buffer."
(interactive)
(let* ((edebug-form (edebug-last-sexp))
(edebug-result-string
;;; Edebug Minor Mode
-;; Global GUD bindings for all emacs-lisp-mode buffers.
-(define-key emacs-lisp-mode-map "\C-x\C-a\C-s" 'edebug-step-mode)
-(define-key emacs-lisp-mode-map "\C-x\C-a\C-n" 'edebug-next-mode)
-(define-key emacs-lisp-mode-map "\C-x\C-a\C-c" 'edebug-go-mode)
-(define-key emacs-lisp-mode-map "\C-x\C-a\C-l" 'edebug-where)
+(defvar gud-inhibit-global-bindings
+ "*Non-nil means don't do global rebindings of C-x C-a subcommands.")
-
-(defvar edebug-mode-map nil)
-(if edebug-mode-map
- nil
- (progn
- (setq edebug-mode-map (copy-keymap emacs-lisp-mode-map))
+;; Global GUD bindings for all emacs-lisp-mode buffers.
+(unless gud-inhibit-global-bindings
+ (define-key emacs-lisp-mode-map "\C-x\C-a\C-s" 'edebug-step-mode)
+ (define-key emacs-lisp-mode-map "\C-x\C-a\C-n" 'edebug-next-mode)
+ (define-key emacs-lisp-mode-map "\C-x\C-a\C-c" 'edebug-go-mode)
+ (define-key emacs-lisp-mode-map "\C-x\C-a\C-l" 'edebug-where))
+
+(defvar edebug-mode-map
+ (let ((map (copy-keymap emacs-lisp-mode-map)))
;; control
- (define-key edebug-mode-map " " 'edebug-step-mode)
- (define-key edebug-mode-map "n" 'edebug-next-mode)
- (define-key edebug-mode-map "g" 'edebug-go-mode)
- (define-key edebug-mode-map "G" 'edebug-Go-nonstop-mode)
- (define-key edebug-mode-map "t" 'edebug-trace-mode)
- (define-key edebug-mode-map "T" 'edebug-Trace-fast-mode)
- (define-key edebug-mode-map "c" 'edebug-continue-mode)
- (define-key edebug-mode-map "C" 'edebug-Continue-fast-mode)
-
- ;;(define-key edebug-mode-map "f" 'edebug-forward) not implemented
- (define-key edebug-mode-map "f" 'edebug-forward-sexp)
- (define-key edebug-mode-map "h" 'edebug-goto-here)
-
- (define-key edebug-mode-map "I" 'edebug-instrument-callee)
- (define-key edebug-mode-map "i" 'edebug-step-in)
- (define-key edebug-mode-map "o" 'edebug-step-out)
+ (define-key map " " 'edebug-step-mode)
+ (define-key map "n" 'edebug-next-mode)
+ (define-key map "g" 'edebug-go-mode)
+ (define-key map "G" 'edebug-Go-nonstop-mode)
+ (define-key map "t" 'edebug-trace-mode)
+ (define-key map "T" 'edebug-Trace-fast-mode)
+ (define-key map "c" 'edebug-continue-mode)
+ (define-key map "C" 'edebug-Continue-fast-mode)
+
+ ;;(define-key map "f" 'edebug-forward) not implemented
+ (define-key map "f" 'edebug-forward-sexp)
+ (define-key map "h" 'edebug-goto-here)
+
+ (define-key map "I" 'edebug-instrument-callee)
+ (define-key map "i" 'edebug-step-in)
+ (define-key map "o" 'edebug-step-out)
;; quitting and stopping
- (define-key edebug-mode-map "q" 'top-level)
- (define-key edebug-mode-map "Q" 'edebug-top-level-nonstop)
- (define-key edebug-mode-map "a" 'abort-recursive-edit)
- (define-key edebug-mode-map "S" 'edebug-stop)
+ (define-key map "q" 'top-level)
+ (define-key map "Q" 'edebug-top-level-nonstop)
+ (define-key map "a" 'abort-recursive-edit)
+ (define-key map "S" 'edebug-stop)
;; breakpoints
- (define-key edebug-mode-map "b" 'edebug-set-breakpoint)
- (define-key edebug-mode-map "u" 'edebug-unset-breakpoint)
- (define-key edebug-mode-map "B" 'edebug-next-breakpoint)
- (define-key edebug-mode-map "x" 'edebug-set-conditional-breakpoint)
- (define-key edebug-mode-map "X" 'edebug-set-global-break-condition)
+ (define-key map "b" 'edebug-set-breakpoint)
+ (define-key map "u" 'edebug-unset-breakpoint)
+ (define-key map "B" 'edebug-next-breakpoint)
+ (define-key map "x" 'edebug-set-conditional-breakpoint)
+ (define-key map "X" 'edebug-set-global-break-condition)
;; evaluation
- (define-key edebug-mode-map "r" 'edebug-previous-result)
- (define-key edebug-mode-map "e" 'edebug-eval-expression)
- (define-key edebug-mode-map "\C-x\C-e" 'edebug-eval-last-sexp)
- (define-key edebug-mode-map "E" 'edebug-visit-eval-list)
+ (define-key map "r" 'edebug-previous-result)
+ (define-key map "e" 'edebug-eval-expression)
+ (define-key map "\C-x\C-e" 'edebug-eval-last-sexp)
+ (define-key map "E" 'edebug-visit-eval-list)
;; views
- (define-key edebug-mode-map "w" 'edebug-where)
- (define-key edebug-mode-map "v" 'edebug-view-outside) ;; maybe obsolete??
- (define-key edebug-mode-map "p" 'edebug-bounce-point)
- (define-key edebug-mode-map "P" 'edebug-view-outside) ;; same as v
- (define-key edebug-mode-map "W" 'edebug-toggle-save-windows)
+ (define-key map "w" 'edebug-where)
+ (define-key map "v" 'edebug-view-outside) ;; maybe obsolete??
+ (define-key map "p" 'edebug-bounce-point)
+ (define-key map "P" 'edebug-view-outside) ;; same as v
+ (define-key map "W" 'edebug-toggle-save-windows)
;; misc
- (define-key edebug-mode-map "?" 'edebug-help)
- (define-key edebug-mode-map "d" 'edebug-backtrace)
+ (define-key map "?" 'edebug-help)
+ (define-key map "d" 'edebug-backtrace)
- (define-key edebug-mode-map "-" 'negative-argument)
+ (define-key map "-" 'negative-argument)
;; statistics
- (define-key edebug-mode-map "=" 'edebug-temp-display-freq-count)
+ (define-key map "=" 'edebug-temp-display-freq-count)
;; GUD bindings
- (define-key edebug-mode-map "\C-c\C-s" 'edebug-step-mode)
- (define-key edebug-mode-map "\C-c\C-n" 'edebug-next-mode)
- (define-key edebug-mode-map "\C-c\C-c" 'edebug-go-mode)
-
- (define-key edebug-mode-map "\C-x " 'edebug-set-breakpoint)
- (define-key edebug-mode-map "\C-c\C-d" 'edebug-unset-breakpoint)
- (define-key edebug-mode-map "\C-c\C-t"
- (function (lambda () (edebug-set-breakpoint t))))
- (define-key edebug-mode-map "\C-c\C-l" 'edebug-where)
- ))
+ (define-key map "\C-c\C-s" 'edebug-step-mode)
+ (define-key map "\C-c\C-n" 'edebug-next-mode)
+ (define-key map "\C-c\C-c" 'edebug-go-mode)
+
+ (define-key map "\C-x " 'edebug-set-breakpoint)
+ (define-key map "\C-c\C-d" 'edebug-unset-breakpoint)
+ (define-key map "\C-c\C-t"
+ (lambda () (interactive) (edebug-set-breakpoint t)))
+ (define-key map "\C-c\C-l" 'edebug-where)
+ map))
;; Autoloading these global bindings doesn't make sense because
;; they cannot be used anyway unless Edebug is already loaded and active.
(defvar global-edebug-prefix "\^XX"
"Prefix key for global edebug commands, available from any buffer.")
-(defvar global-edebug-map nil
+(defvar global-edebug-map
+ (let ((map (make-sparse-keymap)))
+
+ (define-key map " " 'edebug-step-mode)
+ (define-key map "g" 'edebug-go-mode)
+ (define-key map "G" 'edebug-Go-nonstop-mode)
+ (define-key map "t" 'edebug-trace-mode)
+ (define-key map "T" 'edebug-Trace-fast-mode)
+ (define-key map "c" 'edebug-continue-mode)
+ (define-key map "C" 'edebug-Continue-fast-mode)
+
+ ;; breakpoints
+ (define-key map "b" 'edebug-set-breakpoint)
+ (define-key map "u" 'edebug-unset-breakpoint)
+ (define-key map "x" 'edebug-set-conditional-breakpoint)
+ (define-key map "X" 'edebug-set-global-break-condition)
+
+ ;; views
+ (define-key map "w" 'edebug-where)
+ (define-key map "W" 'edebug-toggle-save-windows)
+
+ ;; quitting
+ (define-key map "q" 'top-level)
+ (define-key map "Q" 'edebug-top-level-nonstop)
+ (define-key map "a" 'abort-recursive-edit)
+
+ ;; statistics
+ (define-key map "=" 'edebug-display-freq-count)
+ map)
"Global map of edebug commands, available from any buffer.")
-(if global-edebug-map
- nil
- (setq global-edebug-map (make-sparse-keymap))
-
- (global-unset-key global-edebug-prefix)
- (global-set-key global-edebug-prefix global-edebug-map)
-
- (define-key global-edebug-map " " 'edebug-step-mode)
- (define-key global-edebug-map "g" 'edebug-go-mode)
- (define-key global-edebug-map "G" 'edebug-Go-nonstop-mode)
- (define-key global-edebug-map "t" 'edebug-trace-mode)
- (define-key global-edebug-map "T" 'edebug-Trace-fast-mode)
- (define-key global-edebug-map "c" 'edebug-continue-mode)
- (define-key global-edebug-map "C" 'edebug-Continue-fast-mode)
-
- ;; breakpoints
- (define-key global-edebug-map "b" 'edebug-set-breakpoint)
- (define-key global-edebug-map "u" 'edebug-unset-breakpoint)
- (define-key global-edebug-map "x" 'edebug-set-conditional-breakpoint)
- (define-key global-edebug-map "X" 'edebug-set-global-break-condition)
-
- ;; views
- (define-key global-edebug-map "w" 'edebug-where)
- (define-key global-edebug-map "W" 'edebug-toggle-save-windows)
-
- ;; quitting
- (define-key global-edebug-map "q" 'top-level)
- (define-key global-edebug-map "Q" 'edebug-top-level-nonstop)
- (define-key global-edebug-map "a" 'abort-recursive-edit)
-
- ;; statistics
- (define-key global-edebug-map "=" 'edebug-display-freq-count)
- )
+(global-unset-key global-edebug-prefix)
+(global-set-key global-edebug-prefix global-edebug-map)
+
(defun edebug-help ()
(interactive)
(defvar edebug-eval-mode-map nil
"Keymap for Edebug Eval mode. Superset of Lisp Interaction mode.")
-(if edebug-eval-mode-map
- nil
- (setq edebug-eval-mode-map (copy-keymap lisp-interaction-mode-map))
+(unless edebug-eval-mode-map
+ (setq edebug-eval-mode-map (make-sparse-keymap))
+ (set-keymap-parent edebug-eval-mode-map lisp-interaction-mode-map)
(define-key edebug-eval-mode-map "\C-c\C-w" 'edebug-where)
(define-key edebug-eval-mode-map "\C-c\C-d" 'edebug-delete-eval-item)
(define-key edebug-eval-mode-map "\C-c\C-u" 'edebug-update-eval-list)
(define-key edebug-eval-mode-map "\C-x\C-e" 'edebug-eval-last-sexp)
- (define-key edebug-eval-mode-map "\C-j" 'edebug-eval-print-last-sexp)
- )
+ (define-key edebug-eval-mode-map "\C-j" 'edebug-eval-print-last-sexp))
(put 'edebug-eval-mode 'mode-class 'special)
-(defun edebug-eval-mode ()
+(define-derived-mode edebug-eval-mode lisp-interaction-mode "Edebug Eval"
"Mode for evaluation list buffer while in Edebug.
In addition to all Interactive Emacs Lisp commands there are local and
\\{edebug-eval-mode-map}
Global commands prefixed by global-edebug-prefix:
-\\{global-edebug-map}
-"
- (lisp-interaction-mode)
- (setq major-mode 'edebug-eval-mode)
- (setq mode-name "Edebug Eval")
- (use-local-map edebug-eval-mode-map))
+\\{global-edebug-map}")
;;; Interface with standard debugger.
;;; Frequency count and coverage
(defun edebug-display-freq-count ()
- "Display the frequency count data for each line of the current
-definition. The frequency counts are inserted as comment lines after
+ "Display the frequency count data for each line of the current definition.
+The frequency counts are inserted as comment lines after
each line, and you can undo all insertions with one `undo' command.
The counts are inserted starting under the `(' before an expression
(defalias 'edebug-window-live-p 'window-live-p)
-;; Mark takes an argument in Emacs 19.
(defun edebug-mark ()
- (mark t)) ;; Does this work for lemacs too?
+ (mark t))
(defun edebug-set-conditional-breakpoint (arg condition)
"Set a conditional breakpoint at nearest sexp.
(interactive
(list
current-prefix-arg
-;; Read condition as follows; getting previous condition is cumbersome:
+ ;; Read condition as follows; getting previous condition is cumbersome:
(let ((edebug-stop-point (edebug-find-stop-point)))
(if edebug-stop-point
(let* ((edebug-def-name (car edebug-stop-point))
(edebug-breakpoints (car (cdr edebug-data)))
(edebug-break-data (assq index edebug-breakpoints))
(edebug-break-condition (car (cdr edebug-break-data)))
- (edebug-expression-history
- ;; Prepend the current condition, if any.
- (if edebug-break-condition
- (cons edebug-break-condition read-expression-history)
- read-expression-history)))
- (prog1
- (read-from-minibuffer
- "Condition: " nil read-expression-map t
- 'edebug-expression-history)
- (setq read-expression-history edebug-expression-history)
- ))))))
+ (initial (and edebug-break-condition
+ (format "%s" edebug-break-condition))))
+ (read-from-minibuffer
+ "Condition: " initial read-expression-map t
+ (if (equal (car read-expression-history) initial)
+ '(read-expression-history . 1)
+ 'read-expression-history)))))))
(edebug-modify-breakpoint t condition arg))
-;;; The default for all above is Emacs.
-
-;; Epoch specific code was in a separate file: edebug-epoch.el.
-
(easy-menu-define edebug-menu edebug-mode-map "Edebug menus" edebug-mode-menus)
\f
;;; Byte-compiler
(provide 'edebug)
+;;; arch-tag: 19c8d05c-4554-426e-ac72-e0fa1fcb0808
;;; edebug.el ends here