GithubHelp home page GithubHelp logo

rktjmp / lush.nvim Goto Github PK

View Code? Open in Web Editor NEW
1.3K 11.0 44.0 6.01 MB

Create Neovim themes with real-time feedback, export anywhere.

License: MIT License

Lua 63.58% MoonScript 35.77% Vim Script 0.64%
neovim-plugin lua neovim-colorscheme color-scheme neovim

lush.nvim's Introduction

Lush Header

Lush CI

Lush is a colorscheme creation aid for Neovim. It gives you real time feedback as you edit, as well as color manipulation tools and some aids building a structured colorscheme.

Lush colorschemes can easily be exported for use without Lush, either as a lua table, vimscript commands or any other format. They can also be imported into other Lua systems to access your color data.

See some colorschemes Made with Lush.

Experimental Treesitter Interface

See issue for new syntax. Syntax is subject to change.

Announcements

  • 2022-05-12: Neovim 0.7 is now a requirement, the 1.0.1 tagged version is the last 0.5 compatible release.
  • 2021-11-05: Deprecation warning, the compiler exclude_keys option has been deprecated in favour of the build system,

Requirements

  • Neovim 0.7 or greater required to use Lush as a development tool
  • termguicolors enabled for true color support

Installation

Install via any package management system, for example, paq:

require paq { 'rktjmp/lush.nvim' }

Interactive Tutorial

Lush Demo

Run :LushRunTutorial for an Interactive guided tour of using Lush.

Guides

See Also

lush.nvim's People

Contributors

adamkali avatar adisen99 avatar astridlyre avatar bew avatar casonadams avatar cgag avatar daneofmanythings avatar davidscotson avatar dettorer avatar ellisonleao avatar james-delorenzo avatar junelva avatar kunzaatko avatar leixb avatar mcchrish avatar metalelf0 avatar migoa avatar muchzill4 avatar ntk148v avatar okaihe avatar olimorris avatar ramojus avatar rktjmp avatar rockyzhang24 avatar ruler501 avatar savq avatar scysta avatar silvasch avatar teto avatar zoomlogo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lush.nvim's Issues

Compile option to mirror gui to cterm

Turns out termguicolors are not the same in Vim and Neovim. vim/vim#1740
Neovim uses gui while Vim uses cterm.

Solution: add an option to just copy the gui value to cterm on compile. Something like copy_cterm_from_gui = true. Default to false.

Suggestions for handling of linting of the "globals" for each of the highlight groups?

I love this project with lush.nvim. Thank you!

My question/issue is mostly around how we might handle all of the "globals" that end up being "undefined" for each of the highlight groups that are defined.

I realize this question is out of scope of this project, I'm more just curious how you, and/or contributors/users of this project and lush.nvim might be handling this.

Thanks!

Lush.ify Could not parse buffer due to Lua error

Is there a way to see what in my file is breaking Lushify?

I do Lushify and nothing happens and when I quit the file I have in terminal
Lush.ify: Could not parse buffer due to Lua error: ...m/site/pack/packer/start/lush.nvim/lua/lush/compiler.lua:9: can't compile, incorrect argument type

Error format hsl

Error:
Lush.ify: Could not parse buffer due to Lua error: line 32: unexpected symbol near ','

Line:
CursorLine { bg = hsl(228, 19%, 20%) }

Note: Doesn't accept hsl colors only hexadecimal.

Calling hsl function with a hex code is slightly off

I stumbled upon this while tweaking https://github.com/npxbr/gruvbox.nvim which is based on lush.nvim. Using hsl('#aabbcc') results in a slightly different color in the highlight.

It was fairly easy to reproduce, I just ran :LushRunQuickstart, followed by :Lushify and changed the highlight of the search, followed by running :hi Search to see the difference:

image

As you can see, #cc241d becomes #cd231d in the highlight.

Is this by design? I'm no color expert but I seem to recall converting between RGB and HSL can be lossy. To me the difference is not so big that I notice it, but I kind of expect that colors set by hex RGB stays the same since :hi takes hex RGB codes.

Allow for dep injection into lush spec function

This is just a "work with the shed door open" kind of issue, subject to change.

_something_(a, b, x).lush(function(a, b, c)
  return {
    Normal { a ... }
  }
end)

This should allow for a scheme to handle light and dark modes without having to maintain two specs.

-- main_spec.lua

-- this would be lush independent, depending on theme author.
-- could be a string, or a table of colors or ...
local style_name = get_some_config_var("g:my_theme_style") -- "dark"
local style_colors = require('lush_theme.my_theme.colours).get_by_name(sub_theme_name)

lush.inject({style_colors, some_other_config}).with(function(style, other)
  return function()
    Normal { fg = style.color_a }
  end
end)

How to do this:

  • in a non-breaking manner
  • in an extends compatible way
local spec = lush.extends({harbour}).inject(style).with(function(inject)
  return {
    ...
  }
end)

Is the chaining all "too smart", maintain old chains but move to a function or table inference and promote more complicated to build the config in parts? Can probably show deprecation warnings when running Lushify.

some_theme = require("lush_theme.harbour")
local config = {
  extend = {harbor},
  -- allows for injection of other themes if wanted, but does not automatically extend those themes
  -- is that confusing?
  inject = {style, harbor, require('lua.some.lib')},
}

config.spec = function(style, harbour, helper_lib)
  return {
    Normal { fg = harbour.normal.fg, bg = style.red500}
  }
end

return lush(config)

.darken/.lighten and other functions of this kind aren't working

Basically, I am creating my onedark-pro theme (available on vs-code extentions market) variant for neovim, lush.nvim parser is amazing, but for some reason the functions to darken and lighten the colors does not work.

Yes I declared the Normal before the comment section, as shown here.

Any help would be appreciated, thanks!

21-09-05_20h:41

[feature] Add language specific definitions extensibility example

Problem

Every example uses eventually uses only one lush function to define the colours.

Proposition

I think that it would be more powerful to define specific features in multiple files and require them only if necessary.

Possible solution

If I understand it correctly, what is being defined by the lush function is a table. Therefore a way to get about it would be to use vim.tbl_extend or something similar to define the colours in mutliple lush functions. If there is no reason not to do it this way, than there should be an example for this functionality, because it is very powerful and could be extensively used for more modularity and code clarity.

Example of use

I created these files for language colour definitions and would like to store them in these separate files and add them to a global colour table definition. Also the files should be added to the template folder I think for better incentive for colourscheme creation to have a greater coverage. (I have something similar for plugins...)

Add a function to generate a readable text color from a background color

The nvim-colorizer.lua has a similar function:

https://github.com/norcalli/nvim-colorizer.lua/blob/master/lua/colorizer.lua#L131-L142

Which is basically the same function as the color-yiq one used in Bootstrap version 4 (two small improvements that Bootstrap added is that it doesn't necessarily return pure white or black, but one of two configurable shades that might be a dark or light gray instead, and that the exact level at which the switchover happens can be tweaked by a variable, which helps with edge cases.

However, I quite like the ideas in Bootstrap v5's equivalent, as it uses a more spohisticated calculation to compare against the background, and it works through 4 colors in order, light, dark, white, black choosing the first with sufficient contrast (which is also something you can decide and pass in as a variable):
https://github.com/twbs/bootstrap/blob/main/scss/_functions.scss#L95-L145

Note they have to do some weird pre-calculation stuff to avoid any dependence on a sass math library since sass doesn't do math.pow natively, but they point to the algorithm they use at WCAG.

Interestingly, the WCAG is working on version 3 of their recommendations and apparently has a whole new calculation in the works, though it still seems at the research stage, and I'd guess the differences for basic usage aren't that extreme. Interesting that it takes font weight into consideration too though:

https://github.com/Myndex/SAPC-APCA

This would be particularly useful in things like Search and IncSearch where you often change the background color, but don't care too much about the fg text as long as it's readable.

Automatic Light/Dark theming using HSLuv

Just throwing this into the world... are there invertLightness & widen functions planned to add to the library?

Given HSLuv is so programable it's pretty easy to think up a way to properly "invert" the brightness of a color scheme while maintaining WCAG Accessibility ratings. Not that Accessbility ratings are things people writing colorschemes care about much, but personally I'd love to be able to just pick my favorite additive colors for certain bits of syntax, editor features, and then be able to flip a switch and have all those colors adjust their relative brightness to the background (grayscale light/dark) without having to re-specify each of the colors for both themes.

I've done this in Elm for a personal project already using elm-hsluv but when I noticed Lush supports hsluv I was like, "I wonder if I can do this in my neovim config too!"

I'll prolly port my "invertLightness" & "widen" (flips a color to 49 / 51 then extends the lightness till it meets AA against a bottom layer) from my side project otherwise.

Theme configuration

#8 (reply in thread)

Wanting to define some optional or customizable highlighting in a just a few lines. You don't have to have a settings section and a highlighting section as in elisons gruvbox.nvim or even in my theme (I will send it to you shortly). (This is nice because, if you want to have a lots of settings you can have them in a section of a couple tens of LOC and not separated by another 400 lines):

config['italic_comments'] = vim.g.scheme_italic_comments == 1 and "italic," or ""

theme = lush(function()
    return {
       Normal { ... },
       ... -- lots of LOC
       Comment { ..., gui = config.italic_comments },
       ...
    }end)

instead, you can have it defined together... (maybe also in the same closure, so you do not even need to read the variable if you don't need it eventually in the scheme based on some condition (plugin not used or different language))

RFC: LushBuild (export lush anywhere, without lush)

Goals

The main goal of this is to allow theme developers to use Lush solely as a theme creation tool with it's live updates, extension system and DSL syntax, while not forcing end users to install Lush. Part of this includes exporting your theme to VimL, but it also includes a Lua exporter with hooks to provide enduser configuration.

As a side effect, it also aims to let you export your Lush data easily to other formats.

WIP PR #77 (sort of misnamed compiler-plugins branch).

RFC:

  • UI issues? Particularly around configuring a lua theme as an end user.
  • Unclear documentation (this is probably a reasonable draft of what will ship in the vimdoc or separately)?
  • Additional features? (Can't promise but interested to know. I think the system is pretty extensible as is.)
  • Usefulness?

Preamble

The Lush build system is designed to take a lush spec (i.e. the color and group data from your theme) and apply any number of transforms to that data. These transforms can include conversion to a vim theme, terminal emulator theme, writing to different files, etc.

Some prerequisite knowledge

-- lush_build.lua
local theme = require("zenbones")
run(theme,
  viml,
  {overwrite, "colors/zenbones.vim"})

The builder simply pushes data through a function pipeline, these functions are termed "transforms".

There are two kinds of transforms: "head" and "tail".

Head transforms must accept a parsed lush spec (returned by require("theme")). It must return a table of any content. You will place a head transform at the start of your pipeline.

Tail transforms must accept a table and must return a table. The contents of these tables is not enforced, they could be strings (a table of lines), functions (such as closures around data), other tables, etc.

Transforms can take any additional number of arguments after the table.

Lush ships with some default transforms:

  • viml (head)
  • lua (head)
  • prepend (tail)
  • append (tail)
  • overwrite (tail)
  • patchwrite (tail)
  • contrib.alacritty (head)
  • contrib.kitty (head)
  • contrib.wezterm (head)

These transforms are automatically injected into the build environment along with lush and run.

You can provide any of your own transforms just by writing a function, either in the build file or in another module.

We will discuss the simplest example, where you have a theme with no variations or configuration options and simply want to let non-lush users use your theme.

A basic theme, exported to VimL

To ship our theme as a viml file, we simply must load our theme, convert it to viml and save the output to a file.

We will use the viml and overwrite transforms.

Our build file would look something like this:

-- lush_build.lua

-- we start by calling run and giving it our theme as the first argument.
-- any other arguments form the pipeline.
local theme = require("my.lush.theme")
run(theme,
  -- now we will convert that theme to a list of viml highlight commands
  viml, 
  -- the viml commands alone are generally not enough for a colorscheme, we
  -- will need to append a few housekeeping lines first.
  -- note how we are passing arguments to append by wrapping the transform
  -- in a table.
  -- {transform 1 2 3} will result in transform(last_pipe_value, 1, 2, 3)
  -- append accepts a table, so this call ends up being:
  -- append(last_pipe_value, {"set...",  "let..."})
  {append {"set background=dark", "let g:colors_name=\"my_theme\""}},
  -- now we are ready to write our colors file. note: there is no reason this has
  -- to be written to the relative "colors" dir, you could write the file to an
  -- entirely different vim plugin.
  {overwrite, "colors/my_theme.vim"})
-- and that is the whole build file

You can run :LushBuild <build_file> which will load and execute the given build file, or if no buildfile is specified, lush_build.lua is used. You probably want to do this from your lush themes root dir but you can run it anywhere.

Take Aways and Notes

It's important to remember:

  • The build file is "just lua", you can use any normal lua inside it, including loops, other modules, etc.
  • run() accepts a parsed lush spec, so you can use lush.extends to generate variations in or outside of the build file.
  • Transformers are "just functions", so it's very simple to write your own extensions to the provided transforms.

As a further example, we will write our own transform next.

Converting a Lush theme into an Alacritty theme

As an example, we will convert a theme into a (truncated) Alacritty theme.

To do this we will need to:

  • collect a subset of groups to export
  • convert #000000 hex values to 0x000000
  • generate a yaml file for use with Alacritty
-- As an example, we will imagine we are developing a lush transform
-- for release into the community.
--
-- We will say this transform expects to get a table shaped as:
--
-- {
--   primary = {
--     bg = color
--     fg = color
--   }
-- }
--
-- along with a name.

local function hash_to_0x(color)
  return string.gsub(color, "^#", "0x")
end

local function alacritty(colors, name)
  return {
    "# Colors: " .. name .. " theme",
    "colors:",
    "  primary:"
    "    background: " .. hash_to_0x(colors.primary.bg),
    "    foreground: " .. hash_to_0x(colors.primary.fg),
  }
end

return alacritty
-- lush_build.lua

local theme = require("my_theme")
local alacritty = require("lush_community.transform.alacritty")

run(theme,
  -- we must adjust our theme to conform to the alacritty transforms format.
  -- we can do this with an inline transform.
  function (groups)
    return {
      primary = {
        bg = groups.Normal.bg,
        fg = groups.Normal.fg
      }
    }
  end,
  -- now we can pass to alacritty, note that it needs a name
  {alacritty, "my_theme"},
  -- and now we can write, either to share or to our local config
  {overwrite, "~/.config/alacritty/theme.yaml"}
  -- note, as overwrite is a transform, it *must* return a table, and infact
  -- overwrite returns the same lines it was given. we can pass these lines
  -- another transform.
  {overwrite, "extra/terms/alacritty.yaml"})

Exporting as configurable lua

The lua transform generates code you can call to load and apply a lush theme without lush. It will require you to provide a support context around it.

By using the patchwrite transform, we can instruct the lush build system to only update its own code, leaving our support code intact.

-- lush_build.lua

run(require("theme"),
  -- generate lua code
  lua,
  -- write the lua code into our destination. 
  -- you must specify open and close markers yourself to account
  -- for differing comment styles, patchwrite isn't limited to lua files.
  {patchwrite "colors/theme.lua", "-- PATCH_OPEN", "-- PATCH_CLOSE"})

Before running this build file, we should prepare the destination for patchwrite.

-- colors/theme.lua

-- content here will not be touched

-- PATCH_OPEN

-- PATCH_CLOSE

-- content here will not be touched

After running :LushBuild, we will have a lush_apply function.

By default, lush_apply will convert your theme (now compiled as a table) into viml highlight commands and apply them, but you can provide optional function hooks to lush_apply to alter data along the way.

The following hooks are provided:

  • configure_group_fn = function(group) ... end
    • Accepts a group and may alter that group if needed, to turn italics on or off by user config for example.
    • Returns a group shaped table.
  • generate_group_fn = function(group) .. end
    • Accepts a group and generate something that apply will understand.
    • By default this is a highlight ... vim command but you could return other viml, raw lua, different tables, etc.
    • The results of this function is collected into a table of "rules", one per group.
  • before_apply_fn = function(rules) ... end
    • A final chance to alter any rules. This could include broad regex's or selective deletion, etc.
  • apply_fn = function(rules) ... end
    • Accepts a table of rules (or whatever was returned by generate_group -> before_apply) and should do something to apply these rules as highlights.
    • By default this passes the rules to vim.cmd but you could write your own handler to use nvim_set_hl, etc.

For complete details, see the documentation in the generated code (or lua/lush/transformer/lua.lua in the branch)

Now that our theme has been exported, we can adjust our theme.lua file to use the generated loader.

-- colors/theme.lua

-- PATCH_OPEN
-- Generated by lush builder on Mon Nov  1 22:20:06 2021
--
-- You can configure how this build function operates by passing in optional
-- function handlers via the options table.
--
-- See each default handler below for guidance on writing your own.
--
-- {
--   apply_fn = function(rules) ... end,
--   before_apply_fn = function(rules) ... end,
--   generate_group_fn = function(group) .. end,
--   configure_group_fn = function(group) ... end,
-- }
--
local lush_groups = { ... }
local lush_apply = function(opts)
...
end
-- PATCH_CLOSE

-- imagine we want to provide some optional adjustments to groups
local overrides = {
  Comment = {italic = false}
}

local setup = function(config)
  if config.italic_comments then
    overrides["Comment"]["italic"] = true
  end

  local my_configure_group = function(group)
    if overrides[group.name] then
      if overrides[group.name]["italic"] then
        -- apply configured override
        group.gui = "italic"
      end
    end

    -- return maybe adjusted group
    return group
  end

  -- run lush loader with our custom configure function to
  -- adjust the groups per user config.
  lush_apply(lush_groups, {
    configure_group_fn = my_configure_group
  })
end

return {
  setup = setup
}

Note, you don't have to run this exported lua directly, you could still have your "core theme file" that takes a config and requires which ever theme is appropriate.

return {
  setup = function(config)
    if config.light then
      require("theme.lush_export.light").apply()
    else
       -- ... etc etc
    end
  end
}

Pipelines are composable

Since run itself is a transform, you can pipe any table value into it, along with a list of transforms to run in that context.

run(zenbones,
  viml,
  {run, {
    {prepend, [["see http://... for more details]]},
    {patchwrite, "../dist/...", [[" M_OPEN]], [[" M_CLOSE]]}}}
  {run, {
    {patchwrite, "colors/", [[" M_OPEN]], [[" M_CLOSE]]}}})

-- or
run(zenbones,
  extract_term_colors, -- generic map of colors to use in terminals
  {run, {
    term_colors_to_kitty_map, -- translate generic map to kitty shaped map
    contrib.kitty,
    {overwrite, "extra/kitty.conf"}}},
  {run, {
    term_colors_to_alacritty_map, -- translate generic map to alacritty shaped map
    contrib.alacritty,
    {overwrite, "extra/alacritty.yaml"}}})

Other Transform Ideas or LushBuild concepts

  • Translate lush's guifg/bg to ctermfg/ctermbg.
  • Terminal themes from Lush themes.
  • Saving/Dumping theme as a "compiled lua" via string.dump().
  • Translating Lush themes into Textmate Emacs themes.
  • Imagine nvim_set_hl becomes stable with 10000x performance increase, you could easily swap viml for a set_hl transform and provide theme.lua and theme_nvim_5_1.vim.
  • "Your Lua loader is bad" β†’ don't have to wait for me to fix it, can build your own to fit your own needs (and share it!)
  • I like this theme but it doesn't support my terminal
    • You can install lush and write your own build file that just loads up the other theme and dumps to whatever you want.

Issues

  • Some murky-ness around how theme variants fit at the development stage
    • This has always been a weak point with lush since it's not something I do personally so the experience around it isn't really tested much.
    • This is especially an issue with the wide methods of configuring a theme, perhaps having a unified lush-lua export may help provide a "happy path" for at least those themes.

Doesn't work for some groups (Comment, Type, etc)

Thanks for the great work, this is very nice!
Most of the groups work and are highlighted correctly, however some of them (Comment, Type, Statement, others) are not. There's nothing overriding them, so it must be something from neovim.

Sample:

local theme = lush(function()
	return {
		Comment {fg = lush.hsl(20, 20, 20)},
	}
end)

All groups are highlighted just fine when calling :Lushify.
Can anyone replicate?

NVIM v0.5.0-897-gd80f262f8

Request: Highlighting calls of the form `hsl '#rrggbb'` like normal `hsl('#rrggbb')`

Currently, a construction of the form hsl('#rrggbb') is highlighted with the proper colour background under :Lushify. However, if I were to do the equivalent hsl '#rrggbb', while it yields the same value, it isn't highlighted in any special way at all.

This isn't a huge problem, but if the user's coding style prefers the later construction over the former in cases like this, they'd loose on the real-time feedback the plugin brings.

With brackets

image

Without brackets

image

Clearing default `gui=` settings.

With the recent changes on how the gui= parameter is handled, it is no longer cleared if left empty. In addition, there is no way to set gui=NONE.

Neovim defines a number of default gui= settings, for example for hi TabLine, and I have had to add gui = "nocombine" to the rules that I want to clear.

Request: Move media out of repo

Currently about 90% of space in repo is media (mainly /images containing gifs for README & Images of themes in /made_with_lush/) without counting .git/ which contains at lest another copy of those media.

These can be uploaded to github or some other host and the README can use links. That makes the repo lighter and instalation faster .

(It just bugs me seeing media taking most of the instalation & Packer just timed out 3 times before installing 😭)

`lush.parse` error when basing from another specs

local lush = require "lush"
local base = require "zenflesh" -- some spec

local specs = lush.parse(function()
	return {
		TabLine { base.TabLine, gui = nil }, -- setting gui to nil, not "italic"
	}
end)

lush.apply(lush.compile(specs))

But it works with extend or merge.

Work around is to do something like:

TabLine { bg = base.TabLine.bg, fg = base.TabLine.fg, gui = nil }

Related: mcchrish/zenbones.nvim#14

Error detected while processing /root/.config/nvim/init.lua:
E5113: Error while calling lua chunk: [NULL] 

Overcoming hsl's lossy conversions to hex

I've been working in a solarized dark variant here: https://github.com/ryansch/lunarized

After experimenting with the hsl function, it became clear to me that the conversion from hsl to the final hex that neovim uses is not exact.

Example: I specify "#002b36" as the base03 color (https://github.com/ryansch/lunarized/blob/843fc965500266649fe2778a889a8ac5b57158a6/lua/lush_theme/lunarized.lua#L58). If I wrap that color with hsl, neovim actually ends up with "#002d38".

Is this just a limitation of how hsl models the colorspace? I'd really like to be able to use the various functions in lush to generate color variants but I'd also like my colors to be accurate.

setting underline color

Thanks for the plugin.

I am looking to highlight LSP colors with an underline that is a different color from the text itself (e.g. the text can be any color while the underline should always be red).

Would you be able to point me in the direction to do this? Usually I think guisp controls underline color but I can't see the effect while using lush and doing something like

DiagnosticUnderlineError { bg = palette.background, gui = "underline", guisp = "palette.red" }

The underline shows but remains the color of the foreground.

Add :LushifyJustHSL or similar

If you're working on a colors file, with no spec, :Lushify will work to highlight those colors but it will also be looking for a spec to apply. It doesn't explode but it will keep complaining.

Improving `:Lushify` with tree-sitter

Ok, this is either dumb or genious, but bear with me.

Right now, :Lushify uses regexes to highlight hsl calls and group names. That's all well and good, except it only highlights very limited patterns. It can't highlight hsl calls that use variables as arguments, or color method calls, (da, li etc).

I like looking at all the colors I'm using, so I write all hsl calls with literals instead of variables. Even though I use a small set of hsl values, I'm defining a lot of colors so there's a lot of repetition. Once I move the colorscheme to hsluv (nice addition btw) I'll probably have more redundant definitions, since I'll need to tweak things less to make the colors look uniform.

Now, we kinda already have a Lua parser lying around. We could use tree-sitter to parse the spec, and highlight more patterns without needing to define regexes for each one. :Lushify already evaluates the buffer, so we can use that to get the values of variables used in hsl calls (I think?).

This may or may not need the treesitter highlighting module. Getting the text regions from the treesitter nodes should be enough.

I'd be interested in adding this, though the docs for the treesitter modules are always… a work in progress, so it might take a while. I'd like to know if this actually fits the project before jumping in.

Add auto-export like mcchrish/zenbones.nvim?

mcchrish/zenbones.nvim ships with colors/zenbones.vim which contains an exported lush theme and colors/zenbones-lua.vim for the lush loaded theme.

This seems.... really obvious....

Exporting a theme could (will) impact existing theme files though, and it would make developing themes a bit awkward (colorsheme my-theme-lua), but it should probably be a function (auto export) and maybe some affordances made in the template repo for this.

The export could place some in-file markers and only replace inside them, which might let it be a bit more opt in and less violent.


Probably:

  • lush-template still ships with lush-loading theme.vim.
  • :Lush export|print|out|save|freeze <fname> will:
    • Warn user we are making a work-flow destructive change (they will have to update config to load the "live" version")
    • Export the currently loaded theme to theme.vim in-between some markers
    • Disable lush-loading in theme.vim (probably just put the lush stuff inside the markers)
    • Export a fresh lush-loading theme to theme-lua|lush|live.vim (or copy the existing file at step 1)

This fixes a long standing pet-peev of mine where end user lush-themes generally require a runtime dependency (lush).


Painpoints:

  • light/dark etc themes
    • need option to specify specific files
  • themes with optional parts (options to load plugin themes or low/high contrast modes)

Group linking from required spec fails without additional property

Should work:

local banana = require('lush_theme.banana')
return lush(function(){
  Normal { banana.Normal } -- nil effect
})

but the props aren't inherited without setting a prop along side:

local banana = require('lush_theme.banana')
return lush(function(){
  Normal { banana.Normal, fg = banana.Normal.fg }
})

Regular inheritance linking does work without additional properties

return lush(function(){
  Normal { fg=... },
  Comment { Normal }
})

Consider using nvim's built-in documentation system

Hi,

I've been using Lush for a little while and I've been loving it so far, however I've found it inconvenient to skim through the readme to find info I don't remember.

I'd like to suggest using the built-in doc system instead of listing everything in the readme. This would make it a bit easier to navigate and find stuff while working in a color scheme without much "context switching".

More generally, I think the documentation is a bit spread out, with duplicated information in the readme, the two tutorials and the examples.

I'd also be interested in contributing this myself, helping to move the existing info and such. Let me know what you think.

Lush.ify: Could not parse buffer due to Lua error:

Hey thanks for this awesome work. this is the complete output of the error I'm getting:

Lush.ify: Could not parse buffer due to Lua error: 
...vim/site/pack/packer/start/lush.nvim/lua/lush/parser.lua:33: 
Invalid hsl operation: '__lush', valid operations: 
da rotate saturate abs_saturate desaturate abs_desaturate lighten abs_lighten darken sa hue saturation lightness ro abs_sa de abs_de li abs_li abs_da abs_darken

Folder structure for the theme:

neon
β”œβ”€β”€ colors
β”‚Β Β  └── neon.vim
└── lua
    └── neon
        └── init.lua

This is where the entire epec for the theme is init.lua and here is the .vim file for the colors folder taken from the lush template neon.vim

More context:

I get the error above when I try to set it as a theme for neovim and also when doing :Lushify in the init.lua, however despite given that errror, it still gives the color and style for almost all the highlight groups of the init.lua file. But it doesn't set the live theme because of the error, Example:
2021-May-14

As I far as I can see, everything is set as explained in the lush template, I don't see where is my error, I would appreciate any help!

Compile with vim-friendly settings

Hi there, this is an extremely cool plugin!

Would you consider adding an option to lush.compile that forces vim-friendly settings? As far as I know,
that would just be the removal of the blend option. I use this function to update my colorscheme:

function! colors#fromlush(name) abort " {{{1
  " use runtimepath?
  let cname = fnamemodify($MYVIMRC, ':h') . '/colors/' . a:name . '.vim'
  if !has('nvim') || getftime(fnamemodify($MYVIMRC, ':h') . '/lua/' . a:name . '/init.lua') <= getftime(cname)
    execute 'colorscheme' a:name
    return
  endif
  let lines = luaeval('require("lush").compile(require("' . a:name . '"), {force_clean = true})')
  " Remove incompatible with vim option -- TODO select based on nvim/vim
  call map(lines, 'substitute(v:val, ''\s\?blend\s*=\s*\S*'', "", "")')
  call writefile(lines, cname)
  execute 'colorscheme' a:name
endfunction

Evidently, it's not a big complication to add this code myself as the user, but it was a bit tricky to understand where the issue was and why my colorscheme was causing issues on loading in vim.

add color mix functions

Rather than lighten or darken colors by a fixed percentage or percentage-point amount, I'd like to move one color towards another (or another way to describe that is to mix them together by some proportion).

The web framework Bootstrap mention why they do this and have an interactive example of the differencee:

https://codepen.io/emdeoh/pen/zYOQOPB

And have static examples of their palette and go into some of the details here:
https://getbootstrap.com/docs/5.0/customize/color/#notes-on-sass

They use the standard Sass mix function which is implemented here for the latest Dart version of the library:

https://github.com/sass/dart-sass/blob/master/lib/src/functions/color.dart#L785

They mostly just use it to generate tones by mixing white and black, but in particular I'm thinking of the ability to say "make this color contrast less with the background color, where you have no idea what that background color is, it could be pure white, pure black, a deep green or a bright pink. But if you have code comments for example, you probably want them to blend in a bit with the background and can state what you want relative to that destination color e.g. comments might be 50% of the Normal fg mixed towards bg but listchars might be 80% and that might work the same (well, within limits) even as the background changes wildly.

TreeSitter group names

I'm creating a treesitter theme, but I am having some issues with some group names. Currently testing with Go. For example, the TS groups var_declaration, const_declaration, function_declaration, select_statement now all fall under the group TSKeyword, meant for 'other' keywords, including the function declaration, which I would expect under the TSKeywordFunction group.

Is it possible to create seperate groups for these?

Add Made with Lush section to Readme

Probably just a short paragraph linking to /made_with_lush/readme.md.

Themes sorted alpha numeric.

Possible contribution guidelines:

  • --- or ### theme name
  • link in form user/repo
  • max ... 50? word description ("Melange is a dark color scheme with a warm, moderate contrast color palette. It supports tree-sitter and regular highlighting (works with Vim8)."
  • max two images
    • one showing some consistent code block (part of lush that wont change much?), for more consistent comparison between themes?
      • might not be realistic
    • one showing anything else
    • some reasonable max size (gh caps readme at 900px wide)
    • named <gh_user_name>_<gh_repo>_1/2.png

Whole spec inheritance

#8 #23

  • Tests & Implementation
  • Docs
  • Readme
  • Example?

Elected for no hard example in examples/ but see :h lush-extending-specs and

-- undo_tree.lua
local base = require 'lush_theme.gruv_base' 

return lush(function()
  return {
   UndoTreeHeading { fg = base.Normal.fg, bg = base.Normal.bg },
   -- note: it *should* be ok to write links here, but whether they work is 
   --       dependent on you actually including the base group in the
   --       final spec, else it ends up linking to nothing.
   UndoTreeTime { base.Comment }
  }
end)
-- gruvbox.lua
local base = require 'lush_theme.gruv_base'

specs = {base}
for _, plugin in ipairs(config.plugins) do
  -- where plugins is something like {"undo_tree", "elixir", "fzf"}
  table.insert(specs, require('lush_theme.plugins.'..plugin))
end

return lush.extends(specs).with((function() return {} end)
-- or return lush.merge(specs)

Consider usung HSLUV rather than HSL

As mentioned in other tickets, I'm looking to programmatically choose and/or adjust colors for themes. This is quite tricky in RGB and HSL because they're not really designed for it.

I was assuming I'd need to come up with some compensation factor to adjust colors for perceptual uniformity but ended up using a pre-existing library that does that based on a color system called HSLUV.

They have an official lua version: https://github.com/hsluv/hsluv-lua/blob/master/hsluv.lua

This works well for my purposes, (I might need to do further tweaks to account for ambient light, but this gives a much more solid foundation) I just do something like this to integrate with Lush via the common language of rgb hex:

background  = hsl(hsluv.hsluv_to_hex{hue, saturation, center-contrast})
foreground  = hsl(hsluv.hsluv_to_hex{hue, saturation, center+contrast})

Now that I've tried it out, and because the HSLUV interface is modelled on HSL, I'm thinking I might write a wrapper so I can just use the standard Lush DSL syntax, and the HSLUV stuff will all happen in the background. But it did occur to me that the goals you're aiming for with the DSL would possibly be better achieved if you switched out HSL for HSLUV but basically kept everything else the same. So this might be something you'd be interested in adopting as the core of lush.

The one big downside appears to be the speed compared with HSL/RGB, but I've not noticed any issues while using it interactively, so not sure if this just means "too computationally expensive to be widely adopted in the 1970s and become part of legacy computing", so possibly worth benchmarking to see if it's a material issue. I'm thinking if it gets adopted at the core of Lush, then all the calculations would be done within the HSLUV color space same as is done now in HSL and there would only be one transformation to hex at the end anyway.

The designer introduces it here:
https://www.boronine.com/2012/03/26/Color-Spaces-for-Human-Beings/

And has a site here, with various demos, color pickers, examples etc. https://www.hsluv.org/comparison/

Lushify hot reload did not apply message

Hi,

I just started to play with lush.nvim. Sounds very interesting.

When I change the HSL numbers, I observe that the colors change but I get the following message:
Lushify hot reload did not apply: /home/oponkork/.loca...s/lush_tutorial.lua:52: unexpected symbol near ','

Just wanted to let you know. :)

:Lushify wont update and has no effect

  1. Ran the quickstart :LushRunQuickstart
  2. Ran Lushify
  3. Uncommented 'Normal'

The tutorial says:
-- You should be on the water now, Lush.ify has automatically recognized
-- our Highlight definition and applied it in real time.

But nothing happens
Am I missing a step? If not then what can I do to debug further?

Investigate LSP highlighting weirdery

When setting LSP highlight groups, they sometimes

  • aren't applied immediately
    • pretty sure this is because vir text highlights arent cleared like normal groups, so they retain old settings
  • cant use group linking
    • I think? Same issu as above maybe.
  • mess with the dynamic highlighting of other groups
    • maybe if the group has some LSP content on it?

Loading an extended theme on startup?

Hiya, I extended a theme: https://github.com/elianiva/gruvy.nvim and the process was easy and the docs were clear, thanks a lot!

I was wondering however how I would load my spec that I extended and specify it to the colorscheme, because currently I can only apply my extensions when :Lushify'ing it manually.

This is my code (it's in Fennel but I can always specify the Lua code):

(module magic.plugin.gruvy
  {autoload {lush lush
             hsl lush.hsl}})

(local colors { :yellow       (hsl :#d8a657)
                :red_error    (hsl :#c14a4a)
                :aqua         (hsl :#89b482)
                :red          (hsl :#EA6962)
                :string_green (hsl :#A9B665)
                :tag          (hsl :#E78A4E)
                :property     (hsl :#D8A657)
                :green        (hsl :#89B482)
                :blue         (hsl :#7DAEA3)
                :gutter       (hsl :#5a524c)
              })


(local gruvy (require :lush_theme.gruvy))

(local spec ((. (lush.extends [gruvy]) :with) (fn []
  [ ( WarningMessage          { :fg colors.yellow })
    ( Error                   { :fg colors.red } )
    ( TSVariable              { :fg colors.aqua })
    ( TSFunction              { :fg colors.red } )
    ( Function                { :fg colors.red } )
    ( String                  { :fg colors.string_green } )
    ( TSConstant              { :fg colors.yellow })
    ( TSVariableBuiltin       { :fg colors.aqua } )
    ( vueTSTag                { :fg colors.tag } )
    ( cssTSProperty           { :fg colors.green } )
    ( javascriptTSProperty    { :fg colors.blue } )
    ( TSProperty              { :fg colors.property } )
    ( javascriptTSConstructor { :fg colors.blue} )
  ])))

spec

Hex colors slightly off?

local lush = require "lush"

local c = lush.hsl("#fbf1c7")
print(c.h, c.s, c.l, c.hex) -- 48 87 88 #FBF0C6

Should still be #fbf1c7 instead of #FBF0C6.

augrouping/conditionals for sets of highlights

#13 (comment)

Would it be possible to make syntax to provide conditions similarly to something like the packer.nvim definition of packages? This could maybe compile into autocmds that are for a given filetype or similar... (You do not need groups for filetypes, that are not actually open before opening them).
The final compilation would be into something similar to this:

augroup rust 
    autocmd FileType rust hi RustComment gui=italic, guibg=red ...
    ...
augroup END

This could make the colourscheme much smaller and faster to load with the same amount of definitions... right?

Background transparency

Hello,
I'm working on a pywal based theme, which ingesting the pywal colors from ~/.cache/was/colors and thanks working great. However, I'm unable to get the background to be transparent. Also is there any facility to reapply lush based on an event? Currently I have to rerun Lushify when I change a background.

conditional lighline loading

hey guys, i see theres a lightline example here . Is there a way we can conditionally load this based if the user has the plugin or not? i am trying to support it in my gruvbox.nvim plugin, but the current code example only works if you have the plugin installed.

I have tried several approaches

if vim.g.lightline then
 -- call lightline fill and colorscheme
end

also:

vim.schedule_wrap(function()
  --- fill and colorscheme calls
end)

all of them are raising errors about lightline fill function not available yet.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.