Change Gnome Terminal Colors by Time of Day
As of Ubuntu 16.04 (maybe earlier) the Gnome Terminal has built in support for Solarized Dark and Light themes. I also run Redshift on my machine to reduce the blue light that can interfere with sleep. (f.lux is another popular app for the same purpose).
I typically use Solarized Dark during the day. However, when Redshift starts working in the evening, the screen gets very difficult to see. I had been using a bash script in combination with .bashrc
to change the colors of the default profile. This stopped working when I updated to Ubuntu 16.04. So it was back to roughing it, and making the change manually until I found another Gnome terminal solarized script to script this change.
However, I ran into another problem with this script. It would not run correctly from cron since it uses dconf
(on Ubuntu 16.04) and the $DBUS_SESSION_BUS_ADDRESS
is not available in the limited cron environment.
I finally found this great answer on stackoverflow that explain how to get a correct $DBUS_SESSION_BUS_ADDRESS
with cron enviroment. I then created the following short script to change the only three parameters that I care about, background-color
, foreground-color
, and bold-color
in my Default profile.
The first three lines are the important part for getting the script to run from cron.
#!/bin/bash
# inspired by https://github.com/Anthony25/gnome-terminal-colors-solarized
# cron script to switch terminal colors in the evening
# Set up environment if necessary
export DISPLAY=:0
# -z True if the length of string is zero.
if [ -z $DBUS_SESSION_BUS_ADDRESS ]; then
# http://stackoverflow.com/questions/10374520/gsettings-with-cron
PID=$(pgrep gnome-session)
export DBUS_SESSION_BUS_ADDRESS=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$PID/environ|cut -d= -f2-)
fi
[ -z $DBUS_SESSION_BUS_ADDRESS ] && exit
# http://ethanschoonover.com/solarized
# light
base3='#fdfdf6f6e3e3' # background
base00='#65657b7b8383' # body text/default code/primary content
base01='#58586e6e7575' # optional emphasized content
# dark
base03='#00002b2b3636' # background
base0='#838394949696' # body text/default code/primary content
base1='#9393a1a1a1a1' # optional emphasized content
profile_id="$(dconf read /org/gnome/terminal/legacy/profiles:/default|sed s/\'//g)"
# echo $profile_id >> /home/antonios/terminal-color.log
# http://www.tldp.org/LDP/abs/html/functions.html
set_dark() {
dconf write /org/gnome/terminal/legacy/profiles:/:$profile_id/background-color "'$base03'"
dconf write /org/gnome/terminal/legacy/profiles:/:$profile_id/foreground-color "'$base0'"
dconf write /org/gnome/terminal/legacy/profiles:/:$profile_id/bold-color "'$base1'"
}
set_light() {
dconf write /org/gnome/terminal/legacy/profiles:/:$profile_id/background-color "'$base3'"
dconf write /org/gnome/terminal/legacy/profiles:/:$profile_id/foreground-color "'$base00'"
dconf write /org/gnome/terminal/legacy/profiles:/:$profile_id/bold-color "'$base01'"
}
# http://www.tldp.org/LDP/abs/html/comparison-ops.html
# quotes needed here, otherwise error when no arguments
if [ "$1" = "light" ]; then
set_light
elif [ "$1" = "dark" ]; then
set_dark
else
# http://www.tldp.org/LDP/abs/html/quotingvar.html
# quotes not needed in this case, because value will always be single word (number)
if [ "$(date +%H)" -ge 17 ]; then
set_light
else
set_dark
fi
fi
I then added the following line via crontab -e
0 17 * * * ~/dotfiles/term-color.sh light
This setup switches all open terminals from dark to light at 5 pm. This has the added benefit of being a reminder to wrap up my work day when the screen turns to the light color scheme. This only works while I am logged in. That is perfectly OK since I only need the switch when I am on my computer. I also run this script when I login to make sure that the terminal is the correct color for the time of day. That part is set up in the graphical Startup Applications app in Ubuntu.
One more step is required for this to work correctly in Vim solarized colorscheme. Both Neovim and Vim8 support timers so this code will work for either.
I added these lines to my .vimrc
:
colorscheme solarized
let hour = strftime("%H")
if hour >= 17
set background=light
else
set background=dark
endif
if hour < 17
let minute = strftime("%M")
let second = strftime("%S")
func ColorHandler(timer)
set background=light
endfunction
let t = timer_start(((17-hour)*60*60-minute*60-second)*1000, 'ColorHandler')
endif
You may be thinking that running a timer is too much overhead for this. I did not notice any performance hit.
If this post was interesting or useful to you I would love to hear your comments below.