doomemacs/lisp/lib/config.el
Henrik Lissner f9201eb218
refactor: introduce doom-context
Introduces a system to announce what execution contexts are active, so I
can react appropriately, emit more helpful logs/warnings in the case of
issues, and throw more meaningful errors.

* bin/doom: load module CLIs in the 'modules' context.
* lisp/cli/doctor.el: load package files in 'packages' context.
* lisp/doom-cli.el:
  - (doom-before-init-hook, doom-after-init-hook): trigger hooks at the
    correct time. This may increase startup load time, as the benchmark
    now times more of the startup process.
  - (doom-cli-execute, doom-cli-context-execute,
    doom-cli-context-restore, doom-cli-context-parse,
    doom-cli--output-benchmark-h, doom-cli-call, doom-cli--restart,
    doom-cli-load, run!): remove redundant context prefix in debug logs,
    it's now redundant with doom-context, which doom-log now prefixes
    them with.
* lisp/doom-lib.el (doom-log): prefix doom-context to doom-log output,
  unless it starts with :.
* lisp/doom-packages.el (package!, doom-packages--read): throw error if
  not used in a packages.el file or in the context of our package
  manager.
* lisp/doom-profiles.el (doom-profile--generate-init-vars,
  doom-profile--generate-load-modules): use modules doom-context instead
  of doom-init-time to detect startup.
* lisp/doom-start.el (doom-load-packages-incrementally-h): move function
  closer to end of doom-after-init-hook.
* lisp/doom.el:
  - (doom-before-init-hook, doom--set-initial-values-h,
    doom--begin-init-h): rename doom--set-initial-values-h to
    doom--begin-init-h and ensure it runs as late in
    doom-before-init-hook as possible, as that is the point where Doom's
    "initialization" formally begins.
  - (doom-after-init-hook): don't trigger at the end of command-line-1
    in non-interactive sessions. This will be triggered manually in
    doom-cli.el's run!.
* lisp/lib/config.el (doom/reload, doom/reload-autoloads,
  doom/reload-env): use 'reload' context for reload commands.
* modules/lang/emacs-lisp/autoload.el (+emacs-lisp-eval): use 'eval'
  context.
* modules/lang/org/config.el: remove doom-reloading-p; check for
  'reload' doom context instead.
2022-09-24 22:09:05 +02:00

138 lines
4.5 KiB
EmacsLisp

;;; lisp/lib/config.el -*- lexical-binding: t; -*-
(defvar doom-bin-dir (expand-file-name "bin/" doom-emacs-dir))
(defvar doom-bin (expand-file-name "doom" doom-bin-dir))
;;;###autoload
(defvar doom-after-reload-hook nil
"A list of hooks to run after `doom/reload' has reloaded Doom.")
;;;###autoload
(defvar doom-before-reload-hook nil
"A list of hooks to run before `doom/reload' has reloaded Doom.")
;;;###autoload
(defun doom/open-private-config ()
"Browse your `doom-user-dir'."
(interactive)
(unless (file-directory-p doom-user-dir)
(make-directory doom-user-dir t))
(doom-project-browse doom-user-dir))
;;;###autoload
(defun doom/find-file-in-private-config ()
"Search for a file in `doom-user-dir'."
(interactive)
(doom-project-find-file doom-user-dir))
;;;###autoload
(defun doom/goto-private-init-file ()
"Open your private init.el file.
And jumps to your `doom!' block."
(interactive)
(find-file (expand-file-name doom-module-init-file doom-user-dir))
(goto-char
(or (save-excursion
(goto-char (point-min))
(search-forward "(doom!" nil t))
(point))))
;;;###autoload
(defun doom/goto-private-config-file ()
"Open your private config.el file."
(interactive)
(find-file (expand-file-name doom-module-config-file doom-user-dir)))
;;;###autoload
(defun doom/goto-private-packages-file ()
"Open your private packages.el file."
(interactive)
(find-file (expand-file-name doom-module-packages-file doom-user-dir)))
;;
;;; Managements
(defmacro doom--if-compile (command on-success &optional on-failure)
(declare (indent 2))
`(let ((default-directory doom-emacs-dir))
(with-current-buffer (compile ,command t)
(let ((w (get-buffer-window (current-buffer))))
(select-window w)
(add-hook
'compilation-finish-functions
(lambda (_buf status)
(if (equal status "finished\n")
(progn
(delete-window w)
,on-success)
,on-failure))
nil 'local)))))
;;;###autoload
(defun doom/reload ()
"Reloads your private config.
This is experimental! It will try to do as `bin/doom sync' does, but from within
this Emacs session. i.e. it reload autoloads files (if necessary), reloads your
package list, and lastly, reloads your private config.el.
Runs `doom-after-reload-hook' afterwards."
(interactive)
(mapc #'require (cdr doom-incremental-packages))
(doom--if-compile (format "%S sync -e" doom-bin)
(doom-with-context '(reload modules)
(doom-run-hooks 'doom-before-reload-hook)
(doom-load (file-name-concat doom-user-dir doom-module-init-file) t)
(with-demoted-errors "PRIVATE CONFIG ERROR: %s"
(general-auto-unbind-keys)
(unwind-protect
(startup--load-user-init-file nil)
(general-auto-unbind-keys t)))
(doom-run-hooks 'doom-after-reload-hook)
(message "Config successfully reloaded!"))
(user-error "Failed to reload your config")))
;;;###autoload
(defun doom/reload-autoloads ()
"Reload only the autoloads of the current profile.
This is much faster and safer than `doom/reload', but not as comprehensive. This
reloads your package and module visibility, but does not install new packages or
remove orphaned ones. It also doesn't reload your private config.
It is useful to only pull in changes performed by 'doom sync' on the command
line."
(interactive)
(require 'doom-profiles)
;; TODO: Make this more robust
(doom-with-context 'reload
(dolist (file (mapcar #'car doom-profile-generators))
(when (string-match-p "/[0-9]+-loaddefs[.-]" file)
(load (doom-path doom-profile-dir doom-profile-init-dir-name file)
'noerror)))))
;;;###autoload
(defun doom/reload-env ()
"Reloads your envvar file.
DOES NOT REGENERATE IT. You must run 'doom env' in your shell OUTSIDE of Emacs.
Doing so from within Emacs will taint your shell environment.
An envvar file contains a snapshot of your shell environment, which can be
imported into Emacs."
(interactive)
(doom-with-context 'reload
(let ((default-directory doom-emacs-dir))
(with-temp-buffer
(doom-load-envvars-file doom-env-file)
(message "Reloaded %S" (abbreviate-file-name doom-env-file))))))
;;;###autoload
(defun doom/upgrade ()
"Run 'doom upgrade' then prompt to restart Emacs."
(interactive)
(doom--if-compile (format "%S upgrade --force" doom-bin)
(when (y-or-n-p "You must restart Emacs for the upgrade to take effect.\n\nRestart Emacs?")
(doom/restart-and-restore))))