Following up on my previous post, Automatic Theme Switching for VS Code, I wanted to apply day-and-night theme switching across all my dotfiles.
Existing Tools
There are many existing tools for managing dotfiles dynamically. Here are a couple examples:
Using yadm:
# Split the config into two versions:
cp ~/.config/alacritty/alacritty.yml ~/.config/alacritty/alacritty.yml##theme=day
cp ~/.config/alacritty/alacritty.yml ~/.config/alacritty/alacritty.yml##theme=night
# Tell yadm to switch between themes:
yadm alt theme=day yadm alt theme=night
Using chezmoi:
{{ if eq .theme "day" }}
import = ["~/.local/share/alacritty-theme/themes/atom_one_light.toml"]
{{ else }}
import = ["~/.local/share/alacritty-theme/themes/onedark.toml"]
{{ end }}
#+end_src
chezmoi set --local theme night
chezmoi apply
My Approach with stow
+ envsubst
However since my dotfiles repo is heavily based on
stow, I wanted a solution that integrates
well with it. That’s when I came across envsubst
from
GNU gettext, which immediately stood
out for its portability and availability as a standard GNU utility.
I ended up implementing
cowboy-bebug/dotfiles/@dde6579
as my solution. Using envsubst
is simple and minimal, as expected from a
GNU utility.
Implementation
First, I created a template file using a shell variable:
import = ["~/.local/share/alacritty-theme/themes/${ALACRITTY_THEME}.toml"]
Then, I dynamically substituted different values based on the time of day:
HOUR=$(date +%H)
if [ "$HOUR" -ge 6 ] && [ "$HOUR" -lt 19 ]; then
export ALACRITTY_THEME="atom_one_light"
else
export ALACRITTY_THEME="onedark"
fi
envsubst < ~/.config/alacritty/alacritty.template.yml > ~/.config/alacritty/alacritty.yml
Gotchas
While implementing this setup, I ran into a couple of caveats worth noting.
1. Exporting Variables
envsubst requires variables to be exported within your script. Without
export
, envsubst
won’t recognise the variable, and the substitution will
silently fail.
2. Neovim Cache
Neovim caches Lua modules, including theme settings. Since I’m using
NvChad , I noticed that even after updating the theme in
~/.config/nvim/lua/chadrc.lua
, changes are not applied immediately. This
happens because Neovim stores compiled Lua files in ~/.cache/nvim/luac
.
To ensure your updated theme is applied on startup, you can force a reaload by
adding this snippet to chadrc.lua
:
vim.api.nvim_create_autocmd("User", {
pattern = "VeryLazy", -- ensures it runs after NvChad lazy loading
callback = function()
require("base46").load_all_highlights()
end,
})