refactor(lib): replace doom-debugger with advice

Writing a debugger for Elisp is too much hassle. `debug` itself isn't
very customizable without a *lot* of boilerplate, so instead of writing
my own, it's more effective to advise debug instead. Certainly, I don't
do anything with it yet, but I will soon.
This commit is contained in:
Henrik Lissner 2022-09-10 17:54:32 +02:00
parent b66ccaeca0
commit d290152a8e
No known key found for this signature in database
GPG key ID: B60957CA074D39A3
3 changed files with 27 additions and 30 deletions

View file

@ -21,12 +21,7 @@
;; UX: Ensure errors are sufficiently verbose from this point on. ;; UX: Ensure errors are sufficiently verbose from this point on.
(when (setq init-file-debug (getenv-internal "DEBUG")) (when (setq init-file-debug (getenv-internal "DEBUG"))
(setq debug-on-error t (setq debug-on-error t))
doom-print-level 'debug)
(message "Debug mode enabled"))
;; FIX: All output via `message' should be seen as debug output.
(setq doom-print-message-level 'debug)
;; HACK: Load `cl' and site files manually to prevent polluting logs and ;; HACK: Load `cl' and site files manually to prevent polluting logs and
;; stdout with deprecation and/or file load messages. ;; stdout with deprecation and/or file load messages.
@ -70,7 +65,7 @@
;; more presentable, and write them to a file. Cleaner backtraces are better ;; more presentable, and write them to a file. Cleaner backtraces are better
;; UX than the giant wall of text the default debugger throws up. ;; UX than the giant wall of text the default debugger throws up.
(doom-require 'doom-lib 'debug) (doom-require 'doom-lib 'debug)
(setq debugger #'doom-debugger) (if init-file-debug (doom-debug-mode +1))
;; Then load the rest of Doom's libs eagerly, since autoloads may not be ;; Then load the rest of Doom's libs eagerly, since autoloads may not be
;; generated/loaded yet. ;; generated/loaded yet.

View file

@ -7,13 +7,13 @@
;;;###autoload ;;;###autoload
(defvar doom-debug-variables (defvar doom-debug-variables
'(;; Doom variables `(;; Doom variables
(doom-print-level . debug) (doom-print-level . debug)
(doom-print-message-level . info)
;; Emacs variables ;; Emacs variables
async-debug async-debug
debug-on-error debug-on-error
(debugger . doom-debugger)
garbage-collection-messages garbage-collection-messages
gcmh-verbose gcmh-verbose
init-file-debug init-file-debug
@ -84,10 +84,29 @@ symbol and CDR is the value to set it to when `doom-debug-mode' is activated.")
;; ;;
;;; Custom debuggers ;;; Custom debugger
;; HACK: I advise `debug' instead of changing `debugger' to hide the debugger
;; itself from the backtrace. Doing it manually would require reimplementing
;; most of `debug', which is a lot of unnecessary work, when I only want to
;; decorate the original one slightly.
(defadvice! doom-debugger-a (fn &rest args)
:around #'debug
;; Without `doom-debug-mode', be as vanilla as possible.
(if (not doom-debug-mode)
(apply fn args)
;; Work around Emacs's heuristic (in eval.c) for detecting errors in the
;; debugger, which would run this handler again on subsequent calls. Taken
;; from `ert--run-test-debugger'.
(if (and noninteractive (fboundp 'doom-cli-debugger))
(apply #'doom-cli-debugger args)
;; TODO: Write backtraces to file
;; TODO: Write backtrace to a buffer in case recursive error interupts the
;; debugger (happens more often than it should).
(apply fn args))))
(autoload 'backtrace-get-frames "backtrace") (autoload 'backtrace-get-frames "backtrace")
;;;###autoload
(defun doom-backtrace () (defun doom-backtrace ()
"Return a stack trace as a list of `backtrace-frame' objects." "Return a stack trace as a list of `backtrace-frame' objects."
;; (let* ((n 0) ;; (let* ((n 0)
@ -134,23 +153,6 @@ symbol and CDR is the value to set it to when `doom-debug-mode' is activated.")
backtrace)) backtrace))
file))) file)))
(defun doom-debugger (&rest args)
"Enter `debugger' in interactive sessions, `doom-cli-debugger' otherwise.
Writes backtraces to file and ensures the backtrace is recorded, so the user can
always access it."
(let ((backtrace (doom-backtrace)))
;; Work around Emacs's heuristic (in eval.c) for detecting errors in the
;; debugger, which would run this handler again on subsequent calls. Taken
;; from `ert--run-test-debugger'.
(cl-incf num-nonmacro-input-events)
(if (and noninteractive (fboundp 'doom-cli-debugger))
(apply #'doom-cli-debugger args)
;; TODO Write backtraces to file
;; TODO Write backtrace to a buffer in case recursive error interupts the
;; debugger (happens more often than it should).
(apply #'debug args))))
;; ;;
;;; Time-stamped *Message* logs ;;; Time-stamped *Message* logs

View file

@ -125,14 +125,14 @@ Accepts `ansi' and `text-properties'. `nil' means don't render styles at all.")
(defvar doom-print-logging-level 'debug (defvar doom-print-logging-level 'debug
"The default logging level used by `doom-log'/`doom-print'.") "The default logging level used by `doom-log'/`doom-print'.")
(defvar doom-print-message-level 'info (defvar doom-print-message-level (if noninteractive 'debug 'info)
"The default logging level used by `message'.") "The default logging level used by `message'.")
(defvar doom-print--levels (defvar doom-print--levels
'(debug ; the system is thinking out loud '(debug ; the system is thinking out loud
info ; a FYI; to keep you posted info ; a FYI; to keep you posted
warning ; a dismissable issue that may have reprecussions later warning ; a dismissable issue that may have reprecussions later
error)) ; functionality has been disabled by misbehavior error)) ; functionality has been disabled/broken by misbehavior
(dotimes (i (length doom-print--levels)) (dotimes (i (length doom-print--levels))
(put (nth i doom-print--levels) 'level i)) (put (nth i doom-print--levels) 'level i))