-- Full Omarchy theme-catalog hot-reload, for hosts that want Neovim to track -- the system theme (`omarchy-theme-set`) instead of a fixed colorscheme. -- -- Omarchy's default LazyVim config gets this for free from lazy.nvim's file -- watcher + a symlinked plugin spec (lua/plugins/theme.lua -> -- ~/.local/state/omarchy/current/theme/neovim.lua). This config doesn't run -- lazy.nvim, so instead: read that same generated spec file directly (it's -- the authoritative theme-name -> colorscheme mapping Omarchy maintains) and -- watch the state directory ourselves with vim.uv. local M = {} local state_dir = vim.fn.expand("~/.local/state/omarchy/current") local theme_spec_file = state_dir .. "/theme/neovim.lua" local transparent_groups = { "Normal", "NormalFloat", "FloatBorder", "Pmenu", "Terminal", "EndOfBuffer", "FoldColumn", "Folded", "SignColumn", "LineNr", "CursorLineNr", "NormalNC", "WhichKeyFloat", "TelescopeBorder", "TelescopeNormal", "TelescopePromptBorder", "TelescopePromptTitle", "NvimTreeNormal", "NvimTreeVertSplit", "NvimTreeEndOfBuffer", "NotifyINFOBody", "NotifyERRORBody", "NotifyWARNBody", "NotifyTRACEBody", "NotifyDEBUGBody", "NotifyINFOTitle", "NotifyERRORTitle", "NotifyWARNTitle", "NotifyTRACETitle", "NotifyDEBUGTitle", "NotifyINFOBorder", "NotifyERRORBorder", "NotifyWARNBorder", "NotifyTRACEBorder", "NotifyDEBUGBorder", } local function apply_transparency() for _, name in ipairs(transparent_groups) do local ok, hl = pcall(vim.api.nvim_get_hl, 0, { name = name, link = false }) if ok then hl.bg = nil vim.api.nvim_set_hl(0, name, hl) end end end -- Pull the colorscheme name out of Omarchy's generated theme spec, e.g.: -- return { -- { "folke/tokyonight.nvim", priority = 1000 }, -- { "LazyVim/LazyVim", opts = { colorscheme = "tokyonight-night" } }, -- } local function read_colorscheme() local chunk, err = loadfile(theme_spec_file) if not chunk then vim.notify("omarchy_theme: " .. tostring(err), vim.log.levels.WARN) return nil end local ok, spec = pcall(chunk) if not ok or type(spec) ~= "table" then return nil end for _, entry in ipairs(spec) do if entry[1] == "LazyVim/LazyVim" and entry.opts and entry.opts.colorscheme then return entry.opts.colorscheme end end end function M.reload() local colorscheme = read_colorscheme() if not colorscheme then return end vim.o.background = "dark" vim.cmd("highlight clear") if vim.fn.exists("syntax_on") == 1 then vim.cmd("syntax reset") end if not pcall(vim.cmd.colorscheme, colorscheme) then vim.notify("omarchy_theme: colorscheme '" .. colorscheme .. "' not found", vim.log.levels.WARN) return end apply_transparency() vim.cmd("redraw!") end local watching = false -- `omarchy-theme-set` swaps the whole `current/theme` directory (rm -rf + -- mv), so re-arm the watch after every fire or it goes stale once the old -- inode is gone. local function watch() if watching then return end watching = true local handle = vim.uv.new_fs_event() local function start() handle:start(state_dir, {}, vim.schedule_wrap(function() handle:stop() vim.defer_fn(function() M.reload() start() end, 150) end)) end start() end function M.setup() M.reload() watch() end return M