diff --git a/lua/winshift/colors.lua b/lua/winshift/colors.lua index 775b5a9..16b026c 100644 --- a/lua/winshift/colors.lua +++ b/lua/winshift/colors.lua @@ -110,31 +110,53 @@ end ---@param group string Syntax group name. ---@param opt HiSpec + + function M.hi(group, opt) local use_tc = vim.o.termguicolors local g = use_tc and "gui" or "cterm" + -- Check if highlight group exists; if not, create a basic version of it + local exists = vim.fn.hlexists(group) + if not exists then + vim.cmd("hi " .. group .. " ctermfg=NONE ctermbg=NONE guifg=NONE guibg=NONE") + end + + local cmd = "hi " .. (opt.default and "def " or "") .. group + if not use_tc then if opt.ctermfg then opt.fg = opt.ctermfg + cmd = cmd .. " ctermfg=" .. opt.fg end if opt.ctermbg then opt.bg = opt.ctermbg + cmd = cmd .. " ctermbg=" .. opt.bg + end + else + if opt.fg then + cmd = cmd .. " guifg=" .. opt.fg + end + if opt.bg then + cmd = cmd .. " guibg=" .. opt.bg end end - vim.cmd(string.format( - "hi %s %s %s %s %s %s %s", - opt.default and "def" or "", - group, - opt.fg and (g .. "fg=" .. opt.fg) or "", - opt.bg and (g .. "bg=" .. opt.bg) or "", - opt.gui and ((use_tc and "gui=" or "cterm=") .. opt.gui) or "", - opt.sp and ("guisp=" .. opt.sp) or "", - opt.blend and ("blend=" .. opt.blend) or "" - )) + if opt.gui then + cmd = cmd .. " " .. (use_tc and "gui=" or "cterm=") .. opt.gui + end + if opt.sp then + cmd = cmd .. " guisp=" .. opt.sp + end + if opt.blend then + cmd = cmd .. " blend=" .. opt.blend + end + + vim.cmd(cmd) end + + ---@param from string Syntax group name. ---@param to? string Syntax group name. (default: `"NONE"`) ---@param opt? HiLinkSpec @@ -187,6 +209,78 @@ M.hl_links = { LineNrBelow = "WinShiftLineNr", } +------------------------ begin ISC licensed code +-- translated from the code found in colour.c in tmux + +-- Copyright (c) 2008 Nicholas Marriott +-- Copyright (c) 2016 Avi Halachmi + +-- Permission to use, copy, modify, and distribute this software for any +-- purpose with or without fee is hereby granted, provided that the above +-- copyright notice and this permission notice appear in all copies. +-- +-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +-- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +-- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +-- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + +local function hex_to_rgb(hex) + -- Check if the input is a string + if type(hex) ~= "string" then + return nil + end + + if string.match(hex, "^#%x%x%x%x%x%x$") then + local r, g, b = hex:match("#(%x%x)(%x%x)(%x%x)") + return tonumber(r, 16), tonumber(g, 16), tonumber(b, 16) + else + return nil, nil, nil + end +end + +function M.v2ci(v) + if v < 48 then return 0 + elseif v < 115 then return 1 + else return math.floor((v - 35) / 40) + end +end + +function M.color_index(ir, ig, ib) + return 36 * ir + 6 * ig + ib +end + +function M.dist_square(A, B, C, a, b, c) + return (A-a)^2 + (B-b)^2 + (C-c)^2 +end + +-- checkss if input is a hex value, if it is return a similar 256 value integer, else return nil +function M.rgbtox256(hex) + local r, g, b = hex_to_rgb(hex) + if r == nil then return nil end + + local ir, ig, ib = M.v2ci(r), M.v2ci(g), M.v2ci(b) + local average = (r + g + b) / 3 + local gray_index = average > 238 and 23 or math.floor((average - 3) / 10) + local i2cv = {0, 0x5f, 0x87, 0xaf, 0xd7, 0xff} + local cr, cg, cb = i2cv[ir + 1], i2cv[ig + 1], i2cv[ib + 1] + local gv = 8 + 10 * gray_index + + local color_err = M.dist_square(cr, cg, cb, r, g, b) + local gray_err = M.dist_square(gv, gv, gv, r, g, b) + + if color_err <= gray_err then + return 16 + M.color_index(ir, ig, ib) + else + return 232 + gray_index + end +end +---------------------- end ISC licensed code + + function M.setup() for name, opt in pairs(M.get_hl_groups()) do M.hi("WinShift" .. name, opt)