feat: Add Helix extras (#409)
* feat: Add Helix extras * docs: remove out of tree extras gen docs --------- Co-authored-by: Folke Lemaitre <folke.lemaitre@gmail.com>
This commit is contained in:
@@ -37,6 +37,7 @@ TokyoNight](https://github.com/enkia/tokyo-night-vscode-theme) theme. Includes
|
|||||||
### 🍭 Extras
|
### 🍭 Extras
|
||||||
|
|
||||||
<!-- extras:start -->
|
<!-- extras:start -->
|
||||||
|
|
||||||
- [Alacritty](https://github.com/alacritty/alacritty) ([alacritty](extras/alacritty))
|
- [Alacritty](https://github.com/alacritty/alacritty) ([alacritty](extras/alacritty))
|
||||||
- [Delta](https://github.com/dandavison/delta) ([delta](extras/delta))
|
- [Delta](https://github.com/dandavison/delta) ([delta](extras/delta))
|
||||||
- [Dunst](https://dunst-project.org/) ([dunst](extras/dunst))
|
- [Dunst](https://dunst-project.org/) ([dunst](extras/dunst))
|
||||||
@@ -44,6 +45,7 @@ TokyoNight](https://github.com/enkia/tokyo-night-vscode-theme) theme. Includes
|
|||||||
- [Fish Themes](https://fishshell.com/docs/current/interactive.html#syntax-highlighting) ([fish_themes](extras/fish_themes))
|
- [Fish Themes](https://fishshell.com/docs/current/interactive.html#syntax-highlighting) ([fish_themes](extras/fish_themes))
|
||||||
- [Foot](https://codeberg.org/dnkl/foot) ([foot](extras/foot))
|
- [Foot](https://codeberg.org/dnkl/foot) ([foot](extras/foot))
|
||||||
- [GitUI](https://github.com/extrawurst/gitui) ([gitui](extras/gitui))
|
- [GitUI](https://github.com/extrawurst/gitui) ([gitui](extras/gitui))
|
||||||
|
- [Helix](https://helix-editor.com/) ([helix](extras/helix))
|
||||||
- [iTerm](https://iterm2.com/) ([iterm](extras/iterm))
|
- [iTerm](https://iterm2.com/) ([iterm](extras/iterm))
|
||||||
- [Kitty](https://sw.kovidgoyal.net/kitty/conf.html) ([kitty](extras/kitty))
|
- [Kitty](https://sw.kovidgoyal.net/kitty/conf.html) ([kitty](extras/kitty))
|
||||||
- [Lua Table for testing](https://www.lua.org) ([lua](extras/lua))
|
- [Lua Table for testing](https://www.lua.org) ([lua](extras/lua))
|
||||||
@@ -300,7 +302,7 @@ How to add a new extra template:
|
|||||||
1. Create a file like `lua/tokyonight/extra/cool-app.lua`.
|
1. Create a file like `lua/tokyonight/extra/cool-app.lua`.
|
||||||
2. Add the name and output file extension to the `extras` table in
|
2. Add the name and output file extension to the `extras` table in
|
||||||
`lua/tokyonight/extra/init.lua`.
|
`lua/tokyonight/extra/init.lua`.
|
||||||
3. Run the following command to generate new [extra](#-extras) themes:
|
3. Run the following command to generate new [extra](#-extras) themes from the tokyonight plugin directory:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
nvim --headless "+lua require('tokyonight.extra').setup()" +qa
|
nvim --headless "+lua require('tokyonight.extra').setup()" +qa
|
||||||
|
|||||||
450
lua/tokyonight/extra/helix.lua
Normal file
450
lua/tokyonight/extra/helix.lua
Normal file
@@ -0,0 +1,450 @@
|
|||||||
|
local util = require("tokyonight.util")
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
--- @param colors ColorScheme
|
||||||
|
function M.generate(colors)
|
||||||
|
-- Ref: https://github.com/helix-editor/helix/blob/master/book/src/themes.md
|
||||||
|
-- nil is used when no equivalent was found.
|
||||||
|
local mapping = M.flatten({
|
||||||
|
attribute = "@attribute",
|
||||||
|
type = {
|
||||||
|
"Type",
|
||||||
|
builtin = "@type.builtin",
|
||||||
|
enum = {
|
||||||
|
"@lsp.type.enum",
|
||||||
|
variant = "@lsp.type.enumMember"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
-- rust: pattern matching `let Some(_) = ...`
|
||||||
|
-- ^^^^
|
||||||
|
constructor = "Type",
|
||||||
|
constant = {
|
||||||
|
"Constant",
|
||||||
|
builtin = {
|
||||||
|
"@constant.builtin",
|
||||||
|
boolean = "Boolean"
|
||||||
|
},
|
||||||
|
character = {
|
||||||
|
"Character",
|
||||||
|
escape = "@string.escape"
|
||||||
|
},
|
||||||
|
numeric = {
|
||||||
|
"Number",
|
||||||
|
float = "Float",
|
||||||
|
integer = "Number"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
string = {
|
||||||
|
"String",
|
||||||
|
regexp = "@string.regex",
|
||||||
|
special = {
|
||||||
|
"@string.special",
|
||||||
|
path = nil,
|
||||||
|
url = nil,
|
||||||
|
symbol = nil
|
||||||
|
}
|
||||||
|
},
|
||||||
|
comment = {
|
||||||
|
"@comment",
|
||||||
|
line = nil,
|
||||||
|
block = {
|
||||||
|
nil,
|
||||||
|
-- not sure about that one
|
||||||
|
documentation = "@string.documentation"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
variable = {
|
||||||
|
"@variable",
|
||||||
|
builtin = "@variable.builtin",
|
||||||
|
parameter = "@parameter",
|
||||||
|
other = {
|
||||||
|
nil,
|
||||||
|
member = "@field"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
label = "@label",
|
||||||
|
keyword = {
|
||||||
|
"@keyword",
|
||||||
|
control = {
|
||||||
|
"Statement",
|
||||||
|
conditional = "Conditional",
|
||||||
|
["repeat"] = "Repeat",
|
||||||
|
import = nil,
|
||||||
|
["return"] = "@keyword.return",
|
||||||
|
exception = "Exception"
|
||||||
|
},
|
||||||
|
operator = "Statement",
|
||||||
|
directive = "PreProc",
|
||||||
|
["function"] = "@keyword.function",
|
||||||
|
storage = {
|
||||||
|
nil, -- rust: `let`
|
||||||
|
type = nil, -- rust: `struct` & `type`
|
||||||
|
modifier = nil -- rust: `mut`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
operator = "Operator",
|
||||||
|
["function"] = {
|
||||||
|
"Function",
|
||||||
|
builtin = "@function.builtin",
|
||||||
|
method = "@method",
|
||||||
|
macro = "@function.macro",
|
||||||
|
-- Defined as "preprocessor in C", so using "PreProc", not sure though
|
||||||
|
special = "PreProc"
|
||||||
|
},
|
||||||
|
tag = {
|
||||||
|
"@tag",
|
||||||
|
-- ???
|
||||||
|
builtin = nil
|
||||||
|
},
|
||||||
|
namespace = "@namespace",
|
||||||
|
special = "Special",
|
||||||
|
markup = {
|
||||||
|
nil,
|
||||||
|
heading = {
|
||||||
|
"@text.title",
|
||||||
|
marker = nil,
|
||||||
|
-- post-processed to remove the 'h' as we already use the first element (1) as the root value.
|
||||||
|
h1 = nil,
|
||||||
|
h2 = nil,
|
||||||
|
h3 = nil,
|
||||||
|
h4 = nil,
|
||||||
|
h5 = nil,
|
||||||
|
h6 = nil,
|
||||||
|
-- UI --
|
||||||
|
completion = "Pmenu",
|
||||||
|
hover = "PmenuSel"
|
||||||
|
},
|
||||||
|
list = {
|
||||||
|
"markdownHeadingDelimiter",
|
||||||
|
unnumbered = nil,
|
||||||
|
numbered = nil,
|
||||||
|
checked = nil,
|
||||||
|
unchecked = nil
|
||||||
|
},
|
||||||
|
bold = "Bold",
|
||||||
|
italic = "Italic",
|
||||||
|
strikethrough = {
|
||||||
|
'helix',
|
||||||
|
modifiers = { 'crossed_out' }
|
||||||
|
},
|
||||||
|
link = {
|
||||||
|
"markdownLinkText",
|
||||||
|
url = "Underlined",
|
||||||
|
label = "markdownCode",
|
||||||
|
text = "markdownCode"
|
||||||
|
},
|
||||||
|
quote = nil,
|
||||||
|
raw = {
|
||||||
|
"markdownCode",
|
||||||
|
inline = "@text.literal.markdown_inline",
|
||||||
|
block = "markdownCodeBlock",
|
||||||
|
-- UI --
|
||||||
|
completion = nil,
|
||||||
|
hover = nil
|
||||||
|
},
|
||||||
|
-- UI --
|
||||||
|
normal = {
|
||||||
|
nil,
|
||||||
|
completion = "CmpItemMenu",
|
||||||
|
hover = "CmpItemKindDefault"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
diff = {
|
||||||
|
nil,
|
||||||
|
plus = "diffAdded",
|
||||||
|
minus = "diffRemoved",
|
||||||
|
delta = {
|
||||||
|
"diffChanged",
|
||||||
|
moved = "diffFile"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ui = {
|
||||||
|
background = {
|
||||||
|
{ "helix", bg = "bg" },
|
||||||
|
separator = nil
|
||||||
|
},
|
||||||
|
cursor = {
|
||||||
|
"Cursor",
|
||||||
|
normal = nil,
|
||||||
|
insert = nil,
|
||||||
|
select = nil,
|
||||||
|
match = "MatchParen",
|
||||||
|
primary = {
|
||||||
|
nil,
|
||||||
|
normal = nil,
|
||||||
|
insert = nil,
|
||||||
|
select = nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
debug = {
|
||||||
|
breakpoint = nil,
|
||||||
|
active = nil
|
||||||
|
},
|
||||||
|
gutter = {
|
||||||
|
nil,
|
||||||
|
selected = nil
|
||||||
|
},
|
||||||
|
highlight = {
|
||||||
|
nil,
|
||||||
|
frameline = nil
|
||||||
|
},
|
||||||
|
linenr = {
|
||||||
|
"LineNr",
|
||||||
|
select = "CursorLineNr",
|
||||||
|
},
|
||||||
|
statusline = {
|
||||||
|
"StatusLine",
|
||||||
|
inactive = "StatusLineNc",
|
||||||
|
-- Inspired from lualine
|
||||||
|
normal = {
|
||||||
|
'helix',
|
||||||
|
bg = "blue",
|
||||||
|
fg = "black"
|
||||||
|
},
|
||||||
|
insert = nil,
|
||||||
|
select = nil,
|
||||||
|
separator = nil
|
||||||
|
},
|
||||||
|
popup = {
|
||||||
|
"TelescopeBorder",
|
||||||
|
info = nil
|
||||||
|
},
|
||||||
|
window = "WinSeparator",
|
||||||
|
help = nil,
|
||||||
|
text = {
|
||||||
|
"Normal",
|
||||||
|
-- TelescopeSelection
|
||||||
|
focus = "Visual",
|
||||||
|
inactive = "Comment",
|
||||||
|
info = "TelescopeNormal",
|
||||||
|
},
|
||||||
|
virtual = {
|
||||||
|
ruler = nil,
|
||||||
|
whitespace = nil,
|
||||||
|
["indent-guide"] = nil,
|
||||||
|
["inlay-hint"] = {
|
||||||
|
"DiagnosticVirtualTextHint",
|
||||||
|
parameter = nil,
|
||||||
|
type = nil,
|
||||||
|
},
|
||||||
|
wrap = nil
|
||||||
|
},
|
||||||
|
menu = {
|
||||||
|
"Pmenu",
|
||||||
|
selected = "PmenuSel",
|
||||||
|
scroll = {
|
||||||
|
'helix',
|
||||||
|
fg = vim.api.nvim_get_hl(0, { name = "PmenuThumb" }).bg,
|
||||||
|
bg = vim.api.nvim_get_hl(0, { name = "PmenuSbar" }).bg,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
selection = {
|
||||||
|
{ 'helix', bg = "bg_highlight" },
|
||||||
|
primary = nil
|
||||||
|
},
|
||||||
|
cursorline = {
|
||||||
|
primary = nil,
|
||||||
|
secondary = nil
|
||||||
|
},
|
||||||
|
cursorcolumn = {
|
||||||
|
primary = nil,
|
||||||
|
secondary = nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
hint = "DiagnosticHint",
|
||||||
|
info = "DiagnosticInfo",
|
||||||
|
warning = "DiagnosticWarn",
|
||||||
|
error = "DiagnosticError",
|
||||||
|
diagnostic = {
|
||||||
|
nil,
|
||||||
|
hint = "DiagnosticUnderlineHint",
|
||||||
|
info = "DiagnosticUnderlineInfo",
|
||||||
|
warning = "DiagnosticUnderlineWarn",
|
||||||
|
error = "DiagnosticUnderlineError"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
local config = {}
|
||||||
|
for hx_scope, group in M.pairsByKeys(mapping) do
|
||||||
|
-- print(hx_scope, util.dump(group))
|
||||||
|
hx_scope = hx_scope:gsub("%.h(%d)", ".%1")
|
||||||
|
if hx_scope:match('%.') then
|
||||||
|
hx_scope = '"' .. hx_scope .. '"'
|
||||||
|
end
|
||||||
|
|
||||||
|
if group == nil then
|
||||||
|
goto continue
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(group) == "table" and group[1] == 'helix' then
|
||||||
|
table.remove(group, 1);
|
||||||
|
table.insert(config, string.format("%s = %s", hx_scope, M.to_toml(group)))
|
||||||
|
goto continue
|
||||||
|
end
|
||||||
|
|
||||||
|
local highlight = vim.api.nvim_get_hl(0, { name = group })
|
||||||
|
while highlight and highlight.link do
|
||||||
|
highlight = vim.api.nvim_get_hl(0, { name = highlight.link })
|
||||||
|
end
|
||||||
|
if highlight == nil then
|
||||||
|
print("Unknown highlight for " .. hx_scope)
|
||||||
|
goto continue
|
||||||
|
end
|
||||||
|
table.insert(config, string.format("%s = %s", hx_scope, M.to_helix_config(highlight)))
|
||||||
|
|
||||||
|
::continue::
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(config, '\n[palette]');
|
||||||
|
for name, color in M.pairsByKeys(M.flatten(colors)) do
|
||||||
|
if name:match('%.') then
|
||||||
|
name = '"' .. name .. '"'
|
||||||
|
end
|
||||||
|
if type(color) == 'string' and not string.starts(name, '_') and name ~= 'none' then
|
||||||
|
table.insert(config, string.format('%s = "%s"', name, color))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return table.concat(config, '\n')
|
||||||
|
end
|
||||||
|
|
||||||
|
function string.starts(String, Start)
|
||||||
|
return string.sub(String, 1, string.len(Start)) == Start
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.flatten(t)
|
||||||
|
local res = {}
|
||||||
|
for k, v in pairs(t) do
|
||||||
|
if type(v) == 'table' then
|
||||||
|
if v[1] ~= 'helix' then
|
||||||
|
for k2, v2 in pairs(M.flatten(v)) do
|
||||||
|
-- Special case for tables like:
|
||||||
|
-- { type = { "@type", enum = "@type.enum" } }
|
||||||
|
if k2 == 1 then
|
||||||
|
res[k] = v2
|
||||||
|
else
|
||||||
|
res[k .. '.' .. k2] = v2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
res[k] = v
|
||||||
|
end
|
||||||
|
else
|
||||||
|
res[k] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
-- https://www.lua.org/pil/19.3.html
|
||||||
|
function M.pairsByKeys(t, f)
|
||||||
|
local a = {}
|
||||||
|
for n in pairs(t) do table.insert(a, n) end
|
||||||
|
table.sort(a, f)
|
||||||
|
local i = 0 -- iterator variable
|
||||||
|
local iter = function() -- iterator function
|
||||||
|
i = i + 1
|
||||||
|
if a[i] == nil then
|
||||||
|
return nil
|
||||||
|
else
|
||||||
|
return a[i], t[a[i]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return iter
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.to_helix_config(highlight)
|
||||||
|
local style = {}
|
||||||
|
for hx_name, nvim_name in pairs({ fg = "fg", bg = "bg" }) do
|
||||||
|
style[hx_name] = M.to_rgb(highlight[nvim_name])
|
||||||
|
end
|
||||||
|
local modifiers = {}
|
||||||
|
for _, mods in ipairs({ highlight, highlight.cterm }) do
|
||||||
|
if mods then
|
||||||
|
if mods.bold then
|
||||||
|
modifiers.bold = true
|
||||||
|
end
|
||||||
|
if mods.italic then
|
||||||
|
modifiers.italic = true
|
||||||
|
end
|
||||||
|
if mods.underline then
|
||||||
|
style.underline = {
|
||||||
|
style = "line"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
if mods.undercurl and highlight.sp then
|
||||||
|
style.underline = {
|
||||||
|
color = M.to_rgb(mods.sp),
|
||||||
|
style = "curl"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if next(modifiers) ~= nil then
|
||||||
|
style.modifiers = M.key_set(modifiers)
|
||||||
|
end
|
||||||
|
return M.to_toml(style)
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.to_rgb(color)
|
||||||
|
if type(color) == "string" then
|
||||||
|
return color
|
||||||
|
elseif type(color) == "number" then
|
||||||
|
return string.format("#%06x", color)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.key_set(t)
|
||||||
|
local keys = {}
|
||||||
|
for key, _ in pairs(t) do
|
||||||
|
table.insert(keys, key)
|
||||||
|
end
|
||||||
|
return keys
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.to_toml(style)
|
||||||
|
local buffer = {}
|
||||||
|
M.insert_as_toml(buffer, style)
|
||||||
|
return table.concat(buffer, '')
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.insert_as_toml(buffer, x)
|
||||||
|
if type(x) == "table" then
|
||||||
|
if next(x) == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if M.is_array(x) then
|
||||||
|
table.insert(buffer, "[")
|
||||||
|
for _, v in pairs(x) do
|
||||||
|
M.insert_as_toml(buffer, v);
|
||||||
|
table.insert(buffer, ", ")
|
||||||
|
end
|
||||||
|
table.remove(buffer)
|
||||||
|
table.insert(buffer, "]")
|
||||||
|
else
|
||||||
|
table.insert(buffer, "{ ")
|
||||||
|
for k, v in M.pairsByKeys(x) do
|
||||||
|
table.insert(buffer, string.format("%s = ", k));
|
||||||
|
M.insert_as_toml(buffer, v);
|
||||||
|
table.insert(buffer, ", ")
|
||||||
|
end
|
||||||
|
table.remove(buffer)
|
||||||
|
table.insert(buffer, " }")
|
||||||
|
end
|
||||||
|
elseif type(x) == "string" then
|
||||||
|
table.insert(buffer, '"' .. x .. '"')
|
||||||
|
elseif type(x) ~= nil then
|
||||||
|
table.insert(buffer, tostring(x))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.is_array(t)
|
||||||
|
local i = 0
|
||||||
|
for _ in pairs(t) do
|
||||||
|
i = i + 1
|
||||||
|
if t[i] == nil then return false end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
@@ -24,6 +24,7 @@ M.extras = {
|
|||||||
zathura = {ext = "zathurarc", url = "https://pwmt.org/projects/zathura/", label = "Zathura"},
|
zathura = {ext = "zathurarc", url = "https://pwmt.org/projects/zathura/", label = "Zathura"},
|
||||||
dunst = {ext = "dunstrc", url = "https://dunst-project.org/", label = "Dunst"},
|
dunst = {ext = "dunstrc", url = "https://dunst-project.org/", label = "Dunst"},
|
||||||
gitui = {ext = "ron", url = "https://github.com/extrawurst/gitui", label = "GitUI"},
|
gitui = {ext = "ron", url = "https://github.com/extrawurst/gitui", label = "GitUI"},
|
||||||
|
helix = { ext = "toml", url = "https://helix-editor.com/", label = "Helix"},
|
||||||
}
|
}
|
||||||
|
|
||||||
local function write(str, fileName)
|
local function write(str, fileName)
|
||||||
@@ -66,7 +67,7 @@ end
|
|||||||
|
|
||||||
function M.setup()
|
function M.setup()
|
||||||
M.docs()
|
M.docs()
|
||||||
local config = require("tokyonight.config")
|
local tokyonight = require("tokyonight")
|
||||||
vim.o.background = "dark"
|
vim.o.background = "dark"
|
||||||
|
|
||||||
-- map of style to style name
|
-- map of style to style name
|
||||||
@@ -81,7 +82,9 @@ function M.setup()
|
|||||||
package.loaded["tokyonight.extra." .. extra] = nil
|
package.loaded["tokyonight.extra." .. extra] = nil
|
||||||
local plugin = require("tokyonight.extra." .. extra)
|
local plugin = require("tokyonight.extra." .. extra)
|
||||||
for style, style_name in pairs(styles) do
|
for style, style_name in pairs(styles) do
|
||||||
config.setup({ style = style })
|
tokyonight.setup({ style = style })
|
||||||
|
tokyonight.load({ style = style })
|
||||||
|
vim.cmd.colorscheme('tokyonight-' .. style)
|
||||||
local colors = require("tokyonight.colors").setup({ transform = true })
|
local colors = require("tokyonight.colors").setup({ transform = true })
|
||||||
local fname = extra .. "/tokyonight_" .. style .. "." .. info.ext
|
local fname = extra .. "/tokyonight_" .. style .. "." .. info.ext
|
||||||
colors["_upstream_url"] = "https://github.com/folke/tokyonight.nvim/raw/main/extras/" .. fname
|
colors["_upstream_url"] = "https://github.com/folke/tokyonight.nvim/raw/main/extras/" .. fname
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ local M = {}
|
|||||||
---@field bg string|nil
|
---@field bg string|nil
|
||||||
---@field sp string|nil
|
---@field sp string|nil
|
||||||
---@field style string|nil|Highlight
|
---@field style string|nil|Highlight
|
||||||
|
---@field link string|nil
|
||||||
|
|
||||||
---@alias Highlights table<string,Highlight>
|
---@alias Highlights table<string,Highlight>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user