Terminal dark/light mode
Here's how to update fish and neovim color scheme following the system theme when running in iTerm2.
๐ Context
I want to benefit from light/dark mode auto switch on as many apps as I can, including my terminal emulator (iTerm2), my favorite shell's (fish) and neovim.
Why light mode do you ask? Well, because when I work in a brightly lit room, a dark terminal strains my eyes. That's also why you'll likely find me using light mode on my IDE during the day (yes, my colleagues often complain about that during video conference, no I don't apologize).
๐ง๐ปโ๐ซ How to
๐ iTerm2 script
The solution I implemented takes advantage of iTerm2's Python API.
Create a new Basic, Long-Running Daemon script with the following content:
#!/usr/bin/env python3.10
import asyncio
import iterm2
import subprocess
async def main(connection):
async with iterm2.VariableMonitor(
connection, iterm2.VariableScopes.APP, "effectiveTheme", None
) as mon:
while True:
# Block until theme changes
theme = await mon.async_get()
# Themes have space-delimited attributes,
# one of which will be light or dark.
parts = theme.split(" ")
if "dark" in parts:
print("changing theme to dark")
subprocess.run(["fish", "-c", "dark"])
else:
print("changing theme to light")
subprocess.run(["fish", "-c", "light"])
# This instructs the script to run the "main" coroutine
# and to keep running even after it returns.
iterm2.run_forever(main)
The print
s are here to help diagnose eventual issues with iTerm2's Script Console (โฅโJ).
This script depends on two functions - light
and dark
, let's create them before enabling the script.
๐ Fish color scheme
function light --description 'Set shell theme to light mode, including neovim'
yes | fish_config theme save "Catppuccin Latte"
update_nvim_theme light
end
function dark --description 'Set shell theme to dark mode, including neovim'
yes | fish_config theme save "Catppuccin Mocha"
update_nvim_theme dark
end
funcsave light
funcsave dark
The light
/dark
functions set the appropriate fish color theme and defer to a third function to update neovim's color scheme.
๐ Neovim background color
function update_nvim_theme --description 'Update neovim theme with light/dark mode' --argument theme
for addr in /var/folders/7r/l55lwv013hl_g8gc971k7kgw0000gn/T/nvim.gaugendre/**/*
nvim --server $addr --remote-send ":set background=$theme <cr>"
end
end
funcsave update_nvim_theme
update_nvim_theme
lists all running instances of neovim and sends a command to update the background color (light or dark). neovim then reacts accordingly and uses an appropriate color scheme.
nvim --headless -c "echo stdpath('run')" -c "q"
โ Enable iTerm2 script
Finally, enable the script from the menu and enjoy fish following your color scheme.
๐ค Thank you
The script and functions presented here are a more advanced version of an answer I posted on SuperUser stack exchange recently. I'd like to thank NotTheDr01ds, who posted the first answer to this question. It led me in the right way.
๐ฎ Future work
I haven't (yet?) solved this for remote connections (ssh with tmux), please let me know if you have ideas!