Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clickable links for error messages encountered during load. #1

Merged
merged 4 commits into from
Dec 12, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 40 additions & 16 deletions init-dir.el
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@
;; load. Display would also have an easy way to reload that file and
;; get new perf data.
;;
;; Improve error messages during load -- Add a link to the location of
;; the read error or the form being evaluated.
;;
;; Improve package debugging -- if selected packages were unable to be
;; activated (indicating they're not installed) display a helpful
;; warning message.
Expand Down Expand Up @@ -130,25 +127,25 @@ time to load."
(setq dir (or dir (expand-file-name "init" user-emacs-directory))
init-dir--error-and-warning-list '())

(mapc #'init-dir--load-single-file
(delete-dups
(mapcar #'file-name-sans-extension
(init-dir--directory-files-filter
dir
#'init-dir--file-init-loadable-p
t))))
(dolist (file (delete-dups
(mapcar #'file-name-sans-extension
(init-dir--directory-files-filter
dir
#'init-dir--file-init-loadable-p
t))))
(init-dir--load-single-file (init-dir--choose-as-load file) dir))

;; Display any warnings.
(when init-dir--error-and-warning-list
(dolist (message (nreverse init-dir--error-and-warning-list))
(display-warning 'init message))))

(defun init-dir--load-single-file (file)
(defun init-dir--load-single-file (file root-dir)
"Load a single file, with additional structure around it.

FILE: File path to a file to load.

FILE has the same meaning as in `load'."
FILE: File path to a file to load. Unlike `load', this must be
an absolute path with an extension.
ROOT-DIR: Directory root being loaded from."
(let ((prev-time (time-convert nil 'list))
(debug-ignored-errors '())
(debug-on-error t)
Expand All @@ -157,20 +154,47 @@ FILE has the same meaning as in `load'."
(init-dir--long-load-time-warning init-dir--long-load-time-warning))

(let* (;; This line actually loads the file as a side effect.
(load-error (catch 'init-dir--load-error (load file) nil))
(load-error (catch 'init-dir--load-error
(load file nil nil t t)
nil))

(cur-time (time-convert nil 'list))
(delta-time (float-time (time-subtract cur-time prev-time))))
(when load-error
(push (format "Loading `%s' had an error: %S"
file (error-message-string load-error))
(init-dir--make-file-link file root-dir)
(error-message-string load-error))
init-dir--error-and-warning-list))
(when (and init-dir--long-load-time-warning
(> delta-time init-dir--long-load-time-warning))
(push (format "Loading `%s' took %f seconds."
file delta-time)
init-dir--error-and-warning-list)))))

(defun init-dir--make-file-link (file root-dir)
"Return clickable text for a link to FILE.

The text will contain FILE, with the ROOT-DIR prefix removed.
Clicking the text will open the FILE, as if by `find-file'.

FILE: An absolute path to a file.
ROOT-DIR: Directory root that file is in."
(if (not (fboundp 'buttonize)) ;Requires GNU Emacs 29.1
file
(buttonize (file-relative-name file root-dir)
#'find-file
file
"Visit this file")))

(defun init-dir--choose-as-load (file)
"Return FILE with the suffix `load' would add."
(catch 'return
(dolist (suffix load-suffixes)
(let ((file-with-suffix (concat file suffix)))
(when (file-exists-p file-with-suffix)
(throw 'return file-with-suffix))))
nil))

(defun init-dir--debugger (&rest args)
"Replacement debugger function while running `init-dir--load-single-file'.

Expand Down
Loading