Setting Emacs theme based on ambient light
matthewbilyeu.com
matthewbilyeu.com
let hr = (strftime('%H'))
if hr >= 17
set background=dark
elseif hr >= 7
set background=light
elseif hr >= 0
set background=dark
endif
Using a light sensor would be cool, but I actually work from a desktop PC most of the time, so no sensor. I guess the next best thing would be something like f.lux does: query some web service for the sunset time at your current location.http://www.yoctopuce.com/EN/products/usb-environmental-senso...
I use one to automatically adjust the brightness of my Dell display.
I'm curious if using `run-with-timer` causes any performance issues in emacs. If so one option is to watch the value outside of emacs and then change the theme using `emacsclient -d "(load-theme 'my-dark-theme t)"` from the script.
Personally, I'd reimplement it the way you suggest - I'd put the timer loop in C code to save on repeatedly starting a process, and then make it run emacsclient -e "(change-theme-for-lighting %d)", where %d is a sensor value, whenever that value crosses a threshold.
Alternatively, if you want to keep the entire business logic within Emacs Lisp code, there's some way to make it work too. I'd look into documentation of #'make-process[0]. There's an argument :FILTER that would let you set a function that receives stdout from that process. Alternatively, #'start-process-shell-command with NIL for buffer, + #'set-process-filter should achieve the same thing. So the C program would be barfing out the sensor value every second or so, and the process filter would read it.
(You might also want to read through the sources of #'shell-command to see how it uses the above facilities to handle asynchronous shell processes - the ones you invoke with M-x async-shell-command - but I think it'll work out of the box, and the process filter will only be executed as new output arrives.)
--
[0] - in Emacs, type: C-h f make-process. Gotta love the self-documenting features of this editor. Actually, half of my comment is based on what I just read in docs of various Emacs functions. Also, hint: make sure you install Emacs with sources - then you can easily jump from help buffer directly into code implementing the thing you're reading about.
(defun daytime? () (sunrise-sunset) (let ((range (mapcar 'car (butlast (solar-sunrise-sunset (calendar-current-date)))))) (let ((sunrise (car range)) (sunset (cadr range)) (now (string-to-number (format-time-string "%H")))) (< sunrise now sunset))))
(if (daytime?) (light) (dark))
f.lux nicely takes away only the blue light but this isn't always enough for the bright backgrounds of modern homepages and text editors.
* do not offer granular enough control of the brightness on the low end (the backlight is either kind of dim, or nearly/completely off, with no in-between setting), or they
* do not have enough contrast at low brightness to read easily.
In either case, the display is more readable by having the backlight on bright, and darkening most of the display (by changing the background color).
Of course, this does not apply to all displays, but every display has pretty fine control its total light output by changing the colors it is displaying.
[1] https://github.com/m-khvoinitsky/dark-background-light-text-...
If Gnome can read your ambient sensor then monitor-sensor is the cli tool from that package to look at.
M-x set-background-color snow2, snow3, or snow4
or wheat2, wheat3, wheat4. or MistyRose1, MistyRose2, MistyRose3.
[0]:https://www.gnu.org/software/emacs/manual/html_node/elisp/Mi...