reddit / emacs
Light/Dark mode
16936883626 · 2022-11-21 07:46
Is there a way in elisp to set the light/dark mode based on the time? I know have used circadian.el, but I am trying to learn more about programming/emacs and was wondering if there was a way to do it without a third party package. Right now I have:
```
;; theme
(defun set-theme-based-on-time ()
"Get the hour for light/dark mode."
((let current-hour "%H"))
(if (or (> current-hour 9) (< current-hour 17))
(load-theme 'modus-operandi t)
(load-theme 'modus-vivendi t)))
(set-theme-based-on-time)
```
funk443 · 2022-11-21 08:17
Don't forget to disable the theme before loading another one
_viz_ · 2022-11-21 09:27
run-at-time should do the job.
ieoa · 2022-11-21 09:48
What do you mean? Like the OP, I just call `load-theme` when I switch themes
funk443 · 2022-11-21 10:16
But I think I saw you have to disable a theme before you load the other one somewhere.
manueldeljesus · 2022-11-21 10:17
I would say that the best way to learn how to do it is to read and understand the code of circadian.el. The package solves the problem in Elisp, so the best way to proceed is to learn how it does it. At least in my opinion.
At the end of the day, third party packages were originally the way to do it by someone that had your same needs but no access to previous work.
_viz_ · 2022-11-21 11:00
Themes can be stacked on top of each other so ideally you do have to disable other themes before enabling one to avoid funny effects. This behaviour might seem funky but remember that custom themes can also set user options, in fact when you use the customise interface to change options they are stored under the special "user" theme.
[deleted] · 2022-11-21 13:49
[deleted]
white-tanuki · 2022-11-21 13:58
Here's a snippet of what I use to illustrate an example (could most certainly be done better, but it works for me).
With something like this you only need to copy/adapt the functions `circadian--frac-to-time`, `circadian-sunrise`, `circadian-sunset`.
```
(defun sunset-formatted ()
(format "%02d:%02d" (car (circadian-sunset)) (car (cdr (circadian-sunset)))))
(let ((light 'modus-operandi)
(dark 'modus-vivendi)
(sunset (sunset-formatted)))
(load-theme light t t)
(load-theme dark t t)
(run-at-time sunset (* 60 60 24)
(lambda (light dark)
(disable-theme light)
(enable-theme dark))
light dark)
(message "Theme loaded"))
```
a-c-d-w · 2022-11-21 15:30
Circadian never worked right for me, so I wrote \[dawn.el\]([https://git.acdw.net/emacs/tree/lisp/dawn.el](https://git.acdw.net/emacs/tree/lisp/dawn.el)) for my own purposes. I use it like this:
(require 'dawn)
(dawn-schedule #'modus-themes-load-operandi
#'modus-themes-load-vivendi)
LionyxML · 2022-11-21 22:34
Well.
There's this package: [https://github.com/LionyxML/auto-dark-emacs](https://github.com/LionyxML/auto-dark-emacs)
But it works by tracking your system settings (works for MacOS, Linux and Windows).
You leave your OS decide when it is time to change themes and Emacs will automatically follow its configs.
Example: Basically if you have MacOS on Light theme, there's some customized light theme on emacs. If MacOS changes to a dark theme, Emacs will change to another custom dark theme.
You can see it working here: [https://raw.githubusercontent.com/LionyxML/auto-dark-emacs/master/images/demo.gif](https://raw.githubusercontent.com/LionyxML/auto-dark-emacs/master/images/demo.gif)
16936883626 · 2022-11-22 03:10
I understand, and circadian was working for me but it had additional functionality I wasn’t using (using sunrise/sunset when I’m only interested in setting it by time). I was also curious about trying it in elisp
16936883626 · 2022-11-22 04:26
What are the arguments that run-at-time takes
16936883626 · 2022-11-22 18:32
Update: I seemed to have solve this problem for the moment. I have not tested it past the time where dark mode should be enabled but this snippet at least enables the correct light theme.
```
(defun onoff (theme1 theme2)
(disable-theme theme1)
(enable-theme theme2))
(defun set-theme-time ()
(let ((light 'modus-operandi)
(dark 'modus-vivendi))
(load-theme light t t)
(load-theme dark t t)
(run-at-time "8:00" nil #'onoff dark light)
(run-at-time "17:00" nil #'onoff light dark)
(message "Theme Loaded")))
(set-theme-time)
```
Thank you everyone for your help!