diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b69190e --- /dev/null +++ b/.gitignore @@ -0,0 +1,45 @@ +# Compiled Lua sources +luac.out + +# luarocks build files +*.src.rock +*.zip +*.tar.gz + +# Object files +*.o +*.os +*.ko +*.obj +*.elf + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo +*.def +*.exp + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +.DS_Store + +# nvim session management +.nvim diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 0000000..a07be16 --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,20 @@ +stds.nvim = { + read_globals = { "jit" }, +} + +std = "lua51+nvim" + +read_globals = { + "vim", +} + +globals = { + "vim.g", + "vim.b", + "vim.w", + "vim.o", + "vim.bo", + "vim.wo", + "vim.go", + "vim.env", +} diff --git a/.luarc.json b/.luarc.json new file mode 100644 index 0000000..8895244 --- /dev/null +++ b/.luarc.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json", + "runtime.version": "LuaJIT", + "diagnostics.globals": [ + "vim" + ], + "runtime.settings.path": [ + "?.lua", + "?/init.lua" + ], + "workspace.checkThirdParty": false, + "workspace.library": [ + "$VIMRUNTIME" + ] +} diff --git a/.yamllint.yaml b/.yamllint.yaml new file mode 100644 index 0000000..7214609 --- /dev/null +++ b/.yamllint.yaml @@ -0,0 +1,5 @@ +--- +extends: default +rules: + truthy: + check-keys: false diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..dc19184 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 mistweaver.co + +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..0753c2f --- /dev/null +++ b/README.md @@ -0,0 +1,47 @@ +
+ +![retro theme Logo](logo.svg) + +# retro-theme.nvim + +![Lua](https://img.shields.io/badge/Made%20with%20Lua-blueviolet.svg?style=for-the-badge&logo=lua) +[![GitHub release (latest by date)](https://img.shields.io/github/v/release/mistweaverco/retro-theme.nvim?style=for-the-badge)](https://github.com/mistweaverco/retro-theme.nvim/releases/latest) +[![Discord](https://img.shields.io/badge/discord-join-7289da?style=for-the-badge&logo=discord)](https://discord.gg/QyVQmfY4Rt) + +[Requirements](#requirements) • [Install](#install) • [Configuration](#configuration) + +

+ +A minimal retro theme for Neovim. + +

