First stab at converting to farout palette

Also renamed all/most instances of tokyonight to farout
This commit is contained in:
2023-12-01 15:30:50 -05:00
parent f247ee700b
commit 1752319cc5
130 changed files with 18963 additions and 301 deletions

166
lua/farout/colors.lua Normal file
View File

@@ -0,0 +1,166 @@
local util = require("farout.util")
local M = {}
---@class Palette
M.default = {
none = "NONE",
bg_dark = "#1f1311",
bg = "#0f0908",
bg_highlight = "#241816",
terminal_black = "#392D2B",
fg = "#E0CCAE",
fg_dark = "#F2A766",
fg_gutter = "#6B4035",
dark3 = "#66292F",
comment = "#6B4035",
dark5 = "#A67458",
blue0 = "#f49d69",
blue = "#d47d49",
cyan = "#a67458",
-- TODO: rename to orange/red
blue1 = "#BF472C",
blue2 = "#A4895C",
blue5 = "#a67458",
blue6 = "#BC907B",
blue7 = "#703F29",
magenta = "#8a4b53",
magenta2 = "#aa6b73",
purple = "#a47a7a",
orange = "#ff9e64",
yellow = "#f2a766",
green = "#a4896f",
green1 = "#c4a98f",
green2 = "#ceb399",
teal = "#c69478",
red = "#bf472c",
red1 = "#df674c",
git = { change = "#66292F", add = "#A4895C", delete = "#BF472C" },
gitSigns = {
add = "#CAAF82",
change = "#8C4F55",
delete = "#E26F55",
},
}
M.night = {
bg = "#1a1b26",
bg_dark = "#16161e",
}
M.day = M.night
M.moon = function()
local ret = {
none = "NONE",
bg_dark = "#1e2030", --
bg = "#222436", --
bg_highlight = "#2f334d", --
terminal_black = "#444a73", --
fg = "#c8d3f5", --
fg_dark = "#828bb8", --
fg_gutter = "#3b4261",
dark3 = "#545c7e",
comment = "#7a88cf", --
dark5 = "#737aa2",
blue0 = "#3e68d7", --
blue = "#82aaff", --
cyan = "#86e1fc", --
blue1 = "#65bcff", --
blue2 = "#0db9d7",
blue5 = "#89ddff",
blue6 = "#b4f9f8", --
blue7 = "#394b70",
purple = "#fca7ea", --
magenta2 = "#ff007c",
magenta = "#c099ff", --
orange = "#ff966c", --
yellow = "#ffc777", --
green = "#c3e88d", --
green1 = "#4fd6be", --
green2 = "#41a6b5",
teal = "#4fd6be", --
red = "#ff757f", --
red1 = "#c53b53", --
}
ret.comment = util.blend(ret.comment, ret.bg, "bb")
ret.git = {
change = util.blend(ret.blue, ret.bg, "ee"),
add = util.blend(ret.green, ret.bg, "ee"),
delete = util.blend(ret.red, ret.bg, "dd"),
}
ret.gitSigns = {
change = util.blend(ret.blue, ret.bg, "66"),
add = util.blend(ret.green, ret.bg, "66"),
delete = util.blend(ret.red, ret.bg, "aa"),
}
return ret
end
---@return ColorScheme
function M.setup(opts)
opts = opts or {}
local config = require("farout.config")
local style = config.is_day() and config.options.light_style or config.options.style
local palette = M[style] or {}
if type(palette) == "function" then
palette = palette()
end
-- Color Palette
---@class ColorScheme: Palette
local colors = vim.tbl_deep_extend("force", vim.deepcopy(M.default), palette)
util.bg = colors.bg
util.day_brightness = config.options.day_brightness
colors.diff = {
add = util.darken(colors.green2, 0.15),
delete = util.darken(colors.red1, 0.15),
change = util.darken(colors.blue7, 0.15),
text = colors.blue7,
}
colors.git.ignore = colors.dark3
colors.black = util.darken(colors.bg, 0.8, "#000000")
colors.border_highlight = util.darken(colors.blue1, 0.8)
colors.border = colors.black
-- Popups and statusline always get a dark background
colors.bg_popup = colors.bg_dark
colors.bg_statusline = colors.bg_dark
-- Sidebar and Floats are configurable
colors.bg_sidebar = config.options.styles.sidebars == "transparent" and colors.none
or config.options.styles.sidebars == "dark" and colors.bg_dark
or colors.bg
colors.bg_float = config.options.styles.floats == "transparent" and colors.none
or config.options.styles.floats == "dark" and colors.bg_dark
or colors.bg
colors.bg_visual = util.darken(colors.blue0, 0.4)
colors.bg_search = colors.blue0
colors.fg_sidebar = colors.fg_dark
-- colors.fg_float = config.options.styles.floats == "dark" and colors.fg_dark or colors.fg
colors.fg_float = colors.fg
colors.error = colors.red1
colors.warning = colors.yellow
colors.info = colors.blue2
colors.hint = colors.teal
colors.delta = {
add = util.darken(colors.green2, 0.45),
delete = util.darken(colors.red1, 0.45),
}
config.options.on_colors(colors)
if opts.transform and config.is_day() then
util.invert_colors(colors)
end
return colors
end
return M

60
lua/farout/config.lua Normal file
View File

@@ -0,0 +1,60 @@
local M = {}
---@class Config
---@field on_colors fun(colors: ColorScheme)
---@field on_highlights fun(highlights: Highlights, colors: ColorScheme)
local defaults = {
style = "storm", -- The theme comes in three styles, `storm`, a darker variant `night` and `day`
light_style = "day", -- The theme is used when the background is set to light
transparent = false, -- Enable this to disable setting the background color
terminal_colors = true, -- Configure the colors used when opening a `:terminal` in Neovim
styles = {
-- Style to be applied to different syntax groups
-- Value is any valid attr-list value for `:help nvim_set_hl`
comments = { italic = true },
keywords = { italic = true },
functions = {},
variables = {},
-- Background styles. Can be "dark", "transparent" or "normal"
sidebars = "dark", -- style for sidebars, see below
floats = "dark", -- style for floating windows
},
sidebars = { "qf", "help" }, -- Set a darker background on sidebar-like windows. For example: `["qf", "vista_kind", "terminal", "packer"]`
day_brightness = 0.3, -- Adjusts the brightness of the colors of the **Day** style. Number between 0 and 1, from dull to vibrant colors
hide_inactive_statusline = false, -- Enabling this option, will hide inactive statuslines and replace them with a thin border instead. Should work with the standard **StatusLine** and **LuaLine**.
dim_inactive = false, -- dims inactive windows
lualine_bold = false, -- When `true`, section headers in the lualine theme will be bold
--- You can override specific color groups to use other groups or a hex color
--- function will be called with a ColorScheme table
---@param colors ColorScheme
on_colors = function(colors) end,
--- You can override specific highlights to use other groups or a hex color
--- function will be called with a Highlights and ColorScheme table
---@param highlights Highlights
---@param colors ColorScheme
on_highlights = function(highlights, colors) end,
use_background = true, -- can be light/dark/auto. When auto, background will be set to vim.o.background
}
---@type Config
M.options = {}
---@param options Config|nil
function M.setup(options)
M.options = vim.tbl_deep_extend("force", {}, defaults, options or {})
end
---@param options Config|nil
function M.extend(options)
M.options = vim.tbl_deep_extend("force", {}, M.options or defaults, options or {})
end
function M.is_day()
return M.options.style == "day" or M.options.use_background and vim.o.background == "light"
end
M.setup()
return M

View File

@@ -0,0 +1,56 @@
local util = require("farout.util")
local M = {}
--- @param colors ColorScheme
function M.generate(colors)
local alacrittyColors = {}
for k, v in pairs(colors) do
if type(v) == "string" then
alacrittyColors[k] = v:gsub("^#", "0x")
end
end
local alacritty = util.template(
[[
# FarOut Alacritty Colors
colors:
# Default colors
primary:
background: '${bg}'
foreground: '${fg}'
# Normal colors
normal:
black: '${black}'
red: '${red}'
green: '${green}'
yellow: '${yellow}'
blue: '${blue}'
magenta: '${magenta}'
cyan: '${cyan}'
white: '${fg_dark}'
# Bright colors
bright:
black: '${terminal_black}'
red: '${red}'
green: '${green}'
yellow: '${yellow}'
blue: '${blue}'
magenta: '${magenta}'
cyan: '${cyan}'
white: '${fg}'
indexed_colors:
- { index: 16, color: '${orange}' }
- { index: 17, color: '${red1}' }
]],
alacrittyColors
)
return alacritty
end
return M

View File

@@ -0,0 +1,27 @@
local util = require("farout.util")
local M = {}
--- @param colors ColorScheme
function M.generate(colors)
local delta = util.template(
[[
[delta]
minus-style = syntax "${diff.delete}"
minus-non-emph-style = syntax "${diff.delete}"
minus-emph-style = syntax "${delta.delete}"
minus-empty-line-marker-style = syntax "${diff.delete}"
line-numbers-minus-style = "${gitSigns.delete}"
plus-style = syntax "${diff.add}"
plus-non-emph-style = syntax "${diff.add}"
plus-emph-style = syntax "${delta.add}"
plus-empty-line-marker-style = syntax "${diff.add}"
line-numbers-plus-style = "${gitSigns.add}"
line-numbers-zero-style = "${fg_gutter}"
]],
colors
)
return delta
end
return M

View File

@@ -0,0 +1,32 @@
local util = require("farout.util")
local M = {}
--- @param colors ColorScheme
function M.generate(colors)
local dunst = util.template(
[[
# TokyoNight colors for dunst
# For more configuraion options see https://github.com/dunst-project/dunst/blob/master/dunstrc
[urgency_low]
background = "${bg_dark}"
foreground = "${fg}"
frame_color = "${fg}"
[urgency_normal]
background = "${bg}"
foreground = "${fg}"
frame_color = "${fg}"
[urgency_critical]
background = "${bg_highlight}"
foreground = "${error}"
frame_color = "${error}"
]],
colors
)
return dunst
end
return M

58
lua/farout/extra/fish.lua Normal file
View File

@@ -0,0 +1,58 @@
local util = require("farout.util")
local M = {}
--- @param colors ColorScheme
function M.generate(colors)
local fishColors = {}
for k, v in pairs(colors) do
if type(v) == "string" then
fishColors[k] = v:gsub("^#", "")
end
end
local fish = util.template(
[[
# TokyoNight Color Palette
set -l foreground ${fg}
set -l selection ${bg_visual}
set -l comment ${comment}
set -l red ${red}
set -l orange ${orange}
set -l yellow ${yellow}
set -l green ${green}
set -l purple ${purple}
set -l cyan ${cyan}
set -l pink ${magenta}
# Syntax Highlighting Colors
set -g fish_color_normal $foreground
set -g fish_color_command $cyan
set -g fish_color_keyword $pink
set -g fish_color_quote $yellow
set -g fish_color_redirection $foreground
set -g fish_color_end $orange
set -g fish_color_error $red
set -g fish_color_param $purple
set -g fish_color_comment $comment
set -g fish_color_selection --background=$selection
set -g fish_color_search_match --background=$selection
set -g fish_color_operator $green
set -g fish_color_escape $pink
set -g fish_color_autosuggestion $comment
# Completion Pager Colors
set -g fish_pager_color_progress $comment
set -g fish_pager_color_prefix $cyan
set -g fish_pager_color_completion $foreground
set -g fish_pager_color_description $comment
set -g fish_pager_color_selected_background --background=$selection
]],
fishColors
)
return fish
end
return M

View File

@@ -0,0 +1,47 @@
local util = require("farout.util")
local M = {}
--- @param colors ColorScheme
function M.generate(colors)
local fishColors = {}
for k, v in pairs(colors) do
if type(v) == "string" then
fishColors[k] = v:gsub("^#", "")
end
end
local fish = util.template(
[[
# TokyoNight
# Syntax Highlighting Colors
fish_color_normal ${fg}
fish_color_command ${cyan}
fish_color_keyword ${magenta}
fish_color_quote ${yellow}
fish_color_redirection ${fg}
fish_color_end ${orange}
fish_color_error ${red}
fish_color_param ${purple}
fish_color_comment ${comment}
fish_color_selection --background=${bg_visual}
fish_color_search_match --background=${bg_visual}
fish_color_operator ${green}
fish_color_escape ${magenta}
fish_color_autosuggestion ${comment}
# Completion Pager Colors
fish_pager_color_progress ${comment}
fish_pager_color_prefix ${cyan}
fish_pager_color_completion ${fg}
fish_pager_color_description ${comment}
fish_pager_color_selected_background --background=${bg_visual}
]],
fishColors
)
return fish
end
return M

52
lua/farout/extra/foot.lua Normal file
View File

@@ -0,0 +1,52 @@
local util = require("farout.util")
local M = {}
--- @param colors ColorScheme
function M.generate(colors)
local footColors = {}
for k, v in pairs(colors) do
if type(v) == "string" then
footColors[k] = v:gsub("^#", "")
end
end
local foot = util.template(
[[
[cursor]
color=${fg} ${bg_visual}
[colors]
foreground=${fg}
background=${bg}
selection-foreground=${fg}
selection-background=${bg_visual}
urls=${green1}
regular0=${black}
regular1=${red}
regular2=${green}
regular3=${yellow}
regular4=${blue}
regular5=${magenta}
regular6=${cyan}
regular7=${fg_dark}
bright0=${terminal_black}
bright1=${red}
bright2=${green}
bright3=${yellow}
bright4=${blue}
bright5=${magenta}
bright6=${cyan}
bright7=${fg}
16=${orange}
17=${red1}]],
footColors
)
return foot
end
return M

View File

@@ -0,0 +1,56 @@
local util = require("farout.util")
local function hex2rgb(key, value)
local hex = value:gsub("#", "")
local r = tonumber(hex:sub(1, 2), 16)
local g = tonumber(hex:sub(3, 4), 16)
local b = tonumber(hex:sub(5, 6), 16)
return string.format("Rgb(%s,%s,%s), // %s %s", r, g, b, key, value)
end
local M = {}
--- @param colors ColorScheme
function M.generate(colors)
local gitui_colors = {}
for k, v in pairs(colors) do
if type(v) == "string" then
gitui_colors[k] = hex2rgb(k, v)
end
end
local gitui = util.template(
[[
(
selected_tab: ${magenta}
command_fg: ${comment}
selection_bg: ${bg_highlight}
selection_fg: ${cyan}
cmdbar_bg: ${bg}
cmdbar_extra_lines_bg: ${bg}
disabled_fg: ${comment}
diff_line_add: ${green}
diff_line_delete: ${red}
diff_file_added: ${green1}
diff_file_removed: ${red1}
diff_file_moved: ${magenta2}
diff_file_modified: ${yellow}
commit_hash: ${magenta}
commit_time: ${teal}
commit_author: ${green}
danger_fg: ${red}
push_gauge_bg: ${bg}
push_gauge_fg: ${fg}
tag_fg: ${magenta2}
branch_fg: ${yellow}
)
]],
gitui_colors
)
return gitui
end
return M

454
lua/farout/extra/helix.lua Normal file
View File

