Time controlled colour schemes for Vim and Iterm2

jim-rohm
Published on May 26th 2020
A screenshot of a computer screen
If you have read any of my other articles, you will know that I live in a terminal. All my work is done in Iterm2, using NeoVim, Tmux and a multitude of other tools. You will probably also know that I have taken the time to get my terminal and Vim looking just how I like it. I have written a theme (Ariake) for both Iterm2 and Vim with light and dark variants.
The reason for the light and dark variants are to help with working through the day into the evening. During the day, I find it easier on the eyes to have a light theme. In the evening, a dark is better. But I would rarely remember to make the switch. I figured there must be a way to automate the process. It turned out to be pretty straightforward.

Setting up Vim

The update to Vim was super simple. Simply add the following lines 'to your init.vim'
1if strftime("%H") < 17
2 set background=light
3else
4 set background=dark
5endif
This follows the 24hr clock so update the 17 (5 pm) accordingly. I have mine change at around 5 pm. Now every time you openVim the time would be checked and the background colour updated accordingly.

Setting up Iterm2

This was a little more involved but nothing to hard. Iterm2 gives the user access to a Python API. With this, we have access to a huge array of functionality and so we can programmatically update it. In our case, we want to update the colour schema of our profile.
From the menu select Scripts > New Python Script and follow the wizard. It does not matter what you select as we are gonna replace the whole lot anyway. Once you have completed the wizard, open the script and replace the contents with the script below.
1#!/usr/bin/env python3.7
2
3import asyncio
4import datetime
5import iterm2
6
7# Clock time to change colours.
8LIGHT_TIME=(7, 0)
9DARK_TIME=(17, 0)
10
11# Color presets to use
12LIGHT_PRESET_NAME="ariake-light"
13DARK_PRESET_NAME="ariake-dark"
14
15# Profiles to update
16PROFILES=["Ariake"]
17
18def datetime_after(t, time):
19 today = datetime.datetime(t.year, t.month, t.day, time[0], time[1])
20 if today > t:
21 return today
22 # Same time tomorrow
23 return today + datetime.timedelta(1)
24
25
26def next_deadline_after(t):
27 light_deadline = datetime_after(t, LIGHT_TIME)
28 dark_deadline = datetime_after(t, DARK_TIME)
29 print("light {} dark {}".format(light_deadline, dark_deadline))
30 if light_deadline < dark_deadline:
31 return (LIGHT_PRESET_NAME, light_deadline)
32 return (DARK_PRESET_NAME, dark_deadline)
33
34def get_duration():
35 now = datetime.datetime.now()
36 preset_name, deadline = next_deadline_after(now)
37 duration = (deadline - now).seconds
38 print("Sleep for {} seconds until {}".format(duration, deadline))
39 return duration, preset_name
40
41async def set_colors(connection, preset_name):
42 print("Change to preset {}".format(preset_name))
43 preset = await iterm2.ColorPreset.async_get(connection, preset_name)
44 for partial in (await iterm2.PartialProfile.async_query(connection)):
45 if partial.name in PROFILES:
46 await partial.async_set_color_preset(preset)
47
48async def main(connection):
49 while True:
50 duration, preset_name = get_duration()
51 await asyncio.sleep(duration)
52 await set_colors(connection, preset_name)
53 await asyncio.sleep(1)
54
55iterm2.run_forever(main)
The only things that need changing are marked with comments. I found the script console handy for debugging the scripts. Once the script is complete you can activate it Scripts > . If you want it to run automatically, move the script to $HOME/Library/ApplicationSupport/iTerm2/Scripts/AutoLaunch. You may need to create this folder.
Now that the scripts are in place, you should have a lovely self-changing development environment allowing you to code all day and night 😀.

Be the first to download the app

Help us build a place where community meets knowledge. Try it out and let us know what you think.
Download on the App StoreGet it on Google Play