Skip to content

spenserlee/theme-switch.nvim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 

Repository files navigation

theme-switch.nvim

A tiny, colorscheme-agnostic theme manager for Neovim.

The plugin knows nothing about any specific colorscheme. Each theme is just a name plus a config function you write (it typically calls some plugin's setup() and sets vim.o.background). The plugin:

  • runs your config, then applies the colorscheme,
  • persists the choice across sessions,
  • derives a normalised UI palette from standard highlight groups and exposes it on vim.g.theme_palette (so a statusline/tabline can stay in sync with any colorscheme — no per-theme colour tables),
  • provides a centred FzfLua picker with live full-editor preview.

Pairs with a theme-switch shell script (tmux + terminal); the two share only theme names by convention.

Requirements

  • Neovim >= 0.9
  • ibhagwan/fzf-lua (picker)
  • Whatever colorscheme plugins you reference in your config callbacks

Setup (lazy.nvim)

{
  "spenserlee/theme-switch.nvim",
  dependencies = { "ibhagwan/fzf-lua" },
  lazy = false,
  priority = 999, -- after colorscheme plugins are on the rtp
  -- The plugin registers no keymap; map the picker yourself. A `keys` spec
  -- works even before the plugin's setup() has run.
  keys = {
    { "<leader>cs", "<cmd>ThemeSwitch<cr>", desc = "Theme: switch" },
  },
  opts = {
    default = "everforest-dark-harder",
    themes = {
      ["everforest-dark-harder"] = {
        colorscheme = "everforest",
        config = function()
          vim.o.background = "dark"
          require("everforest").setup({ background = "harder", italics = true })
        end,
      },
      ["gruvbox-light"] = {
        colorscheme = "gruvbox",
        config = function()
          vim.o.background = "light"
          require("gruvbox").setup({
            contrast = "medium",
            -- gruvbox leaves Normal transparent; pin it so the editor bg is light
            overrides = { Normal = { bg = "#fbf1c7" }, SignColumn = { bg = "#fbf1c7" } },
          })
        end,
      },
    },
  },
}

Adding a new colorscheme is just: install its plugin, add one themes entry with a config callback. The plugin never needs to change.

Theme spec

field type description
colorscheme string name passed to :colorscheme
config function? runs before applying: set background, call setup()
after function? runs after applying: extra highlight tweaks
term_bg string? optional #rrggbb pushed to the terminal via OSC 11

If term_bg is omitted, the resolved Normal background is used.

API

local ts = require("theme-switch")
ts.apply("gruvbox-dark")        -- apply (no persist)
ts.apply("gruvbox-dark", true)  -- apply + persist
ts.load_saved()                 -- restore persisted theme (or default)
ts.list()                       -- { name, ... } (alphanumeric)
ts.pick()                       -- open the FzfLua picker  (also :ThemeSwitch)

apply is callable from outside Neovim, which is how a companion shell script keeps running instances in sync:

nvim --server "$SOCK" --remote-send "<cmd>lua require('theme-switch').apply('gruvbox-dark', true)<cr>"

vim.g.theme_palette

After each apply, derived from standard highlight groups:

{
  accent, accent_bg,          -- from Function/String fg, TabLineSel bg
  bar_bg, bar_dim,            -- from TabLineFill / Normal bg
  tab_active_fg, tab_active_bg,
  tab_inactive_fg, tab_inactive_bg,
  normal_bg, normal_fg,
}

A tabline (e.g. tabby) can read these to stay in sync with the active theme, without the theme manager knowing anything about the colorscheme.

Options

option default description
themes {} the theme table (required)
default first (sorted) fallback theme on first run
state_file stdpath data where the persisted choice is stored
register_command true create the :ThemeSwitch command

Themes are always listed alphanumerically in the picker.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages