For a long time, I’ve relied on themes that support both well-defined dark and light modes. I tend to switch between these depending on the lighting around me. So, I developed a small tool called SolarSwap to handle theme switching across various applications, including Neovim, tmux, GNOME Terminal, iTerm, and even my OS. While I won’t go into the details of SolarSwap here, I’ll share a solution for a lingering issue: getting open Neovim sessions to automatically pick up theme changes without a manual refresh. I found a way to monitor SolarSwap’s settings file and reload it when a change is detected—here’s how.

Configuration

SolarSwap writes its settings to ~/.solarswap/tools/nvim/settings/solarswap.lua, which typically looks like this:

vim.cmd.colorscheme("catppuccin")
vim.opt.background = "dark"
vim.g.airline_theme = "catppuccin"

To make Neovim automatically detect updates in the SolarSwap settings, I added this configuration to my Neovim setup:

local solarswap_config = vim.fn.expand("$HOME/.solarswap/tools/nvim/settings/solarswap.lua")
local uv = vim.loop  -- This loop is where we will watch the above file

if vim.fn.has("termguicolors") then
  vim.opt.termguicolors = true
end

vim.cmd([[
  set t_ut=
  set t_Co=256
  let &t_8f = "\<Esc>[38:2:%lu:%lu:%lum"
  let &t_8b = "\<Esc>[48:2:%lu:%lu:%lum"
  let &t_Cs = "\e[4:3m"
  let &t_Ce = "\e[4:0m"
]])

local function load_colorscheme()
  local ok, _ = pcall(dofile, solarswap_config)
  if not ok then
    vim.cmd.colorscheme("default")
  end
end

local function watch_solarswap_config()  -- Here is the magic.  Using `uv.fs_event_start` to watch the file and then we reaload the colorscheme file.
  local handle = uv.new_fs_event()
  uv.fs_event_start(
    handle,
    solarswap_config,
    {},
    vim.schedule_wrap(function()
      load_colorscheme()
    end)
  )
end

vim.api.nvim_create_user_command("SolarSwap", function()
  os.execute(vim.fn.expand("$HOME/bin/SolarSwap.sh"))
  load_colorscheme()
end, {})

load_colorscheme()

if uv.fs_stat(solarswap_config) then
  watch_solarswap_config()
end

Explanation

  1. In the Neovim configuration, the watch_solarswap_config function uses uv.fs_event_start to monitor the SolarSwap settings file.
  2. vim.schedule_wrap runs the load_colorscheme function when SolarSwap writes changes to the settings file.

Conclusion

So that’s it! Now, when I run SolarSwap, all open Neovim sessions automatically update to the new mode set in the SolarSwap settings file. I may write more about SolarSwap in the future—it’s highly personalized, but I think it could be helpful to others who frequently switch between dark and light modes.