Struggling to understand an interaction between consult-theme and alphapapa's customize-theme-faces

For my light theme I like ef-maris-light quite a bit, however I’m not a fan of the ERC colors, so I decided to change them on my own. In order to do this I came across a function Alphapapa wrote to customize themes on his github, and added it to my config:

(defun unpackaged/customize-theme-faces (theme &rest faces)
  "Customize THEME with FACES.
Advises `enable-theme' with a function that customizes FACES when
THEME is enabled.  If THEME is already enabled, also applies
faces immediately.  Calls `custom-theme-set-faces', which see."
  (declare (indent defun))
  (when (member theme custom-enabled-themes)
    ;; Theme already enabled: apply faces now.
    (let ((custom--inhibit-theme-enable nil))
      (apply #'custom-theme-set-faces theme faces)))
  (let ((fn-name (intern (concat "unpackaged/enable-theme-advice-for-" (symbol-name theme)))))
    ;; Apply advice for next time theme is enabled.
    (fset fn-name
          (lambda (enabled-theme)
            (when (eq enabled-theme theme)
              (let ((custom--inhibit-theme-enable nil))
                (apply #'custom-theme-set-faces theme faces)))))
    (advice-remove #'enable-theme fn-name)
    (advice-add #'enable-theme :after fn-name)))

I applied it to ef-themes in my config:

(use-package ef-themes
  :config
  (dolist (theme ef-themes-collection)
    (ef-themes-with-colors
    (unpackaged/customize-theme-faces theme
      `(erc-notice-face ((t :foreground ,fg-dim)))
      `(erc-default-face ((t :foreground ,fg-main)))
      `(erc-input-face ((t :foreground ,fg-alt :weight bold)))
      `(erc-my-nick-face ((t :foreground ,fg-alt)))
      `(erc-current-nick-face ((t :foreground ,warning :weight bold)))
      `(erc-direct-msg-face ((t :foreground ,green-cooler)))
      `(erc-nick-msg-face ((t :foreground ,green-cooler)))
      `(erc-timestamp-face ((t :foreground ,fg-dim)))
      `(erc-header-face ((t :box ,fg-main :foreground ,docstring)))))))

I usually run the dolist sexp manually, never did figure out how to hook this right, and figured it was a low-effort enough task that I just forgot about trying to hook it. This setup worked fine with counsel and counsel-load-theme. However, it seems to interact with consult-theme somewhere, namely adding this to my config makes the preview function of consult-theme stop working. It also seems to stop consult-theme from recognizing that a theme has been changed once it’s already been loaded once. Anyone know what might be causing the conflict?

I used with-emacs.sh to try to reproduce this with the latest version of ef-themes and consult. I used the consult-theme command (there seem to be no consult-load-theme command). And I used the use-package form you provided. Everything seems to work fine, including consult-theme’s previews and selecting a theme.

That’s odd.

Here’s what I see:

url_upload_665603167c343.mp4 [video-to-gif output image]

And here’s a minimal reproducible config

(require 'package)

(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
(package-initialize)

(unless package-archive-contents
  (package-refresh-contents))

(unless (package-installed-p 'use-package)
  (package-install 'use-package))

(require 'use-package)
(setq use-package-always-ensure t)

(defun unpackaged/customize-theme-faces (theme &rest faces)
  "Customize THEME with FACES.
Advises `enable-theme' with a function that customizes FACES when
THEME is enabled.  If THEME is already enabled, also applies
faces immediately.  Calls `custom-theme-set-faces', which see."
  (declare (indent defun))
  (when (member theme custom-enabled-themes)
    ;; Theme already enabled: apply faces now.
    (let ((custom--inhibit-theme-enable nil))
      (apply #'custom-theme-set-faces theme faces)))
  (let ((fn-name (intern (concat "unpackaged/enable-theme-advice-for-" (symbol-name theme)))))
    ;; Apply advice for next time theme is enabled.
    (fset fn-name
          (lambda (enabled-theme)
            (when (eq enabled-theme theme)
              (let ((custom--inhibit-theme-enable nil))
                (apply #'custom-theme-set-faces theme faces)))))
    (advice-remove #'enable-theme fn-name)
    (advice-add #'enable-theme :after fn-name)))

(use-package ef-themes
  :config
  (dolist (theme ef-themes-collection)
    (ef-themes-with-colors
    (unpackaged/customize-theme-faces theme
      `(erc-notice-face ((t :foreground ,fg-dim)))
      `(erc-default-face ((t :foreground ,fg-main)))
      `(erc-input-face ((t :foreground ,fg-alt :weight bold)))
      `(erc-my-nick-face ((t :foreground ,fg-alt)))
      `(erc-current-nick-face ((t :foreground ,warning :weight bold)))
      `(erc-direct-msg-face ((t :foreground ,green-cooler)))
      `(erc-nick-msg-face ((t :foreground ,green-cooler)))
      `(erc-timestamp-face ((t :foreground ,fg-dim)))
      `(erc-header-face ((t :box ,fg-main :foreground ,docstring))))))
  )

(use-package vertico
  :config (vertico-mode))

(use-package consult)

And here’s what I expect:

url_upload_665603a4b4ded.mp4 [video-to-gif output image]
with a minimal reproducible config:

(require 'package)

(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
(package-initialize)

(unless package-archive-contents
  (package-refresh-contents))

(unless (package-installed-p 'use-package)
  (package-install 'use-package))

(require 'use-package)
(setq use-package-always-ensure t)

(use-package vertico
  :config (vertico-mode))

(use-package consult)

I wonder if anyone else can reproduce my issue?

My emacs version is GNU Emacs 29.3 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.41, cairo version 1.18.0), my ef-themes version is 1.7.0, and my consult version is consult-20240523.754.

Also, my fault, it is consult-theme like you stated, not consult-load-theme.

My browser says those video files are corrupt.

Anyway, please note that the config you provided is not the same as what I tested with. I would recommend testing with what I did first, i.e. run with-emacs.sh -i consult -i ef-themes, then evaluate the (use-package ef-themes ...) form, then M-x consult-theme RET and try previewing the various themes. If that still fails, it will be curious. If it doesn’t, then the difference between that config and what you pasted will likely point to the problem.

I’ve changed the videos to gifs, but they’re small so not sure it’s any more viewable.

Could you try it with Vertico enabled? I’m not sure how I would recreate (or really even have the concept of) the effect I’m seeing without having a way to switch selections like you can with vertico. If I use your with-emacs.sh script with vertico

./with-emacs.sh -i consult -i ef-themes -i vertico

enable vertico mode, evaluate the (use-package ef-themes ...) form and the unpackaged/customize-theme-faces definition then I can recreate the effect.

output2

Gif is hard to see so I’ve also uploaded to streamable just so what I’m doing is in plain sight, but the link will expire in 48 hours. As you can see, it previews the first theme fine (Tango), but does not preview the rest of the themes.

Okay, here’s a video showing how it works for me, even with Vertico:

You can also view it here: Welcome to unpackaged.el Discussions! · alphapapa/unpackaged.el · Discussion #26 · GitHub (And Firefox also claims that that file is corrupted, even though it was recorded with ffmpeg and plays fine in VLC, so who knows what’s going on there. It seems to play in Chromium.)

I have no idea why it would do this, but after I paste everything into the scratch buffer as you did and evaluate the defun and use-package sexps individually it works. If I do C-c C-e, evaluating the whole buffer, it gives me the error I’m seeing.

On a wholly different note, odd what’s happening with the videos. I also used ffmpeg to record. I could not open the video you posted from my phone on either this site or on github, however on my desktop I was able to open it on the github site (still not on this site).

Hm, I can confirm the same behavior. That is strange, indeed.

I also don’t understand what’s up with the video. I just told ffmpeg to output to a .mp4 file and left everything else as default. But video encoding is a world of its own.