doomemacs
doomemacs copied to clipboard
Support for dark/light theme switching (match OS preference, e.g. under macOS)
Describe your request
macOS allows the user to specify a preference for a dark or light UI theme, with apps adapting both UI elements and (in some cases) their content presentation to match the user preference. E.g. browsers forward the preference to websites via the prefers-color-scheme
CSS media query; editors switch syntax highlighting themes; etc.
The feature could be implemented by asking the user to define their preferred light and dark mode themes, with sensible defaults, e.g. instead of (or in addition to) (setq doom-theme ...)
, the user could specify (setq doom-theme-dark 'modus-vivendi doom-theme-light 'modus-operandi)
.
In my current personal config (I'm in the process of giving Doom Emacs a try), I have the following snippet:
(setq system-is-mac (equal 'darwin system-type))
(defun get-appearance-preferences ()
(if system-is-mac
(do-applescript "
tell application \"System Events\"
tell appearance preferences
if (dark mode) then
return dark
else
return light
end if
end tell
end tell
")
"dark")
This is accompanied by https://github.com/cormacrelf/dark-notify and a shell script that is running in the background (installed manually in system preferences / users / login items):
#!/bin/sh
set -eu
# brew install cormacrelf/tap/dark-notify
export PATH=/opt/homebrew/bin:/usr/local/bin:$PATH
exec dark-notify -c "emacsclient -e '(update-theme)'"
The function update-theme
polls get-appearance-preferences
and selects the preferred theme.
Of course it would be wonderful if this scheme was OS-independent (I'm also an OpenBSD user, but I'm not sure what's the standard method for specifying dark/light preference), and if it required less manual setup on macOS (although that's probably something that Emacs itself should address).
Briefly explain its use-case
The user can specify the variables doom-theme-dark
and doom-theme-light
(with sane defaults), and Emacs automatically chooses the theme based on these preferences, and the current system setting. Ideally, Emacs switches between light/dark mode whenever the rest of the system does.
emacs-plus
already has this.
Any other OS except windows it's a pot luck if a user has a way to specify dark/light preference (GNOME is currently the outlier)
there is https://github.com/LionyxML/auto-dark-emacs which should work on linux- it says it only supports gnome, but it registers a dbus listener for the org.freedesktop.appearance.color-scheme settings key, which is a standard on linux that already has quite decent support I believe- KDE plasma, gnome and the elementary OS desktop at least should work.
I'll try this out ^^
If you're not using a full Desktop Environment, you can use darkman
to automatically switch various programs between light and dark mode, and there's darkman.el
to sync the Emacs theme.
there is https://github.com/LionyxML/auto-dark-emacs which should work on linux- it says it only supports gnome, but it registers a dbus listener for the org.freedesktop.appearance.color-scheme settings key, which is a standard on linux that already has quite decent support I believe- KDE plasma, gnome and the elementary OS desktop at least should work.
I'll try this out ^^
Works without issues on Fedora 39.
So I added
(use-package! auto-dark
:after doom-themes
:config (auto-dark-mode t)
(setq auto-dark-dark-theme 'doom-one)
(setq auto-dark-light-theme 'doom-one-light))
to my config and it works, but there is an issue on startup- it seems to load two themes somehow, which affects for example the color of the line numbers to the left of the buffer.
If I start emacs in light mode, I have doom-one, leuven
in custom-enabled-themes
and in dark mode it's doom-one, wombat
. I haven't found a way to fix this yet. When I switch themes while emacs is running it works as expected.
@NANASHI0X74 You need doom-ui
instead of doom-themes
as of doom v2023-12-08, I already updated the example upstream: https://github.com/LionyxML/auto-dark-emacs/pull/40 - With that custom-enabled-themes
only has one theme as value for me (both after startup and switching).
Not sure how leuven
/wombat
could get in there for you. Changing to doom-ui
will likely mask that issue because auto-dark-mode
will overwrite it. But still maybe make sure this is not from some other config? (I.e., start doom with the default config and see if the issue persists.)
wombat and leuven are the defaultd auto-dark-emacs uses, I suspect that's why they get in there
Sláinte, Rian Lindenberger
On Tue, 19 Dec 2023, 10:12 Luis Gerhorst, @.***> wrote:
@NANASHI0X74 https://github.com/NANASHI0X74 You need doom-ui instead of doom-themes as of doom v2023-12-08, I already updated the example upstream: LionyxML/auto-dark-emacs#40 https://github.com/LionyxML/auto-dark-emacs/pull/40 - With that custom-enabled-themes only has one theme as value for me (both after startup and switching).
Not sure how leuven/wombat could get in there for you. Changing to doom-ui will likely mask that issue because auto-dark-mode will overwrite it. But still maybe make sure this is not from some other config? (I.e., start doom with the default config and see if the issue persists.)
— Reply to this email directly, view it on GitHub https://github.com/doomemacs/doomemacs/issues/6424#issuecomment-1862384198, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEF3ZHURRHE64U377K33ZZTYKFK6HAVCNFSM5XGQQXU2U5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOBWGIZTQNBRHE4A . You are receiving this because you were mentioned.Message ID: @.***>
Makes sense. I just realized you have to set the variables before activating the mode. Otherwise they are not in effect until the code runs again.
I recommend using emacs-plus on Mac, which automatically change theme with the system.
@yonghuier
I recommend using emacs-plus on Mac, which automatically change theme with the system.
I use emacs-plus, and I was previously on Spacemacs where I was able to get said hook to work; but on DOOM I just can't seem to manage it. I've put the add-hook
in config.el
, in init.el
, in Emacs' init.el
, I've used load-theme
, setq doom-theme
, every alternative I can imagine; and yet, it simply does not register. Where do I put it and how do I do it to get it to actually work?
DEAR PEOPLE FROM THE FUTURE: I don't fully understand what the problem was, but either one of letf!
or setq doom-theme
made it not work. The config.el
snippet that finally got it working for me uses only standard elisp:
(progn
(defun lighting (mood)
(pcase mood
('light (load-theme 'doom-one-light t))
('dark (load-theme 'doom-one t))))
(add-hook 'ns-system-appearance-change-functions #'lighting))
If anyone knows what the heck is going on there that'd be great. I'd like to know which of me or DOOM is dumber.
Try putting auto-dark-mode
on the doom-init-ui-hook
instead. (after! doom-ui ...)
is the same as having no after!
block at all, since there's no scenario where doom-ui
isn't already loaded by that point. E.g.
(use-package! auto-dark
:hook (doom-init-ui . auto-dark-mode)
:config
(setq auto-dark-dark-theme 'doom-one)
(setq auto-dark-light-theme 'doom-one-light))
Fwiw, this works well in my config:
(use-package! auto-dark
:defer t
:init
(setq! auto-dark-dark-theme 'doom-solarized-dark
auto-dark-light-theme 'doom-solarized-light)
;; Inspired by doom-ui.el.
;; Note that server-after-make-frame-hook also avoids the issues with an early
;; start of the emacs daemon using systemd, which causes problems with the
;; DBus connection that auto-dark mode relies upon.
(let ((hook (if (daemonp)
'server-after-make-frame-hook
'after-init-hook)))
;; Depth -95 puts this before doom-init-theme-h, which sounds like a good
;; idea, if only for performance reasons.
(add-hook hook #'auto-dark-mode -95)))