evil
evil copied to clipboard
Unable to set certain variables by `:custom` in `use-package`
Issue type
- Bug report
Environment
Emacs version: GNU Emacs 29.1 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.38, cairo version 1.17.8)
Operating System: Arch Linux
Evil version: Evil version 1.15.0
Evil installation type: MELPA
Graphical/Terminal: Wayland/Terminal
Tested in a make emacs
session (see CONTRIBUTING.md): No
Reproduction steps
- Set variable
evil-want-Y-yank-to-eol
withuse-package
(pewcfg::use-package evil
:custom
(evil-want-Y-yank-to-eol t)
:config
(evil-mode 1))
- Start Emacs
Expected behavior
The value of evil-want-Y-yank-to-eol
is t
.
Actual behavior
The value of evil-want-Y-yank-to-eol
is nil
.
Further notes
This seems to be a bug caused by the initializers stored in evil-pending-custom-initialize
.
For example, the custom variable evil-want-Y-yank-to-eol
has a initializer evil-custom-initialize-pending-reset
which adds a initialization form to the list evil-pending-custom-initialize
.
https://github.com/emacs-evil/evil/blob/d28206ccff74bc07ba335b8ff77805564f6928d7/evil-vars.el#L623-L628
That list is iterated by evil-run-pending-custom-initialize
.
https://github.com/emacs-evil/evil/blob/d28206ccff74bc07ba335b8ff77805564f6928d7/evil-vars.el#L68-L74
That function is called by hook evil-after-load-hook
whenever package evil
is required.
https://github.com/emacs-evil/evil/blob/d28206ccff74bc07ba335b8ff77805564f6928d7/evil.el#L154
If we expand a use-package
form
(message "%s" (pp-to-string (macroexpand-all '(use-package evil
:init
(something in :init)
:config
(something else in :config)
(evil-mode 1)
:custom
(evil-want-Y-yank-to-eol t)))))
Then we have
(progn
(use-package-ensure-elpa 'evil
'(t)
'nil)
(defvar use-package--warning71
#'(lambda
(keyword err)
(let
((msg
(format "%s/%s: %s" 'evil keyword
(error-message-string err))))
(display-warning 'use-package msg :error))))
(condition-case err
(progn
(let
((custom--inhibit-theme-enable nil))
(if
(memq 'use-package custom-known-themes)
nil
(custom-declare-theme 'use-package 'use-package-theme nil
(list))
(enable-theme 'use-package)
(setq custom-enabled-themes
(remq 'use-package custom-enabled-themes)))
(custom-theme-set-variables 'use-package
'(evil-want-Y-yank-to-eol t nil nil "Customized with use-package evil")))
(condition-case err
(something in :init)
((debug error)
(funcall use-package--warning71 :init err)))
(if
(not
(require 'evil nil t))
(display-warning 'use-package
(format "Cannot load %s" 'evil)
:error)
(condition-case err
(progn
(something else in :config)
(evil-mode 1)
t)
((debug error)
(funcall use-package--warning71 :config err)))))
((debug error)
(funcall use-package--warning71 :catch err))))
We can see that custom-theme-set-variables
is invoked before require
. Then our customized value is inevitably overwritten.
Same thing applies to variables
-
evil-search-module
-
evil-visual-newline-commands
-
evil-motions
-
evil-intercept-maps
-
evil-overriding-maps
-
evil-disable-insert-state-bindings
-
evil-want-Y-yank-to-eol
However, a strange thing is, if these variable are set with setq
in either :init
or :config
block of use-package
, they work perfectly fine. I think this might because of the setter of these custom variables, which uses set-default
. I don't know too much about this mechanism.
Final thought
evil-pending-custom-initialize
was added 11 years ago.
https://github.com/emacs-evil/evil/commit/b26b2861d943a601814ac373c8deb7e4863fbaec
This piece of code seems stale and not update-to-date with current use cases. I can see a lot custom variables now in Evil do not use this initialization idiom.
Do we still need it?
Someone asked the same problem back in 2021 but the issue was closed as it was not considered an Evil bug: https://github.com/emacs-evil/evil/issues/1486#issuecomment-876371225