Skip to content

shushtain/farba.nvim

Repository files navigation

Farba for Neovim

One theme to have them all.

"фарба" is a Ukrainian word for paint.
Has to be of German origin, right?

Examples

These are meant to inspire you to mix your own Farba. If you especially like one of them, use the provided color values. Read the Setup section for more details.

Jungle

Jungle

{
  gray    = {  90,   5 },
  red     = {   0, 100 },
  green   = {  20, 100 },
  yellow  = {  70,  50 },
  blue    = {  20,  75 },
  magenta = {  90,  50 },
  cyan    = {   0, 300 },
}

Dream

Dream

{
  gray    = { 260,  25 },
  red     = {   0, 100 },
  green   = { 140,  50 },
  yellow  = {  20,  75 },
  blue    = { 220,  50 },
  magenta = { 260,  50 },
  cyan    = { 180,  50 },
}

Candy

Candy

{
  gray    = {   0,   5 },
  red     = {   0, 100 },
  green   = { 340, 100 },
  yellow  = { 170,  50 },
  blue    = { 340,  75 },
  magenta = { 340,  50 },
  cyan    = { 340, 300 },
}

Default

Default

{
  gray    = {   0,   0 },
  red     = {   0, 100 },
  green   = { 120,  50 },
  yellow  = {  40,  75 },
  blue    = { 200,  50 },
  magenta = { 280,  50 },
  cyan    = { 150,  50 },
}

Features

  • By default, it's just a standard theme (see screenshots).
  • Colors are cterm inspired: gray, red, green, yellow, blue, magenta, cyan.
  • You can change hue and saturation for different highlight groups:
    • General (this is primarily about UI/editor).
    • Status (errors, warnings, successes, diffs).
    • Syntax (native, treesitter and LSP highlights).
    • Terminal (have separate terminal colors if you want).

How it works?

  • Provided hue/saturation pairs are converted to the ranges of HEX swatches.
  • Conversion is similar to HSL -> HEX, but actually uses Cubehelix, so:
    • Color contrast is the same, no matter you prefer blue or yellow themes.
    • To achieve that, saturation of 100% is actually less than in HSL.
    • You have to set 500% saturation for some colors to get the maximum.
    • Using more than 100% saturation may break color contrast consistency.

Installation

Lazy

{
  "shushtain/farba.nvim",
  lazy = false,
  priority = 1000,
  config = function()
    require("farba").setup()
    vim.cmd("colorscheme farba")
  end,
}

Setup

Defaults

  • Colors are provides with hue (0-360) and saturation (0-100+) as { hue, sat }.
  • false means the "general" version will be used.
require("farba").setup({
  light_mode = false,
  background = true,
  colors = {
    general = {
      gray = { 0, 0 },
      red = { 0, 100 },
      green = { 120, 50 },
      yellow = { 40, 75 },
      blue = { 200, 50 },
      magenta = { 280, 50 },
      cyan = { 150, 50 },
    },
    status = {
      red = false, -- error, diff deleted
      yellow = false, -- warning, diff changed
      green = false, -- success, diff added
    },
    terminal = {
      gray = false,
      red = false,
      green = false,
      yellow = false,
      blue = false,
      magenta = false,
      cyan = false,
    },
    syntax = {
      gray = false,
      red = false,
      green = false,
      yellow = false,
      blue = false,
      magenta = false,
      cyan = false,
    },
  },
})

Example

  • To set a color, provide it as { hue, sat }.
    • Invalid values for general become { 0, 0 } (gray).
    • Invalid values for other groups use general.
  • Omitted values use defaults.
{
  "shushtain/farba.nvim",
  lazy = false,
  priority = 1000,
  config = function()
    -- Here is my light theme.
    -- It's for presenting to people, so I will keep defaults.
    -- I also don't need a separate background since my terminal matches, and since I often disable it for OBS layering.
    -- Dark yellow is ugly, so I want to use orange.
    ---@type Farba.Config
    local light = {
      light_mode = true,
      background = false,
      colors = {
        general = {
          yellow = { 25, 75 },
        },
      },
    }

    -- Here is my dark theme.
    ---@type Farba.Config
    local dark = {
      colors = {
        -- I don't want any UI colors distracting me.
        general = {
          gray = false, -- since this is not valid, it's the same as { 0, 0 }
          red = false,
          green = false,
          yellow = false,
          blue = false,
          magenta = false,
          cyan = false,
        },
        -- Max color for alerts!!!
        status = {
          red = { 0, 100 }, -- error, diff deleted
          yellow = { 30, 100 }, -- warning, diff changed
          green = { 120, 100 }, -- success, diff added
        },
        -- Not all terminal colors are useful to me.
        terminal = {
          red = { 0, 100 },
          green = { 120, 50 },
          yellow = { 30, 75 },
        },
        -- Neither I nor my theme should be clownish.
        -- Let's do something like Gruvbox or my flowerpot.
        syntax = {
          gray = { 25, 50 }, -- orange comments
          red = { 0, 100 }, -- red errors
          green = { 120, 50 }, -- green for my types and modules
          yellow = { 40, 50 }, -- warm yellow for my literals
          blue = { 90, 50 }, -- warm green for my vars and constants to protect eyes
          magenta = { 120, 50 }, -- green for keywords
          cyan = { 0, 50 }, -- red for functions, but not as bright
        },
      },
    }

   -- Here I detect OS theme.
    local is_light_mode = function()
      -- The actual implementation depends on the OS.
    end

    -- Here I automatically switch themes.
    -- I could also track where I start Neovim from, for instance.
    local scheme = function()
      if is_light_mode then
        return light
      return dark
      end
    end

    require("farba").setup(scheme)
    vim.cmd("colorscheme farba")
  end,
}

Issues

  • The theme is fresh, and some highlights may not be set in a smart way. Expect future changes with stable overall vibe.
  • Plugin support, for now, often relies on sensible fallbacks.

Floating windows and menus

  • It is recommended to give floating windows some sort of border or backdrop, since they don't have a separate background. This is slowly becoming a standard since the most popular plugins (like Telescope, Which-key, Lazy, Mason, etc) expect no background change while often providing borders or backdrops.
  • Menus, like the ones you see for command line suggestions and overall completions, use a separate background, so you don't need a border for them. This saves space.

Light mode

  • Light mode works by simply inverting lightness values, so there may be some untracked issues.

About

one theme to have them all

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages