rktjmp / lush.nvim

Create Neovim themes with real-time feedback, export anywhere.
MIT License
1.4k stars 46 forks source link

`:Lushify` error: Could not parse buffer due to Lua error #100

Open ramojus opened 2 years ago

ramojus commented 2 years ago

Minimal example of what I'm working with: ./lua/my_theme/init.lua:

local M = {}

M.get_theme = function()
    local lush = require 'lush'
    local hsl = lush.hsl

    local bg = hsl(24, 10, 10)
    local fg = bg.li(80)

    local theme = lush(function()
        return {
            Normal       { bg = bg, fg = fg }, -- Normal text
        }
    end)
    return theme
end

return M

./colors/my_theme.lua:

vim.opt.background = 'dark'
vim.g.colors_name = 'my_theme'

package.loaded['my_theme'] = nil

require('lush')(require('my_theme').get_theme())

Opening ./lua/my_theme/init.lua file and runing :Lushify, throws this error: Lush.ify: Could not parse buffer due to Lua error: ...vim/site/pack/packer/opt/lush.nvim/lua/lush/compiler.lua:91: attempt to index local 'def' (a function value)

rktjmp commented 2 years ago

:Lushify requires the file you're evaluating return a parsed spec so it can evaluate and apply it. Right now you're returning a module and it doesn't know what do to with it, but thinks it's a spec.

Returning the spec will fix the error return M.get_theme(), though obviously that's not really what you want.

I have added a get_spec option to the lua interface to Lushify. It should be a function that receives the buffers result (so your module in this case) and returns a spec.

Right now this is only in the get_spec branch if you want to update your clone. I will post back on this issue when I mainline it (may change the option name).

:lua require('lush').ify({get_spec = function(mod) return mod.get_theme() end})
ramojus commented 2 years ago

:Lushify requires the file you're evaluating return a parsed spec so it can evaluate and apply it. Right now you're returning a module and it doesn't know what do to with it, but thinks it's a spec.

That makes a lot of sense, had no idea how lush worked.

I've checked the get_spec branch and it sort of worked, the problem is that I have now moved my colors to a different file and when I change a color, highlighting does not update. I'm not sure if that would even be possible to fix and I'm not in the need for a fix, as my colorscheme is basically done and I could always revert to single file if I needed live preview, so just putting it out there.

I wouldn't mind if you close the issue now, thanks!

rktjmp commented 2 years ago

Probably this is happening because Lua has cached your module.

Assuming you have

-- colors.lua
return {
   red = ...
   green = ...
}

and

-- theme.lua
local M = {}

M.get_theme = function()
    local lush = require 'lush'
    local colors = require 'colors'
    local theme = lush(function()
        return {
            Normal       { bg = colors.green }, -- Normal text
        }
    end)
    return theme
end

return M

You need to clear lua's module cache for colors so it re-loads it. You can do this by setting it to nil in the package.loaded table. So during dev you might have this in your theme file:

-- theme.lua
local M = {}

M.get_theme = function()
    local lush = require 'lush'
    -- remove any cached colors module
    package.loaded["colors"]  = nil -- or "my.theme.colors", etc
    -- this require will now always hit the disk
    local colors = require 'colors'
   ...

See also the first paragraph here: http://www.lua.org/manual/5.1/manual.html#pdf-require

ramojus commented 2 years ago

Yes, that was it. Only that :lua require('lush').ify({get_spec = function(mod) return mod.get_theme() end}) command now needs to be rerun for colors to update.

So here is another thing, some highlights don't seem to work. This how it looks when I set the theme normally with :colorscheme meliora: image

And this is how it looks when I run :lua require('lush').ify({get_spec = function(mod) return mod.get_theme() end}): image

Some of the relevant parts of ./lua/meliora/highlights.lua:

CursorLine   { bg = colors.bg2 },
LineNr       { fg = colors.fg4.li(10), bg = colors.dark_bg },
SignColumn   { LineNr },
CursorLineNr { bg = CursorLine.bg, fg = LineNr.fg },

No idea why this is happening

rktjmp commented 2 years ago

Do you mind putting your theme online for me to take a look at? It would be nice if this workflow worked if possible.

ramojus commented 2 years ago

Here, it's a bit more complex now, hopefully that's alright, highlights still behave the same way as in my previous comment.