Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow for dep injection into lush spec function #36

Open
rktjmp opened this issue Apr 16, 2021 · 5 comments
Open

Allow for dep injection into lush spec function #36

rktjmp opened this issue Apr 16, 2021 · 5 comments
Labels
enhancement New feature or request

Comments

@rktjmp
Copy link
Owner

rktjmp commented Apr 16, 2021

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)
@rktjmp rktjmp added the enhancement New feature or request label Apr 16, 2021
@rktjmp
Copy link
Owner Author

rktjmp commented Apr 26, 2021

lush(...) already infers on table && table.__lush && table.__lush.type == "parsed_lush_spec", so we would either

  • be checking the table didn't have those keys, or
  • or have a lush.new_config() which returns a map with type information
  • or you call lush.with_config() or similar

@rktjmp
Copy link
Owner Author

rktjmp commented Apr 26, 2021

I have a theme, it has two styles, regular and no italics, how do I build this?

spec into extends(spec).with(group = {spec.group, gui = "" or gui = spec.group.gui.rep(italic, "")

I have a theme, it has two styles, subzero and scorpion. It is a direct palette swap.

lush.inject(palette).with( normal fg = palette.normal.fg, bg = palette.color1)

I have a theme, it has two styles, lake and ocean, ocean is generally the same as lake but some colors are darker and a few groups change.

Get lake as parsed spec, ocean extends lake and just fiddles which groups it needs to.

Two styles, light and dark. Half the specs are shared half are not.

Palettes should conform to some agreed shape, probably have three specs

  • base (never exposed to end user) probably just the raw function that accepts a palette
  • light
  • dark

Define palettes

-- norm and comment are different colors but are applied the same
-- no matter which spec

-- light_palette.lua         -- dark_palette.lua
light = {                    dark = {
  norm = hsl(blue),            norm = hsl(dark_blue),
  comment = hsl(red)           comment = hsl(dark_red),
  light_tone = hsl(green)      dark_tone = hsl(orange)
}                            }

Define base

-- base.lua
return function(palette)
  Normal { fg = palette.norm },
  Comment { fg = palett.comment }
end

Define light

-- light.lua

-- get palette
palette = require("lush_theme.ld.light_palette")

-- get base generator
base_fn = require("lush_theme.ld.base")
-- apply palette to base
base_spec = lush.inject(palette).with(base_fn)

-- extend base for light specifics
return lush.extends(base_spec).with(function()
  CursorLine { bg = palette.light_tone },
  Search { base.Normal, fg = base.Normal.fg.lighten(20) }
end)

Define dark

-- dark.lua

-- get palette
palette = require("lush_theme.ld.dark_palette")

-- get base generator
base_fn = require("lush_theme.ld.base")
-- apply palette to base
base_spec = lush.inject(palette).with(base_fn)

-- extend base for light specifics
return lush.extends(base_spec).with(function()
  CursorLine { bg = palette.dark_tone },
  Search { base.Normal, fg = base.Normal.fg.darken(20) }
end)

Important, both light.lua and dark.lua return valid specs, so they can be used with extends by an end user. A lush spec file should always return a lush spec, fully formed.

Now either colors.vim checks some config val

" colors.vim
if g:ld_style == "light" then
  lua require("lush")(require("lush_theme.ld.light")
else
  lua require("lush")(require("lush_theme.ld.light")
end

OR, there is a third "spec" that does the same thing in lua and returns the real spec.

-- light_or_dark.lua
return require("lush_theme.ld."..vim.g.ld_style)
-- colors.vim
lua require("lush")(require("lush_theme.ld.light_or_dark")

@rktjmp
Copy link
Owner Author

rktjmp commented Apr 26, 2021

The split files starts to break :Lushify, buit fwatch can actually fix this for us, probably :LushifyDir and just bang lush on every file change? Needs to do the unwatch/rewatch shuffle for vims save style.

@mcchrish
Copy link
Contributor

mcchrish commented Oct 6, 2021

This is an interesting feature for me. I'm building some spin-offs to zenbones but my solution so far is "monkey-patching" the palette module used in generating the specs. It technically works but it's ugly and probably a maintenance hell.

It can probably be worked around by wrapping things into functions that can generate palettes or specs.

local function generate_specs(palette)
	return lush(function()
		return {
			Normal { fg = palette.fg }
		}
	end)
end

lush(generate_specs({ fg = lush.hsl(0, 0, 0) }))

@musjj
Copy link
Contributor

musjj commented Dec 17, 2022

My idea for backwards compatibility: in addition to colors that can be stringified, we can have a function that accepts a dependency table.
Of course there should be a helper to make it easy:

local function InjectableColors()
  return setmetatable({}, {
    __index = function(_, key)
      return function(deps) return deps[key] end
    end,
  })
end

local colors = InjectableColors()

local parsed = lush(function()
  return {
    HighlightA = colors.blue, -- function that can accept a dependency later on
    HighlightB = hsl("#dadada"), -- can be stringified directly
  }
end)

lush(parsed) -- errors, because dependency is still missing

parsed.inject { blue = hsl("#3238a8") } -- associate this table as a dependency for this spec
lush(parsed) -- injectable color objects will now be resolved here using the table above

parsed.inject { blue = hsl("#16c4f7") } -- re-injection is possible
lush(parsed)

What do you think of this workflow?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants