-
-
Notifications
You must be signed in to change notification settings - Fork 49
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.