rktjmp / lush.nvim

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

How to define treesitter `@x.y` groups #109

Open rktjmp opened 2 years ago

rktjmp commented 2 years ago

This interface is experimental, please subscribe to this issue for notification if the interface changes, also taking suggestions on alterations.

As of Neovim 0.8, highlight groups may contain . and @, in addition to a-Z. These group names are used for treesitter highlights (eg: @type.rust).

@ is an invalid variable name in Lua, so it's not possible to define these groups in the normal way.

Instead you must use a special sym function, which is provided via a table argument to your lush-spec function. sym stands for "symbol". This might change to group or group_name in the future.

1)

-- functions are injected via a table for future extension
local theme = lush(function(injected_functions)

2)

  -- you probably want to alias it locally
  local sym = injected_functions.sym 

3)

  -- then call sym when defining the name
  return {
    Normal { bg = red, fg = blue },
    -- define groups as normal, but replace the group name with the function call
    -- you may omit the function call parenthesis as per lua.
    sym"@type.rust" { fg = green },
    -- You can access these groups in the same manner as normal groups
    X { sym"@type.rust" }, -- link
    Y { sym"@type.rust", bg = gold }, -- inherit 
    Z { fg = sym"@type.rust".fg } -- field access
})

Lushify support

mhanberg commented 2 years ago

I have updated my theme to use this new syntax, but it seems like all highlights defined after the treesitter ones are not having any affect.

I tested this by moving a style above the treesitter definitions and then it worked when i restarted neovim.

I am not sure if this is a lush thing, or if I did something wrong when converting the TSFooBar highlights into sym("@foo.bar").

Changes for reference https://github.com/mhanberg/thicc_forest/pull/1/files

rktjmp commented 2 years ago

Your missing the new argument/sym alias, and one of the names is invalid due to whitespace.

The error reporting is bad, not your fault and the design of Lush is kind of straining here. If you don't assign sym, then it's the same as a "missing symbol lookup" for normal group definitions, so Lush thinks you're doing:

return {
  sym "@some.thing" { fg = ...}, -- => sym("@some.thing")({fg = ...}) <- looks like you want to define a group called `sym` lush/lua
  NextGroup { fg = ... }, -- NextGroup({fg = ...})
}

I should add some error report if a group def is called without a table argument at least though.

Does this diff solve your issue?

@@ -99,7 +99,8 @@ vim.g.VM_Cursor_hl = "Cursor"
 vim.g.VM_Insert_hl = "Cursor"

 -- stylua: ignore start
-local theme = lush(function()
+local theme = lush(function(injected_functions)
+  local sym = injected_functions.sym
   return {
     ColorColumn { fg = nil, bg = bg1 }, -- used for the columns set with 'colorcolumn'
     Conceal { fg = grey1, bg = nil }, -- placeholder characters substituted for concealed text (see 'conceallevel')
@@ -332,7 +333,7 @@ local theme = lush(function()
     sym("@boolean")  { Purple },
     sym("@character") { Yellow },
     sym("@comment") { Grey },
-    sym("@conditional ") { Red },
+    sym("@conditional") { Red },
     sym("@constant.builtin") { PurpleItalic },
     sym("@constant.macro") { Purple },
     sym("@constant") { PurpleItalic },
oncomouse commented 2 years ago

I'm trying to implement this in a theme that uses shipwright (specifically require("shipwright.transform.lush").to_vimscript) and none of the new groups are being created in the resulting vimscript colorscheme file.

I'm not sure I defined the groups correctly right, but here's my code: https://github.com/oncomouse/lushwal.nvim/blob/new-ts/lua/lushwal/addons/treesitter.lua

OkanEsen commented 2 years ago

I may be wrong but I think you have to change the syntax a little bit:

- sym("@preproc")({ PreProc }),
+ sym("@preproc") { PreProc },
mhanberg commented 2 years ago

Oh sorry, I totally missed the function argument part. I think I was thrown off by the words import and alias. I'll try this later.

rktjmp commented 2 years ago

I'm trying to implement this in a theme that uses shipwright (specifically require("shipwright.transform.lush").to_vimscript) and none of the new groups are being created in the resulting vimscript colorscheme file.

I'm not sure I defined the groups correctly right, but here's my code: https://github.com/oncomouse/lushwal.nvim/blob/new-ts/lua/lushwal/addons/treesitter.lua

If I copy the TS groups into base.lua and build they show up. Maybe addons/treesitter isn't being required before building? @text.note also links to an undefined group SpecialComment (no other refs to that in the repo).

There is also possibly a bug with the vimscript export for X ({ strikethrough = true }),. Works in other theme.

mhanberg commented 2 years ago

All good on my end now 👍

oncomouse commented 2 years ago

@rktjmp Thanks for taking a look. Best I can tell, it looks like a couple of the highlight groups were defined twice, which was causing an error in compilation that was only getting reported (for me) when the groups were defined base.lua. I think it's working now.

chmnchiang commented 2 years ago

Hi, does this feature works with lushwright.to_lua? This produce something like

@variable.builtin = {fg = "#E991B0"},

which is causing syntax error.

rktjmp commented 2 years ago

@chmnchiang Should be fixed!

Actually, it's not!

Actually fixed!

chmnchiang commented 2 years ago

~@chmnchiang Should be fixed!~

~Actually, it's not!~

Actually fixed!

Can confirmed it is fixed. Thanks for the swift update!

musjj commented 1 year ago

For some reason, it's not working for me:

local colors = require("theme.colors")
...
sym("@annotation") { fg = colors.foo }, -- doesn't work
sym("@attribute") { fg = colors.bar }, -- doesn't work either
WhichKey { fg = colors.blue }, -- this line and beyond also stops working
...

sym(...) highlights and any highlight assignments afterwards doesn't work. Once I removed all lines with sym(...), the rest of the highlights are functioning again. I'm guessing that it's not parsing the table access correctly?

rockyzhang24 commented 1 year ago

No issues on my side. It works perfectly as usual. Do you adjust it to the code below?

local theme = lush(function(injected_functions)
  local sym = injected_functions.sym
  return {
    ....
    sym("@class") { fg = blue_green },
    ....
  }
end)
return theme

FYI: my theme repo https://github.com/rockyzhang24/arctic.nvim.

musjj commented 1 year ago

local sym = injected_functions.sym

Argh, for some reason my eyes skipped that line! Thanks for the quick reply!