Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 81 additions & 78 deletions lua/volt/color.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@
local M = {}

-- Convert a hex color value to RGB
-- @param hex: The hex color value
-- @return r: Red (0-255)
-- @return g: Green (0-255)
-- @return b: Blue (0-255)
M.hex2rgb = function(hex)
--- @param hex string: The hex color value
--- @return integer|nil r: Red (0-255)
--- @return integer|nil g: Green (0-255)
--- @return integer|nil b: Blue (0-255)
function M.hex2rgb(hex)
local hash = string.sub(hex, 1, 1) == "#"
if string.len(hex) ~= (7 - (hash and 0 or 1)) then
return nil
return
end

local r = tonumber(hex:sub(2 - (hash and 0 or 1), 3 - (hash and 0 or 1)), 16)
Expand All @@ -43,27 +43,31 @@ M.hex2rgb = function(hex)
end

-- Convert a hex color value to RGB ratio
-- @param hex: The hex color value
-- @return r: Red (0-100)
-- @return g: Green (0-100)
-- @return b: Blue (0-100)
M.hex2rgb_ratio = function(hex)
--- @param hex string: The hex color value
--- @return integer r: Red (0-100)
--- @return integer g: Green (0-100)
--- @return integer b: Blue (0-100)
function M.hex2rgb_ratio(hex)
local r, g, b = M.hex2rgb(hex)
return math.floor(r / 255 * 100), math.floor(g / 255 * 100), math.floor(b / 255 * 100)
end

-- Convert an RGB color value to hex
-- @param r: Red (0-255)
-- @param g: Green (0-255)
-- @param b: Blue (0-255)
-- @return The hexadecimal string representation of the color
M.rgb2hex = function(r, g, b)
--- @param r number: Red (0-255)
--- @param g number: Green (0-255)
--- @param b number: Blue (0-255)
--- @return string hex: The hexadecimal string representation of the color
function M.rgb2hex(r, g, b)
return string.format("#%02x%02x%02x", math.floor(r), math.floor(g), math.floor(b))
end

-- Helper function to convert a HSL color value to RGB
-- Not to be used directly, use M.hsl2rgb instead
M.hsl2rgb_helper = function(p, q, a)
--- @param p number
--- @param q number
--- @param a number
--- @return number
function M.hsl2rgb_helper(p, q, a)
if a < 0 then
a = a + 6
end
Expand All @@ -72,48 +76,50 @@ M.hsl2rgb_helper = function(p, q, a)
end
if a < 1 then
return (q - p) * a + p
elseif a < 3 then
end
if a < 3 then
return q
elseif a < 4 then
end
if a < 4 then
return (q - p) * (4 - a) + p
else
return p
end

return p
end

-- Convert a HSL color value to RGB
-- @param h: Hue (0-360)
-- @param s: Saturation (0-1)
-- @param l: Lightness (0-1)
-- @return r: Red (0-255)
-- @return g: Green (0-255)
-- @return b: Blue (0-255)
M.hsl2rgb = function(h, s, l)
--- @param h number: Hue (0-360)
--- @param s number: Saturation (0-1)
--- @param l number: Lightness (0-1)
--- @return integer r: Red (0-255)
--- @return integer g: Green (0-255)
--- @return integer b: Blue (0-255)
function M.hsl2rgb(h, s, l)
local t1, t2, r, g, b

h = h / 60
if l <= 0.5 then
t2 = l * (s + 1)
else
t2 = l + s - (l * s)
end

h = h / 60
t1 = l * 2 - t2
r = M.hsl2rgb_helper(t1, t2, h + 2) * 255
g = M.hsl2rgb_helper(t1, t2, h) * 255
b = M.hsl2rgb_helper(t1, t2, h - 2) * 255

return r, g, b
return math.floor(r), math.floor(g), math.floor(b)
end

-- Convert an RGB color value to HSL
-- @param r Red (0-255)
-- @param g Green (0-255)
-- @param b Blue (0-255)
-- @return h Hue (0-360)
-- @return s Saturation (0-1)
-- @return l Lightness (0-1)
M.rgb2hsl = function(r, g, b)
--- @param r number: Red (0-255)
--- @param g number: Green (0-255)
--- @param b number: Blue (0-255)
--- @return number h: Hue (0-360)
--- @return number s: Saturation (0-1)
--- @return number l: Lightness (0-1)
function M.rgb2hsl(r, g, b)
local min, max, l, s, maxcolor, h
r, g, b = r / 255, g / 255, b / 255

