¿Cómo edebug una función definida en un bloque de paquete de uso?

7

Aquí hay un ejemplo mínimo de trabajo para demostrar el problema, deberá tener el use-packagepaquete instalado:

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

Cuando intento agregar instrumentación de edebug al dummy/functionuso M-x edebug-defun, se inicia el edebug de inmediato como si ya lo hubiera hecho M-x dummy/function. Tengo que dejar eso golpeando q. Pero cuando realmente lo hago M-x dummy/function, no veo la activación de edebug.

¿Hay algo sobre el use-packagecontenedor que se mete con la instrumentación de edebug? ¿Cómo se puede arreglar?

Kaushal Modi
fuente
No sé cómo funciona use-package, pero ¿la definición dummy/functionen el nivel superior (es decir, fuera de use-package) soluciona el problema inmediato? He dejado de usar funciones lambda anónimas a favor de funciones con nombre para tratar problemas similares en los ganchos de modo.
Tyler
@ Sí, las funciones definidas fuera del use-packagecontenedor se pueden depurar bien. Me gustaría envolver todo lo relacionado con el paquete X dentro (use-package X ..), incluidas mis funciones personalizadas relacionadas con X. Pero si edebug de esas funciones es un problema, entonces necesitaría repensar mi organización de código ...
Kaushal Modi
Si cree que el comportamiento que busca debe ser proporcionada, pero no lo es, considerar la presentación de una solicitud de mejora de Emacs: M-x report-emacs-bug. Esté preparado para proporcionar una receta simple que comience desde emacs -Q.
Dibujó el
1
Creo que edebug-defundepura la forma de nivel superior, que en este caso es la (use-package ...)propia en lugar de la defun que está pasando a la use-packagemacro. ¿Puedes usar edebug-on-entryy dar el nombre de la función que has definido?
glucas
1
FWIW, uso el depurador de Emacs normal debug, no edebug. Por ejemplo, M-x debug-on-entry. HTH.
Dibujó

Respuestas:

9

Cuando lo llama edebug-defun, depura el formulario de nivel superior, que en este caso es (use-package ...).

Puede usar debug-on-entrypara depurar una función con nombre.

glucas
fuente
4
  1. Marque el defun apropiado y llame C-x nn( narrow-to-region)
  2. C-u C-M-x( edebug-defun)
  3. C-x nw( widen)

Si te gusta hacer las cosas rápidamente, atajo lispy para esto es N xe W.

abo-abo
fuente
1
Esto no funciona porque se narrow-to-defunreduce a la misma (use-package ...)forma que edebug-defunencuentra. Sin embargo, funciona si marca el defun primero y lo usa narrow-to-region.
glucas
Sí, a eso me refería. En realidad no lo uso narrow-to-defun. lispy's Nselecciona región y llama narrow-to-region.
abo-abo
3

edebug-defun

Gracias a @ abo-abo por el consejo para marcar el defun primero.

Aquí hay una forma rápida de habilitar / deshabilitar edebug-defun. Esto se usa search-backward-regexppara edebug-instrument o evaluar el nombre defun o defmacro correctamente, ya sea que esté definido en el use-packagecontenedor o no.

;; 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))))

Uso : con el punto en cualquier lugar de la función / cuerpo de macro, la llamada modi/toggle-edebug-defunhabilitará o deshabilitará edebugesa entidad.

debug-on-entry

Gracias a @glucas y @Drew, he preparado una forma conveniente de alternar debug-on-entry. Esto también utiliza el mismo enfoque que el anterior para analizar el nombre defun / defmacro.

;; 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)))))

Uso : con el punto en cualquier parte del cuerpo de la función, la llamada modi/toggle-debug-defunhabilitará o cancelará la debug-on-errorfunción.

Kaushal Modi
fuente