+ +
+ +## Requirements + +> [!WARNING] +> Requires Neovim 0.10.0+. + +## Install + +Via [lazy.nvim](https://github.com/folke/lazy.nvim): + +```lua +{ 'mistweaverco/retro-theme.nvim' }, +``` +See [configuration options](#configuration) for more information. + +## Configuration + +```lua +{ + 'mistweaverco/retro-theme.nvim', + opts = { + italic_comments = true, + disable_cache = false, + hot_reload = false, + } +}, +``` + diff --git a/colors/retro-theme.lua b/colors/retro-theme.lua new file mode 100644 index 0000000..7d0b0c2 --- /dev/null +++ b/colors/retro-theme.lua @@ -0,0 +1 @@ +require('retro-theme').load() diff --git a/logo.png b/logo.png new file mode 100644 index 0000000..cae74d6 Binary files /dev/null and b/logo.png differ diff --git a/logo.svg b/logo.svg new file mode 100644 index 0000000..7762205 --- /dev/null +++ b/logo.svg @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lua/lualine/themes/retro-theme.lua b/lua/lualine/themes/retro-theme.lua new file mode 100644 index 0000000..f10bd76 --- /dev/null +++ b/lua/lualine/themes/retro-theme.lua @@ -0,0 +1,47 @@ +local t = { + bg = "#1c1e26", + fg = "#c8d0e0", + normalFG = "#c8d0e0", + green = "#00ffbf", + red = "#ff445d", + purple = "#bd93f9", + blue = "#00dfff", + blueDark = "#336699", + grey3 = "#1b1d23", + grey5 = "#2d333e", + grey7 = "#384252", + grey20 = "#4a5a73", +} + +return { + normal = { + a = { bg = t.blue, fg = t.bg }, + b = { bg = t.grey7, fg = t.fg }, + c = { bg = t.grey3, fg = t.fg } + }, + insert = { + a = { bg = t.blueDark, fg = t.bg }, + b = { bg = t.grey7, fg = t.blueDark }, + c = { bg = t.grey3, fg = t.fg } + }, + visual = { + a = { bg = t.purple, fg = t.bg }, + b = { bg = t.grey7, fg = t.purple }, + c = { bg = t.grey3, fg = t.fg } + }, + replace = { + a = { bg = t.red, fg = t.bg }, + b = { bg = t.grey7, fg = t.red }, + c = { bg = t.grey3, fg = t.fg } + }, + command = { + a = { bg = t.green, fg = t.bg }, + b = { bg = t.grey7, fg = t.green }, + c = { bg = t.grey3, fg = t.fg } + }, + inactive = { + a = { bg = t.grey20, fg = t.grey3, }, + b = { bg = t.grey5, fg = t.grey20 }, + c = { bg = t.grey5, fg = t.grey20 } + } +} diff --git a/lua/retro-theme/cache/.gitignore b/lua/retro-theme/cache/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/lua/retro-theme/cache/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/lua/retro-theme/colorscheme.lua b/lua/retro-theme/colorscheme.lua new file mode 100644 index 0000000..db74fe0 --- /dev/null +++ b/lua/retro-theme/colorscheme.lua @@ -0,0 +1,16 @@ +local cache = require("retro-theme.lib.cache") +local colors = {} + +if cache.exists() then + colors = cache.read() +else + colors = require("retro-theme.palette.colors") + cache.write(colors) +end + +vim.cmd("highlight clear") +vim.cmd("set t_Co=256") + +for group, attrs in pairs(colors) do + vim.api.nvim_set_hl(0, group, attrs) +end diff --git a/lua/retro-theme/icons.lua b/lua/retro-theme/icons.lua new file mode 100644 index 0000000..bb2dda7 --- /dev/null +++ b/lua/retro-theme/icons.lua @@ -0,0 +1,89 @@ +return { + kind = { + Codeium = "", + Copilot = "", + TabNine = "󰏚", + + Class = "󰠱", + Color = "󰏘", + Constant = "󰏿", + Constructor = "", + Enum = "", + EnumMember = "", + Event = "", + Field = "", + File = "󰈙", + Folder = "󰉋", + Function = "󰊕", + Interface = "", + Keyword = "󰌋", + Method = "", + Module = "󰆧", + Operator = "󰆕", + Property = "󰜢", + Reference = "", + Snippet = "", + Text = "", + TypeParameter = "󰗴", + Unit = "", + Value = "󰎠", + + Array = "", + Boolean = "", + Collapsed = "", + Control = "", + Key = "󰌋", + Namespace = "󰦮", + Null = "", + Number = "󰎠", + Object = "", + Package = "", + String = "", + Struct = "󰆼", + Variable = "󰀫", + }, + git = { + LineAdded = "", + LineModified = "", + LineRemoved = "", + LineLeft = "▎", + LineMiddle = "│", + }, + ui = { + Search = "", + Selected = "❯", + Pointer = "➜", + Bug = "", + Circle = "", + Round = "", + Ellipsis = "", + Plus = "", + Robot = "󰚩", + LSP = "", + Fold = "", + }, + task = { + Canceled = " ", + Failure = " ", + Success = " ", + Running = " ", + }, + diagnostics = { + BoldError = "", + Error = "", + BoldWarning = "", + Warning = "󰗖", + BoldInformation = "", + Information = "", + BoldHint = "󰟃", + Hint = "", + }, + spinner = { "", "", "", "", "", "", "", "", "", "", "", "", "" }, + dap = { + Stopped = { " ", "DiagnosticWarn", "DapStoppedLine" }, + Breakpoint = " ", + BreakpointCondition = " ", + BreakpointRejected = { " ", "DiagnosticError" }, + LogPoint = "󰮔 ", + }, +} diff --git a/lua/retro-theme/init.lua b/lua/retro-theme/init.lua new file mode 100644 index 0000000..301f2c2 --- /dev/null +++ b/lua/retro-theme/init.lua @@ -0,0 +1,32 @@ +local M = {} + +local defaultConfig = { + italic_comments = true, + disable_cache = false, + hot_reload = false, +} + +M.config = defaultConfig + +function M.reload() + M.load() +end + +function M.load() + require('retro-theme.colorscheme') + vim.g.colors_name = 'retro-theme' +end + +function M.clear_cache() + require('retro-theme.lib.cache').clear() +end + +function M.setup(options) + M.config = vim.tbl_deep_extend("force", {}, defaultConfig, options or {}) + if M.config.hot_reload then + local path = require("retro-theme.lib.path") + require("retro-theme.lib.hotreload").watch(path.palette_colors) + end +end + +return M diff --git a/lua/retro-theme/lib/cache.lua b/lua/retro-theme/lib/cache.lua new file mode 100644 index 0000000..1ee95d3 --- /dev/null +++ b/lua/retro-theme/lib/cache.lua @@ -0,0 +1,44 @@ +local config = require("retro-theme").config +local path = require("retro-theme.lib.path") + +local M = {} + +M.clear = function() + if config.disable_cache or config.hot_reload then + return + end + if vim.fn.filereadable(path.cache) == 1 then + assert(os.remove(path.cache)) + end +end + +M.exists = function() + if config.disable_cache or config.hot_reload then + return false + end + return vim.fn.filereadable(path.cache) == 1 +end + +M.write = function(colors) + if (config.disable_cache or config.hot_reload) then + return + end + local serpent = require("retro-theme.lib.serpent") + local str = serpent.dump(colors) + local file = io.open(path.cache, "wb") + file:write(str) + file:close() +end + +M.read = function() + if (config.disable_cache or config.hot_reload) then + return nil + end + local colors = require('retro-theme.cache.default') + if not colors then + return nil + end + return colors +end + +return M diff --git a/lua/retro-theme/lib/colorparser.lua b/lua/retro-theme/lib/colorparser.lua new file mode 100644 index 0000000..b8b80f4 --- /dev/null +++ b/lua/retro-theme/lib/colorparser.lua @@ -0,0 +1,58 @@ +local config = require("retro-theme").config + +local M = {} + +local has_no_gui = vim.fn.has("gui") == 0 + +local function is_valid_key(key) + return key == "fg" or key == "bg" or key == "sp" or key == "gui" or key == "blend" or key == "italic" or key == "bold" +end + +local is_valid_color_table = function(color) + return type(color) == "table" and color.hex ~= nil +end + +local is_embedded_table = function(color) + return type(color) == "table" and color.hex == nil +end + +local merge_groups = function(group_def_table, group_def_table_value) + for key, value in pairs(group_def_table_value) do + if group_def_table[key] == nil then + group_def_table[key] = value + end + end +end + +M.parse = function(colors) + for _, group_def_table in pairs(colors) do + if type(group_def_table) ~= "table" then + vim.print("Invalid group definition: " .. vim.inspect(group_def_table)) + return + end + for group_def_table_key, group_def_table_value in pairs(group_def_table) do + if is_embedded_table(group_def_table_value) then + merge_groups(group_def_table, group_def_table_value) + end + if is_valid_key(group_def_table_key) == false then + group_def_table[group_def_table_key] = nil + end + end + end + + for _, group_def_table in pairs(colors) do + for group_def_table_key, group_def_table_value in pairs(group_def_table) do + if group_def_table_key == "gui" and has_no_gui then + group_def_table[group_def_table_key] = nil + else + if is_valid_color_table(group_def_table_value) then + group_def_table[group_def_table_key] = group_def_table_value.hex + else + group_def_table[group_def_table_key] = group_def_table_value + end + end + end + end +end + +return M diff --git a/lua/retro-theme/lib/hotreload.lua b/lua/retro-theme/lib/hotreload.lua new file mode 100644 index 0000000..7ea93b9 --- /dev/null +++ b/lua/retro-theme/lib/hotreload.lua @@ -0,0 +1,46 @@ +local serpent = require("retro-theme.lib.serpent") +local uv = vim.loop + +local function get_plugin() + local plug = require("lazy.core.config").plugins["retro-theme.nvim"] + return plug +end + +local on_event = function(err, filename, events) + if err then + vim.notify("Error in retro-theme.nvim hot_reload fs_event: " .. err) + else + if events.change == nil then + return + end + local plugin = get_plugin() + require("lazy.core.loader").reload(plugin) + vim.cmd("colorscheme retro-theme") + end +end + +local M = {} + +M.watch = function(path) + local handle = uv.new_fs_event() + + local flags = { + watch_entry = false, + stat = false, + recursive = false, + } + + local event_cb = function(err, filename, events) + if err then + vim.notify("Error in retro-theme.nvim hot_reload fs_event: " .. err) + else + vim.schedule(function() + on_event(err, filename, events) + end) + end + end + + uv.fs_event_start(handle, path, flags, event_cb) +end + +return M diff --git a/lua/retro-theme/lib/hsl.lua b/lua/retro-theme/lib/hsl.lua new file mode 100644 index 0000000..ae040d0 --- /dev/null +++ b/lua/retro-theme/lib/hsl.lua @@ -0,0 +1,312 @@ +local clamp = require('retro-theme.lib.math').clamp +local round = require('retro-theme.lib.math').round + +-- +-- HSL-like colour functions +-- +-- Vivid supports both HSL and HSLuv colourspaces, which functionally +-- behave the same except when they are converting out into RGB. +-- +-- This module provides common operations on hsl-like colours. +-- + +local function hsl_clamp(color) + local h, s, l + h = round(color.h % 360) + s = round(clamp(color.s, 0, 100)) + l = round(clamp(color.l, 0, 100)) + return { h = h, s = s, l = l } +end + +-- (color, key) -> (value) -> {h, s, l} +-- Given a color and key (h, s or l), returns a function which accepts a value which will +-- return a new color with the key set to given value +local function make_abs_fn(color, key) + return function(abs_value) + if type(abs_value) ~= "number" then error("Must provide number to HSL modifiers", 0) end + local new_values = {h = color.h, s = color.s, l = color.l} + new_values[key] = new_values[key] + abs_value + return new_values + end +end + +-- (color, key) -> (value) -> {h, s, l} +-- Given a color and key (h, s or l), returns a function which accepts a value which will +-- return a new color with the key lerped by given value +local function make_lerp_fn(color, key) + return function(percent) + if type(percent) ~= "number" then error("Must provide number to HSL modifiers", 0) end + + -- we never modifiy the caller + local new_values = {h = color.h, s = color.s, l = color.l} + -- we can safely bounds all relative adjustments to 0, 100 + -- because you can't 'relatively rotate' hue + local min, max = 0, 100 + -- we want to lerp between the current value, and the potential largest + -- change for -percent this is [0, current], +percent, [0, max - current] + local lerp_space = percent < min and new_values[key] or (max - new_values[key]) + -- perform the lerp + new_values[key] = new_values[key] + (lerp_space * (percent / 100)) + return new_values + end +end + +-- (color) -> (n) -> {h + n, s, l} +local function op_rotate(color) + return make_abs_fn(color, "h") +end + +-- (color) -> (n) -> {h, s lerp n, l} +local function op_saturate(color) + return make_lerp_fn(color, "s") +end + +-- (color) -> (n) -> {h, s + n, l} +local function op_abs_saturate(color) + return make_abs_fn(color, "s") +end + +-- (color) -> (n) -> {h, s lerp -n, l} +local function op_desaturate(color) + return function(percent) + if type(percent) ~= "number" then error("Must provide number to HSL modifiers", 0) end + return make_lerp_fn(color, "s")(-percent) + end +end + +-- (color) -> (n) -> {h, s - n, l} +local function op_abs_desaturate(color) + return function(abs_value) + if type(abs_value) ~= "number" then error("Must provide number to HSL modifiers", 0) end + return make_abs_fn(color, "s")(-abs_value) + end +end + +-- (color) -> (n) -> {h, s, l lerp n} +local function op_lighten(color) + return make_lerp_fn(color, "l") +end + +-- (color) -> (n) -> {h, s, l + n} +local function op_abs_lighten(color) + return make_abs_fn(color, "l") +end + +-- (color) -> (n) -> {h, s, l lerp -n} +local function op_darken(color) + return function(percent) + if type(percent) ~= "number" then error("Must provide number to HSL modifiers", 0) end + return make_lerp_fn(color, "l")(-percent) + end +end + +-- (color) -> (n) -> {h, s, l - n} +local function op_abs_darken(color) + return function(abs_value) + if type(abs_value) ~= "number" then error("Must provide number to HSL modifiers", 0) end + return make_abs_fn(color, "l")(-abs_value) + end +end + +-- mix ref: +-- https://stackoverflow.com/questions/35816179/calculation-algorithm-to-mix-3-hsl-colors +-- (color) -> (color, n) -> {h x h x n, s x s x n, l x l x n} +local function op_mix(color) + return function(target, strength) + assert(strength, "must provide strength to mix") + strength = clamp(strength, 0, 100) / 100 + -- strength of 0 means no mix towards target, so + -- color vector strength is 1 + local cv_str = (1 - strength) + -- target strength is the remainder, so + -- str = 0, cv_str = 1, tv_str = 0 + -- str = 100, cv_str = 0, tv_str = 1 + local tv_str = 1 - cv_str + + -- convert colors to vector + local cv = { + x = math.cos(color.h / 180 * math.pi) * color.s, + y = math.sin(color.h / 180 * math.pi) * color.s, + z = color.l + } + local tv = { + x = math.cos(target.h / 180 * math.pi) * target.s, + y = math.sin(target.h / 180 * math.pi) * target.s, + z = target.l + } + -- combine + local rv = { + x = ((cv.x * cv_str) + (tv.x * tv_str)) / 1, + y = ((cv.y * cv_str) + (tv.y * tv_str)) / 1, + z = ((cv.z * cv_str) + (tv.z * tv_str)) / 1, + } + -- back to color + local new_values = { + h = math.atan2(rv.y, rv.x) * (180 / math.pi), + s = math.sqrt(rv.x * rv.x + rv.y * rv.y), + l = rv.z + } + return new_values + end +end + +-- (color) -> (n) -> {n, s, l} +local function op_hue(color) + return function(hue) + if type(hue) ~= "number" then error("Must provide number to HSL modifiers", 0) end + return {h = hue, s = color.s, l = color.l} + end +end + +-- (color) -> (n) -> {h, n, l} +local function op_saturation(color) + return function(saturation) + if type(saturation) ~= "number" then error("Must provide number to HSL modifiers", 0) end + return {h = color.h, s = saturation, l = color.l} + end +end + +-- (color) -> (n) -> {h, s, n} +local function op_lightness(color) + return function(lightness) + if type(lightness) ~= "number" then error("Must provide number to HSL modifiers", 0) end + return {h = color.h, s = color.s, l = lightness} + end +end + +-- (color) -> (n) -> {h, s, 0 | 100} +local function op_readable(color) + return function() + if color.l >= 50 then + return {h = color.h, s = color.s, l = 0} + else + return {h = color.h, s = color.s, l = 100} + end + end +end + +local function decorate_hsl_table(color, to_hex_fn) + -- make sure our color is valid + color = hsl_clamp(color) + + local op_fns = { + rotate = op_rotate, + ro = op_rotate, + + saturate = op_saturate, + sa = op_saturate, + abs_saturate = op_abs_saturate, + abs_sa = op_abs_saturate, + + desaturate = op_desaturate, + de = op_desaturate, + abs_desaturate = op_abs_desaturate, + abs_de = op_abs_desaturate, + + lighten = op_lighten, + li = op_lighten, + abs_lighten = op_abs_lighten, + abs_li = op_abs_lighten, + + darken = op_darken, + da = op_darken, + abs_darken = op_abs_darken, + abs_da = op_abs_darken, + + mix = op_mix, + readable = op_readable, + + hue = op_hue, + saturation = op_saturation, + lightness = op_lightness, + } + + return setmetatable({}, { + -- it's hsl colors all the way down + __index = function(_, key_name) + if key_name == "h" then return color.h end + if key_name == "s" then return color.s end + if key_name == "l" then return color.l end + if key_name == "hsl" then return {h = color.h, s = color.s, l = color.l} end + if key_name == "hex" then return to_hex_fn(color) end + if key_name == "rgb" then + local hex = to_hex_fn(color) + local cnv = require("lush.vivid.rgb.convert") + return cnv.hex_to_rgb(hex) + end + + -- look up requested key in operations table and call out + -- if it exists, else try to show a nice warning. + if op_fns[key_name] then + return function(...) + local altered_color = op_fns[key_name](color)(...) + return decorate_hsl_table(altered_color, to_hex_fn) + end + else + local ops = "" + for op, _ in pairs(op_fns) do + ops = ops .. " " .. op + end + ops = ops .. " h s l hex hsl" + error("Invalid hsl operation: '" + .. key_name + .. "', valid operations:" + .. ops, 2) + end + end, + + -- possibly this won't be useless, but for now disable + __newindex = function(_, _, _) + error('Member setting disabled', 2) + end, + + __tostring = function(hsl) + return to_hex_fn(hsl) + end, + + __concat = function(lhs, rhs) + return tostring(lhs) .. tostring(rhs) + end, + + -- if we call, return the raw value + __call = function() + return color + end + }) +end + +local M = function(h_or_hex, s, l, type_fns) + assert(type_fns, "must provide type_fns") + assert(type_fns.name, "must provide name() type_fn") + assert(type_fns.from_hex, type_fns.name() .. " must provide from_hex() type_fn") + assert(type_fns.to_hex, type_fns.name() .. " must provide to_hex() type_fn") + + assert(h_or_hex, type_fns.name() .. " expects (number, number, number) or (string)") + + local h, hex_str = h_or_hex, h_or_hex + local hsl + + if type(hex_str) == "string" then + -- normalise + local hex = "[abcdef0-9][abcdef0-9]" + local pat = "^#("..hex..")("..hex..")("..hex..")$" + hex_str = string.lower(hex_str) + + -- smoke test + assert(string.find(hex_str, pat) ~= nil, + "hex_to_rgb: invalid hex_str: " .. tostring(hex_str)) + + hsl = type_fns.from_hex(hex_str) + else + if type(h) ~= "number" or + type(s) ~= "number" or + type(l) ~= "number" then + error(type_fns.name() .. " expects (number, number, number) or (string)", 2) + end + hsl = {h = h, s = s, l = l} + end + + return decorate_hsl_table(hsl, type_fns.to_hex) +end + +return M diff --git a/lua/retro-theme/lib/hsl/convert.lua b/lua/retro-theme/lib/hsl/convert.lua new file mode 100644 index 0000000..c3c5944 --- /dev/null +++ b/lua/retro-theme/lib/hsl/convert.lua @@ -0,0 +1,88 @@ +-- Support module to convert between HSL and RGB_HEX values +-- +-- RGB -> HSL and HSL -> RGB adapted from +-- https://github.com/EmmanuelOga/columns/blob/master/utils/color.lua + +local round = require('retro-theme.lib.math').round +local rgb_convert = require('retro-theme.lib.rgb.convert') + +local function hsl_to_rgb(hsl) + local r, g, b + local h, s, l = hsl.h, hsl.s, hsl.l + + if s == 0 then + r, g, b = l, l, l -- achromatic + else + local function hue2rgb(p, q, t) + if t < 0 then t = t + 1 end + if t > 1 then t = t - 1 end + if t < 1/6 then return p + (q - p) * 6 * t end + if t < 1/2 then return q end + if t < 2/3 then return p + (q - p) * (2/3 - t) * 6 end + return p + end + + local q + if l < 0.5 then q = l * (1 + s) else q = l + s - l * s end + local p = 2 * l - q + + r = hue2rgb(p, q, h + 1/3) + g = hue2rgb(p, q, h) + b = hue2rgb(p, q, h - 1/3) + end + + return { + r = round(r * 255), + g = round(g * 255), + b = round(b * 255) + } +end + +local function rgb_to_hsl(rgb) + local r, g, b = rgb.r / 255, rgb.g / 255, rgb.b / 255 + + local max, min = math.max(r, g, b), math.min(r, g, b) + local h, s, l + + l = (max + min) / 2 + + if max == min then + h, s = 0, 0 -- achromatic + else + local d = max - min + if l > 0.5 then s = d / (2 - max - min) else s = d / (max + min) end + if max == r then + h = (g - b) / d + if g < b then h = h + 6 end + elseif max == g then h = (b - r) / d + 2 + elseif max == b then h = (r - g) / d + 4 + end + h = h / 6 + end + + return {h = h, s = s, l = l} +end + +local M = { + hex_to_hsl = function(hex) + local rgb = rgb_convert.hex_to_rgb(hex) + local hsl = rgb_to_hsl(rgb) + return { + h = round(hsl.h * 360), + s = round(hsl.s * 100), + l = round(hsl.l * 100), + } + end, + hsl_to_hex = function(hsl) + -- normalise for convert fuction + hsl = { + h = hsl.h / 360, + s = hsl.s / 100, + l = hsl.l / 100, + } + local rgb = hsl_to_rgb(hsl) + return rgb_convert.rgb_to_hex(rgb) + end +} + +return M diff --git a/lua/retro-theme/lib/hsl/type.lua b/lua/retro-theme/lib/hsl/type.lua new file mode 100644 index 0000000..46856db --- /dev/null +++ b/lua/retro-theme/lib/hsl/type.lua @@ -0,0 +1,20 @@ +local hsl_convert = require('retro-theme.lib.hsl.convert') +local hsl = require('retro-theme.lib.hsl') + +-- +-- HSL Color +-- +-- expects to be called as hsl(hue, sat, light) or hsl("#RRGGBB") +-- + +local type_fns = { + from_hex = hsl_convert.hex_to_hsl, + to_hex = hsl_convert.hsl_to_hex, + name = function() return "hsl()" end +} + +local M = function(h_or_hex, s, l) + return hsl(h_or_hex, s, l, type_fns) +end + +return M diff --git a/lua/retro-theme/lib/math.lua b/lua/retro-theme/lib/math.lua new file mode 100644 index 0000000..82f53b3 --- /dev/null +++ b/lua/retro-theme/lib/math.lua @@ -0,0 +1,13 @@ +local clamp = function(val, min, max) + return math.min(max, math.max(min, val)) +end + +-- round float, implementation rounds 0.5 upwards. +local round = function(val) + return math.floor(val + 0.5) +end + +return { + round = round, + clamp = clamp +} diff --git a/lua/retro-theme/lib/path.lua b/lua/retro-theme/lib/path.lua new file mode 100644 index 0000000..ddbebe6 --- /dev/null +++ b/lua/retro-theme/lib/path.lua @@ -0,0 +1,13 @@ +local config = require("retro-theme").config + +local lua_path = vim.fs.dirname(debug.getinfo(1).source:sub(2)) .. "/.." +local compile_path = lua_path .. "/cache" +local cache_path = compile_path .. "/default.lua" +local palette_colors_path = lua_path .. "/palette/colors.lua" + +local M = {} + +M.cache = cache_path +M.palette_colors = palette_colors_path + +return M diff --git a/lua/retro-theme/lib/rgb/convert.lua b/lua/retro-theme/lib/rgb/convert.lua new file mode 100644 index 0000000..9826785 --- /dev/null +++ b/lua/retro-theme/lib/rgb/convert.lua @@ -0,0 +1,29 @@ +-- Support module to convert between RGB and HEX + +local function rgb_to_hex(rgb) + return string.format("#%02X%02X%02X", rgb.r, rgb.g, rgb.b) +end + +local function hex_to_rgb(hex_str) + -- normalise + local hex = "[abcdef0-9][abcdef0-9]" + local pat = "^#("..hex..")("..hex..")("..hex..")$" + hex_str = string.lower(hex_str) + + -- smoke test + assert(string.find(hex_str, pat) ~= nil, + "hex_to_rgb: invalid hex_str: " .. tostring(hex_str)) + + -- convert + local r,g,b = string.match(hex_str, pat) + r, g, b = tonumber(r, 16), tonumber(g, 16), tonumber(b, 16) + + return {r = r, g = g, b = b} +end + +local M = { + rgb_to_hex = rgb_to_hex, + hex_to_rgb = hex_to_rgb +} + +return M diff --git a/lua/retro-theme/lib/serpent.lua b/lua/retro-theme/lib/serpent.lua new file mode 100644 index 0000000..e3bdb1a --- /dev/null +++ b/lua/retro-theme/lib/serpent.lua @@ -0,0 +1,258 @@ +local n, v = "serpent", "0.302" -- (C) 2012-18 Paul Kulchenko; MIT License +local c, d = "Paul Kulchenko", "Lua serializer and pretty printer" +local snum = + { [tostring(1 / 0)] = "1/0 --[[math.huge]]", [tostring(-1 / 0)] = "-1/0 --[[-math.huge]]", [tostring(0 / 0)] = "0/0" } +local badtype = { thread = true, userdata = true, cdata = true } +local getmetatable = debug and debug.getmetatable or getmetatable +local pairs = function(t) + return next, t +end -- avoid using __pairs in Lua 5.2+ +local keyword, globals, G = {}, {}, (_G or _ENV) +for _, k in ipairs({ + "and", + "break", + "do", + "else", + "elseif", + "end", + "false", + "for", + "function", + "goto", + "if", + "in", + "local", + "nil", + "not", + "or", + "repeat", + "return", + "then", + "true", + "until", + "while", +}) do + keyword[k] = true +end +for k, v in pairs(G) do + globals[v] = k +end -- build func to name mapping +for _, g in ipairs({ "coroutine", "debug", "io", "math", "string", "table", "os" }) do + for k, v in pairs(type(G[g]) == "table" and G[g] or {}) do + globals[v] = g .. "." .. k + end +end + +local function s(t, opts) + local name, indent, fatal, maxnum = opts.name, opts.indent, opts.fatal, opts.maxnum + local sparse, custom, huge = opts.sparse, opts.custom, not opts.nohuge + local space, maxl = (opts.compact and "" or " "), (opts.maxlevel or math.huge) + local maxlen, metatostring = tonumber(opts.maxlength), opts.metatostring + local iname, comm = "_" .. (name or ""), opts.comment and (tonumber(opts.comment) or math.huge) + local numformat = opts.numformat or "%.17g" + local seen, sref, syms, symn = {}, { "local " .. iname .. "={}" }, {}, 0 + local function gensym(val) + return "_" + .. ( + tostring(tostring(val)):gsub("[^%w]", ""):gsub( + "(%d%w+)", + -- tostring(val) is needed because __tostring may return a non-string value + function(s) + if not syms[s] then + symn = symn + 1 + syms[s] = symn + end + return tostring(syms[s]) + end + ) + ) + end + local function safestr(s) + return type(s) == "number" and tostring(huge and snum[tostring(s)] or numformat:format(s)) + or type(s) ~= "string" and tostring(s) -- escape NEWLINE/010 and EOF/026 + or ("%q"):format(s):gsub("\010", "n"):gsub("\026", "\\026") + end + local function comment(s, l) + return comm and (l or 0) < comm and " --[[" .. select(2, pcall(tostring, s)) .. "]]" or "" + end + local function globerr(s, l) + return globals[s] and globals[s] .. comment(s, l) + or not fatal and safestr(select(2, pcall(tostring, s))) + or error("Can't serialize " .. tostring(s)) + end + local function safename(path, name) -- generates foo.bar, foo[3], or foo['b a r'] + local n = name == nil and "" or name + local plain = type(n) == "string" and n:match("^[%l%u_][%w_]*$") and not keyword[n] + local safe = plain and n or "[" .. safestr(n) .. "]" + return (path or "") .. (plain and path and "." or "") .. safe, safe + end + local alphanumsort = type(opts.sortkeys) == "function" and opts.sortkeys + or function(k, o, n) -- k=keys, o=originaltable, n=padding + local maxn, to = tonumber(n) or 12, { number = "a", string = "b" } + local function padnum(d) + return ("%0" .. tostring(maxn) .. "d"):format(tonumber(d)) + end + table.sort(k, function(a, b) + -- sort numeric keys first: k[key] is not nil for numerical keys + return (k[a] ~= nil and 0 or to[type(a)] or "z") .. (tostring(a):gsub("%d+", padnum)) + < (k[b] ~= nil and 0 or to[type(b)] or "z") .. (tostring(b):gsub("%d+", padnum)) + end) + end + local function val2str(t, name, indent, insref, path, plainindex, level) + local ttype, level, mt = type(t), (level or 0), getmetatable(t) + local spath, sname = safename(path, name) + local tag = plainindex and ((type(name) == "number") and "" or name .. space .. "=" .. space) + or (name ~= nil and sname .. space .. "=" .. space or "") + if seen[t] then -- already seen this element + sref[#sref + 1] = spath .. space .. "=" .. space .. seen[t] + return tag .. "nil" .. comment("ref", level) + end + -- protect from those cases where __tostring may fail + if type(mt) == "table" and metatostring ~= false then + local to, tr = pcall(function() + return mt.__tostring(t) + end) + local so, sr = pcall(function() + return mt.__serialize(t) + end) + if to or so then -- knows how to serialize itself + seen[t] = insref or spath + t = so and sr or tr + ttype = type(t) + end -- new value falls through to be serialized + end + if ttype == "table" then + if level >= maxl then + return tag .. "{}" .. comment("maxlvl", level) + end + seen[t] = insref or spath + if next(t) == nil then + return tag .. "{}" .. comment(t, level) + end -- table empty + if maxlen and maxlen < 0 then + return tag .. "{}" .. comment("maxlen", level) + end + local maxn, o, out = math.min(#t, maxnum or #t), {}, {} + for key = 1, maxn do + o[key] = key + end + if not maxnum or #o < maxnum then + local n = #o -- n = n + 1; o[n] is much faster than o[#o+1] on large tables + for key in pairs(t) do + if o[key] ~= key then + n = n + 1 + o[n] = key + end + end + end + if maxnum and #o > maxnum then + o[maxnum + 1] = nil + end + if opts.sortkeys and #o > maxn then + alphanumsort(o, t, opts.sortkeys) + end + local sparse = sparse and #o > maxn -- disable sparsness if only numeric keys (shorter output) + for n, key in ipairs(o) do + local value, ktype, plainindex = t[key], type(key), n <= maxn and not sparse + if + opts.valignore and opts.valignore[value] -- skip ignored values; do nothing + or opts.keyallow and not opts.keyallow[key] + or opts.keyignore and opts.keyignore[key] + or opts.valtypeignore and opts.valtypeignore[type(value)] -- skipping ignored value types + or sparse and value == nil + then -- skipping nils; do nothing + elseif ktype == "table" or ktype == "function" or badtype[ktype] then + if not seen[key] and not globals[key] then + sref[#sref + 1] = "placeholder" + local sname = safename(iname, gensym(key)) -- iname is table for local variables + sref[#sref] = val2str(key, sname, indent, sname, iname, true) + end + sref[#sref + 1] = "placeholder" + local path = seen[t] .. "[" .. tostring(seen[key] or globals[key] or gensym(key)) .. "]" + sref[#sref] = path .. space .. "=" .. space .. tostring(seen[value] or val2str(value, nil, indent, path)) + else + out[#out + 1] = val2str(value, key, indent, nil, seen[t], plainindex, level + 1) + if maxlen then + maxlen = maxlen - #out[#out] + if maxlen < 0 then + break + end + end + end + end + local prefix = string.rep(indent or "", level) + local head = indent and "{\n" .. prefix .. indent or "{" + local body = table.concat(out, "," .. (indent and "\n" .. prefix .. indent or space)) + local tail = indent and "\n" .. prefix .. "}" or "}" + return (custom and custom(tag, head, body, tail, level) or tag .. head .. body .. tail) .. comment(t, level) + elseif badtype[ttype] then + seen[t] = insref or spath + return tag .. globerr(t, level) + elseif ttype == "function" then + seen[t] = insref or spath + if opts.nocode then + return tag .. "function() --[[..skipped..]] end" .. comment(t, level) + end + local ok, res = pcall(string.dump, t) + local func = ok and "((loadstring or load)(" .. safestr(res) .. ",'@serialized'))" .. comment(t, level) + return tag .. (func or globerr(t, level)) + else + return tag .. safestr(t) + end -- handle all other types + end + local sepr = indent and "\n" or ";" .. space + local body = val2str(t, name, indent) -- this call also populates sref + local tail = #sref > 1 and table.concat(sref, sepr) .. sepr or "" + local warn = opts.comment and #sref > 1 and space .. "--[[incomplete output with shared/self-references skipped]]" + or "" + return not name and body .. warn or "do local " .. body .. sepr .. tail .. "return " .. name .. sepr .. "end" +end + +local function deserialize(data, opts) + local env = (opts and opts.safe == false) and G + or setmetatable({}, { + __index = function(t, k) + return t + end, + __call = function(t, ...) + error("cannot call functions") + end, + }) + local f, res = (loadstring or load)("return " .. data, nil, nil, env) + if not f then + f, res = (loadstring or load)(data, nil, nil, env) + end + if not f then + return f, res + end + if setfenv then + setfenv(f, env) + end + return pcall(f) +end + +local function merge(a, b) + if b then + for k, v in pairs(b) do + a[k] = v + end + end + return a +end +return { + _NAME = n, + _COPYRIGHT = c, + _DESCRIPTION = d, + _VERSION = v, + serialize = s, + load = deserialize, + dump = function(a, opts) + return s(a, merge({ name = "_", compact = true, sparse = true }, opts)) + end, + line = function(a, opts) + return s(a, merge({ sortkeys = true, comment = true }, opts)) + end, + block = function(a, opts) + return s(a, merge({ indent = " ", sortkeys = true, comment = true }, opts)) + end, +} diff --git a/lua/retro-theme/lib/shade.lua b/lua/retro-theme/lib/shade.lua new file mode 100644 index 0000000..c9878f4 --- /dev/null +++ b/lua/retro-theme/lib/shade.lua @@ -0,0 +1,9 @@ +local function shade(color, value) + if (vim.o.background == "light") then + return color.darken(value) + else + return color.lighten(value) + end +end + +return shade diff --git a/lua/retro-theme/lib/utils.lua b/lua/retro-theme/lib/utils.lua new file mode 100644 index 0000000..e69de29 diff --git a/lua/retro-theme/palette/colors.lua b/lua/retro-theme/palette/colors.lua new file mode 100644 index 0000000..1829733 --- /dev/null +++ b/lua/retro-theme/palette/colors.lua @@ -0,0 +1,930 @@ +local colorparser = require("retro-theme.lib.colorparser") +local hsl = require("retro-theme.lib.hsl.type") +local shade = require("retro-theme.lib.shade") +local config = require("retro-theme").config + +local t = { + bg = hsl("#1c1e26"), + bgFloat = hsl("#1b1d23"), + fg = hsl("#c8d0e0"), + cursor = hsl("#ffdd33"), + keyword = hsl("#ff5df4"), + comment = hsl("#7fd1b9"), + punctuation = hsl("#f4a1ff"), + method = hsl("#00ffbf"), + type = hsl("#ff6ac1"), + string = hsl("#b7ff6a"), + number = hsl("#ff57ff"), + constant = hsl("#bd93f9"), + tag = hsl("#6cdbff"), + attribute = hsl("#8cff8f"), + property = hsl("#6de0b4"), + parameter = hsl("#9df9ff"), + label = hsl("#50e3c2"), + + -- workspace + primary = hsl("#00dfff"), + selection = hsl("#336699"), + search = hsl("#00ff88"), + diffAdd = hsl("#00ff88"), + diffChange = hsl("#00bfff"), + diffDelete = hsl("#ff5555"), + added = hsl("#2ee085"), + changed = hsl("#00ccff"), + deleted = hsl("#ff4d6a"), + + diffText = hsl("#00bfff").lighten(15), + error = hsl("#ff445d"), + errorBG = hsl("#ffccd2"), + warning = hsl("#6be6a2"), + warningBG = hsl("#d4ffe0"), + info = hsl("#00dfff"), + infoBG = hsl("#d0f4ff"), + hint = hsl("#a3adff"), + mergeCurrent = hsl("#5a4472"), + mergeCurrentLabel = hsl("#8f5ea5"), + mergeIncoming = hsl("#4465b3"), + mergeIncomingLabel = hsl("#558edc"), + mergeParent = hsl("#7946b8"), + mergeParentLabel = hsl("#8b5edc"), +} + +t.shade1 = shade(t.bg, 1) +t.shade2 = shade(t.bg, 2) +t.shade3 = shade(t.bg, 3) +t.shade4 = shade(t.bg, 4) +t.shade5 = shade(t.bg, 5) +t.shade6 = shade(t.bg, 6) +t.shade7 = shade(t.bg, 7) +t.shade8 = shade(t.bg, 8) +t.shade9 = shade(t.bg, 9) +t.shade10 = shade(t.bg, 10) +t.shade20 = shade(t.bg, 20) +t.shade25 = shade(t.bg, 25) +t.shade30 = shade(t.bg, 30) +t.shade40 = shade(t.bg, 40) +t.shade50 = shade(t.bg, 50) +t.shade60 = shade(t.bg, 60) +t.shade70 = shade(t.bg, 70) +t.shade80 = shade(t.bg, 80) +t.shade90 = shade(t.bg, 90) + +t.grey3 = t.shade3.mix(t.primary, 3) +t.grey5 = t.shade5.mix(t.primary, 5) +t.grey7 = t.shade7.mix(t.primary, 7) +t.grey10 = t.shade10.mix(t.primary, 10) +t.grey20 = t.shade20.mix(t.primary, 10) +t.grey25 = t.shade25.mix(t.primary, 10) +t.grey30 = t.shade30.mix(t.primary, 10) +t.grey40 = t.shade40.mix(t.primary, 12) + +t.white = hsl("#ffffff") +t.green = hsl("#008200") + +local colors = {} + +-- normal text +colors["Normal"] = { fg = t.fg, bg = t.bg } + +-- Screen-line at the cursor, when 'cursorline' is set. +-- Low-priority if foreground (ctermfg OR guifg) is not set. +colors["CursorLine"] = { bg = t.grey7 } + +-- Screen-column at the cursor, when 'cursorcolumn' is set. +colors["CursorColumn"] = colors["CursorLine"] +colors["Whitespace"] = { fg = t.grey10 } + + -- any comment +colors["Comment"] = { fg = t.comment, italic = config.italic_comments } + +-- Line number for ":number" and ":#" commands, +-- and when 'number' or 'relativenumber' option is set. +colors["LineNr"] = { fg = t.comment } + +-- Like LineNr when 'cursorline' or 'relativenumber' is set for the cursor line. +colors["CursorLineNr"] = { fg = t.comment } +colors["Search"] = { bg = t.search } +colors["IncSearch"] = { bg = t.cursor.mix(t.bg, 10), fg = t.bg } +colors["CurSearch"] = colors["Search"] +colors["NormalFloat"] = { bg = t.bgFloat, blend = 5 } -- Normal text in floating windows. +colors["FloatBorder"] = { fg = t.punctuation } +colors["NormalSB"] = { bg = t.bgFloat } -- Normal text in floating windows. +colors["ColorColumn"] = { bg = t.grey5 } -- used for the columns set with 'colorcolumn' +colors["Conceal"] = {} -- placeholder characters substituted for concealed text (see 'conceallevel') +colors["Cursor"] = { bg = t.cursor, fg = t.bg } -- character under the cursor +colors["lCursor"] = colors["Cursor"] -- the character under the cursor when |language-mapping| is used (see 'guicursor') +colors["CursorIM"] = colors["Cursor"] -- like Cursor, but used when in IME mode |CursorIM| +colors["Directory"] = { fg = t.keyword } -- directory names (and other special names in listings) +colors["DiffAdd"] = { bg = t.diffAdd } -- diff mode: Added line |diff.txt| +colors["DiffChange"] = { bg = t.diffChange } -- diff mode: Changed line |diff.txt| +colors["DiffDelete"] = { bg = t.diffDelete } -- diff mode: Deleted line |diff.txt| +colors["DiffText"] = { bg = t.diffText } -- diff mode: Changed text within a changed line |diff.txt| +colors["EndOfBuffer"] = { fg = t.punctuation } -- filler lines (~) after the end of the buffer. By default, this is highlighted like |hl-NonText|. +colors["TermCursor"] = colors["Cursor"] -- cursor in a focused terminal +colors["TermCursorNC"] = {} -- cursor in an unfocused terminal +colors["ErrorMsg"] = { fg = t.error } -- error messages on the command line +colors["VertSplit"] = { fg = t.grey30 } -- the column separating vertically split windows +colors["Winseparator"] = colors["VertSplit"] -- Separator between window splits. Inherts from |hl-VertSplit| by default, which it will replace eventually. +colors["Folded"] = { bg = t.shade7, fg = t.tag } -- line used for closed folds +colors["SignColumn"] = colors["Normal"] -- column where |signs| are displayed +colors["FoldColumn"] = colors["SignColumn"] -- 'foldcolumn' +colors["Substitute"] = colors["IncSearch"] -- |:substitute| replacement text highlighting +colors["MatchParen"] = { bg = t.punctuation, fg = t.bg } -- The character under the cursor or just before it, if it is a paired bracket, and its match. |pi_paren.txt| +colors["ModeMsg"] = colors["Normal"] -- 'showmode' message (e.g., "-- INSERT -- ") +colors["MsgArea"] = colors["Normal"] -- Area for messages and cmdline +-- MsgSeparator = { } -- Separator for scrolled messages, `msgsep` flag of 'display' +colors["MoreMsg"] = { fg = t.primary } -- |more-prompt| +colors["NonText"] = { fg = t.shade30 } -- '@' 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|. +colors["NormalNC"] = colors["Normal"] -- normal text in non-current windows +-- Pmenu = { bg = t.bg, blend = 5 } +colors["Pmenu"] = colors["NormalFloat"] +colors["PmenuSel"] = { bg = t.selection } -- Popup menu: selected item. +colors["PmenuSbar"] = { bg = t.grey5 } -- Popup menu: scrollbar. +colors["PmenuThumb"] = { bg = t.shade20 } -- Popup menu: Thumb of the scrollbar. +colors["Question"] = { fg = t.primary } -- |hit-enter| prompt and yes/no questions +colors["QuickFixLine"] = { bg = t.primary, fg = t.white } -- Current |quickfix| item in the quickfix window. Combined with |hl-CursorLine| when the cursor is there. +colors["SpecialKey"] = { fg = t.attribute } -- Unprintable characters: text displayed differently from what it really is. But not 'listchars' whitespace. |hl-Whitespace| +-- TODO: spelling +-- SpellBad { gui = "undercurl", sp = t.error } -- Word that is not recognized by the spellchecker. |spell| Combined with the highlighting used otherwise. +-- SpellCap { } -- Word that should start with a capital. |spell| Combined with the highlighting used otherwise. +-- SpellLocal { } -- Word that is recognized by the spellchecker as one that is used in another region. |spell| Combined with the highlighting used otherwise. +-- SpellRare { } -- Word that is recognized by the spellchecker as one that is hardly ever used. |spell| Combined with the highlighting used otherwise. +-- +colors["StatusLine"] = { bg = t.grey10, gui = "" } -- status line of current window +colors["StatusLineNC"] = { bg = t.shade5 } -- status lines of not-current windows Note: if this is equal to "StatusLine" Vim will use "^^^" in the status line of the current window. +-- +colors["TabLine"] = { bg = t.shade3, fg = t.shade30 } -- tab pages line, not active tab page label +colors["TabLineFill"] = { bg = t.bg } -- tab pages line, where there are no labels +colors["TabLineSel"] = { bg = t.shade10, sp = t.primary, gui = "underline" } -- tab pages line, active tab page label +-- +colors["Title"] = { fg = t.primary } -- titles for output from ":set all", ":autocmd" etc. +colors["Visual"] = { bg = t.selection } -- Visual mode selection +colors["VisualNOS"] = { bg = t.selection } -- Visual mode selection when vim is "Not Owning the Selection". +colors["WarningMsg"] = { fg = t.warning } -- warning messages +colors["WildMenu"] = { bg = t.selection } -- current match in 'wildmenu' completion +-- +colors["Constant"] = { fg = t.constant } -- (preferred) any constant +colors["String"] = { fg = t.string } -- a string constant: "this is a string" +colors["Character"] = { fg = t.attribute } -- a character constant: 'c', '\n' +colors["Number"] = { fg = t.number } -- a number constant: 234, 0xff +colors["Boolean"] = { fg = t.keyword } -- a boolean constant: TRUE, false +-- Float { } -- a floating point constant: 2.3e10 +colors["Identifier"] = { fg = t.fg } -- (preferred) any variable name +colors["Function"] = { fg = t.method } -- function name (also: methods for classes) +colors["Method"] = { fg = t.method } -- function name (also: methods for classes) +colors["Property"] = { fg = t.property } +colors["Field"] = colors["Property"] +colors["Parameter"] = { fg = t.parameter } +colors["Statement"] = { fg = t.keyword } -- (preferred) any statement +-- Conditional { } -- if, then, else, endif, switch, etc. +-- Repeat { } -- for, do, while, etc. +-- Label { } -- case, default, etc. +colors["Punctuation"] = { fg = t.punctuation } -- "sizeof", "+", "*", etc. +colors["Operator"] = { fg = t.punctuation } -- "sizeof", "+", "*", etc. +colors["Keyword"] = colors["Statement"] -- any other keyword +-- Exception { } -- try, catch, throw +colors["PreProc"] = { fg = t.keyword } -- (preferred) generic Preprocessor +-- Include { } -- preprocessor #include +-- Define { } -- preprocessor #define +-- Macro { } -- same as Define +-- PreCondit { } -- preprocessor #if, #else, #endif, etc. +colors["Type"] = { fg = t.type } -- (preferred) int, long, char, etc. +colors["Struct"] = colors["Type"] +colors["Class"] = colors["Type"] +-- StorageClass { } -- static, register, volatile, etc. +-- Structure { } -- struct, union, enum, etc. +-- Typedef { } -- A typedef +colors["Special"] = colors["Character"] -- (preferred) any special symbol +colors["Attribute"] = colors["Character"] -- (preferred) any special symbol +-- SpecialChar = {} -- special character in a constant +colors["Tag"] = { fg = t.tag } -- you can use CTRL-] on this +-- Delimiter = {} -- character that needs attention +-- SpecialComment = { } -- special things inside a comment +-- Debug { } -- debugging statements +colors["Underlined"] = { gui = "underline" } -- (preferred) text that stands out, HTML links +colors["Bold"] = { gui = "bold" } +colors["Italic"] = { gui = "italic" } +-- ("Ignore", below, may be invisible...) +colors["Ignore"] = { fg = t.bg } -- (preferred) left blank, hidden |hl-Ignore| +colors["Error"] = colors["ErrorMsg"] -- (preferred) any erroneous construct +colors["Todo"] = { bg = t.info, fg = t.white } -- (preferred) anything that needs extra attention; mostly the keywords TODO FIXME and XXX +colors["WinBar"] = { fg = t.tag, gui = "bold" } +colors["WinBarNC"] = { fg = t.fg, gui = "" } + +-- +-- These groups are for the native LSP client and diagnostic system. Some +-- other LSP clients may use these groups, or use their own. Consult your +-- LSP client's documentation. + +-- See :h lsp-highlight, some groups may not be listed, submit a PR fix to lush-template! +-- +-- LspReferenceText { } , -- Used for highlighting "text" references +-- LspReferenceRead { } , -- Used for highlighting "read" references +-- LspReferenceWrite { } , -- Used for highlighting "write" references +-- LspCodeLens { } , -- Used to color the virtual text of the codelens. See |nvim_buf_set_extmark()|. +-- LspCodeLensSeparator { } , -- Used to color the seperator between two or more code lens. +-- LspSignatureActiveParameter = { } , -- Used to highlight the active parameter in the signature help. See |vim.lsp.handlers.signature_help()|. + +-- See :h diagnostic-highlights, some groups may not be listed, submit a PR fix to lush-template! +-- +colors["DiagnosticError"] = colors["Error"] -- Used as the base highlight group. Other Diagnostic highlights link to this by default (except Underline) +colors["DiagnosticWarn"] = colors["WarningMsg"] -- Used as the base highlight group. Other Diagnostic highlights link to this by default (except Underline) +colors["DiagnosticInfo"] = { fg = t.info } -- Used as the base highlight group. Other Diagnostic highlights link to this by default (except Underline) +colors["DiagnosticHint"] = { fg = t.hint } -- Used as the base highlight group. Other Diagnostic highlights link to this by default (except Underline) +colors["DiagnosticVirtualTextError"] = { colors["DiagnosticError"], bg = t.bg.mix(t.error, 20) } -- Used for "Error" diagnostic virtual text. +colors["DiagnosticVirtualTextWarn"] = { colors["DiagnosticWarn"], bg = t.bg.mix(t.warning, 20) } -- Used for "Warn" diagnostic virtual text. +colors["DiagnosticVirtualTextInfo"] = { colors["DiagnosticInfo"], bg = t.bg.mix(t.info, 20) } -- Used for "Info" diagnostic virtual text. +colors["DiagnosticVirtualTextHint"] = { colors["DiagnosticHint"], bg = t.bg.mix(t.hint, 20) } -- Used for "Hint" diagnostic virtual text. +colors["DiagnosticUnderlineError"] = { gui = "undercurl", sp = t.error } -- Used to underline "Error" diagnostics. +colors["DiagnosticUnderlineWarn"] = { gui = "undercurl", sp = t.warning } -- Used to underline "Warn" diagnostics. +colors["DiagnosticUnderlineInfo"] = { gui = "undercurl", sp = t.info } -- Used to underline "Info" diagnostics. +colors["DiagnosticUnderlineHint"] = { gui = "undercurl", sp = t.hint } -- Used to underline "Hint" diagnostics. +-- DiagnosticFloatingError { } , -- Used to color "Error" diagnostic messages in diagnostics float. See |vim.diagnostic.open_float()| +-- DiagnosticFloatingWarn { } , -- Used to color "Warn" diagnostic messages in diagnostics float. +-- DiagnosticFloatingInfo { } , -- Used to color "Info" diagnostic messages in diagnostics float. +-- DiagnosticFloatingHint { } , -- Used to color "Hint" diagnostic messages in diagnostics float. +-- DiagnosticSignError { } , -- Used for "Error" signs in sign column. +-- DiagnosticSignWarn { } , -- Used for "Warn" signs in sign column. +-- DiagnosticSignInfo { } , -- Used for "Info" signs in sign column. +-- DiagnosticSignHint { } , -- Used for "Hint" signs in sign column. + +-- These groups are for the neovim tree-sitter highlights. +-- As of writing, tree-sitter support is a WIP, group names may change. +-- By default, most of these groups link to an appropriate Vim group, +-- TSError -> Error for example, so you do not have to define these unless +-- you explicitly want to support Treesitter's improved syntax awareness. + +-- +-- TSError { } -- For syntax/parser errors. +colors["@constructor"] = { fg = t.type } +colors["@punctuation"] = { fg = t.punctuation } +colors["@punctuation.bracket"] = { fg = t.punctuation } +colors["@punctuation.delimiter"] = { fg = t.punctuation } +colors["@punctuation.special"] = { fg = t.punctuation } +colors["@symbol"] = { fg = t.constant } +colors["@constant"] = { fg = t.constant } +colors["@constant.builtin"] = { fg = t.keyword } +colors["@string.escape"] = colors["Character"] +colors["@method"] = { fg = t.method } +colors["@function"] = { fg = t.method } +colors["@function.call"] = { fg = t.method } +colors["@function.builtin"] = { fg = t.method } +colors["@parameter"] = { fg = t.parameter } +colors["@field"] = colors["Property"] +colors["@property"] = colors["Property"] +colors["@label"] = { fg = t.label } -- For labels: `label:` in C and `:label:` in Lua. +colors["@type"] = colors["Type"] +colors["@type.builtin"] = { fg = t.keyword } +colors["@type.qualifier"] = colors["Statement"] +colors["@keyword"] = colors["Statement"] +colors["@keyword.modifier"] = colors["Statement"] -- Same as @type.qualifier +colors["@namespace"] = colors["Type"] +colors["@annotation"] = colors["@label"] -- For labels: `label:` in C and `:label:` in Lua. +colors["@text"] = colors["Identifier"] +colors["@text.strong"] = colors["Bold"] +colors["@text.italic"] = colors["Italic"] +colors["@text.underline"] = colors["Underlined"] +colors["@text.title"] = { fg = t.keyword } +colors["@text.literal"] = colors["Property"] +colors["@text.uri"] = { fg = t.tag, sp = t.tag, gui = "underline" } -- Any URI like a link or email. +colors["@variable"] = colors["Identifier"] -- Variable names that are defined by the languages like `this` or `self`. +colors["@variable.builtin"] = colors["Statement"] -- Variable names that are defined by the languages like `this` or `self`. +colors["@tag"] = colors["Tag"] +colors["@attribute"] = { fg = t.label } -- Variable names that are defined by the languages, like `this` or `self`. +colors["@tag.attribute"] = { fg = t.attribute } -- Variable names that are defined by the languages, like `this` or `self`. +colors["@error"] = colors["Error"] -- Variable names that are defined by the languages like `this` or `self`. +colors["@warning"] = colors["WarningMsg"] +colors["@info"] = { fg = t.info } +-- +-- ["@markup.link.label"] = { } -- SpecialChar +-- ["@character.special"] = { } -- SpecialChar +-- ["@function.macro"] = { } -- Macro +-- ["@keyword.debug"] = { } -- Debug + +-- Language Overrides +-- JSON +colors["@label.json"] = { fg = t.property } -- For labels: `label:` in C and `:label:` in Lua. +colors["@label.jsonc"] = { fg = t.property } -- For labels: `label:` in C and `:label:` in Lua. +-- help files +colors["@label.help"] = colors["@text.uri"] +-- html +colors["@text.uri.html"] = { gui = "underline" } + + +-- Treesitter highlight groups update +-- Treesitter standard capture groups +colors["@variable.parameter"] = colors["@parameter"] +colors["@variable.member"] = colors["@field"] +colors["@module"] = colors["@namespace"] +colors["@string.special.symbol"] = colors["@symbol"] +colors["@markup.strong"] = colors["@text.strong"] +colors["@markup.underline"] = colors["@text.underline"] +colors["@markup.heading"] = colors["@text.title"] +colors["@markup.link.url"] = colors["@text.uri"] +colors["@markup.raw"] = colors["@text.literal"] +colors["@markup.list"] = colors["@punctuation.special"] + +-- Helix capture groups +colors["@function.method"] = colors["@method"] +colors["@string.special.url"] = colors["@text.uri"] + + +-- semantic highlighting +colors["@lsp.type.namespace"] = colors["@namespace"] +colors["@lsp.type.type"] = colors["@type"] +colors["@lsp.type.class"] = colors["@type"] +colors["@lsp.type.enum"] = colors["@type"] +colors["@lsp.type.interface"] = colors["@type"] +colors["@lsp.type.struct"] = colors["@type"] +colors["@lsp.type.parameter"] = colors["@parameter"] +colors["@lsp.type.variable"] = colors["@variable"] +colors["@lsp.type.property"] = colors["@property"] +colors["@lsp.type.enumMember"] = colors["@constant"] +colors["@lsp.type.function"] = colors["@function"] +colors["@lsp.type.method"] = colors["@method"] +colors["@lsp.type.macro"] = colors["@label"] +colors["@lsp.type.decorator"] = colors["@label"] +colors["@lsp.mod.readonly"] = colors["@constant"] +colors["@lsp.typemod.function.declaration"] = colors["@function"] +colors["@lsp.typemod.function.readonly"] = colors["@function"] + +-- gui vim +-- VimR +colors["VimrDefaultCursor"] = { fg = t.cursor, bg = t.bg } +colors["VimrInsertCursor"] = { fg = t.cursor, bg = t.bg } +-- gitsigns +colors["GitSignsAdd"] = { fg = t.added } +colors["GitSignsChange"] = { fg = t.changed } +colors["GitSignsDelete"] = { fg = t.deleted } +-- TODO: improve bufferline +colors["BufferlineFill"] = colors["NormalFloat"] +-- BufferlineBackground = { bg = t.bg } +-- BufferlineDevIconLua = { bg = t.bg, fg = t.keyword } +-- BufferlineDevIconLuaSelected = { bg = t.bg, fg = t.keyword } +-- BufferlineBufferVisible = { bg = t.bg } +-- BufferlineBufferSelected = { bg = t.bg } + +-- BufferlineIndicatorVisible = { bg = t.type } -- shows which buffers are visible in windows currently + +-- BufferLineSeparatorSelected = { fg = t.type, sp = t.primary, gui = "underline" } +-- BufferLineWarningDiagnosticSelected = { fg = t.warning, sp = t.primary, gui = "underline" } +-- BufferLineErrorDiagnosticSelected = { fg = t.error, sp = t.primary, gui = "underline" } +-- BufferLineInfoDiagnosticSelected = { fg = t.info, sp = t.primary, gui = "underline" } +-- BufferLineHintDiagnosticSelected = { fg = t.hint, sp = t.primary, gui = "underline" } +-- BufferLineTabSeparatorSelected = { sp = t.primary, gui = "underline" } +-- BufferLineCloseButtonSelected = { sp = t.primary, gui = "underline" } +-- BufferLineDiagnosticSelected = { sp = t.primary, gui = "underline" } +-- BufferLineDevIconLuaSelected = { sp = t.primary, gui = "underline" } +-- BufferLineIndicatorSelected = { sp = t.primary, gui = "underline" } +-- BufferLineDuplicateSelected = { sp = t.primary, gui = "underline" } +-- BufferLineModifiedSelected = { sp = t.primary, gui = "underline" } +-- BufferLineNumbersSelected = { sp = t.primary, gui = "underline" } +-- BufferLineBufferSelected = { sp = t.primary, gui = "underline" } +-- BufferLinePickSelected = { sp = t.primary, gui = "underline" } +-- BufferLineTabSelected = { sp = t.primary, gui = "underline" } +-- BufferLineWarningSelected = { fg = t.warning, sp = t.primary, gui = "underline" } +-- BufferLineErrorSelected = { fg = t.error, sp = t.primary, gui = "underline" } +-- BufferLineInfoSelected = { fg = t.info, sp = t.primary, gui = "underline" } +-- BufferLineHintSelected = { fg = t.hint, sp = t.primary, gui = "underline" } +-- + +-- BarBar +colors["BufferCurrent"] = colors["Normal"] +colors["BufferCurrentIndex"] = colors["BufferCurrent"] +colors["BufferCurrentIcon"] = colors["BufferCurrentIndex"] +colors["BufferCurrentMod"] = colors["BufferCurrent"] +colors["BufferCurrentSign"] = { fg = t.keyword, bg = colors["BufferCurrent"].bg } +colors["BufferCurrentTarget"] = { colors["BufferCurrent"], fg = t.type } +colors["BufferCurrentWARN"] = { fg = colors["DiagnosticWarn"].fg, bg = colors["BufferCurrent"].bg } +colors["BufferCurrentINFO"] = { fg = colors["DiagnosticInfo"].fg, bg = colors["BufferCurrent"].bg } +colors["BufferCurrentERROR"] = { fg = colors["DiagnosticError"].fg, bg = colors["BufferCurrent"].bg } +colors["BufferCurrentHINT"] = { fg = colors["DiagnosticHint"].fg, bg = colors["BufferCurrent"].bg } +-- +colors["BufferInactive"] = { fg = t.shade40, bg = t.bgFloat } +colors["BufferInactiveIcon"] = colors["BufferInactive"] +colors["BufferInactiveIndex"] = colors["BufferInactive"] +colors["BufferInactiveMod"] = colors["BufferInactive"] +colors["BufferInactiveSign"] = colors["BufferInactive"] +colors["BufferInactiveTarget"] = { colors["BufferInactive"], fg = t.type } +colors["BufferInactiveWARN"] = { colors["BufferCurrentWARN"], bg = colors["BufferInactive"].bg } +colors["BufferInactiveINFO"] = { colors["BufferCurrentINFO"], bg = colors["BufferInactive"].bg } +colors["BufferInactiveERROR"] = { colors["BufferCurrentERROR"], bg = colors["BufferInactive"].bg } +colors["BufferInactiveHINT"] = { colors["BufferCurrentHINT"], bg = colors["BufferInactive"].bg } +-- +colors["BufferVisible"] = { colors["BufferCurrent"], bg = t.bgFloat } +colors["BufferVisibleIndex"] = colors["BufferVisible"] +colors["BufferVisibleIcon"] = colors["BufferVisibleIndex"] +colors["BufferVisibleMod"] = colors["BufferVisible"] +colors["BufferVisibleSign"] = colors["BufferVisible"] +colors["BufferVisibleTarget"] = { colors["BufferVisible"], fg = t.type } +colors["BufferVisibleWARN"] = colors["BufferInactiveWARN"] +colors["BufferVisibleINFO"] = colors["BufferInactiveINFO"] +colors["BufferVisibleERROR"] = colors["BufferInactiveERROR"] +colors["BufferVisibleHINT"] = colors["BufferInactiveHINT"] +-- +colors["BufferAlternate"] = colors["BufferInactive"] +colors["BufferAlternateIndex"] = colors["BufferAlternate"] +colors["BufferAlternateIcon"] = colors["BufferAlternateIndex"] +colors["BufferAlternateMod"] = colors["BufferInactiveMod"] +colors["BufferAlternateSign"] = { colors["BufferInactiveSign"], fg = t.constant } +colors["BufferAlternateTarget"] = { colors["BufferAlternate"], fg = t.type } +colors["BufferAlternateWARN"] = colors["BufferInactiveWARN"] +colors["BufferAlternateINFO"] = colors["BufferInactiveINFO"] +colors["BufferAlternateERROR"] = colors["BufferInactiveERROR"] +colors["BufferAlternateHINT"] = colors["BufferInactiveHINT"] +-- +colors["BufferTabpages"] = { colors["BufferInactive"], fg = t.fg } +colors["BufferTabpageFill"] = { colors["BufferTabpages"], fg = t.bg } +colors["BufferOffset"] = colors["BufferTabpageFill"] +-- + +-- Telescope +-- Sets the highlight for selected items within the picker. +-- TelescopeSelection {} +-- TelescopeSelectionCaret {} +colors["TelescopeMultiSelection"] = { fg = t.attribute } +colors["TelescopeMultiIcon"] = { fg = t.primary } +-- +-- -- "Normal" in the floating windows created by telescope. +-- TelescopeNormal = { fg = t.fg, bg = t.bg } +-- TelescopeNormal = { fg = t.fg, bg = t.bg, blend = 5 } +colors["TelescopeNormal"] = colors["NormalFloat"] +-- TelescopePreviewNormal {} +-- TelescopePromptNormal = { fg = t.fg, bg = t.bg } +-- TelescopeResultsNormal {} + +-- Border highlight groups. +-- Use TelescopeBorder to override the default. +-- Otherwise set them specifically + +colors["TelescopeBorder"] = { colors["NormalFloat"], fg = t.punctuation } +-- TelescopePromptBorder {} +-- TelescopeResultsBorder {} +-- TelescopePreviewBorder {} + +-- -- Title highlight groups. +-- -- Use TelescopeTitle to override the default. +-- -- Otherwise set them specifically +-- TelescopeTitle {fg = t.constant} +-- TelescopePromptTitle {} +-- TelescopeResultsTitle {} +-- TelescopePreviewTitle {} + +-- TelescopePromptCounter {} + +-- -- Used for highlighting characters that you match. +colors["TelescopeMatching"] = { fg = t.keyword } +-- -- Used for the prompt prefix +colors["TelescopePromptPrefix"] = { fg = t.punctuation } +-- -- Used for highlighting the matched line inside Previewer. Works only for (vim_buffer_ previewer) +-- TelescopePreviewLine {} +-- TelescopePreviewMatch {} + +-- TelescopePreviewPipe {} +-- TelescopePreviewCharDev {} +-- TelescopePreviewDirectory {} +-- TelescopePreviewBlock {} +colors["TelescopePreviewLink"] = { fg = t.label } +colors["TelescopePreviewSocket"] = { fg = t.property } +-- TelescopePreviewRead {} +colors["TelescopePreviewWrite"] = { fg = t.type } +colors["TelescopePreviewExecute"] = { fg = t.method } +-- TelescopePreviewHyphen {} +-- TelescopePreviewSticky {} +colors["TelescopePreviewSize"] = { fg = t.number } +colors["TelescopePreviewUser"] = { fg = t.property } +colors["TelescopePreviewGroup"] = { fg = t.property } +colors["TelescopePreviewDate"] = { fg = t.string } +-- TelescopePreviewMessage {} +-- TelescopePreviewMessageFillchar {} + +-- -- Used for Picker specific Results highlighting +colors["TelescopeResultsClass"] = colors["Class"] +-- TelescopeResultsConstant {} +colors["TelescopeResultsField"] = colors["Field"] +-- TelescopeResultsFunction {} +-- TelescopeResultsMethod {} +-- TelescopeResultsOperator {} +-- TelescopeResultsStruct {} +colors["TelescopeResultsVariable"] = colors["Identifier"] +-- TelescopeResultsLineNr {} +-- TelescopeResultsIdentifier {} +-- TelescopeResultsNumber {} +-- TelescopeResultsComment {} +colors["TelescopeResultsSpecialComment"] = colors["Comment"] +-- -- Used for git status Results highlighting +-- TelescopeResultsDiffChange {} +-- TelescopeResultsDiffAdd {} +-- TelescopeResultsDiffDelete {} +-- TelescopeResultsDiffUntracked {} +-- + +-- lspsaga +colors["TitleIcon"] = colors["Function"] +colors["SagaNormal"] = colors["NormalFloat"] +colors["SagaExpand"] = colors["Normal"] +colors["SagaCollapse"] = colors["SagaExpand"] +colors["SagaCount"] = colors["Number"] +colors["SagaBeacon"] = { bg = t.cursor, blend = 70 } +colors["CodeActionNumber"] = colors["Statement"] +colors["FinderSelection"] = colors["Visual"] +-- FinderFileName = colors["Comment"] +colors["FinderCount"] = colors["Number"] +colors["FinderIcon"] = colors["Punctuation"] +colors["FinderType"] = colors["Title"] +colors["SagaLightBulb"] = colors["Attribute"] +-- SagaShadow = colors["FloatShadow"] +colors["OutlineIndent"] = colors["Whitespace"] +-- +-- lspsaga winbar +-- SagaWinbarModule = {} +-- SagaWinbarInterface = {} +-- SagaWinbarConstructor = {} +-- SagaWinbarStruct = {} +-- SagaWinbarObject = {} +-- SagaWinbarUnit = {} +colors["SagaWinbarFile"] = { fg = t.fg } +colors["SagaWinbarSnippet"] = { fg = t.label } +-- SagaWinbarText = {} +-- SagaWinbarTypeAlias = {} +-- SagaWinbarEvent = {} +-- SagaWinbarParameter = {} +colors["SagaWinbarKey"] = colors["Property"] +colors["SagaWinbarValue"] = colors["String"] +-- SagaWinbarMacro = {} +-- SagaWinbarNumber = {} +-- SagaWinbarConstant = {} +-- SagaWinbarFunction = {} +colors["SagaWinbarEnum"] = colors["Type"] +-- SagaWinbarField = {} +-- SagaWinbarProperty = {} +-- SagaWinbarMethod = {} +colors["SagaWinbarClass"] = colors["Type"] +colors["SagaWinbarFolder"] = colors["Tag"] +-- SagaWinbarPackage = {} +-- SagaWinbarStaticMethod = {} +-- SagaWinbarTypeParameter = {} +colors["SagaWinbarEnumMember"] = colors["Property"] +-- SagaWinbarOperator = {} +colors["SagaWinbarNull"] = colors["Statement"] +-- SagaWinbarNamespace = {} +-- SagaWinbarArray = {} +-- SagaWinbarBoolean = {} +-- SagaWinbarString = {} +-- SagaWinbarVariable = {} +colors["SagaWinbarFilename"] = colors["SagaWinbarFile"] +colors["SagaWinbarFolderName"] = {} +colors["SagaWinbarFileIcon"] = {} +colors["SagaWinbarSep"] = { fg = t.punctuation } +-- + +-- Trouble +colors["TroubleCount"] = { fg = t.number } +colors["TroubleNormal"] = { bg = t.bgFloat } +-- TroubleTextInformation = {} +-- TroubleSignWarning = {} +colors["TroubleLocation"] = { fg = t.attribute } +-- TroubleWarning = {} +-- TroublePreview = {} +-- TroubleTextError = {} +-- TroubleSignInformation = {} +-- TroubleIndent = {} +-- TroubleSource = {} +-- TroubleSignHint = {} +-- TroubleSignOther = {} +-- TroubleFoldIcon = {} +-- TroubleTextWarning = {} +-- TroubleCode = {} +-- TroubleInformation = {} +-- TroubleSignError = { fg = t.number} +-- TroubleFile = {} +-- TroubleHint = {} +-- TroubleTextHint = {} +colors["TroubleText"] = {} +-- + +-- Cmp +colors["CmpDocumentation"] = { fg = t.fg, bg = t.bgFloat } +colors["CmpDocumentationBorder"] = { fg = t.punctuation, bg = t.bgFloat } +colors["CmpItemAbbr"] = { fg = t.fg } +colors["CmpItemAbbrDeprecated"] = { fg = t.fg, gui = "strikethrough" } +colors["CmpItemAbbrMatch"] = { fg = t.primary } +colors["CmpItemAbbrMatchFuzzy"] = { fg = t.primary } +colors["CmpItemMenu"] = { fg = t.attribute } +colors["CmpItemKindText"] = { fg = t.comment } +colors["CmpItemKindDefault"] = { fg = t.fb } +colors["CmpItemKindKeyword"] = { fg = t.keyword } +colors["CmpItemKindVariable"] = { fg = t.fg } +colors["CmpItemKindConstant"] = { fg = t.constant } +colors["CmpItemKindReference"] = { fg = t.fg } +colors["CmpItemKindValue"] = { fg = t.fg } +colors["CmpItemKindFunction"] = { fg = t.method } +colors["CmpItemKindMethod"] = { fg = t.method } +colors["CmpItemKindConstructor"] = { fg = t.type } +colors["CmpItemKindClass"] = { fg = t.type } +colors["CmpItemKindInterface"] = { fg = t.type } +colors["CmpItemKindStruct"] = { fg = t.type } +colors["CmpItemKindEvent"] = { fg = t.label } +colors["CmpItemKindEnum"] = { fg = t.type } +colors["CmpItemKindUnit"] = { fg = t.number } +colors["CmpItemKindModule"] = { fg = t.keyword } +colors["CmpItemKindProperty"] = { fg = t.property } +colors["CmpItemKindField"] = { fg = t.property } +colors["CmpItemKindTypeParameter"] = { fg = t.type } +colors["CmpItemKindEnumMember"] = { fg = t.type } +colors["CmpItemKindOperator"] = { fg = t.punctuation } +colors["CmpItemKindSnippet"] = { fg = t.label } +-- + +-- nvim illuminate +colors["IlluminatedWordText"] = { bg = t.grey7 } +colors["IlluminatedWordRead"] = { bg = t.grey7 } +colors["IlluminatedWordWrite"] = { bg = t.grey7 } +-- + +-- cursor word +colors["CursorWord"] = { bg = t.grey7 } +colors["CursorWord0"] = { bg = t.grey7 } +colors["CursorWord1"] = { bg = t.grey7 } +-- + +-- mason +colors["MasonNormal"] = colors["NormalFloat"] +colors["MasonHeader"] = { bg = t.primary, fg = t.bg } +colors["MasonHeaderSecondary"] = { bg = t.constant, fg = t.bg } +colors["MasonHighlight"] = { fg = t.primary } +colors["MasonHighlightBlock"] = { bg = t.primary, fg = t.bg } +colors["MasonHighlightBlockBold"] = { bg = t.primary, fg = t.bg, gui = "bold" } +colors["MasonHighlightSecondary"] = { fg = t.constant } +colors["MasonHighlightBlockSecondary"] = { bg = t.constant, fg = t.bg } +colors["MasonHighlightBlockBoldSecondary"] = { bg = t.constant, fg = t.bg, gui = "bold" } +colors["MasonLink"] = colors["@text.uri"] +colors["MasonMuted"] = { fg = t.shade50 } +colors["MasonMutedBlock"] = { bg = t.shade40, fg = t.bg } +colors["MasonMutedBlockBold"] = { bg = t.shade40, fg = t.bg, gui = "bold" } +colors["MasonError"] = colors["Error"] +colors["MasonHeading"] = { gui = "bold,underline", fg = t.fg } +-- + +-- which-key +colors["WhichKey"] = colors["Character"] +colors["WhichKeyGroup"] = colors["Tag"] +colors["WhichKeySeparator"] = colors["Operator"] +colors["WhichKeyDesc"] = colors["@text.title"] +-- WhichKeyFloat = {} +-- WhichKeyBorder = {} +-- WhichKeyValue = colors["Character"] + + +-- Diffview +colors["DiffviewStatusAdded"] = { fg = t.method } +colors["DiffviewStatusModified"] = { fg = t.keyword } +colors["DiffviewStatusRenamed"] = { fg = t.keyword } +colors["DiffviewStatusCopied"] = { fg = t.keyword } +colors["DiffviewStatusTypeChanged"] = { fg = t.keyword } +colors["DiffviewStatusUnmerged"] = { fg = t.number } +colors["DiffviewStatusUnknown"] = { fg = t.property } +colors["DiffviewStatusDeleted"] = { fg = t.type } +-- DiffviewStatusBroken = {} +colors["DiffviewStatusIgnored"] = { fg = t.comment } +colors["DiffviewFilePanelInsertions"] = { fg = t.added } +colors["DiffviewFilePanelDeletions"] = { fg = t.deleted } +colors["DiffviewFilePanelRootPath"] = { fg = t.tag } +colors["DiffviewFilePanelTitle"] = { fg = t.constant } +colors["DiffviewFilePanelCounter"] = { fg = t.attribute } +-- DiffviewFilePanelFileName = {} +colors["DiffviewFilePanelPath"] = { fg = t.comment } +colors["DiffviewFilePanelConflicts"] = { fg = t.number } +colors["DiffviewFolderName"] = colors["Directory"] +-- DiffviewFolderSign = {} +-- DiffviewReference = {} +colors["DiffviewPrimary"] = { fg = t.keyword } +colors["DiffviewSecondary"] = { fg = t.tag } +-- + +-- vim-fugitive +colors["diffAdded"] = { fg = t.method } +colors["diffRemoved"] = { fg = t.type } +-- + +-- nvim tree +colors["NvimTreeNormal"] = { bg = t.bgFloat } +colors["NvimTreeNormalNC"] = { bg = t.bgFloat } +colors["NvimTreeWindowPicker"] = { fg = t.fg, bg = t.selection, gui = "bold" } +colors["NvimTreeIndentMarker"] = { fg = t.punctuation } +colors["NvimTreeRootFolder"] = { fg = t.tag } +colors["NvimTreeFolderIcon"] = { fg = t.keyword } +colors["NvimTreeFolderName"] = { fg = t.tag } +colors["NvimTreeOpenedFolderName"] = { fg = t.keyword } +colors["NvimTreeSpecialFile"] = { fg = t.constant } +colors["NvimTreeExecFile"] = { fg = t.method } +colors["NvimTreeGitStaged"] = { fg = t.method } +colors["NvimTreeGitDirty"] = { fg = t.type } +colors["NvimTreeGitMerge"] = { fg = t.number } +colors["NvimTreeGitDeleted"] = { fg = t.deleted } +colors["NvimTreeGitNew"] = { fg = t.method } +-- + +-- git-conflict +colors["GitConflictCurrent"] = { bg = t.mergeCurrent, blend = 5 } +colors["GitConflictIncoming"] = { bg = t.mergeIncoming, blend = 5 } +colors["GitConflictAncestor"] = { bg = t.mergeParent, blend = 5 } +colors["GitConflictCurrentLabel"] = { bg = t.mergeCurrentLabel, blend = 5 } +colors["GitConflictIncomingLabel"] = { bg = t.mergeIncomingLabel, blend = 5 } +colors["GitConflictAncestorLabel"] = { bg = t.mergeParentLabel, blend = 5 } +-- + +-- notify +colors["NotifyBackground"] = colors["NormalFloat"] +colors["NotifyERRORBorder"] = { colors["Normal"], fg = t.error } +colors["NotifyWARNBorder"] = { colors["Normal"], fg = t.warning } +colors["NotifyINFOBorder"] = { colors["Normal"], fg = t.info } +colors["NotifyDEBUGBorder"] = { colors["Normal"], fg = t.punctuation } +colors["NotifyTRACEBorder"] = { colors["Normal"], fg = t.property } +colors["NotifyERRORIcon"] = colors["NotifyERRORBorder"] +colors["NotifyWARNIcon"] = colors["NotifyWARNBorder"] +colors["NotifyINFOIcon"] = colors["NotifyINFOBorder"] +colors["NotifyDEBUGIcon"] = colors["NotifyDEBUGBorder"] +colors["NotifyTRACEIcon"] = colors["NotifyTRACEBorder"] +colors["NotifyERRORTitle"] = colors["NotifyERRORBorder"] +colors["NotifyWARNTitle"] = colors["NotifyWARNBorder"] +colors["NotifyINFOTitle"] = colors["NotifyINFOBorder"] +colors["NotifyDEBUGTitle"] = colors["NotifyDEBUGBorder"] +colors["NotifyTRACETitle"] = colors["NotifyTRACEBorder"] +-- + +-- -- Visual Multi. +-- VM_Extend = { bg = colors.selection_inactive } +-- VM_Cursor = { bg = colors.selection_inactive, sp = colors.fg, underline = true } +-- VM_Insert = { sp = colors.fg, underline = true } +-- VM_Mono = { fg = colors.bg, bg = colors.comment } +-- + +-- hlargs (semantic parameter highlighting) +colors["Hlargs"] = colors["@parameter"] +-- + +-- virt-column +colors["VirtColumn"] = colors["Whitespace"] +-- + +-- indent blankline +-- IblScope = {} +-- RainbowDelimiterRed = {} +-- RainbowDelimiterYellow = {} +-- RainbowDelimiterBlue = {} +-- RainbowDelimiterOrange = {} +-- RainbowDelimiterGreen = {} +-- RainbowDelimiterViolet = {} +-- RainbowDelimiterCyan = {} + +-- Neotest +colors["NeotestPassed"] = { fg = t.added } +colors["NeotestRunning"] = colors["DiagnosticInfo"] +colors["NeotestSkipped"] = colors["DiagnosticWarn"] +colors["NeotestFailed"] = colors["DiagnosticError"] +colors["NeotestAdapterName"] = {} +colors["NeotestBorder"] = {} +colors["NeotestDir"] = colors["Directory"] +colors["NeotestExpandMarker"] = {} +colors["NeotestFile"] = { fg = t.tag } +colors["NeotestFocused"] = {} +colors["NeotestIndent"] = {} +colors["NeotestMarked"] = {} +colors["NeotestNamespace"] = {} +colors["NeotestWinSelect"] = {} +colors["NeotestTarget"] = {} +colors["NeotestTest"] = {} +colors["NeotestUnknown"] = {} +colors["NeotestWatching"] = { fg = t.constant } + +-- basic highlighting without treesitter +-- + +-- javascript +colors["javaScript"] = colors["Identifier"] +colors["javaScriptIdentifier"] = colors["Statement"] +colors["javaScriptFunction"] = colors["Statement"] +colors["javaScriptParens"] = colors["Punctuation"] +colors["javaScriptBraces"] = colors["Punctuation"] +colors["javaScriptNumber"] = colors["Number"] +-- + +-- typescript +colors["typeScriptImport"] = colors["Statement"] +colors["typeScriptExport"] = colors["Statement"] +colors["typeScriptIdentifier"] = colors["Statement"] +colors["typescriptVariable"] = colors["Statement"] +colors["typeScriptFunction"] = colors["Statement"] +colors["typescriptPredefinedType"] = colors["@type.builtin"] +colors["typescriptClassStatic"] = colors["Statement"] +colors["typescriptNodeGlobal"] = colors["Statement"] +colors["typescriptExceptions"] = colors["Statement"] +colors["typeScriptParens"] = colors["Punctuation"] +colors["typeScriptBraces"] = colors["Punctuation"] +colors["typescriptTypeBrackets"] = colors["Punctuation"] +colors["typescriptInterfaceTypeParameter"] = colors["Punctuation"] +colors["typescriptConditionalType"] = colors["Punctuation"] +colors["typeScriptNumber"] = colors["Number"] +colors["typeScriptAliasDeclaration"] = colors["Type"] +colors["typeScriptTypeReference"] = colors["Type"] +colors["typeScriptTypeParameter"] = colors["Type"] +colors["typescriptClassName"] = colors["Type"] +colors["typescriptClassHeritage"] = colors["Type"] +colors["typescriptProp"] = colors["Property"] +colors["typescriptOperator"] = colors["Operator"] +colors["typescriptBinaryOp"] = colors["Operator"] +colors["typescriptDocNotation"] = { fg = t.shade50 } +colors["typescriptDocTags"] = colors["typescriptDocNotation"] +-- + +-- json +colors["jsonKeyword"] = colors["Property"] +colors["jsonQuote"] = colors["String"] +colors["jsonBraces"] = colors["Punctuation"] +colors["jsonBraces"] = colors["jsonBraces"] +-- + +--html +colors["htmlTagName"] = colors["Tag"] +colors["htmlSpecialTagName"] = colors["Tag"] +colors["htmlTag"] = colors["htmlTagName"] +colors["htmlEndTag"] = colors["htmlTagName"] +colors["htmlTagN"] = colors["htmlTagName"] +colors["htmlArg"] = colors["Special"] +colors["htmlSpecialChar"] = colors["Constant"] +-- + +-- xml +colors["xmlTag"] = colors["Tag"] +colors["xmlProcessing"] = colors["Tag"] +colors["xmlProcessingDelim"] = colors["Tag"] +colors["xmlDoctypeDecl"] = colors["Tag"] +colors["xmlTagName"] = colors["Tag"] +colors["xmlDoctype"] = colors["Statement"] +colors["xmlAttrib"] = colors["Attribute"] +colors["xmlEqual"] = colors["Punctuation"] +colors["xmlEntityPunct"] = colors["Punctuation"] +colors["xmlEntity"] = colors["Constant"] +colors["xmlCdataStart"] = colors["@label"] +-- + +-- css +colors["cssProp"] = colors["Property"] +colors["cssBraces"] = colors["Punctuation"] +colors["cssNoise"] = colors["Punctuation"] +colors["cssSelectorOp"] = colors["Punctuation"] +colors["cssSelectorOp2"] = colors["Punctuation"] +colors["cssAttrComma"] = colors["Punctuation"] +colors["cssClassNameDot"] = colors["Punctuation"] +colors["cssFunctionComma"] = colors["Punctuation"] +colors["cssClassName"] = colors["Special"] +colors["cssIdentifier"] = colors["Type"] +colors["cssImportant"] = colors["Statement"] +colors["cssTagName"] = colors["Tag"] +colors["cssUrl"] = { colors["String"], gui = "underline" } +colors["cssUnitDecorators"] = colors["Constant"] +-- + +-- rust +colors["rustModPathSep"] = colors["Punctuation"] +colors["rustFoldBraces"] = colors["Punctuation"] +colors["rustBoxPlacementBalance"] = colors["Punctuation"] +colors["rustSigil"] = colors["Punctuation"] +colors["rustStorage"] = colors["Statement"] +-- + +-- ruby +colors["rubyConstant"] = colors["Constant"] +colors["rubyCurlyBlockDelimiter"] = colors["Punctuation"] +colors["rubyInterpolation"] = colors["Punctuation"] +colors["rubyInterpolationDelimiter"] = colors["Punctuation"] +colors["rubyStringDelimiter"] = colors["String"] +colors["rubyKeywordAsMethod"] = colors["Function"] +-- + +-- python +colors["pythonDecorator"] = colors["@annotation"] +colors["pythonDecoratorName"] = colors["@annotation"] +colors["pythonAttribute"] = colors["Property"] +colors["pythonBuiltin"] = colors["@type.builtin"] +-- + +-- yaml +colors["yamlBlockMappingKey"] = colors["Property"] +colors["yamlKeyValueDelimiter"] = colors["Punctuation"] +colors["yamlNodeTag"] = colors["Statement"] + +-- flash.nvim +--https://github.com/folke/flash.nvim?tab=readme-ov-file#-highlights +colors["FlashBackdrop"] = { fg = t.fg, bg = t.bg } +colors["FlashMatch"] = { fg = t.selection, bg = t.grey40 } +colors["FlashCurrent"] = { fg = t.fg, bg = t.bg } +colors["FlashLabel"] = { fg = t.primary, bg = t.bg } +colors["FlashPrompt"] = { fg = t.fg, bg = t.bg } +colors["FlashCursor"] = { fg = t.fg, bg = t.bg } +-- colors["FlashPromptIcon"] = { fg = t.fg, bg = t.bg } + +colorparser.parse(colors) + +return colors diff --git a/stylua.toml b/stylua.toml new file mode 100644 index 0000000..da39b71 --- /dev/null +++ b/stylua.toml @@ -0,0 +1,5 @@ +indent_type = "Spaces" +indent_width = 2 +column_width = 120 +[sort_requires] +enabled = false