Expand Down Expand Up @@ -155,31 +161,30 @@ M.rgb2hsl = function(r, g, b)
end

-- Convert a hex color value to HSL
-- @param hex: The hex color value
-- @param h: Hue (0-360)
-- @param s: Saturation (0-1)
-- @param l: Lightness (0-1)
M.hex2hsl = function(hex)
--- @param hex string: The hex color value
--- @return number h: Hue (0-360)
--- @return number s: Saturation (0-1)
--- @return number l: Lightness (0-1)
function M.hex2hsl(hex)
local r, g, b = M.hex2rgb(hex)
return M.rgb2hsl(r, g, b)
end

-- Convert a HSL color value to hex
-- @param h: Hue (0-360)
-- @param s: Saturation (0-1)
-- @param l: Lightness (0-1)
-- @returns hex color value
M.hsl2hex = function(h, s, l)
--- @param h number: Hue (0-360)
--- @param s number: Saturation (0-1)
--- @param l number: Lightness (0-1)
--- @return string hex: The hex color value
function M.hsl2hex(h, s, l)
local r, g, b = M.hsl2rgb(h, s, l)
return M.rgb2hex(r, g, b)
end

-- Change the hue of a color by a given amount
-- @param hex The hex color value
-- @param amount The amount to change the hue.
-- Negative values decrease the hue, positive values increase it.
-- @return The hex color value
M.change_hex_hue = function(hex, percent)
--- @param hex string: The hex color value
--- @param percent integer: The amount to change the hue
--- @return string hex: The hex color value
function M.change_hex_hue(hex, percent)
local h, s, l = M.hex2hsl(hex)
-- Convert percentage to a degree shift
local shift = (percent / 100) * 360
Expand All @@ -191,11 +196,10 @@ M.change_hex_hue = function(hex, percent)
end

-- Desaturate or saturate a color by a given percentage
-- @param hex The hex color value
-- @param percent The percentage to desaturate or saturate the color.
-- Negative values desaturate the color, positive values saturate it
-- @return The hex color value
M.change_hex_saturation = function(hex, percent)
--- @param hex string: The hex color value
--- @param percent number: The percentage to desaturate or saturate the color.
--- @return string hex: The hex color value
function M.change_hex_saturation(hex, percent)
local h, s, l = M.hex2hsl(hex)
s = s + (percent / 100)
if s > 1 then
Expand All @@ -208,11 +212,10 @@ M.change_hex_saturation = function(hex, percent)
end

-- Lighten or darken a color by a given percentage
-- @param hex The hex color value
-- @param percent The percentage to lighten or darken the color.
-- Negative values darken the color, positive values lighten it
-- @return The hex color value
M.change_hex_lightness = function(hex, percent)
--- @param hex string: The hex color value
--- @param percent number: The percentage to lighten or darken the color.
--- @return string hex: The hex color value
function M.change_hex_lightness(hex, percent)
local h, s, l = M.hex2hsl(hex)
l = l + (percent / 100)
if l > 1 then
Expand All @@ -225,11 +228,11 @@ M.change_hex_lightness = function(hex, percent)
end

-- Compute a gradient between two colors
-- @param hex1 The first hex color value
-- @param hex2 The second hex color value
-- @param steps The number of steps to compute
-- @return A table of hex color values
M.compute_gradient = function(hex1, hex2, steps)
--- @param hex1 string: The first hex color value
--- @param hex2 string: The second hex color value
--- @param steps integer: The number of steps to compute
--- @return string[] gradient: A table of hex color values
function M.compute_gradient(hex1, hex2, steps)
local h1, s1, l1 = M.hex2hsl(hex1)
local h2, s2, l2 = M.hex2hsl(hex2)
local h, s, l
Expand All @@ -249,10 +252,10 @@ M.compute_gradient = function(hex1, hex2, steps)
end

-- Generate complementary colors
-- @param hex The hex color value (string)
-- @param count The number of complementary colors to generate
-- @return A table containing the complementary colors in hex format
M.hex2complementary = function(hex, count)
--- @param hex string: The hex color value (string)
--- @param count integer: The number of complementary colors to generate
--- @return string[] complementary_colors: A table containing the complementary colors in hex format
function M.hex2complementary(hex, count)
local h, s, l = M.hex2hsl(hex)
local complementary_colors = {}

