7

Here is a minimum working example to demonstrate the problem, you will need to have the use-package package installed:

(use-package ido
  :config
  (progn
    (defun dummy/function ()
      (interactive)
      (message "I am in the dummy function."))))

When I try to add edebug instrumentation to the dummy/function using M-x edebug-defun, it starts the edebug rightaway as if I already did M-x dummy/function. I have to quit that by hitting q. But then when I actually do M-x dummy/function, I don't see the edebug activating.

Is there something about the use-package wrapper that messes with the edebug instrumentation? How can it be fixed?

  • I don't know how use-package works, but does defining dummy/function at top-level (i.e., outside of use-package) fix the immediate problem? I've stopped using anonymous lambda functions in favor of named functions to deal with similar sorts of problems in mode-hooks. – Tyler Jan 22 '15 at 20:47
  • @Yes, functions defined outside the use-package wrapper can be edebugged fine. I would like to wrapper everything related to package X inside (use-package X ..), including my custom functions related to X. But if edebug of those functions is an issue, then I would need to rethink my code organization.. – Kaushal Modi Jan 22 '15 at 21:02
  • If you think the behavior you are looking for should be provided but is not, consider filing an Emacs enhancement request: M-x report-emacs-bug. Be prepared to provide a simple recipe that starts from emacs -Q. – Drew Jan 22 '15 at 21:24
  • 1
    I think edebug-defun debugs the top-level form, which in this case is the (use-package ...) itself rather than the defun you are passing in to the use-package macro. Can you use edebug-on-entry and give the name of the function you've defined? – glucas Jan 22 '15 at 21:42
  • 1
    FWIW, I use the regular Emacs debugger, debug, not edebug. For example, M-x debug-on-entry. HTH. – Drew Jan 22 '15 at 22:01
9

When you call edebug-defun it debugs the top-level form, which in this case is (use-package ...).

You can use debug-on-entry to debug a named function.

| improve this answer | |
4
  1. Mark the appropriate defun and call C-x nn (narrow-to-region)
  2. C-u C-M-x (edebug-defun)
  3. C-x nw (widen)

If you like doing things quickly, lispy shortcut for this is N xe W.

| improve this answer | |
  • 1
    This doesn't work because narrow-to-defun narrows to the same (use-package ...) form that edebug-defun finds. However it does work if you mark the defun first and use narrow-to-region. – glucas Jan 23 '15 at 15:04
  • Yes, that's what I meant. I don't actually use narrow-to-defun. lispy's N selects region and calls narrow-to-region. – abo-abo Jan 23 '15 at 15:20
3

edebug-defun

Thanks to @abo-abo for the tip to mark the defun first.

Here is a quick way to enable/disable edebug-defun. This uses search-backward-regexp to edebug-instrument or eval the defun or defmacro name correctly, whether it is defined in use-package wrapper or not.

;; Edebug a defun or defmacro
(defvar modi/fns-in-edebug nil
  "List of functions for which `edebug' is instrumented.")

(defconst modi/fns-regexp (concat "(\\s-*"
                                  "\\(defun\\|defmacro\\)\\s-+"
                                  "\\(?1:\\(\\w\\|\\s_\\)+\\)\\_>") ; word or symbol char
  "Regexp to find defun or defmacro definition.")

(defun modi/toggle-edebug-defun ()
  (interactive)
  (let (fn)
    (save-excursion
      (search-backward-regexp modi/fns-regexp)
      (setq fn (match-string 1))
      (mark-sexp)
      (narrow-to-region (point) (mark))
      (if (member fn modi/fns-in-edebug)
          ;; If the function is already being edebugged, uninstrument it
          (progn
            (setq modi/fns-in-edebug (delete fn modi/fns-in-edebug))
            (eval-region (point) (mark))
            (setq-default eval-expression-print-length 12)
            (setq-default eval-expression-print-level  4)
            (message "Edebug disabled: %s" fn))
        ;; If the function is not being edebugged, instrument it
        (progn
          (add-to-list 'modi/fns-in-edebug fn)
          (setq-default eval-expression-print-length nil)
          (setq-default eval-expression-print-level  nil)
          (edebug-defun)
          (message "Edebug: %s" fn)))
      (widen))))

Usage - With the point anywhere in the function/macro body, calling modi/toggle-edebug-defun will enable or disable edebug for that entity.

debug-on-entry

Thanks to @glucas and @Drew, I have cooked up a convenient way to toggle debug-on-entry. This also uses the same approach as above to parse the defun/defmacro name.

;; Debug on entry
(defvar modi/fns-in-debug nil
  "List of functions for which `debug-on-entry' is instrumented.")

(defun modi/toggle-debug-defun ()
  (interactive)
  (let (fn)
    (save-excursion
      (search-backward-regexp modi/fns-regexp)
      (setq fn (match-string 1)))
    (if (member fn modi/fns-in-debug)
        ;; If the function is already being debugged, cancel its debug on entry
        (progn
          (setq modi/fns-in-debug (delete fn modi/fns-in-debug))
          (cancel-debug-on-entry (intern fn))
          (message "Debug-on-entry disabled: %s" fn))
      ;; If the function is not being debugged, debug it on entry
      (progn
        (add-to-list 'modi/fns-in-debug fn)
        (debug-on-entry (intern fn))
        (message "Debug-on-entry: %s" fn)))))

Usage - With the point anywhere in the function body, calling modi/toggle-debug-defun will enable or cancel the debug-on-error for that function.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.