@@ -0,0 +1,454 @@
local util = require("farout.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

98
lua/farout/extra/init.lua Normal file
View File

@@ -0,0 +1,98 @@
local M = {}
-- map of plugin name to plugin extension
--- @type table<string, {ext:string, url:string, label:string}>
-- stylua: ignore
M.extras = {
kitty = {ext = "conf", url = "https://sw.kovidgoyal.net/kitty/conf.html", label = "Kitty"},
fish = {ext = "fish", url = "https://fishshell.com/docs/current/index.html", label = "Fish"},
fish_themes = {ext = "theme", url = "https://fishshell.com/docs/current/interactive.html#syntax-highlighting", label = "Fish Themes"},
alacritty = {ext = "yml", url = "https://github.com/alacritty/alacritty", label = "Alacritty"},
wezterm = {ext = "toml", url = "https://wezfurlong.org/wezterm/config/files.html", label = "WezTerm"},
tmux = {ext = "tmux", url = "https://github.com/tmux/tmux/wiki", label = "Tmux"},
xresources = {ext = "Xresources", url = "https://wiki.archlinux.org/title/X_resources", label = "Xresources"},
xfceterm = {ext = "theme", url = "https://docs.xfce.org/apps/terminal/advanced", label = "Xfce Terminal"},
foot = {ext = "ini", url = "https://codeberg.org/dnkl/foot", label = "Foot"},
tilix = {ext = "json", url = "https://github.com/gnunn1/tilix", label = "Tilix"},
iterm = {ext = "itermcolors", url = "https://iterm2.com/", label = "iTerm"},
lua = {ext = "lua", url = "https://www.lua.org", label = "Lua Table for testing"},
sublime = {ext = "tmTheme", url = "https://www.sublimetext.com/docs/themes", label = "Sublime Text"},
delta = {ext = "gitconfig", url = "https://github.com/dandavison/delta", label = "Delta"},
terminator = {ext = "conf", url = "https://gnome-terminator.readthedocs.io/en/latest/config.html", label = "Terminator"},
prism = {ext = "js", url = "https://prismjs.com", label = "Prism"},
windows_terminal = {ext = "json", url = "https://aka.ms/terminal-documentation", label = "Windows Terminal"},
zathura = {ext = "zathurarc", url = "https://pwmt.org/projects/zathura/", label = "Zathura"},
dunst = {ext = "dunstrc", url = "https://dunst-project.org/", label = "Dunst"},
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)
print("[write] extra/" .. fileName)
vim.fn.mkdir(vim.fs.dirname("extras/" .. fileName), "p")
local file = io.open("extras/" .. fileName, "w")
file:write(str)
file:close()
end
function M.read_file(file)
local fd = assert(io.open(file, "r"))
---@type string
local data = fd:read("*a")
fd:close()
return data
end
function M.write_file(file, contents)
local fd = assert(io.open(file, "w+"))
fd:write(contents)
fd:close()
end
function M.docs()
local file = vim.fn.fnamemodify(debug.getinfo(1, "S").source:sub(2), ":p:h:h:h:h") .. "/README.md"
local tag = "extras"
local pattern = "(<%!%-%- " .. tag .. ":start %-%->).*(<%!%-%- " .. tag .. ":end %-%->)"
local readme = M.read_file(file)
local lines = {}
local names = vim.tbl_keys(M.extras)
table.sort(names)
for _, name in ipairs(names) do
local info = M.extras[name]
table.insert(lines, "- [" .. info.label .. "](" .. info.url .. ") ([" .. name .. "](extras/" .. name .. "))")
end
readme = readme:gsub(pattern, "%1\n" .. table.concat(lines, "\n") .. "\n%2")
M.write_file(file, readme)
end
function M.setup()
M.docs()
local farout = require("farout")
vim.o.background = "dark"
-- map of style to style name
local styles = {
storm = " Storm",
night = "",
day = " Day",
moon = " Moon",
}
for extra, info in pairs(M.extras) do
package.loaded["farout.extra." .. extra] = nil
local plugin = require("farout.extra." .. extra)
for style, style_name in pairs(styles) do
farout.setup({ style = style })
farout.load({ style = style })
vim.cmd.colorscheme("farout-" .. style)
local colors = require("farout.colors").setup({ transform = true })
local fname = extra .. "/farout" .. style .. "." .. info.ext
colors["_upstream_url"] = "https://github.com/thallada/farout.nvim/raw/main/extras/" .. fname
colors["_style_name"] = "FarOut" .. style_name
colors["_name"] = "farout" .. style
write(plugin.generate(colors), fname)
end
end
end
return M

375
lua/farout/extra/iterm.lua Normal file
View File

@@ -0,0 +1,375 @@
local function get_component(hex, component)
hex = hex:gsub("#", "")
local num
if component == "r" then
num = tonumber("0x" .. hex:sub(1, 2)) / 255
elseif component == "g" then
num = tonumber("0x" .. hex:sub(3, 4)) / 255
elseif component == "b" then
num = tonumber("0x" .. hex:sub(5, 6)) / 255
end
return string.format("%.16f", num)
end
local function template(str, table)
return (str:gsub("($%b{})", function(w)
return get_component(table[w:sub(3, -4)], w:sub(-2, -2))
end))
end
local M = {}
function M.generate(colors)
local iterm = template([[
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Ansi 0 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>${black.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${black.g}</real>
<key>Red Component</key>
<real>${black.r}</real>
</dict>
<key>Ansi 1 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>${red.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${red.g}</real>
<key>Red Component</key>
<real>${red.r}</real>
</dict>
<key>Ansi 10 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>${green.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${green.g}</real>
<key>Red Component</key>
<real>${green.r}</real>
</dict>
<key>Ansi 11 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>${yellow.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${yellow.g}</real>
<key>Red Component</key>
<real>${yellow.r}</real>
</dict>
<key>Ansi 12 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>${blue.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${blue.g}</real>
<key>Red Component</key>
<real>${blue.r}</real>
</dict>
<key>Ansi 13 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>${magenta.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${magenta.g}</real>
<key>Red Component</key>
<real>${magenta.r}</real>
</dict>
<key>Ansi 14 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>${cyan.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${cyan.g}</real>
<key>Red Component</key>
<real>${cyan.r}</real>
</dict>
<key>Ansi 15 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>${fg.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${fg.g}</real>
<key>Red Component</key>
<real>${fg.r}</real>
</dict>
<key>Ansi 2 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>${green.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${green.g}</real>
<key>Red Component</key>
<real>${green.r}</real>
</dict>
<key>Ansi 3 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>${yellow.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${yellow.g}</real>
<key>Red Component</key>
<real>${yellow.r}</real>
</dict>
<key>Ansi 4 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>${blue.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${blue.g}</real>
<key>Red Component</key>
<real>${blue.r}</real>
</dict>
<key>Ansi 5 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>${magenta.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${magenta.g}</real>
<key>Red Component</key>
<real>${magenta.r}</real>
</dict>
<key>Ansi 6 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>${cyan.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${cyan.g}</real>
<key>Red Component</key>
<real>${cyan.r}</real>
</dict>
<key>Ansi 7 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>${fg_dark.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${fg_dark.g}</real>
<key>Red Component</key>
<real>${fg_dark.r}</real>
</dict>
<key>Ansi 8 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>${terminal_black.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${terminal_black.g}</real>
<key>Red Component</key>
<real>${terminal_black.r}</real>
</dict>
<key>Ansi 9 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>${red.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${red.g}</real>
<key>Red Component</key>
<real>${red.r}</real>
</dict>
<key>Background Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>${bg.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${bg.g}</real>
<key>Red Component</key>
<real>${bg.r}</real>
</dict>
<key>Badge Color</key>
<dict>
<key>Alpha Component</key>
<real>0.5</real>
<key>Blue Component</key>
<real>0.0</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.1491314172744751</real>
<key>Red Component</key>
<real>1</real>
</dict>
<key>Bold Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>${teal.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${teal.g}</real>
<key>Red Component</key>
<real>${teal.r}</real>
</dict>
<key>Cursor Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>${fg.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${fg.g}</real>
<key>Red Component</key>
<real>${fg.r}</real>
</dict>
<key>Cursor Guide Color</key>
<dict>
<key>Alpha Component</key>
<real>0.25</real>
<key>Blue Component</key>
<real>${fg.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${fg.g}</real>
<key>Red Component</key>
<real>${fg.r}</real>
</dict>
<key>Cursor Text Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>${bg.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${bg.g}</real>
<key>Red Component</key>
<real>${bg.r}</real>
</dict>
<key>Foreground Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>${fg.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${fg.g}</real>
<key>Red Component</key>
<real>${fg.r}</real>
</dict>
<key>Link Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>${green1.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${green1.g}</real>
<key>Red Component</key>
<real>${green1.r}</real>
</dict>
<key>Selected Text Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>${fg.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${fg.g}</real>
<key>Red Component</key>
<real>${fg.r}</real>
</dict>
<key>Selection Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>${bg_visual.b}</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>${bg_visual.g}</real>
<key>Red Component</key>
<real>${bg_visual.r}</real>
</dict>
</dict>
</plist>]],
colors
)
return iterm
end
return M
-- vim: sw=2

View File

@@ -0,0 +1,65 @@
local util = require("farout.util")
local M = {}
--- @param colors ColorScheme
function M.generate(colors)
local kitty = util.template(
[[
# vim:ft=kitty
## name: ${_style_name}
## license: MIT
## author: Folke Lemaitre
## upstream: ${_upstream_url}
background ${bg}
foreground ${fg}
selection_background ${bg_visual}
selection_foreground ${fg}
url_color ${green1}
cursor ${fg}
cursor_text_color ${bg}
# Tabs
active_tab_background ${blue}
active_tab_foreground ${bg_dark}
inactive_tab_background ${bg_highlight}
inactive_tab_foreground ${dark3}
#tab_bar_background ${black}
# Windows
active_border_color ${blue}
inactive_border_color ${bg_highlight}
# normal
color0 ${black}
color1 ${red}
color2 ${green}
color3 ${yellow}
color4 ${blue}
color5 ${magenta}
color6 ${cyan}
color7 ${fg_dark}
# bright
color8 ${terminal_black}
color9 ${red}
color10 ${green}
color11 ${yellow}
color12 ${blue}
color13 ${magenta}
color14 ${cyan}
color15 ${fg}
# extended colors
color16 ${orange}
color17 ${red1}
]],
colors
)
return kitty
end
return M

28
lua/farout/extra/lua.lua Normal file
View File

@@ -0,0 +1,28 @@
local M = {}
--- @param colors ColorScheme
function M.generate(colors)
local function deepcopy(tbl)
local ret = tbl
if type(tbl) == "table" then
ret = {}
for key, value in pairs(tbl) do
ret[key] = deepcopy(value)
end
end
return ret
end
colors = vim.deepcopy(colors)
colors._upstream_url = nil
colors._style_name = nil
local ret = "local colors = "
.. vim.inspect(colors)
.. "\n\nlocal highlights = "
.. vim.inspect(deepcopy(require("farout.theme").setup().highlights))
.. "\n"
return ret
end
return M

View File

@@ -0,0 +1,88 @@
local util = require("farout.util")
local M = {}
--- @param colors ColorScheme
function M.generate(colors)
return util.template(M.template, colors)
end
M.template = [[
module.exports = {
plain: {
color: "${fg}",
backgroundColor: "${bg}",
},
styles: [
{
types: ["prolog", "builtin"],
style: {
color: "${red}",
},
},
{
types: ["function"],
style: {
color: "${blue}",
},
},
{
types: ["symbol"],
style: {
color: "${blue1}",
},
},
{
types: ["punctuation"],
style: {
color: "${magenta}",
},
},
{
types: ["string", "char", "tag", "selector"],
style: {
color: "${green}",
},
},
{
types: ["keyword"],
style: {
color: "${purple}",
},
},
{
types: ["operator"],
style: {
color: "${blue5}",
},
},
{
types: ["constant", "boolean"],
style: {
color: "${orange}",
},
},
{
types: ["variable"],
style: {
color: "${fg}",
},
},
{
types: ["comment"],
style: {
color: "${comment}",
fontStyle: "italic",
},
},
{
types: ["attr-name"],
style: {
color: "rgb(241, 250, 140)",
},
},
],
};
]]
return M

1379
lua/farout/extra/sublime.lua Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,19 @@
local util = require("farout.util")
local M = {}
--- @param colors ColorScheme
function M.generate(colors)
local terminator = util.template(
[=[
[[${_style_name}]]
palette = "${black}:${red}:${green}:${yellow}:${blue}:${magenta}:${cyan}:${fg_dark}:${terminal_black}:${red}:${green}:${yellow}:${blue}:${magenta}:${cyan}:${purple}"
background_color = "${bg}"
foreground_color = "${fg}"
]=],
colors
)
return terminator
end
return M

View File

@@ -0,0 +1,40 @@
local util = require("farout.util")
local M = {}
--- @param colors ColorScheme
function M.generate(colors)
local tilix = util.template(
[[
{
"name": "${_style_name}",
"comment": "",
"use-theme-colors": false,
"foreground-color": "${fg}",
"background-color": "${bg}",
"palette": [
"${black}",
"${red}",
"${green}",
"${yellow}",
"${blue}",
"${magenta}",
"${cyan}",
"${fg_dark}",
"${terminal_black}",
"${red}",
"${green}",
"${yellow}",
"${blue}",
"${magenta}",
"${cyan}",
"${fg}"
]
}
]],
colors
)
return tilix
end
return M

53
lua/farout/extra/tmux.lua Normal file
View File

@@ -0,0 +1,53 @@
local util = require("farout.util")
local M = {}
--- @param colors ColorScheme
function M.generate(colors)
local tmux = util.template(
[[
#!/usr/bin/env bash
# FarOut colors for Tmux
set -g mode-style "fg=${blue},bg=${fg_gutter}"
set -g message-style "fg=${blue},bg=${fg_gutter}"
set -g message-command-style "fg=${blue},bg=${fg_gutter}"
set -g pane-border-style "fg=${fg_gutter}"
set -g pane-active-border-style "fg=${blue}"
set -g status "on"
set -g status-justify "left"
set -g status-style "fg=${blue},bg=${bg_statusline}"
set -g status-left-length "100"
set -g status-right-length "100"
set -g status-left-style ${none}
set -g status-right-style ${none}
set -g status-left "#[fg=${black},bg=${blue},bold] #S #[fg=${blue},bg=${bg_statusline},nobold,nounderscore,noitalics]"
set -g status-right "#[fg=${bg_statusline},bg=${bg_statusline},nobold,nounderscore,noitalics]#[fg=${blue},bg=${bg_statusline}] #{prefix_highlight} #[fg=${fg_gutter},bg=${bg_statusline},nobold,nounderscore,noitalics]#[fg=${blue},bg=${fg_gutter}] %Y-%m-%d  %I:%M %p #[fg=${blue},bg=${fg_gutter},nobold,nounderscore,noitalics]#[fg=${black},bg=${blue},bold] #h "
if-shell '[ "$(tmux show-option -gqv "clock-mode-style")" == "24" ]' {
set -g status-right "#[fg=${bg_statusline},bg=${bg_statusline},nobold,nounderscore,noitalics]#[fg=${blue},bg=${bg_statusline}] #{prefix_highlight} #[fg=${fg_gutter},bg=${bg_statusline},nobold,nounderscore,noitalics]#[fg=${blue},bg=${fg_gutter}] %Y-%m-%d  %H:%M #[fg=${blue},bg=${fg_gutter},nobold,nounderscore,noitalics]#[fg=${black},bg=${blue},bold] #h "
}
setw -g window-status-activity-style "underscore,fg=${fg_sidebar},bg=${bg_statusline}"
setw -g window-status-separator ""
setw -g window-status-style "${none},fg=${fg_sidebar},bg=${bg_statusline}"
setw -g window-status-format "#[fg=${bg_statusline},bg=${bg_statusline},nobold,nounderscore,noitalics]#[default] #I  #W #F #[fg=${bg_statusline},bg=${bg_statusline},nobold,nounderscore,noitalics]"
setw -g window-status-current-format "#[fg=${bg_statusline},bg=${fg_gutter},nobold,nounderscore,noitalics]#[fg=${blue},bg=${fg_gutter},bold] #I  #W #F #[fg=${fg_gutter},bg=${bg_statusline},nobold,nounderscore,noitalics]"
# tmux-plugins/tmux-prefix-highlight support
set -g @prefix_highlight_output_prefix "#[fg=${yellow}]#[bg=${bg_statusline}]#[fg=${bg_statusline}]#[bg=${yellow}]"
set -g @prefix_highlight_output_suffix ""
]],
colors
)
return tmux
end
return M

View File

@@ -0,0 +1,58 @@
local util = require("farout.util")
local M = {}
--- @param colors ColorScheme
function M.generate(colors)
local wezterm = util.template(
[[
[colors]
foreground = "${fg}"
background = "${bg}"
cursor_bg = "${fg}"
cursor_border = "${fg}"
cursor_fg = "${bg}"
selection_bg = "${bg_visual}"
selection_fg = "${fg}"
split = "${blue}"
compose_cursor = "${orange}"
ansi = ["${black}", "${red}", "${green}", "${yellow}", "${blue}", "${magenta}", "${cyan}", "${fg_dark}"]
brights = ["${terminal_black}", "${red}", "${green}", "${yellow}", "${blue}", "${magenta}", "${cyan}", "${fg}"]
[colors.tab_bar]
inactive_tab_edge = "${bg_dark}"
background = "${bg}"
[colors.tab_bar.active_tab]
fg_color = "${bg_dark}"
bg_color = "${blue}"
[colors.tab_bar.inactive_tab]
fg_color = "${dark3}"
bg_color = "${bg_highlight}"
[colors.tab_bar.inactive_tab_hover]
fg_color = "${blue}"
bg_color = "${bg_highlight}"
# intensity = "Bold"
[colors.tab_bar.new_tab_hover]
fg_color = "${blue}"
bg_color = "${bg}"
intensity = "Bold"
[colors.tab_bar.new_tab]
fg_color = "${blue}"
bg_color = "${bg}"
[metadata]
aliases = []
author = "folke"
name = "${_name}"]],
colors
)
return wezterm
end
return M

View File

@@ -0,0 +1,41 @@
local util = require("farout.util")
local M = {}
--- @param colors ColorScheme
function M.generate(colors)
local windows_terminal = util.template(
[[
# Add the following object to your Windows Terminal configuration
# https://learn.microsoft.com/en-us/windows/terminal/customize-settings/color-schemes#creating-your-own-color-scheme
{
"background": "${bg}",
"black": "${black}",
"blue": "${blue}",
"brightBlack": "${terminal_black}",
"brightBlue": "${blue}",
"brightCyan": "${cyan}",
"brightGreen": "${green}",
"brightPurple": "${purple}",
"brightRed": "${red}",
"brightWhite": "${fg}",
"brightYellow": "${yellow}",
"cursorColor": "${fg}",
"cyan": "${cyan}",
"foreground": "${fg}",
"green": "${green}",
"name": "${_style_name}",
"purple": "${magenta}",
"red": "${red}",
"selectionBackground": "${bg_visual}",
"white": "${fg_dark}",
"yellow": "${yellow}"
}
]],
colors
)
return windows_terminal
end
return M

View File

@@ -0,0 +1,24 @@
local util = require("farout.util")
local M = {}
-- @param colors ColorScheme
function M.generate(colors)
local xfceterm = util.template(
[[
[Scheme]
Name=FarOut Colors
ColorBackground=${bg}
ColorForeground=${fg}
ColorSelectionBackground=${bg_visual}
ColorSelection=${fg}
ColorPalette=${black};${red};${green};${yellow};${blue};${magenta};${cyan};${fg_dark};${terminal_black};${red};${green};${yellow};${blue};${magenta};${cyan};${fg}
]],
colors
)
return xfceterm
end
return M

View File

@@ -0,0 +1,38 @@
local util = require("farout.util")
local M = {}
--- @param colors ColorScheme
function M.generate(colors)
local xr = util.template(
[[
! FarOut colors for Xresources
*background: ${bg}
*foreground: ${fg}
*color0: ${black}
*color1: ${red}
*color2: ${green}
*color3: ${yellow}
*color4: ${blue}
*color5: ${magenta}
*color6: ${cyan}
*color7: ${fg_dark}
*color8: ${terminal_black}
*color9: ${red}
*color10: ${green}
*color11: ${yellow}
*color12: ${blue}
*color13: ${magenta}
*color14: ${cyan}
*color15: ${fg}
]],
colors
)
return xr
end
return M

View File

@@ -0,0 +1,53 @@
local util = require("farout.util")
local M = {}
--- @param colors ColorScheme
function M.generate(colors)
local zathura = util.template(
[[
# Tokyonight color theme for Zathura
# Swaps Foreground for Background to get a light version if the user prefers
#
# Tokyonight color theme
#
set notification-error-bg "${red}"
set notification-error-fg "${fg}"
set notification-warning-bg "${yellow}"
set notification-warning-fg "${terminal_black}"
set notification-bg "${bg}"
set notification-fg "${fg}"
set completion-bg "${bg}"
set completion-fg "${fg_dark}"
set completion-group-bg "${bg}"
set completion-group-fg "${fg_dark}"
set completion-highlight-bg "${terminal_black}"
set completion-highlight-fg "${fg}"
set index-bg "${bg}"
set index-fg "${fg}"
set index-active-bg "${terminal_black}"
set index-active-fg "${fg}"
set inputbar-bg "${bg}"
set inputbar-fg "${fg}"
set statusbar-bg "${bg}"
set statusbar-fg "${fg}"
set highlight-color "${yellow}"
set highlight-active-color "${green}"
set default-bg "${bg}"
set default-fg "${fg}"
set render-loading true
set render-loading-fg "${bg}"
set render-loading-bg "${fg}"
#
# Recolor mode settings
# <C-r> to switch modes
#
set recolor-lightcolor "${bg}"
set recolor-darkcolor "${fg}"
]],
colors
)
return zathura
end
return M

338
lua/farout/hsluv.lua Normal file
View File

@@ -0,0 +1,338 @@
--[[
Lua implementation of HSLuv and HPLuv color spaces
Homepage: http://www.hsluv.org/
Copyright (C) 2019 Alexei Boronine
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local hsluv = {}
local hexChars = "0123456789abcdef"
local distance_line_from_origin = function(line)
return math.abs(line.intercept) / math.sqrt((line.slope ^ 2) + 1)
end
local length_of_ray_until_intersect = function(theta, line)
return line.intercept / (math.sin(theta) - line.slope * math.cos(theta))
end
hsluv.get_bounds = function(l)
local result = {}
local sub2
local sub1 = ((l + 16) ^ 3) / 1560896
if sub1 > hsluv.epsilon then
sub2 = sub1
else
sub2 = l / hsluv.kappa
end
for i = 1, 3 do
local m1 = hsluv.m[i][1]
local m2 = hsluv.m[i][2]
local m3 = hsluv.m[i][3]
for t = 0, 1 do
local top1 = (284517 * m1 - 94839 * m3) * sub2
local top2 = (838422 * m3 + 769860 * m2 + 731718 * m1) * l * sub2 - 769860 * t * l
local bottom = (632260 * m3 - 126452 * m2) * sub2 + 126452 * t
table.insert(result, { slope = top1 / bottom, intercept = top2 / bottom })
end
end
return result
end
hsluv.max_safe_chroma_for_l = function(l)
local bounds = hsluv.get_bounds(l)
local min = 1.7976931348623157e+308
for i = 1, 6 do
local length = distance_line_from_origin(bounds[i])
if length >= 0 then
min = math.min(min, length)
end
end
return min
end
hsluv.max_safe_chroma_for_lh = function(l, h)
local hrad = h / 360 * math.pi * 2
local bounds = hsluv.get_bounds(l)
local min = 1.7976931348623157e+308
for i = 1, 6 do
local bound = bounds[i]
local length = length_of_ray_until_intersect(hrad, bound)
if length >= 0 then
min = math.min(min, length)
end
end
return min
end
hsluv.dot_product = function(a, b)
local sum = 0
for i = 1, 3 do
sum = sum + a[i] * b[i]
end
return sum
end
hsluv.from_linear = function(c)
if c <= 0.0031308 then
return 12.92 * c
else
return 1.055 * (c ^ 0.416666666666666685) - 0.055
end
end
hsluv.to_linear = function(c)
if c > 0.04045 then
return ((c + 0.055) / 1.055) ^ 2.4
else
return c / 12.92
end
end
hsluv.xyz_to_rgb = function(tuple)
return {
hsluv.from_linear(hsluv.dot_product(hsluv.m[1], tuple)),
hsluv.from_linear(hsluv.dot_product(hsluv.m[2], tuple)),
hsluv.from_linear(hsluv.dot_product(hsluv.m[3], tuple)),
}
end
hsluv.rgb_to_xyz = function(tuple)
local rgbl = { hsluv.to_linear(tuple[1]), hsluv.to_linear(tuple[2]), hsluv.to_linear(tuple[3]) }
return {
hsluv.dot_product(hsluv.minv[1], rgbl),
hsluv.dot_product(hsluv.minv[2], rgbl),
hsluv.dot_product(hsluv.minv[3], rgbl),
}
end
hsluv.y_to_l = function(Y)
if Y <= hsluv.epsilon then
return Y / hsluv.refY * hsluv.kappa
else
return 116 * ((Y / hsluv.refY) ^ 0.333333333333333315) - 16
end
end
hsluv.l_to_y = function(L)
if L <= 8 then
return hsluv.refY * L / hsluv.kappa
else
return hsluv.refY * (((L + 16) / 116) ^ 3)
end
end
hsluv.xyz_to_luv = function(tuple)
local X = tuple[1]
local Y = tuple[2]
local divider = X + 15 * Y + 3 * tuple[3]
local varU = 4 * X
local varV = 9 * Y
if divider ~= 0 then
varU = varU / divider
varV = varV / divider
else
varU = 0
varV = 0
end
local L = hsluv.y_to_l(Y)
if L == 0 then
return { 0, 0, 0 }
end
return { L, 13 * L * (varU - hsluv.refU), 13 * L * (varV - hsluv.refV) }
end
hsluv.luv_to_xyz = function(tuple)
local L = tuple[1]
local U = tuple[2]
local V = tuple[3]
if L == 0 then
return { 0, 0, 0 }
end
local varU = U / (13 * L) + hsluv.refU
local varV = V / (13 * L) + hsluv.refV
local Y = hsluv.l_to_y(L)
local X = 0 - (9 * Y * varU) / (((varU - 4) * varV) - varU * varV)
return { X, Y, (9 * Y - 15 * varV * Y - varV * X) / (3 * varV) }
end
hsluv.luv_to_lch = function(tuple)
local L = tuple[1]
local U = tuple[2]
local V = tuple[3]
local C = math.sqrt(U * U + V * V)
local H
if C < 0.00000001 then
H = 0
else
H = math.atan2(V, U) * 180.0 / 3.1415926535897932
if H < 0 then
H = 360 + H
end
end
return { L, C, H }
end
hsluv.lch_to_luv = function(tuple)
local L = tuple[1]
local C = tuple[2]
local Hrad = tuple[3] / 360.0 * 2 * math.pi
return { L, math.cos(Hrad) * C, math.sin(Hrad) * C }
end
hsluv.hsluv_to_lch = function(tuple)
local H = tuple[1]
local S = tuple[2]
local L = tuple[3]
if L > 99.9999999 then
return { 100, 0, H }
end
if L < 0.00000001 then
return { 0, 0, H }
end
return { L, hsluv.max_safe_chroma_for_lh(L, H) / 100 * S, H }
end
hsluv.lch_to_hsluv = function(tuple)
local L = tuple[1]
local C = tuple[2]
local H = tuple[3]
local max_chroma = hsluv.max_safe_chroma_for_lh(L, H)
if L > 99.9999999 then
return { H, 0, 100 }
end
if L < 0.00000001 then
return { H, 0, 0 }
end
return { H, C / max_chroma * 100, L }
end
hsluv.hpluv_to_lch = function(tuple)
local H = tuple[1]
local S = tuple[2]
local L = tuple[3]
if L > 99.9999999 then
return { 100, 0, H }
end
if L < 0.00000001 then
return { 0, 0, H }
end
return { L, hsluv.max_safe_chroma_for_l(L) / 100 * S, H }
end
hsluv.lch_to_hpluv = function(tuple)
local L = tuple[1]
local C = tuple[2]
local H = tuple[3]
if L > 99.9999999 then
return { H, 0, 100 }
end
if L < 0.00000001 then
return { H, 0, 0 }
end
return { H, C / hsluv.max_safe_chroma_for_l(L) * 100, L }
end
hsluv.rgb_to_hex = function(tuple)
local h = "#"
for i = 1, 3 do
local c = math.floor(tuple[i] * 255 + 0.5)
local digit2 = math.fmod(c, 16)
local x = (c - digit2) / 16
local digit1 = math.floor(x)
h = h .. string.sub(hexChars, digit1 + 1, digit1 + 1)
h = h .. string.sub(hexChars, digit2 + 1, digit2 + 1)
end
return h
end
hsluv.hex_to_rgb = function(hex)
hex = string.lower(hex)
local ret = {}
for i = 0, 2 do
local char1 = string.sub(hex, i * 2 + 2, i * 2 + 2)
local char2 = string.sub(hex, i * 2 + 3, i * 2 + 3)
local digit1 = string.find(hexChars, char1) - 1
local digit2 = string.find(hexChars, char2) - 1
ret[i + 1] = (digit1 * 16 + digit2) / 255.0
end
return ret
end
hsluv.lch_to_rgb = function(tuple)
return hsluv.xyz_to_rgb(hsluv.luv_to_xyz(hsluv.lch_to_luv(tuple)))
end
hsluv.rgb_to_lch = function(tuple)
return hsluv.luv_to_lch(hsluv.xyz_to_luv(hsluv.rgb_to_xyz(tuple)))
end
hsluv.hsluv_to_rgb = function(tuple)
return hsluv.lch_to_rgb(hsluv.hsluv_to_lch(tuple))
end
hsluv.rgb_to_hsluv = function(tuple)
return hsluv.lch_to_hsluv(hsluv.rgb_to_lch(tuple))
end
hsluv.hpluv_to_rgb = function(tuple)
return hsluv.lch_to_rgb(hsluv.hpluv_to_lch(tuple))
end
hsluv.rgb_to_hpluv = function(tuple)
return hsluv.lch_to_hpluv(hsluv.rgb_to_lch(tuple))
end
hsluv.hsluv_to_hex = function(tuple)
return hsluv.rgb_to_hex(hsluv.hsluv_to_rgb(tuple))
end
hsluv.hpluv_to_hex = function(tuple)
return hsluv.rgb_to_hex(hsluv.hpluv_to_rgb(tuple))
end
hsluv.hex_to_hsluv = function(s)
return hsluv.rgb_to_hsluv(hsluv.hex_to_rgb(s))
end
hsluv.hex_to_hpluv = function(s)
return hsluv.rgb_to_hpluv(hsluv.hex_to_rgb(s))
end
hsluv.m = {
{ 3.240969941904521, -1.537383177570093, -0.498610760293 },
{ -0.96924363628087, 1.87596750150772, 0.041555057407175 },
{ 0.055630079696993, -0.20397695888897, 1.056971514242878 },
}
hsluv.minv = {
{ 0.41239079926595, 0.35758433938387, 0.18048078840183 },
{ 0.21263900587151, 0.71516867876775, 0.072192315360733 },
{ 0.019330818715591, 0.11919477979462, 0.95053215224966 },
}
hsluv.refY = 1.0
hsluv.refU = 0.19783000664283
hsluv.refV = 0.46831999493879
hsluv.kappa = 903.2962962
hsluv.epsilon = 0.0088564516
return hsluv

31
lua/farout/init.lua Normal file
View File

@@ -0,0 +1,31 @@
local util = require("farout.util")
local theme = require("farout.theme")
local config = require("farout.config")
local M = {}
function M._load(style)
if style and not M._style then
M._style = require("farout.config").options.style
end
if not style and M._style then
require("farout.config").options.style = M._style
M._style = nil
end
M.load({ style = style, use_background = style == nil })
end
---@param opts Config|nil
function M.load(opts)
if opts then
require("farout.config").extend(opts)
end
util.load(theme.setup())
end
M.setup = config.setup
-- keep for backward compatibility
M.colorscheme = M.load
return M

828
lua/farout/theme.lua Normal file
View File

@@ -0,0 +1,828 @@
local util = require("farout.util")
local colors = require("farout.colors")
local M = {}
--
---@class Highlight
---@field fg string|nil
---@field bg string|nil
---@field sp string|nil
---@field style string|nil|Highlight
---@field link string|nil
---@alias Highlights table<string,Highlight>
---@return Theme
function M.setup()
local config = require("farout.config")
local options = config.options
---@class Theme
---@field highlights Highlights
local theme = {
config = options,
colors = colors.setup(),
}
local c = theme.colors
theme.highlights = {
Foo = { bg = c.magenta2, fg = c.fg },
Comment = { fg = c.comment, style = options.styles.comments }, -- any comment
ColorColumn = { bg = c.black }, -- used for the columns set with 'colorcolumn'
Conceal = { fg = c.dark5 }, -- placeholder characters substituted for concealed text (see 'conceallevel')
Cursor = { fg = c.bg, bg = c.fg }, -- character under the cursor
lCursor = { fg = c.bg, bg = c.fg }, -- the character under the cursor when |language-mapping| is used (see 'guicursor')
CursorIM = { fg = c.bg, bg = c.fg }, -- like Cursor, but used when in IME mode |CursorIM|
CursorColumn = { bg = c.bg_highlight }, -- Screen-column at the cursor, when 'cursorcolumn' is set.
CursorLine = { bg = c.bg_highlight }, -- Screen-line at the cursor, when 'cursorline' is set. Low-priority if foreground (ctermfg OR guifg) is not set.
Directory = { fg = c.blue }, -- directory names (and other special names in listings)
DiffAdd = { bg = c.diff.add }, -- diff mode: Added line |diff.txt|
DiffChange = { bg = c.diff.change }, -- diff mode: Changed line |diff.txt|
DiffDelete = { bg = c.diff.delete }, -- diff mode: Deleted line |diff.txt|
DiffText = { bg = c.diff.text }, -- diff mode: Changed text within a changed line |diff.txt|
EndOfBuffer = { fg = c.bg }, -- filler lines (~) after the end of the buffer. By default, this is highlighted like |hl-NonText|.
-- TermCursor = { }, -- cursor in a focused terminal
-- TermCursorNC= { }, -- cursor in an unfocused terminal
ErrorMsg = { fg = c.error }, -- error messages on the command line
VertSplit = { fg = c.border }, -- the column separating vertically split windows
WinSeparator = { fg = c.border, bold = true }, -- the column separating vertically split windows
Folded = { fg = c.blue, bg = c.fg_gutter }, -- line used for closed folds
FoldColumn = { bg = options.transparent and c.none or c.bg, fg = c.comment }, -- 'foldcolumn'
SignColumn = { bg = options.transparent and c.none or c.bg, fg = c.fg_gutter }, -- column where |signs| are displayed
SignColumnSB = { bg = c.bg_sidebar, fg = c.fg_gutter }, -- column where |signs| are displayed
Substitute = { bg = c.red, fg = c.black }, -- |:substitute| replacement text highlighting
LineNr = { fg = c.fg_gutter }, -- Line number for ":number" and ":#" commands, and when 'number' or 'relativenumber' option is set.
CursorLineNr = { fg = c.dark5 }, -- Like LineNr when 'cursorline' or 'relativenumber' is set for the cursor line.
MatchParen = { fg = c.orange, bold = true }, -- The character under the cursor or just before it, if it is a paired bracket, and its match. |pi_paren.txt|
ModeMsg = { fg = c.fg_dark, bold = true }, -- 'showmode' message (e.g., "-- INSERT -- ")
MsgArea = { fg = c.fg_dark }, -- Area for messages and cmdline
-- MsgSeparator= { }, -- Separator for scrolled messages, `msgsep` flag of 'display'
MoreMsg = { fg = c.blue }, -- |more-prompt|
NonText = { fg = c.dark3 }, -- '@' at the end of the window, characters from 'showbreak' and other characters that do not really exist in the text (e.g., ">" displayed when a double-wide character doesn't fit at the end of the line). See also |hl-EndOfBuffer|.
Normal = { fg = c.fg, bg = options.transparent and c.none or c.bg }, -- normal text
NormalNC = { fg = c.fg, bg = options.transparent and c.none or options.dim_inactive and c.bg_dark or c.bg }, -- normal text in non-current windows
NormalSB = { fg = c.fg_sidebar, bg = c.bg_sidebar }, -- normal text in sidebar
NormalFloat = { fg = c.fg_float, bg = c.bg_float }, -- Normal text in floating windows.
FloatBorder = { fg = c.border_highlight, bg = c.bg_float },
FloatTitle = { fg = c.border_highlight, bg = c.bg_float },
Pmenu = { bg = c.bg_popup, fg = c.fg }, -- Popup menu: normal item.
PmenuSel = { bg = util.darken(c.fg_gutter, 0.8) }, -- Popup menu: selected item.
PmenuSbar = { bg = util.lighten(c.bg_popup, 0.95) }, -- Popup menu: scrollbar.
PmenuThumb = { bg = c.fg_gutter }, -- Popup menu: Thumb of the scrollbar.
Question = { fg = c.blue }, -- |hit-enter| prompt and yes/no questions
QuickFixLine = { bg = c.bg_visual, bold = true }, -- Current |quickfix| item in the quickfix window. Combined with |hl-CursorLine| when the cursor is there.
Search = { bg = c.bg_search, fg = c.fg }, -- Last search pattern highlighting (see 'hlsearch'). Also used for similar items that need to stand out.
IncSearch = { bg = c.orange, fg = c.black }, -- 'incsearch' highlighting; also used for the text replaced with ":s///c"
CurSearch = { link = "IncSearch" },
SpecialKey = { fg = c.dark3 }, -- Unprintable characters: text displayed differently from what it really is. But not 'listchars' whitespace. |hl-Whitespace|
SpellBad = { sp = c.error, undercurl = true }, -- Word that is not recognized by the spellchecker. |spell| Combined with the highlighting used otherwise.
SpellCap = { sp = c.warning, undercurl = true }, -- Word that should start with a capital. |spell| Combined with the highlighting used otherwise.
SpellLocal = { sp = c.info, undercurl = true }, -- Word that is recognized by the spellchecker as one that is used in another region. |spell| Combined with the highlighting used otherwise.
SpellRare = { sp = c.hint, undercurl = true }, -- Word that is recognized by the spellchecker as one that is hardly ever used. |spell| Combined with the highlighting used otherwise.
StatusLine = { fg = c.fg_sidebar, bg = c.bg_statusline }, -- status line of current window
StatusLineNC = { fg = c.fg_gutter, bg = c.bg_statusline }, -- status lines of not-current windows Note: if this is equal to "StatusLine" Vim will use "^^^" in the status line of the current window.
TabLine = { bg = c.bg_statusline, fg = c.fg_gutter }, -- tab pages line, not active tab page label
TabLineFill = { bg = c.black }, -- tab pages line, where there are no labels
TabLineSel = { fg = c.black, bg = c.blue }, -- tab pages line, active tab page label
Title = { fg = c.blue, bold = true }, -- titles for output from ":set all", ":autocmd" etc.
Visual = { bg = c.bg_visual }, -- Visual mode selection
VisualNOS = { bg = c.bg_visual }, -- Visual mode selection when vim is "Not Owning the Selection".
WarningMsg = { fg = c.warning }, -- warning messages
Whitespace = { fg = c.fg_gutter }, -- "nbsp", "space", "tab" and "trail" in 'listchars'
WildMenu = { bg = c.bg_visual }, -- current match in 'wildmenu' completion
-- These groups are not listed as default vim groups,
-- but they are defacto standard group names for syntax highlighting.
-- commented out groups should chain up to their "preferred" group by
-- default,
-- Uncomment and edit if you want more specific syntax highlighting.
Constant = { fg = c.orange }, -- (preferred) any constant
String = { fg = c.green }, -- a string constant: "this is a string"
Character = { fg = c.green }, -- a character constant: 'c', '\n'
-- Number = { }, -- a number constant: 234, 0xff
-- Boolean = { }, -- a boolean constant: TRUE, false
-- Float = { }, -- a floating point constant: 2.3e10
Identifier = { fg = c.magenta, style = options.styles.variables }, -- (preferred) any variable name
Function = { fg = c.blue, style = options.styles.functions }, -- function name (also: methods for classes)
Statement = { fg = c.magenta }, -- (preferred) any statement
-- Conditional = { }, -- if, then, else, endif, switch, etc.
-- Repeat = { }, -- for, do, while, etc.
-- Label = { }, -- case, default, etc.
Operator = { fg = c.blue5 }, -- "sizeof", "+", "*", etc.
Keyword = { fg = c.cyan, style = options.styles.keywords }, -- any other keyword
-- Exception = { }, -- try, catch, throw
PreProc = { fg = c.cyan }, -- (preferred) generic Preprocessor
-- Include = { }, -- preprocessor #include
-- Define = { }, -- preprocessor #define
-- Macro = { }, -- same as Define
-- PreCondit = { }, -- preprocessor #if, #else, #endif, etc.
Type = { fg = c.blue1 }, -- (preferred) int, long, char, etc.
-- StorageClass = { }, -- static, register, volatile, etc.
-- Structure = { }, -- struct, union, enum, etc.
-- Typedef = { }, -- A typedef
Special = { fg = c.blue1 }, -- (preferred) any special symbol
-- SpecialChar = { }, -- special character in a constant
-- Tag = { }, -- you can use CTRL-] on this
-- Delimiter = { }, -- character that needs attention
-- SpecialComment= { }, -- special things inside a comment
Debug = { fg = c.orange }, -- debugging statements
Underlined = { underline = true }, -- (preferred) text that stands out, HTML links
Bold = { bold = true },
Italic = { italic = true },
-- ("Ignore", below, may be invisible...)
-- Ignore = { }, -- (preferred) left blank, hidden |hl-Ignore|
Error = { fg = c.error }, -- (preferred) any erroneous construct
Todo = { bg = c.yellow, fg = c.bg }, -- (preferred) anything that needs extra attention; mostly the keywords TODO FIXME and XXX
qfLineNr = { fg = c.dark5 },
qfFileName = { fg = c.blue },
htmlH1 = { fg = c.magenta, bold = true },
htmlH2 = { fg = c.blue, bold = true },
-- mkdHeading = { fg = c.orange, bold = true },
-- mkdCode = { bg = c.terminal_black, fg = c.fg },
mkdCodeDelimiter = { bg = c.terminal_black, fg = c.fg },
mkdCodeStart = { fg = c.teal, bold = true },
mkdCodeEnd = { fg = c.teal, bold = true },
-- mkdLink = { fg = c.blue, underline = true },
markdownHeadingDelimiter = { fg = c.orange, bold = true },
markdownCode = { fg = c.teal },
markdownCodeBlock = { fg = c.teal },
markdownH1 = { fg = c.magenta, bold = true },
markdownH2 = { fg = c.blue, bold = true },
markdownLinkText = { fg = c.blue, underline = true },
["helpCommand"] = { bg = c.terminal_black, fg = c.blue },
debugPC = { bg = c.bg_sidebar }, -- used for highlighting the current line in terminal-debug
debugBreakpoint = { bg = util.darken(c.info, 0.1), fg = c.info }, -- used for breakpoint colors in terminal-debug
dosIniLabel = { link = "@property" },
-- These groups are for the native LSP client. Some other LSP clients may
-- use these groups, or use their own. Consult your LSP client's
-- documentation.
LspReferenceText = { bg = c.fg_gutter }, -- used for highlighting "text" references
LspReferenceRead = { bg = c.fg_gutter }, -- used for highlighting "read" references
LspReferenceWrite = { bg = c.fg_gutter }, -- used for highlighting "write" references
DiagnosticError = { fg = c.error }, -- Used as the base highlight group. Other Diagnostic highlights link to this by default
DiagnosticWarn = { fg = c.warning }, -- Used as the base highlight group. Other Diagnostic highlights link to this by default
DiagnosticInfo = { fg = c.info }, -- Used as the base highlight group. Other Diagnostic highlights link to this by default
DiagnosticHint = { fg = c.hint }, -- Used as the base highlight group. Other Diagnostic highlights link to this by default
DiagnosticUnnecessary = { fg = c.terminal_black }, -- Used as the base highlight group. Other Diagnostic highlights link to this by default
DiagnosticVirtualTextError = { bg = util.darken(c.error, 0.1), fg = c.error }, -- Used for "Error" diagnostic virtual text
DiagnosticVirtualTextWarn = { bg = util.darken(c.warning, 0.1), fg = c.warning }, -- Used for "Warning" diagnostic virtual text
DiagnosticVirtualTextInfo = { bg = util.darken(c.info, 0.1), fg = c.info }, -- Used for "Information" diagnostic virtual text
DiagnosticVirtualTextHint = { bg = util.darken(c.hint, 0.1), fg = c.hint }, -- Used for "Hint" diagnostic virtual text
DiagnosticUnderlineError = { undercurl = true, sp = c.error }, -- Used to underline "Error" diagnostics
DiagnosticUnderlineWarn = { undercurl = true, sp = c.warning }, -- Used to underline "Warning" diagnostics
DiagnosticUnderlineInfo = { undercurl = true, sp = c.info }, -- Used to underline "Information" diagnostics
DiagnosticUnderlineHint = { undercurl = true, sp = c.hint }, -- Used to underline "Hint" diagnostics
LspSignatureActiveParameter = { bg = util.darken(c.bg_visual, 0.4), bold = true },
LspCodeLens = { fg = c.comment },
LspInlayHint = { bg = util.darken(c.blue7, 0.1), fg = c.dark3 },
LspInfoBorder = { fg = c.border_highlight, bg = c.bg_float },
ALEErrorSign = { fg = c.error },
ALEWarningSign = { fg = c.warning },
DapStoppedLine = { bg = util.darken(c.warning, 0.1) }, -- Used for "Warning" diagnostic virtual text
-- These groups are for the Neovim tree-sitter highlights.
-- As of writing, tree-sitter support is a WIP, group names may change.
--- Misc
-- TODO:
-- ["@comment.documentation"] = { },
["@operator"] = { fg = c.blue5 }, -- For any operator: `+`, but also `->` and `*` in C.
--- Punctuation
["@punctuation.delimiter"] = { fg = c.blue5 }, -- For delimiters ie: `.`
["@punctuation.bracket"] = { fg = c.fg_dark }, -- For brackets and parens.
["@punctuation.special"] = { fg = c.blue5 }, -- For special punctutation that does not fall in the catagories before.
["@punctuation.special.markdown"] = { fg = c.orange, bold = true },
--- Literals
["@string.documentation"] = { fg = c.yellow },
["@string.regex"] = { fg = c.blue6 }, -- For regexes.
["@string.escape"] = { fg = c.magenta }, -- For escape characters within a string.
--- Functions
["@constructor"] = { fg = c.magenta }, -- For constructor calls and definitions: `= { }` in Lua, and Java constructors.
["@parameter"] = { fg = c.yellow }, -- For parameters of a function.
["@parameter.builtin"] = { fg = util.lighten(c.yellow, 0.8) }, -- For builtin parameters of a function, e.g. "..." or Smali's p[1-99]
--- Keywords
["@keyword"] = { fg = c.purple, style = options.styles.keywords }, -- For keywords that don't fall in previous categories.
-- TODO:
-- ["@keyword.coroutine"] = { }, -- For keywords related to coroutines.
["@keyword.function"] = { fg = c.magenta, style = options.styles.functions }, -- For keywords used to define a fuction.
["@label"] = { fg = c.blue }, -- For labels: `label:` in C and `:label:` in Lua.
--- Types
["@type.builtin"] = { fg = util.darken(c.blue1, 0.8) },
["@field"] = { fg = c.green1 }, -- For fields.
["@property"] = { fg = c.green1 },
--- Identifiers
["@variable"] = { fg = c.fg, style = options.styles.variables }, -- Any variable name that does not have another highlight.
["@variable.builtin"] = { fg = c.red }, -- Variable names that are defined by the languages, like `this` or `self`.
["@namespace.builtin"] = { fg = c.red }, -- Variable names that are defined by the languages, like `this` or `self`.
--- Text
-- ["@text.literal.markdown"] = { fg = c.blue },
["@text.literal.markdown_inline"] = { bg = c.terminal_black, fg = c.blue },
["@text.reference"] = { fg = c.teal },
["@text.todo.unchecked"] = { fg = c.blue }, -- For brackets and parens.
["@text.todo.checked"] = { fg = c.green1 }, -- For brackets and parens.
["@text.warning"] = { fg = c.bg, bg = c.warning },
["@text.danger"] = { fg = c.bg, bg = c.error },
["@text.diff.add"] = { link = "DiffAdd" },
["@text.diff.delete"] = { link = "DiffDelete" },
["@namespace"] = { link = "Include" },
-- tsx
["@tag.tsx"] = { fg = c.red },
["@constructor.tsx"] = { fg = c.blue1 },
["@tag.delimiter.tsx"] = { fg = util.darken(c.blue, 0.7) },
-- LSP Semantic Token Groups
["@lsp.type.boolean"] = { link = "@boolean" },
["@lsp.type.builtinType"] = { link = "@type.builtin" },
["@lsp.type.comment"] = { link = "@comment" },
["@lsp.type.decorator"] = { link = "@attribute" },
["@lsp.type.deriveHelper"] = { link = "@attribute" },
["@lsp.type.enum"] = { link = "@type" },
["@lsp.type.enumMember"] = { link = "@constant" },
["@lsp.type.escapeSequence"] = { link = "@string.escape" },
["@lsp.type.formatSpecifier"] = { link = "@punctuation.special" },
["@lsp.type.generic"] = { link = "@variable" },
["@lsp.type.interface"] = { fg = util.lighten(c.blue1, 0.7) },
["@lsp.type.keyword"] = { link = "@keyword" },
["@lsp.type.lifetime"] = { link = "@storageclass" },
["@lsp.type.namespace"] = { link = "@namespace" },
["@lsp.type.number"] = { link = "@number" },
["@lsp.type.operator"] = { link = "@operator" },
["@lsp.type.parameter"] = { link = "@parameter" },
["@lsp.type.property"] = { link = "@property" },
["@lsp.type.selfKeyword"] = { link = "@variable.builtin" },
["@lsp.type.selfTypeKeyword"] = { link = "@variable.builtin" },
["@lsp.type.string"] = { link = "@string" },
["@lsp.type.typeAlias"] = { link = "@type.definition" },
["@lsp.type.unresolvedReference"] = { undercurl = true, sp = c.error },
["@lsp.type.variable"] = {}, -- use treesitter styles for regular variables
["@lsp.typemod.class.defaultLibrary"] = { link = "@type.builtin" },
["@lsp.typemod.enum.defaultLibrary"] = { link = "@type.builtin" },
["@lsp.typemod.enumMember.defaultLibrary"] = { link = "@constant.builtin" },
["@lsp.typemod.function.defaultLibrary"] = { link = "@function.builtin" },
["@lsp.typemod.keyword.async"] = { link = "@keyword.coroutine" },
["@lsp.typemod.keyword.injected"] = { link = "@keyword" },
["@lsp.typemod.macro.defaultLibrary"] = { link = "@function.builtin" },
["@lsp.typemod.method.defaultLibrary"] = { link = "@function.builtin" },
["@lsp.typemod.operator.injected"] = { link = "@operator" },
["@lsp.typemod.string.injected"] = { link = "@string" },
["@lsp.typemod.struct.defaultLibrary"] = { link = "@type.builtin" },
["@lsp.typemod.type.defaultLibrary"] = { fg = util.darken(c.blue1, 0.8) },
["@lsp.typemod.typeAlias.defaultLibrary"] = { fg = util.darken(c.blue1, 0.8) },
["@lsp.typemod.variable.callable"] = { link = "@function" },
["@lsp.typemod.variable.defaultLibrary"] = { link = "@variable.builtin" },
["@lsp.typemod.variable.injected"] = { link = "@variable" },
["@lsp.typemod.variable.static"] = { link = "@constant" },
-- NOTE: maybe add these with distinct highlights?
-- ["@lsp.typemod.variable.globalScope"] (global variables)
-- ts-rainbow
rainbowcol1 = { fg = c.red },
rainbowcol2 = { fg = c.yellow },
rainbowcol3 = { fg = c.green },
rainbowcol4 = { fg = c.teal },
rainbowcol5 = { fg = c.blue },
rainbowcol6 = { fg = c.magenta },
rainbowcol7 = { fg = c.purple },
-- ts-rainbow2 (maintained fork)
TSRainbowRed = { fg = c.red },
TSRainbowOrange = { fg = c.orange },
TSRainbowYellow = { fg = c.yellow },
TSRainbowGreen = { fg = c.green },
TSRainbowBlue = { fg = c.blue },
TSRainbowViolet = { fg = c.purple },
TSRainbowCyan = { fg = c.cyan },
-- rainbow-delimiters
RainbowDelimiterRed = { fg = c.red },
RainbowDelimiterOrange = { fg = c.orange },
RainbowDelimiterYellow = { fg = c.yellow },
RainbowDelimiterGreen = { fg = c.green },
RainbowDelimiterBlue = { fg = c.blue },
RainbowDelimiterViolet = { fg = c.purple },
RainbowDelimiterCyan = { fg = c.cyan },
-- LspTrouble
TroubleText = { fg = c.fg_dark },
TroubleCount = { fg = c.magenta, bg = c.fg_gutter },
TroubleNormal = { fg = c.fg_sidebar, bg = c.bg_sidebar },
-- Illuminate
illuminatedWord = { bg = c.fg_gutter },
illuminatedCurWord = { bg = c.fg_gutter },
IlluminatedWordText = { bg = c.fg_gutter },
IlluminatedWordRead = { bg = c.fg_gutter },
IlluminatedWordWrite = { bg = c.fg_gutter },
-- diff
diffAdded = { fg = c.git.add },
diffRemoved = { fg = c.git.delete },
diffChanged = { fg = c.git.change },
diffOldFile = { fg = c.yellow },
diffNewFile = { fg = c.orange },
diffFile = { fg = c.blue },
diffLine = { fg = c.comment },
diffIndexLine = { fg = c.magenta },
-- Neogit
NeogitBranch = { fg = c.magenta },
NeogitRemote = { fg = c.purple },
NeogitHunkHeader = { bg = c.bg_highlight, fg = c.fg },
NeogitHunkHeaderHighlight = { bg = c.fg_gutter, fg = c.blue },
NeogitDiffContextHighlight = { bg = util.darken(c.fg_gutter, 0.5), fg = c.fg_dark },
NeogitDiffDeleteHighlight = { fg = c.git.delete, bg = c.diff.delete },
NeogitDiffAddHighlight = { fg = c.git.add, bg = c.diff.add },
-- Neotest
NeotestPassed = { fg = c.green },
NeotestRunning = { fg = c.yellow },
NeotestFailed = { fg = c.red },
NeotestSkipped = { fg = c.blue },
NeotestTest = { fg = c.fg_sidebar },
NeotestNamespace = { fg = c.green2 },
NeotestFocused = { fg = c.yellow },
NeotestFile = { fg = c.teal },
NeotestDir = { fg = c.blue },
NeotestBorder = { fg = c.blue },
NeotestIndent = { fg = c.fg_sidebar },
NeotestExpandMarker = { fg = c.fg_sidebar },
NeotestAdapterName = { fg = c.purple, bold = true },
NeotestWinSelect = { fg = c.blue },
NeotestMarked = { fg = c.blue },
NeotestTarget = { fg = c.blue },
--[[ NeotestUnknown = {}, ]]
-- GitGutter
GitGutterAdd = { fg = c.gitSigns.add }, -- diff mode: Added line |diff.txt|
GitGutterChange = { fg = c.gitSigns.change }, -- diff mode: Changed line |diff.txt|
GitGutterDelete = { fg = c.gitSigns.delete }, -- diff mode: Deleted line |diff.txt|
GitGutterAddLineNr = { fg = c.gitSigns.add },
GitGutterChangeLineNr = { fg = c.gitSigns.change },
GitGutterDeleteLineNr = { fg = c.gitSigns.delete },
-- GitSigns
GitSignsAdd = { fg = c.gitSigns.add }, -- diff mode: Added line |diff.txt|
GitSignsChange = { fg = c.gitSigns.change }, -- diff mode: Changed line |diff.txt|
GitSignsDelete = { fg = c.gitSigns.delete }, -- diff mode: Deleted line |diff.txt|
-- Telescope
TelescopeBorder = { fg = c.border_highlight, bg = c.bg_float },
TelescopeNormal = { fg = c.fg, bg = c.bg_float },
-- NvimTree
NvimTreeNormal = { fg = c.fg_sidebar, bg = c.bg_sidebar },
NvimTreeWinSeparator = {
fg = options.styles.sidebars == "transparent" and c.border or c.bg_sidebar,
bg = c.bg_sidebar,
},
NvimTreeNormalNC = { fg = c.fg_sidebar, bg = c.bg_sidebar },
NvimTreeRootFolder = { fg = c.blue, bold = true },
NvimTreeGitDirty = { fg = c.git.change },
NvimTreeGitNew = { fg = c.git.add },
NvimTreeGitDeleted = { fg = c.git.delete },
NvimTreeOpenedFile = { bg = c.bg_highlight },
NvimTreeSpecialFile = { fg = c.purple, underline = true },
NvimTreeIndentMarker = { fg = c.fg_gutter },
NvimTreeImageFile = { fg = c.fg_sidebar },
NvimTreeSymlink = { fg = c.blue },
NvimTreeFolderIcon = { bg = c.none, fg = c.blue },
-- NvimTreeFolderName= { fg = c.fg_float },
NeoTreeNormal = { fg = c.fg_sidebar, bg = c.bg_sidebar },
NeoTreeNormalNC = { fg = c.fg_sidebar, bg = c.bg_sidebar },
NeoTreeDimText = { fg = c.fg_gutter },
-- Fern
FernBranchText = { fg = c.blue },
-- glyph palette
GlyphPalette1 = { fg = c.red1 },
GlyphPalette2 = { fg = c.green },
GlyphPalette3 = { fg = c.yellow },
GlyphPalette4 = { fg = c.blue },
GlyphPalette6 = { fg = c.green1 },
GlyphPalette7 = { fg = c.fg },
GlyphPalette9 = { fg = c.red },
-- Dashboard
DashboardShortCut = { fg = c.cyan },
DashboardHeader = { fg = c.blue },
DashboardCenter = { fg = c.magenta },
DashboardFooter = { fg = c.blue1 },
DashboardKey = { fg = c.orange },
DashboardDesc = { fg = c.cyan },
DashboardIcon = { fg = c.cyan, bold = true },
-- Alpha
AlphaShortcut = { fg = c.orange },
AlphaHeader = { fg = c.blue },
AlphaHeaderLabel = { fg = c.orange },
AlphaFooter = { fg = c.blue1 },
AlphaButtons = { fg = c.cyan },
-- WhichKey
WhichKey = { fg = c.cyan },
WhichKeyGroup = { fg = c.blue },
WhichKeyDesc = { fg = c.magenta },
WhichKeySeperator = { fg = c.comment },
WhichKeySeparator = { fg = c.comment },
WhichKeyFloat = { bg = c.bg_sidebar },
WhichKeyValue = { fg = c.dark5 },
-- LspSaga
DiagnosticWarning = { link = "DiagnosticWarn" },
DiagnosticInformation = { link = "DiagnosticInfo" },
LspFloatWinNormal = { bg = c.bg_float },
LspFloatWinBorder = { fg = c.border_highlight },
LspSagaBorderTitle = { fg = c.cyan },
LspSagaHoverBorder = { fg = c.blue },
LspSagaRenameBorder = { fg = c.green },
LspSagaDefPreviewBorder = { fg = c.green },
LspSagaCodeActionBorder = { fg = c.blue },
LspSagaFinderSelection = { fg = c.bg_visual },
LspSagaCodeActionTitle = { fg = c.blue1 },
LspSagaCodeActionContent = { fg = c.purple },
LspSagaSignatureHelpBorder = { fg = c.red },
ReferencesCount = { fg = c.purple },
DefinitionCount = { fg = c.purple },
DefinitionIcon = { fg = c.blue },
ReferencesIcon = { fg = c.blue },
TargetWord = { fg = c.cyan },
-- NeoVim
healthError = { fg = c.error },
healthSuccess = { fg = c.green1 },
healthWarning = { fg = c.warning },
-- BufferLine
BufferLineIndicatorSelected = { fg = c.git.change },
-- Barbar
BufferCurrent = { bg = c.bg, fg = c.fg },
BufferCurrentERROR = { bg = c.bg, fg = c.error },
BufferCurrentHINT = { bg = c.bg, fg = c.hint },
-- BufferCurrentIcon = { bg = c.bg, fg = c.},
BufferCurrentINFO = { bg = c.bg, fg = c.info },
BufferCurrentWARN = { bg = c.bg, fg = c.warning },
BufferCurrentIndex = { bg = c.bg, fg = c.info },
BufferCurrentMod = { bg = c.bg, fg = c.warning },
BufferCurrentSign = { bg = c.bg, fg = c.bg },
BufferCurrentTarget = { bg = c.bg, fg = c.red },
BufferAlternate = { bg = c.fg_gutter, fg = c.fg },
BufferAlternateERROR = { bg = c.fg_gutter, fg = c.error },
BufferAlternateHINT = { bg = c.fg_gutter, fg = c.hint },
-- BufferAlternateIcon = { bg = c.fg_gutter, fg = c. },
BufferAlternateIndex = { bg = c.fg_gutter, fg = c.info },
BufferAlternateINFO = { bg = c.fg_gutter, fg = c.info },
BufferAlternateMod = { bg = c.fg_gutter, fg = c.warning },
BufferAlternateSign = { bg = c.fg_gutter, fg = c.info },
BufferAlternateTarget = { bg = c.fg_gutter, fg = c.red },
BufferAlternateWARN = { bg = c.fg_gutter, fg = c.warning },
BufferVisible = { bg = c.bg_statusline, fg = c.fg },
BufferVisibleERROR = { bg = c.bg_statusline, fg = c.error },
BufferVisibleHINT = { bg = c.bg_statusline, fg = c.hint },
-- BufferVisibleIcon = { bg = c.bg_statusline, fg = c. },
BufferVisibleINFO = { bg = c.bg_statusline, fg = c.info },
BufferVisibleWARN = { bg = c.bg_statusline, fg = c.warning },
BufferVisibleIndex = { bg = c.bg_statusline, fg = c.info },
BufferVisibleMod = { bg = c.bg_statusline, fg = c.warning },
BufferVisibleSign = { bg = c.bg_statusline, fg = c.info },
BufferVisibleTarget = { bg = c.bg_statusline, fg = c.red },
BufferInactive = { bg = util.darken(c.bg_highlight, 0.4), fg = util.darken(c.dark5, 0.8) },
BufferInactiveERROR = { bg = util.darken(c.bg_highlight, 0.4), fg = util.darken(c.error, 0.8) },
BufferInactiveHINT = { bg = util.darken(c.bg_highlight, 0.4), fg = util.darken(c.hint, 0.8) },
-- BufferInactiveIcon = { bg = c.bg_statusline, fg = util.darken(c., 0.1) },
BufferInactiveINFO = { bg = util.darken(c.bg_highlight, 0.4), fg = util.darken(c.info, 0.8) },
BufferInactiveWARN = { bg = util.darken(c.bg_highlight, 0.4), fg = util.darken(c.warning, 0.8) },
BufferInactiveIndex = { bg = util.darken(c.bg_highlight, 0.4), fg = c.dark5 },
BufferInactiveMod = { bg = util.darken(c.bg_highlight, 0.4), fg = util.darken(c.warning, 0.8) },
BufferInactiveSign = { bg = util.darken(c.bg_highlight, 0.4), fg = c.bg },
BufferInactiveTarget = { bg = util.darken(c.bg_highlight, 0.4), fg = c.red },
BufferOffset = { bg = c.bg_statusline, fg = c.dark5 },
BufferTabpageFill = { bg = util.darken(c.bg_highlight, 0.8), fg = c.dark5 },
BufferTabpages = { bg = c.bg_statusline, fg = c.none },
-- Sneak
Sneak = { fg = c.bg_highlight, bg = c.magenta },
SneakScope = { bg = c.bg_visual },
-- Hop
HopNextKey = { fg = c.magenta2, bold = true },
HopNextKey1 = { fg = c.blue2, bold = true },
HopNextKey2 = { fg = util.darken(c.blue2, 0.6) },
HopUnmatched = { fg = c.dark3 },
TSNodeKey = { fg = c.magenta2, bold = true },
TSNodeUnmatched = { fg = c.dark3 },
LeapMatch = { bg = c.magenta2, fg = c.fg, bold = true },
LeapLabelPrimary = { fg = c.magenta2, bold = true },
LeapLabelSecondary = { fg = c.green1, bold = true },
LeapBackdrop = { fg = c.dark3 },
FlashBackdrop = { fg = c.dark3 },
FlashLabel = { bg = c.magenta2, bold = true, fg = c.fg },
LightspeedGreyWash = { fg = c.dark3 },
-- LightspeedCursor = { link = "Cursor" },
LightspeedLabel = { fg = c.magenta2, bold = true, underline = true },
LightspeedLabelDistant = { fg = c.green1, bold = true, underline = true },
LightspeedLabelDistantOverlapped = { fg = c.green2, underline = true },
LightspeedLabelOverlapped = { fg = c.magenta2, underline = true },
LightspeedMaskedChar = { fg = c.orange },
LightspeedOneCharMatch = { bg = c.magenta2, fg = c.fg, bold = true },
LightspeedPendingOpArea = { bg = c.magenta2, fg = c.fg },
LightspeedShortcut = { bg = c.magenta2, fg = c.fg, bold = true, underline = true },
-- LightspeedShortcutOverlapped = { link = "LightspeedShortcut" },
-- LightspeedUniqueChar = { link = "LightspeedUnlabeledMatch" },
LightspeedUnlabeledMatch = { fg = c.blue2, bold = true },
-- Cmp
CmpDocumentation = { fg = c.fg, bg = c.bg_float },
CmpDocumentationBorder = { fg = c.border_highlight, bg = c.bg_float },
CmpGhostText = { fg = c.terminal_black },
CmpItemAbbr = { fg = c.fg, bg = c.none },
CmpItemAbbrDeprecated = { fg = c.fg_gutter, bg = c.none, strikethrough = true },
CmpItemAbbrMatch = { fg = c.blue1, bg = c.none },
CmpItemAbbrMatchFuzzy = { fg = c.blue1, bg = c.none },
CmpItemMenu = { fg = c.comment, bg = c.none },
CmpItemKindDefault = { fg = c.fg_dark, bg = c.none },
CmpItemKindCodeium = { fg = c.teal, bg = c.none },
CmpItemKindCopilot = { fg = c.teal, bg = c.none },
CmpItemKindTabNine = { fg = c.teal, bg = c.none },
-- headlines.nvim
CodeBlock = { bg = c.bg_dark },
-- navic
NavicSeparator = { fg = c.fg, bg = c.none },
NavicText = { fg = c.fg, bg = c.none },
AerialNormal = { fg = c.fg, bg = c.none },
AerialGuide = { fg = c.fg_gutter },
AerialLine = { link = "LspInlayHint" },
IndentBlanklineChar = { fg = c.fg_gutter, nocombine = true },
IndentBlanklineContextChar = { fg = c.purple, nocombine = true },
IblIndent = { fg = c.fg_gutter, nocombine = true },
IblScope = { fg = c.purple, nocombine = true },
-- Scrollbar
ScrollbarHandle = { fg = c.none, bg = c.bg_highlight },
ScrollbarSearchHandle = { fg = c.orange, bg = c.bg_highlight },
ScrollbarSearch = { fg = c.orange, bg = c.none },
ScrollbarErrorHandle = { fg = c.error, bg = c.bg_highlight },
ScrollbarError = { fg = c.error, bg = c.none },
ScrollbarWarnHandle = { fg = c.warning, bg = c.bg_highlight },
ScrollbarWarn = { fg = c.warning, bg = c.none },
ScrollbarInfoHandle = { fg = c.info, bg = c.bg_highlight },
ScrollbarInfo = { fg = c.info, bg = c.none },
ScrollbarHintHandle = { fg = c.hint, bg = c.bg_highlight },
ScrollbarHint = { fg = c.hint, bg = c.none },
ScrollbarMiscHandle = { fg = c.purple, bg = c.bg_highlight },
ScrollbarMisc = { fg = c.purple, bg = c.none },
-- Yanky
YankyPut = { link = "IncSearch" },
YankyYanked = { link = "IncSearch" },
-- Lazy
LazyProgressDone = { bold = true, fg = c.magenta2 },
LazyProgressTodo = { bold = true, fg = c.fg_gutter },
-- Notify
NotifyBackground = { fg = c.fg, bg = c.bg },
--- Border
NotifyERRORBorder = { fg = util.darken(c.error, 0.3), bg = options.transparent and c.none or c.bg },
NotifyWARNBorder = { fg = util.darken(c.warning, 0.3), bg = options.transparent and c.none or c.bg },
NotifyINFOBorder = { fg = util.darken(c.info, 0.3), bg = options.transparent and c.none or c.bg },
NotifyDEBUGBorder = { fg = util.darken(c.comment, 0.3), bg = options.transparent and c.none or c.bg },
NotifyTRACEBorder = { fg = util.darken(c.purple, 0.3), bg = options.transparent and c.none or c.bg },
--- Icons
NotifyERRORIcon = { fg = c.error },
NotifyWARNIcon = { fg = c.warning },
NotifyINFOIcon = { fg = c.info },
NotifyDEBUGIcon = { fg = c.comment },
NotifyTRACEIcon = { fg = c.purple },
--- Title
NotifyERRORTitle = { fg = c.error },
NotifyWARNTitle = { fg = c.warning },
NotifyINFOTitle = { fg = c.info },
NotifyDEBUGTitle = { fg = c.comment },
NotifyTRACETitle = { fg = c.purple },
--- Body
NotifyERRORBody = { fg = c.fg, bg = options.transparent and c.none or c.bg },
NotifyWARNBody = { fg = c.fg, bg = options.transparent and c.none or c.bg },
NotifyINFOBody = { fg = c.fg, bg = options.transparent and c.none or c.bg },
NotifyDEBUGBody = { fg = c.fg, bg = options.transparent and c.none or c.bg },
NotifyTRACEBody = { fg = c.fg, bg = options.transparent and c.none or c.bg },
-- Mini
MiniCompletionActiveParameter = { underline = true },
MiniCursorword = { bg = c.fg_gutter },
MiniCursorwordCurrent = { bg = c.fg_gutter },
MiniIndentscopeSymbol = { fg = c.blue1, nocombine = true },
MiniIndentscopePrefix = { nocombine = true }, -- Make it invisible
MiniJump = { bg = c.magenta2, fg = "#ffffff" },
MiniJump2dSpot = { fg = c.magenta2, bold = true, nocombine = true },
MiniStarterCurrent = { nocombine = true },
MiniStarterFooter = { fg = c.yellow, italic = true },
MiniStarterHeader = { fg = c.blue },
MiniStarterInactive = { fg = c.comment, style = options.styles.comments },
MiniStarterItem = { fg = c.fg, bg = options.transparent and c.none or c.bg },
MiniStarterItemBullet = { fg = c.border_highlight },
MiniStarterItemPrefix = { fg = c.warning },
MiniStarterSection = { fg = c.blue1 },
MiniStarterQuery = { fg = c.info },
MiniStatuslineDevinfo = { fg = c.fg_dark, bg = c.bg_highlight },
MiniStatuslineFileinfo = { fg = c.fg_dark, bg = c.bg_highlight },
MiniStatuslineFilename = { fg = c.fg_dark, bg = c.fg_gutter },
MiniStatuslineInactive = { fg = c.blue, bg = c.bg_statusline },
MiniStatuslineModeCommand = { fg = c.black, bg = c.yellow, bold = true },
MiniStatuslineModeInsert = { fg = c.black, bg = c.green, bold = true },
MiniStatuslineModeNormal = { fg = c.black, bg = c.blue, bold = true },
MiniStatuslineModeOther = { fg = c.black, bg = c.teal, bold = true },
MiniStatuslineModeReplace = { fg = c.black, bg = c.red, bold = true },
MiniStatuslineModeVisual = { fg = c.black, bg = c.magenta, bold = true },
MiniSurround = { bg = c.orange, fg = c.black },
MiniTablineCurrent = { fg = c.fg, bg = c.fg_gutter },
MiniTablineFill = { bg = c.black },
MiniTablineHidden = { fg = c.dark5, bg = c.bg_statusline },
MiniTablineModifiedCurrent = { fg = c.warning, bg = c.fg_gutter },
MiniTablineModifiedHidden = { bg = c.bg_statusline, fg = util.darken(c.warning, 0.7) },
MiniTablineModifiedVisible = { fg = c.warning, bg = c.bg_statusline },
MiniTablineTabpagesection = { bg = c.bg_statusline, fg = c.none },
MiniTablineVisible = { fg = c.fg, bg = c.bg_statusline },
MiniTestEmphasis = { bold = true },
MiniTestFail = { fg = c.red, bold = true },
MiniTestPass = { fg = c.green, bold = true },
MiniTrailspace = { bg = c.red },
-- Noice
NoiceCompletionItemKindDefault = { fg = c.fg_dark, bg = c.none },
TreesitterContext = { bg = util.darken(c.fg_gutter, 0.8) },
Hlargs = { fg = c.yellow },
-- TreesitterContext = { bg = util.darken(c.bg_visual, 0.4) },
}
-- lsp symbol kind and completion kind highlights
local kinds = {
Array = "@punctuation.bracket",
Boolean = "@boolean",
Class = "@type",
Color = "Special",
Constant = "@constant",
Constructor = "@constructor",
Enum = "@lsp.type.enum",
EnumMember = "@lsp.type.enumMember",
Event = "Special",
Field = "@field",
File = "Normal",
Folder = "Directory",
Function = "@function",
Interface = "@lsp.type.interface",
Key = "@field",
Keyword = "@lsp.type.keyword",
Method = "@method",
Module = "@namespace",
Namespace = "@namespace",
Null = "@constant.builtin",
Number = "@number",
Object = "@constant",
Operator = "@operator",
Package = "@namespace",
Property = "@property",
Reference = "@text.reference",
Snippet = "Conceal",
String = "@string",
Struct = "@lsp.type.struct",
Unit = "@lsp.type.struct",
Text = "@text",
TypeParameter = "@lsp.type.typeParameter",
Variable = "@variable",
Value = "@string",
}
local kind_groups = { "NavicIcons%s", "Aerial%sIcon", "CmpItemKind%s", "NoiceCompletionItemKind%s" }
for kind, link in pairs(kinds) do
local base = "LspKind" .. kind
theme.highlights[base] = { link = link }
for _, plugin in pairs(kind_groups) do
theme.highlights[plugin:format(kind)] = { link = base }
end
end
local markdown_rainbow = { c.blue, c.yellow, c.green, c.teal, c.magenta, c.purple }
for i, color in ipairs(markdown_rainbow) do
theme.highlights["@text.title." .. i .. ".markdown"] = { fg = color, bold = true }
theme.highlights["Headline" .. i] = { bg = util.darken(color, 0.05) }
end
theme.highlights["Headline"] = { link = "Headline1" }
if not vim.diagnostic then
local severity_map = {
Error = "Error",
Warn = "Warning",
Info = "Information",
Hint = "Hint",
}
local types = { "Default", "VirtualText", "Underline" }
for _, type in ipairs(types) do
for snew, sold in pairs(severity_map) do
theme.highlights["LspDiagnostics" .. type .. sold] = {
link = "Diagnostic" .. (type == "Default" and "" or type) .. snew,
}
end
end
end
---@type table<string, table>
theme.defer = {}
if options.hide_inactive_statusline then
local inactive = { underline = true, bg = c.none, fg = c.bg, sp = c.border }
-- StatusLineNC
theme.highlights.StatusLineNC = inactive
-- LuaLine
for _, section in ipairs({ "a", "b", "c" }) do
theme.defer["lualine_" .. section .. "_inactive"] = inactive
end
-- mini.statusline
theme.highlights.MiniStatuslineInactive = inactive
end
options.on_highlights(theme.highlights, theme.colors)
if config.is_day() then
util.invert_colors(theme.colors)
util.invert_highlights(theme.highlights)
end
return theme
end
return M

380
lua/farout/treesitter.lua Normal file
View File

@@ -0,0 +1,380 @@
local M = {}
function M.new_style()
---@diagnostic disable-next-line: undefined-field
return vim.treesitter.highlighter.hl_map == nil
end
function M.get(group)
if group:sub(1, 1) ~= "@" or M.new_style() then
return group
end
group = group:sub(2)
local lang
while group do
if M.fallbacks[group] then
return (lang or "") .. M.fallbacks[group]
end
group, lang = group:match("(.*)%.(.*)")
end
end
-- taken from https://github.com/nvim-treesitter/nvim-treesitter/blob/master/lua/nvim-treesitter/highlight.lua
M.fallbacks = {
["annotation"] = "TSAnnotation",
["attribute"] = "TSAttribute",
["boolean"] = "TSBoolean",
["character"] = "TSCharacter",
["character.special"] = "TSCharacterSpecial",
["comment"] = "TSComment",
["conditional"] = "TSConditional",
["constant"] = "TSConstant",
["constant.builtin"] = "TSConstBuiltin",
["constant.macro"] = "TSConstMacro",
["constructor"] = "TSConstructor",
["debug"] = "TSDebug",
["define"] = "TSDefine",
["error"] = "TSError",
["exception"] = "TSException",
["field"] = "TSField",
["float"] = "TSFloat",
["function"] = "TSFunction",
["function.call"] = "TSFunctionCall",
["function.builtin"] = "TSFuncBuiltin",
["function.macro"] = "TSFuncMacro",
["include"] = "TSInclude",
["keyword"] = "TSKeyword",
["keyword.function"] = "TSKeywordFunction",
["keyword.operator"] = "TSKeywordOperator",
["keyword.return"] = "TSKeywordReturn",
["label"] = "TSLabel",
["method"] = "TSMethod",
["method.call"] = "TSMethodCall",
["namespace"] = "TSNamespace",
["none"] = "TSNone",
["number"] = "TSNumber",
["operator"] = "TSOperator",
["parameter"] = "TSParameter",
["parameter.reference"] = "TSParameterReference",
["preproc"] = "TSPreProc",
["property"] = "TSProperty",
["punctuation.delimiter"] = "TSPunctDelimiter",
["punctuation.bracket"] = "TSPunctBracket",
["punctuation.special"] = "TSPunctSpecial",
["repeat"] = "TSRepeat",
["storageclass"] = "TSStorageClass",
["string"] = "TSString",
["string.regex"] = "TSStringRegex",
["string.escape"] = "TSStringEscape",
["string.special"] = "TSStringSpecial",
["symbol"] = "TSSymbol",
["tag"] = "TSTag",
["tag.attribute"] = "TSTagAttribute",
["tag.delimiter"] = "TSTagDelimiter",
["text"] = "TSText",
["text.strong"] = "TSStrong",
["text.emphasis"] = "TSEmphasis",
["text.underline"] = "TSUnderline",
["text.strike"] = "TSStrike",
["text.title"] = "TSTitle",
["text.literal"] = "TSLiteral",
["text.uri"] = "TSURI",
["text.math"] = "TSMath",
["text.reference"] = "TSTextReference",
["text.environment"] = "TSEnvironment",
["text.environment.name"] = "TSEnvironmentName",
["text.note"] = "TSNote",
["text.warning"] = "TSWarning",
["text.danger"] = "TSDanger",
["text.todo"] = "TSTodo",
["type"] = "TSType",
["type.builtin"] = "TSTypeBuiltin",
["type.qualifier"] = "TSTypeQualifier",
["type.definition"] = "TSTypeDefinition",
["variable"] = "TSVariable",
["variable.builtin"] = "TSVariableBuiltin",
}
M.defaults = {
["@annotation"] = {
default = true,
link = "PreProc",
},
["@attribute"] = {
default = true,
link = "PreProc",
},
["@boolean"] = {
default = true,
link = "Boolean",
},
["@character"] = {
default = true,
link = "Character",
},
["@character.special"] = {
default = true,
link = "SpecialChar",
},
["@comment"] = {
default = true,
link = "Comment",
},
["@conditional"] = {
default = true,
link = "Conditional",
},
["@constant"] = {
default = true,
link = "Constant",
},
["@constant.builtin"] = {
default = true,
link = "Special",
},
["@constant.macro"] = {
default = true,
link = "Define",
},
["@constructor"] = {
default = true,
link = "Special",
},
["@debug"] = {
default = true,
link = "Debug",
},
["@define"] = {
default = true,
link = "Define",
},
["@exception"] = {
default = true,
link = "Exception",
},
["@field"] = {
default = true,
link = "Identifier",
},
["@float"] = {
default = true,
link = "Float",
},
["@function"] = {
default = true,
link = "Function",
},
["@function.builtin"] = {
default = true,
link = "Special",
},
["@function.call"] = {
default = true,
link = "@function",
},
["@function.macro"] = {
default = true,
link = "Macro",
},
["@include"] = {
default = true,
link = "Include",
},
["@keyword"] = {
default = true,
link = "Keyword",
},
["@keyword.coroutine"] = {
default = true,
link = "@keyword",
},
["@keyword.function"] = {
default = true,
link = "Keyword",
},
["@keyword.operator"] = {
default = true,
link = "@operator",
},
["@keyword.return"] = {
default = true,
link = "@keyword",
},
["@label"] = {
default = true,
link = "Label",
},
["@method"] = {
default = true,
link = "Function",
},
["@method.call"] = {
default = true,
link = "@method",
},
["@namespace"] = {
default = true,
link = "Include",
},
["@none"] = {
default = true,
},
["@number"] = {
default = true,
link = "Number",
},
["@operator"] = {
default = true,
link = "Operator",
},
["@parameter"] = {
default = true,
link = "Identifier",
},
["@preproc"] = {
default = true,
link = "PreProc",
},
["@property"] = {
default = true,
link = "Identifier",
},
["@punctuation.bracket"] = {
default = true,
link = "Delimiter",
},
["@punctuation.delimiter"] = {
default = true,
link = "Delimiter",
},
["@punctuation.special"] = {
default = true,
link = "Delimiter",
},
["@repeat"] = {
default = true,
link = "Repeat",
},
["@storageclass"] = {
default = true,
link = "StorageClass",
},
["@string"] = {
default = true,
link = "String",
},
["@string.escape"] = {
default = true,
link = "SpecialChar",
},
["@string.regex"] = {
default = true,
link = "String",
},
["@string.special"] = {
default = true,
link = "SpecialChar",
},
["@symbol"] = {
default = true,
link = "Identifier",
},
["@tag"] = {
default = true,
link = "Label",
},
["@tag.attribute"] = {
default = true,
link = "@property",
},
["@tag.delimiter"] = {
default = true,
link = "Delimiter",
},
["@text"] = {
default = true,
link = "@none",
},
["@text.danger"] = {
default = true,
link = "WarningMsg",
},
["@text.emphasis"] = {
default = true,
italic = true,
},
["@text.environment"] = {
default = true,
link = "Macro",
},
["@text.environment.name"] = {
default = true,
link = "Type",
},
["@text.literal"] = {
default = true,
link = "String",
},
["@text.math"] = {
default = true,
link = "Special",
},
["@text.note"] = {
default = true,
link = "SpecialComment",
},
["@text.reference"] = {
default = true,
link = "Constant",
},
["@text.strike"] = {
strikethrough = true,
},
["@text.strong"] = {
bold = true,
default = true,
},
["@text.title"] = {
default = true,
link = "Title",
},
["@text.underline"] = {
underline = true,
},
["@text.uri"] = {
default = true,
link = "Underlined",
},
["@text.warning"] = {
default = true,
link = "Todo",
},
["@text.todo"] = {
default = true,
link = "Todo",
},
["@type"] = {
default = true,
link = "Type",
},
["@type.builtin"] = {
default = true,
link = "Type",
},
["@type.definition"] = {
default = true,
link = "Typedef",
},
["@type.qualifier"] = {
default = true,
link = "@keyword",
},
["@variable.builtin"] = {
default = true,
link = "Special",
},
}
return M

214
lua/farout/util.lua Normal file
View File

@@ -0,0 +1,214 @@
local ts = require("farout.treesitter")
local M = {}
M.bg = "#000000"
M.fg = "#ffffff"
M.day_brightness = 0.3
---@param c string
local function hexToRgb(c)
c = string.lower(c)
return { tonumber(c:sub(2, 3), 16), tonumber(c:sub(4, 5), 16), tonumber(c:sub(6, 7), 16) }
end
---@param foreground string foreground color
---@param background string background color
---@param alpha number|string number between 0 and 1. 0 results in bg, 1 results in fg
function M.blend(foreground, background, alpha)
alpha = type(alpha) == "string" and (tonumber(alpha, 16) / 0xff) or alpha
local bg = hexToRgb(background)
local fg = hexToRgb(foreground)
local blendChannel = function(i)
local ret = (alpha * fg[i] + ((1 - alpha) * bg[i]))
return math.floor(math.min(math.max(0, ret), 255) + 0.5)
end
return string.format("#%02x%02x%02x", blendChannel(1), blendChannel(2), blendChannel(3))
end
function M.darken(hex, amount, bg)
return M.blend(hex, bg or M.bg, amount)
end
function M.lighten(hex, amount, fg)
return M.blend(hex, fg or M.fg, amount)
end
function M.invert_color(color)
local hsluv = require("farout.hsluv")
if color ~= "NONE" then
local hsl = hsluv.hex_to_hsluv(color)
hsl[3] = 100 - hsl[3]
if hsl[3] < 40 then
hsl[3] = hsl[3] + (100 - hsl[3]) * M.day_brightness
end
return hsluv.hsluv_to_hex(hsl)
end
return color
end
---@param group string
function M.highlight(group, hl)
group = ts.get(group)
if not group then
return
end
if hl.style then
if type(hl.style) == "table" then
hl = vim.tbl_extend("force", hl, hl.style)
elseif hl.style:lower() ~= "none" then
-- handle old string style definitions
for s in string.gmatch(hl.style, "([^,]+)") do
hl[s] = true
end
end
hl.style = nil
end
vim.api.nvim_set_hl(0, group, hl)
end
---@param config Config
function M.autocmds(config)
local group = vim.api.nvim_create_augroup("farout", { clear = true })
vim.api.nvim_create_autocmd("ColorSchemePre", {
group = group,
callback = function()
vim.api.nvim_del_augroup_by_id(group)
end,
})
local function set_whl()
local win = vim.api.nvim_get_current_win()
local whl = vim.split(vim.wo[win].winhighlight, ",")
vim.list_extend(whl, { "Normal:NormalSB", "SignColumn:SignColumnSB" })
whl = vim.tbl_filter(function(hl)
return hl ~= ""
end, whl)
vim.opt_local.winhighlight = table.concat(whl, ",")
end
vim.api.nvim_create_autocmd("FileType", {
group = group,
pattern = table.concat(config.sidebars, ","),
callback = set_whl,
})
if vim.tbl_contains(config.sidebars, "terminal") then
vim.api.nvim_create_autocmd("TermOpen", {
group = group,
callback = set_whl,
})
end
end
-- Simple string interpolation.
--
-- Example template: "${name} is ${value}"
--
---@param str string template string
---@param table table key value pairs to replace in the string
function M.template(str, table)
return (
str:gsub("($%b{})", function(w)
return vim.tbl_get(table, unpack(vim.split(w:sub(3, -2), ".", { plain = true }))) or w
end)
)
end
function M.syntax(syntax)
for group, colors in pairs(syntax) do
M.highlight(group, colors)
end
end
---@param colors ColorScheme
function M.terminal(colors)
-- dark
vim.g.terminal_color_0 = colors.black
vim.g.terminal_color_8 = colors.terminal_black
-- light
vim.g.terminal_color_7 = colors.fg_dark
vim.g.terminal_color_15 = colors.fg
-- colors
vim.g.terminal_color_1 = colors.red
vim.g.terminal_color_9 = colors.red
vim.g.terminal_color_2 = colors.green
vim.g.terminal_color_10 = colors.green
vim.g.terminal_color_3 = colors.yellow
vim.g.terminal_color_11 = colors.yellow
vim.g.terminal_color_4 = colors.blue
vim.g.terminal_color_12 = colors.blue
vim.g.terminal_color_5 = colors.magenta
vim.g.terminal_color_13 = colors.magenta
vim.g.terminal_color_6 = colors.cyan
vim.g.terminal_color_14 = colors.cyan
end
---@param colors ColorScheme
function M.invert_colors(colors)
if type(colors) == "string" then
---@diagnostic disable-next-line: return-type-mismatch
return M.invert_color(colors)
end
for key, value in pairs(colors) do
colors[key] = M.invert_colors(value)
end
return colors
end
---@param hls Highlights
function M.invert_highlights(hls)
for _, hl in pairs(hls) do
if hl.fg then
hl.fg = M.invert_color(hl.fg)
end
if hl.bg then
hl.bg = M.invert_color(hl.bg)
end
if hl.sp then
hl.sp = M.invert_color(hl.sp)
end
end
end
---@param theme Theme
function M.load(theme)
-- only needed to clear when not the default colorscheme
if vim.g.colors_name then
vim.cmd("hi clear")
end
vim.o.termguicolors = true
vim.g.colors_name = "farout"
if ts.new_style() then
for group, colors in pairs(ts.defaults) do
if not theme.highlights[group] then
M.highlight(group, colors)
end
end
end
M.syntax(theme.highlights)
-- vim.api.nvim_set_hl_ns(M.ns)
if theme.config.terminal_colors then
M.terminal(theme.colors)
end
M.autocmds(theme.config)
vim.defer_fn(function()
M.syntax(theme.defer)
end, 100)
end
return M