EdenEast / nightfox.nvim

🦊A highly customizable theme for vim and neovim with support for lsp, treesitter and a variety of plugins.
MIT License
3.15k stars 147 forks source link

Interactive theme update. #126

Closed JoseConseco closed 2 years ago

JoseConseco commented 2 years ago

Is your feature request related to a problem? Please describe. I wish we had interactive way to adjust Nightfox theme in realtime - something like https://github.com/rktjmp/lush.nvim The way I do it now:

Describe the solution you'd like We run cmd eg :InteractiveFox - it would run autocmd on buffer change or similar event where it would automatically load update config and refresh highlights). something like:

au TextChanged
   :luafile%<CR>  -- reload current file - we assume current edited file has `require("nightfox").setup { updated_ops  - eg. palette.bg1}`
   :run highlights update/ compile function.

Describe alternatives you've considered https://github.com/rktjmp/lush.nvim - but it works by editing vim highlights only, and there is no easy way to bring updated highlight color into nightfox config.

Additional context image

EdenEast commented 2 years ago

This is an interesting idea, although I am not sure how to get it working like lush does on text change. However with that said I can see something like updating the colorscheme based on buffer write.

In the colors/*.vim files I have a block section that checks to see if the variable nightfox_debug is true. If it is then it will unset all the loaded modules in lua and resource them. I use this when iterating and debugging. I could expose this functionality into a command that someone would call if they wanted to iterate over their nightfox config.

I see a command like NightfoxInteractive that would create an autocmd for that buffer that would resource nightfox's config on BufferWritePost and recall colorscheme <name>. Nightfox's settings also merge. By this I mean that consecutive calls to setup functions will merge what is currently set with the new configuration being added. The internal state of nightfox would also have to be reset (overrides and config).

JoseConseco commented 2 years ago

If you have your internal debug thing, then exposing it to theme devs would be cool. Not sure how it works internally, but yes I think u would have to load defaults, then put user changes on top. Here is example autocmd from packer nvim:

vim.cmd([[
  augroup packer_user_config
    autocmd!
    autocmd BufWritePost plugins.lua source <afile> | PackerCompile
  augroup end
]])

I guess they are using BufWritePost - since you cant source module, before its content is saved (unless BufUpdate would save the file itself, then source). I'm not sure what <afile> does. I bet you already to something similar for nightfox debug.

EdenEast commented 2 years ago

I have created a pr to implement this feature let me know what you think.

JoseConseco commented 2 years ago

Thx, it does not seem to work for me (I assume changes are done on save? ) :

https://user-images.githubusercontent.com/13521338/163139694-f2af1f8b-5f33-4e37-b9a8-c3bca55df5dd.mp4 you can see that changing bg1 did nothing, but changing bg2 changed statusline ok. I did not get any errors.
btw. my config:

local dayfox_col = require("nightfox.palette").load "dayfox"
local nightfox_col = require("nightfox.palette").load "nightfox"
local dawnfox_col = require("nightfox.palette").load "dawnfox"
-- local dayfox_spec = require('nightfox.spec').load("nightfox")

require("nightfox").setup {
  options = {
    transparent = false,
    dim_inactive = true,
    styles = { -- Style to be applied to different syntax groups
      functions = "bold",
      keywords = "bold",
      conditional = "italic",
    },
    inverse = { -- Inverse highlight for different types
      match_paren = false,
      visual = true,
      search = true,
    },
  },
  palettes = {
    nightfox = {
      red = { base = "#df6959", bright = "#df6959", dim = "#df6959" },
      orange_br = "#e49464",
    },
    nordfox = {
      comment = "#60728a",
    },
    dayfox = {
      white = { base = "#ee9310", bright = "#f19615", dim = "#d38305" },

      bg0 = "#dfdfdf", -- Dark bg (status line and float)
      bg1 = "#F7F7FA", -- Default bg
      bg2 = "#dce1e8", -- Lighter bg (cursor line)
      bg3 = "#ebecec", -- Lighter bg (colorcolm folds)
      bg4 = "#dcdcdc", -- Conceal, border fg

      sel0 = "#eeefef", -- Popup bg, visual selection bg
      sel1 = "#dcdcdc", -- Popup sel bg, search bg
      cyan = { base = "#208990", bright = "#259495", dim = "#107980" }, -- darken
    },
    dawnfox = {
      bg1 = "#FFFAF3", -- brighter
      bg2 = "#eae1e3", -- brighter
      yellow = { base = "#ee9310", bright = "#f19615", dim = "#d38305" },
    },
  },
  specs = {
    dayfox = {
      syntax = {
        func = dayfox_col.blue.bright, -- was blue.dim
        conditional = dayfox_col.red.base, -- if, then etc
        -- operator = dayfox_col.red.base, -- for and, or etc - was black
        ident = dayfox_col.magenta.base, -- cyan by default
      },
    },
    dawnfox = {
      syntax = {
        func = dawnfox_col.blue.bright, -- was blue.dim
        conditional = dawnfox_col.red.base, -- if, then etc
        -- operator = dawnfox_col.red.base, -- for and, or etc - was black
      },
    },
    nightfox = {
      syntax = {
        func = nightfox_col.blue.bright, -- was blue.dim
        conditional = nightfox_col.red.base, -- if, then etc
      },
    },
  },
  groups = {
    -- Conditional = { fg = "syntax.builtin0", style = "bold" },
    Conditional = { link = "TSKeywordFunction" },
    TSKeywordOperator = { link = "TSKeywordFunction" },
    -- Operator = { link = "TSKeywordFunction" },

    -- TelescopeBorder = { link = "NormalFloat" },
    -- TelescopePromptBorder = { link = "Folded" },
    -- TelescopePromptNormal = {link = "Folded"},
    -- TelescopePromptPrefix = {link = "Folded"},
    -- TelescopeNormal = { link = "NormalFloat" },
    -- TelescopePreviewTitle = { link = "Search" },
    -- TelescopePromptTitle = { link = "Search" },
    -- TelescopeResultsTitle = { link = "Search"},
    -- TelescopeMatching = { link = "PmenuSel"},
  },
}
EdenEast commented 2 years ago

Yes this pr works on save. Also looking at your config you do not need to require the original color palettes. Instead you can use templates.

require("nightfox").setup({
  options = {
    transparent = false,
    dim_inactive = true,
    styles = { -- Style to be applied to different syntax groups
      functions = "bold",
      keywords = "bold",
      conditional = "italic",
    },
    inverse = { -- Inverse highlight for different types
      match_paren = false,
      visual = true,
      search = true,
    },
  },
  palettes = {
    nightfox = {
      red = { base = "#df6959", bright = "#df6959", dim = "#df6959" },
      orange_br = "#e49464",
    },
    nordfox = {
      comment = "#60728a",
    },
    dayfox = {
      white = { base = "#ee9310", bright = "#f19615", dim = "#d38305" },

      bg0 = "#dfdfdf", -- Dark bg (status line and float)
      bg1 = "#F7F7FA", -- Default bg
      bg2 = "#dce1e8", -- Lighter bg (cursor line)
      bg3 = "#ebecec", -- Lighter bg (colorcolm folds)
      bg4 = "#dcdcdc", -- Conceal, border fg

      sel0 = "#eeefef", -- Popup bg, visual selection bg
      sel1 = "#dcdcdc", -- Popup sel bg, search bg
      cyan = { base = "#208990", bright = "#259495", dim = "#107980" }, -- darken
    },
    dawnfox = {
      bg1 = "#FFFAF3", -- brighter
      bg2 = "#eae1e3", -- brighter
      yellow = { base = "#ee9310", bright = "#f19615", dim = "#d38305" },
    },
  },
  specs = {
    dayfox = {
      syntax = {
        func = "palette.blue.bright", -- was blue.dim
        conditional = "palette.red", -- if, then etc
        ident = "palette.magenta", -- cyan by default
      },
    },
    dawnfox = {
      syntax = {
        func = "palette.blue.bright", -- was blue.dim
        conditional = "palette.red", -- if, then etc
      },
    },
    nightfox = {
      syntax = {
        func = "palette.blue.bright", -- was blue.dim
        conditional = "palette.red", -- if, then etc
      },
    },
  },
  groups = {
    Conditional = { link = "TSKeywordFunction" },
    TSKeywordOperator = { link = "TSKeywordFunction" },
  },
})
JoseConseco commented 2 years ago

Ok, I found the docs about interactive mode, and after NightfoxClean the interactive mode works! Well except - I had to remove "palette" from specs color (leave only eg. "blue.dim" ) . Thx for this. It will make life way easier :D

EdenEast commented 2 years ago

Ah yes specs use palettes as templates instead of specs. Good to see that it works for you.

JoseConseco commented 2 years ago

btw @EdenEast why can you run NightfoxClean() when executing Interactive mode automatically?

EdenEast commented 2 years ago

That would be a good idea.

EdenEast commented 2 years ago

This was added in commit 8473b3a.