Estimated reading time: 4 minutes
Vim with day/night colourschemes¶
The fabulous Miss Biddulph asks via our EADS Linux list:
So, like most things this can either be really simple or horribly convoluted depending on where you wish to draw the usability line. Because Laura is asking, we’ll scratch the surface of a few odd ways to do this.
The simple solution¶
In many ways this is related to my awesome-timed-wallpaper hack, and to start with I’m going to proceed in a similar way.
The snippet below will configure the background and colourscheme depending on the time of day. You can change the bounds in any way you see fit1.
let hour = strftime('%H')
if hour >= 18
set background=dark
colorscheme jnrowe " Best theme
elseif hour >= 9
set background=light
colorscheme taqua
else
" Midnight to 08:59
set background=dark
colorscheme monokai
endif
If you (re-)start vim regularly this is all you’ll probably need. If — like me — you have very long running vim sessions, you’ll have to put in some more effort to make it work:
The easiest option would be binding it to a key and triggering it when you notice eye strain
Use vim 8’s new asynchronous timer support, see
:h timer
2Support pre-v8 vim by adding an autocmd on CursorHold
Script vim externally using vim’s client server support
…
Create a systemd user timer that triggers at a given time ;)
The ridiculous solution¶
We’ll need to figure out the actual daylight state. There are an enormous number of options available.
With Python¶
My upoints package can calculate sunrise and sunset:
>>> from upoints.point import Point
>>> p = Point(52.2, 0.2)
>>> p.sun_events() # UTC results
(datetime.time(5, 32), datetime.time(18, 15))
>>> p.sun_events(zenith='civil') # twilight
(datetime.time(4, 58), datetime.time(18, 49))
With redshift
¶
If you already use redshift — and you should — getting the current state is quite easy. Below is example output, and a quick sed-based method to parse the output for script usage:
$ redshift -p
Waiting for current location to become available...
Location: 52.2 N, 0.2 E
Period: Night
Colour temperature: 4500K
Brightness: 1.00
$ redshift -p 2>/dev/null | sed -E '/:/s,(.*): (.*),\U\1\E="\2", ; s,(\b) (\b),\1_\2,g'
PERIOD="Night"
COLOUR_TEMPERATURE="4500K"
BRIGHTNESS="1.00"
Another option might be to use redshift’s hook support, see the man page for how to configure hooks.
#!/bin/zsh
case $1 {
(period-changed)
case $3 {
(day) { notify-send "Make bright" } ;;
(night) { notify-send "Make dark" } ;;
}
}
Camera input¶
Assuming you have access to either a very good or very bad webcam you could even script support that takes in to account cloud cover, or occultation caused by buildings and trees.
For example, ImageMagick can be used to extract brightness from an image.
$ curl $cam_url \
| convert - -colorspace Gray -format "%[fx:quantumrange*image.mean]" info:
38244.2
$ convert pattern:GRAY0 -format "%[fx:quantumrange*image.mean]" info:
0
$ convert pattern:GRAY100 -format "%[fx:quantumrange*image.mean]" info:
65535
Note
As can be seen from the black(GRAY0
) and white(GRAY100
) examples,
the result on my system is a value between 0 and 65535. You should take
note that quantumrange
is a compile time depth setting; it can be
queried with the %q
escape, or by checking the Q
value in the
convert --version
output.
The above will only really work with very poor webcams that don’t attempt to autobalance their images, with reasonable devices it will be close to useless.
However, if you have a good quality camera image you may be able to extract the balancing data used from the image tags, and use that to infer the light level. exiv2 is great option to extract that data when available, and also supports gobject introspection making it possible to use it with lgi in awesomewm for desktop colours too!
Thoughts¶
That is definitely enough of that rabbit hole for me right now… I’m really looking forward to seeing people code golf some other solutions, be they useful or [hopefully] intriguing variations.
Footnotes
Authenticate this page by pasting this signature into Keybase.
Have a suggestion or see a typo? Edit this page