Something went wrong. Try again.
Vim/Neovim configurations just for me
neovim
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246local M = {}
---@class rc.Highlight.Operation---@field reverse? true---@field extend? string | rc.Highlight---@field mix? { hl: string | rc.Highlight, ratio: integer }---@field clear? 'fg' | 'bg' | 'sp'---@field bold? boolean
---@class rc.Highlight---@field name string---@field package operations rc.Highlight.Operation[]local Highlight = {}---@privateHighlight.__index = Highlight
---@param hl_name string---@return rc.Highlightfunction M.get(hl_name) return setmetatable({ name = hl_name, operations = {}, }, Highlight)end
---@param hl_name string---@param hl fun(): rc.Highlight---@return rc.Highlightfunction M.ensure(hl_name, hl) local self = M.get(hl_name) if self:exists() then return self else return hl():set(hl_name) endend
---@param new_hl_name string?---@return selffunction Highlight:set(new_hl_name) local name = new_hl_name or self.name local _self = vim.deepcopy(self) local function set_hl() vim.api.nvim_set_hl(0, name, _self:get_hl_info()) end set_hl() vim.api.nvim_create_autocmd("ColorScheme", { callback = set_hl }) self.name = name return selfend
---@param color integer---@return stringlocal function int2hex(color) return ("#%06x"):format(color)end
---@param color integer---@return integer, integer, integerlocal function int2rgb(color) return bit.rshift(color, 2 ^ 4), bit.band(bit.rshift(color, 2 ^ 3), 0xff), bit.band(color, 0xff)end
---@param r integer---@param g integer---@param b integer---@return integerlocal function rgb2int(r, g, b) return bit.lshift(r, 2 ^ 4) + bit.lshift(g, 2 ^ 3) + bend
---@param color string---@return integerlocal function hex2int(color) return rgb2int( tonumber(color:sub(2, 3), 16), tonumber(color:sub(4, 5), 16), tonumber(color:sub(6, 7), 16) )end
---@param min integer---@param n integer---@param max integer---@return integerlocal function clamp(min, n, max) return math.min(math.max(n, min), max)end
---@param base integer---@param other integer---@param ratio number 0.0 ~ 1.0---@return integerlocal function mix_colors(base, other, ratio) ratio = clamp(0, ratio, 1) local base_r, base_g, base_b = int2rgb(base) local other_r, other_g, other_b = int2rgb(other) return rgb2int( clamp(0, base_r * (1 - ratio) + other_r * ratio, 0xff), clamp(0, base_g * (1 - ratio) + other_g * ratio, 0xff), clamp(0, base_b * (1 - ratio) + other_b * ratio, 0xff) )end
---@return vim.api.keyset.highlightfunction Highlight:get_hl_info() local info = vim.api.nvim_get_hl(0, { name = self.name, link = false }) --[[@as table]] ---@type vim.api.keyset.highlight info = vim.tbl_isempty(info) and {} or info
for _, op in ipairs(self.operations) do local reverse = op.reverse if reverse ~= nil then info.fg, info.bg = info.bg, info.fg info.ctermfg, info.ctermbg = info.ctermbg, info.ctermfg end
local extend = op.extend if extend ~= nil then if type(extend) == "string" then info = vim.tbl_extend("keep", info, M.get(extend):get_hl_info()) else info = vim.tbl_extend("keep", info, extend:get_hl_info()) end end
local mix = op.mix if mix ~= nil then local hl = mix.hl if type(hl) == "string" then hl = M.get(hl) end local other = hl:copy():extend("Normal"):get_hl_info() for _, key in ipairs({ "fg", "bg", "sp" }) do local base_color, other_color = info[key], other[key] if base_color and other_color then info[key] = int2hex( mix_colors( type(base_color) == "number" and base_color or hex2int(base_color), type(other_color) == "number" and other_color or hex2int(other_color), mix.ratio / 100 ) ) end end end
local clear = op.clear if clear ~= nil then info[clear] = nil end
local bold = op.bold if bold ~= nil then info.bold = bold end end
return infoend
---@return rc.Highlightfunction Highlight:copy() return vim.deepcopy(self)end
---@return booleanfunction Highlight:exists() return not vim.tbl_isempty(vim.api.nvim_get_hl(0, { name = self.name }))end
---@private---@param op rc.Highlight.Operationfunction Highlight:push_operation(op) table.insert(self.operations, op)end
---@param other rc.Highlight | string---@return selffunction Highlight:extend(other) self:push_operation({ extend = other }) return selfend
---@return selffunction Highlight:reverse() self:push_operation({ reverse = true }) return selfend
---@return selffunction Highlight:clear_fg() self:push_operation({ clear = "fg" }) return selfend
---@return selffunction Highlight:clear_bg() self:push_operation({ clear = "bg" }) return selfend
---@param hl string | rc.Highlight---@param ratio integer 0 ~ 100---@return selffunction Highlight:mix(hl, ratio) self:push_operation({ mix = { hl = hl, ratio = ratio } }) return selfend
---@param bold boolean---@return selffunction Highlight:bold(bold) self:push_operation({ bold = bold }) return selfend
---@param name string---@param val vim.api.keyset.highlight | rc.Highlightlocal function set(name, val) if getmetatable(val) == Highlight then ---@cast val rc.Highlight val:set(name) else ---@cast val vim.api.keyset.highlight local function set_hl() vim.api.nvim_set_hl(0, name, val) end set_hl() vim.api.nvim_create_autocmd("ColorScheme", { callback = set_hl }) endend
---@param highlights { [string]: string | rc.Highlight }function M.set(highlights) for name, val in pairs(highlights) do if type(val) == "string" then set(name, { link = val }) else set(name, val) end endend
return M