-
-
Notifications
You must be signed in to change notification settings - Fork 43
Caveats with after‐init‐hook and emacs‐startup‐hook
Elpaca does its work asynchronously, after reading your init file.
These means after-init-hook
and emacs-startup-hook
are run before packages are activated.
Elpaca provides elpaca-after-init-hook
, which is run after all queues in the init file are processed.
You can add the following to the end of your init file if you must rely on after-init-hook
or emacs-startup-hook
, but it is better to use elpaca-after-init-hook
:
;;END OF INIT FILE
;; prevents `elpaca-after-init-hook` from running more than once.
(setq elpaca-after-init-time (or elpaca-after-init-time (current-time)))
(elpaca-wait)
Users will notice that a configuration like the following:
(use-package desktop
:ensure nil
:config
(desktop-save-mode 1))
may frequently cause issues. Namely, when desktop-save-mode
is enabled immediately when desktop.el is loaded, desktop will automatically call desktop-read
to restore your buffer. The problem is that this call to desktop-read
occurs in the after-init-hook
: we see the code responsible for this at the end of desktop.el:
;; ----------------------------------------------------------------------------
;; When `desktop-save-mode' is non-nil and "--no-desktop" is not specified on the
;; command line, we do the rest of what it takes to use desktop, but do it
;; after finishing loading the init file.
;; We cannot use `command-switch-alist' to process "--no-desktop" because these
;; functions are processed after `after-init-hook'.
(add-hook
'after-init-hook
(lambda ()
(let ((key "--no-desktop"))
(when (member key command-line-args)
(setq command-line-args (delete key command-line-args))
(desktop-save-mode 0)))
(when desktop-save-mode
(desktop-read)
(setq inhibit-startup-screen t))))
Problems arise because desktop may restore buffers prior to elpaca having fully initialized and loaded user configurations. Consequently, for example, additions to org-mode-hook
may not run because desktop opened your org buffers prior to those additions being run by elpaca.
To resolve this, we may do something like the following:
(use-package desktop
:ensure nil
:hook
(elpaca-after-init-hook
. (lambda ()
(desktop-save-mode 1) ; Enable the mode right before
(let ((key "--no-desktop"))
(when (member key command-line-args)
(setq command-line-args (delete key command-line-args))
(desktop-save-mode 0)))
(when desktop-save-mode
(desktop-read)
(setq inhibit-startup-screen t)))))
Effectively, we have added the same function desktop.el adds to after-init-hook
but to elpaca-after-init-hook
. But we must be sure to ensure that desktop-save-mode
is called only right before desktop-read
is called --- in the above, we place it prior to the let form --- instead of in e.g. :config, for doing so will then cause desktop.el to still restore buffers via after-init-hook
.
With this solution, we preserve the behavior we would have had without elpaca, including respecting the --no-desktop
flag passed to Emacs.