Expand All @@ -271,12 +274,11 @@ M.hex2complementary = function(hex, count)
end

-- Mix two colors with a given percentage.
-- @param first The primary hex color.
-- @param second The hex color you want to mix into the first color.
-- @param strength The percentage of second color in the output.
-- This needs to be a number between 0 - 100.
-- @return The mixed color as a hex value
M.mix = function(first, second, strength)
--- @param first string: The primary hex color.
--- @param second string: The hex color you want to mix into the first color.
--- @param strength number: The percentage of second color in the output (0-100).
--- @return string mixed: The mixed color as a hex value
function M.mix(first, second, strength)
if strength == nil then
strength = 0.5
end
Expand All @@ -291,7 +293,8 @@ M.mix = function(first, second, strength)

if s == 0 then
return first
elseif s == 1 then
end
if s == 1 then
return second
end

Expand Down
1 change: 1 addition & 0 deletions lua/volt/draw.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ local api = vim.api
local set_extmark = api.nvim_buf_set_extmark
local state = require "volt.state"

--- @param buf integer
return function(buf, section)
local v = state[buf]
local section_lines = section.lines(buf)
Expand Down
17 changes: 12 additions & 5 deletions lua/volt/events.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,20 @@ local MouseMove = vim.keycode "<MouseMove>"
local LeftMouse = vim.keycode "<LeftMouse>"
local map = vim.keymap.set

local get_item_from_col = function(tb, n)
local function get_item_from_col(tb, n)
for _, val in ipairs(tb) do
if val.col_start <= n and val.col_end >= n then
return val
end
end
end

local run_func = function(foo)
--- @param foo function|string
local function run_func(foo)
---@cast foo function
if type(foo) == "function" then
foo()
---@cast foo string
elseif type(foo) == "string" then
vim.cmd(foo)
end
Expand Down Expand Up @@ -56,6 +59,9 @@ local function set_cursormoved_autocmd(buf)
})
end

--- @param buf integer
--- @param row integer
--- @param col integer
local function handle_hover(buf_state, buf, row, col)
-- clear old hovers!
if buf_state.hovered_extmarks then
Expand All @@ -81,7 +87,8 @@ local function handle_hover(buf_state, buf, row, col)
end
end

local buf_mappings = function(buf)
--- @param buf integer
local function buf_mappings(buf)
set_cursormoved_autocmd(buf)

map("n", "<CR>", function()
Expand All @@ -101,7 +108,7 @@ local M = {}

M.bufs = {}

M.add = function(val)
function M.add(val)
if type(val) == "table" then
for _, buf in ipairs(val) do
table.insert(M.bufs, buf)
Expand All @@ -113,7 +120,7 @@ M.add = function(val)
end
end

M.enable = function()
function M.enable()
vim.g.extmarks_events = true
vim.o.mousemev = true

Expand Down
9 changes: 7 additions & 2 deletions lua/volt/highlights.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ local api = vim.api
local lighten = require("volt.color").change_hex_lightness
local bg = vim.o.bg

---@type table<string, vim.api.keyset.highlight>
local highlights = {}

local hexadecimal_to_hex = function(hex)
--- @param hex? integer
local function hexadecimal_to_hex(hex)
return "#" .. ("%06x"):format((hex == nil and 0 or hex))
end

Expand All @@ -29,7 +31,9 @@ if vim.g.base46_cache then
CommentFg = { fg = colors.light_grey },
}
else
---@type string|integer|nil
local normal_bg = api.nvim_get_hl(0, { name = "Normal" }).bg
---@type string|integer|nil
local comment_fg = api.nvim_get_hl(0, { name = "comment" }).fg

normal_bg = hexadecimal_to_hex(normal_bg)
Expand All @@ -39,7 +43,8 @@ else
local lighter_bg = lighten(normal_bg, 5)
local black3_bg = lighten(normal_bg, 10)

local get_hl = function(name)
--- @param name string
local function get_hl(name)
local data = api.nvim_get_hl(0, { name = name })
return hexadecimal_to_hex(data.fg)
end
Expand Down
Loading