:title: Themes :date: 2025-07-08 :tags: emacs :identifier: 20250708T133920 :signature: 5=2=1 Themes ====== Doric Themes ------------ Prot's new `doric-themes `__ are worth exploring .. code-block:: elisp (use-package doric-themes :ensure t) Modus Themes ------------ The excellent `modus-themes `__ are available out of the box in recent Emacs versions. .. code-block:: elisp :filename: emacs/lisp/alc-theme.el (require 'dbus) ; needed for later ;; Use `setopt' since modus supports automatically reloading the theme when these ;; are changed via the `customize' framework (setopt modus-themes-bold-constructs t modus-themes-italic-constructs t modus-themes-prompts '(bold italic) modus-themes-variable-pitch-ui nil) Loading them seems slighty complicated though? I want to run one of the ``modus-themes-load-`` functions so that the ``modus-themes-after-load-theme-hook`` hook is run however, these functions are not initially loaded by Emacs. ``(require 'modus-themes)`` does not work either, so I first have to run ``(load-theme 'modus- t)`` which will load the relevant module and then load the theme a second time with ``(modus-themes-load-)``. .. code-block:: elisp :filename: emacs/lisp/alc-theme.el (defun alc-theme-load-theme (variant) "Load the light or dark theme according to VARIANT." (require-theme 'modus-themes t) (if (eq 1 variant) (progn (modus-themes-load-theme 'modus-vivendi)) (modus-themes-load-theme 'modus-operandi))) Specifics of theme loading aside, let's pick a variant based on the current system theme. (Thanks to `auto-dark-emacs `__ for the DBus specifics.) .. code-block:: elisp :filename: emacs/lisp/alc-theme.el (defun alc-theme-sync-to-system-theme (_frame) "Choose a light/dark theme based on the current system preference." (alc-theme-load-theme (caar (dbus-call-method :session "org.freedesktop.portal.Desktop" "/org/freedesktop/portal/desktop" "org.freedesktop.portal.Settings" "Read" "org.freedesktop.appearance" "color-scheme")))) Also, set up a listener so that Emacs automatically updates if the preference changes (again, thanks to ``auto-dark-emacs`` for the DBus incantation) .. code-block:: elisp (when (display-graphic-p) (setq alc-theme-dbus-listener (dbus-register-signal :session "org.freedesktop.portal.Desktop" "/org/freedesktop/portal/desktop" "org.freedesktop.portal.Settings" "SettingChanged" (lambda (path var val) (when (and (string= path "org.freedesktop.appearance") (string= var "color-scheme")) (alc-theme-load-theme (car val))))))) If I ever need to, the listener can be disabled by running ``(dbus-unregister-object alc-theme-dbus-listener)`` However, the dbus code fails when I am SSH-ing into my Raspberry Pi so in that case we just want a theme loaded and be done with it. .. code-block:: elisp :filename: emacs/lisp/alc-theme.el (unless (display-graphic-p) (alc-theme-load-theme 1)) ; dark (provide 'alc-theme)