diff --git a/lua/mellifluous/color.lua b/lua/mellifluous/color.lua index 51d4106..60ac008 100644 --- a/lua/mellifluous/color.lua +++ b/lua/mellifluous/color.lua @@ -70,6 +70,10 @@ function color_meta:with_lightness(val) return M.new(oklch_to_hex(oklch)) end +function color_meta:get_hsl() + return hex_to_okhsl(self.hex) +end + function color_meta:saturated(val) local okhsl = hex_to_okhsl(self.hex) okhsl.s = clip(okhsl.s + val, 0, 100) diff --git a/lua/mellifluous/highlights/custom_groups.lua b/lua/mellifluous/highlights/custom_groups.lua new file mode 100644 index 0000000..c5f351c --- /dev/null +++ b/lua/mellifluous/highlights/custom_groups.lua @@ -0,0 +1,62 @@ +local M = {} + +-- Any shared highlight groups that cannot be found in general highlights or +-- treesitter highlights are created here. + +function M.get(colors) + local config = require('mellifluous.config').config + local shader = require('mellifluous.utils.shader') + + return { + MainKeyword = { fg = colors.main_keywords, style = config.styles.keywords }, + + IndentLine = function(bg) + return { fg = shader.replicate_shade(colors.bg, colors.fg4, bg) } + end, + IndentLineActive = function(bg) + return { fg = shader.replicate_shade(colors.bg, colors.fg5, bg) } + end, + IndentLineInactive = function(bg) + return { + fg = config.is_bg_dark + and shader.replicate_shade(colors.bg, colors.bg4, bg) + or shader.replicate_shade(colors.bg, colors.dark_bg2, bg) + } + end, + + MenuButton = { fg = colors.ui_blue }, + MenuButtonSelected = function(bg) + local applied_bg = config.is_bg_dark + and shader.replicate_shade(colors.bg, colors.bg4, bg) + or shader.replicate_shade(colors.bg, colors.dark_bg2, bg) + return { + fg = shader.replicate_shade(colors.bg, applied_bg, colors.ui_blue), + bg = applied_bg, + } + end, + + FileTree = { + fg = colors.fg2, + bg = (config.transparent_background.file_tree + and 'NONE') + or config.flat_background.file_tree + and colors.bg + or colors.dark_bg + }, + FileTreeWinSeparator = function(bg) + return { + fg = config.flat_background.line_numbers ~= config.flat_background.file_tree + and bg -- no separator if LineNr bg differs from this bg + or config.flat_background.line_numbers and config.flat_background.file_tree + and colors.fg5 -- stronger separator if both bg are flat + or config.is_bg_dark + and colors.bg3 + or colors.dark_bg2, + + bg = bg, + } + end, + } +end + +return M diff --git a/lua/mellifluous/highlights/general.lua b/lua/mellifluous/highlights/general.lua index fec18b8..53cc9bb 100644 --- a/lua/mellifluous/highlights/general.lua +++ b/lua/mellifluous/highlights/general.lua @@ -3,6 +3,7 @@ local M = {} function M.set(hl, colors) local shader = require('mellifluous.utils.shader') local config = require('mellifluous.config').config + local groups = require('mellifluous.highlights.custom_groups').get(colors) hl.set('Normal', { bg = (config.transparent_background.enabled and 'NONE') @@ -131,33 +132,32 @@ function M.set(hl, colors) hl.set('Float', { link = 'Constant', style = config.styles.numbers or {} }) -- A floating point constant: 2.3e10 hl.set('Identifier', { fg = colors.fg, style = config.styles.variables or {} }) -- (*) Any variable name hl.set('Function', { fg = colors.functions, style = config.styles.functions or {} }) -- Function name (also: methods for classes) - hl.set('Statement', { link = 'Keyword' }) -- (*) Any statement + hl.set('Statement', { link = 'Keyword' }) -- (*) Any statement hl.set('Conditional', { fg = colors.main_keywords, style = config.styles.conditionals or {} }) -- if, then, else, endif, switch, etc. hl.set('Repeat', { fg = colors.main_keywords, style = config.styles.loops or {} }) -- for, do, while, etc. hl.set('Label', { fg = colors.other_keywords }) hl.set('Operator', { fg = config.is_bg_dark and colors.operators or colors.fg3, style = config.styles.operators or {} - }) -- 'sizeof', '+', '*', etc. - hl.set('Keyword', { fg = colors.other_keywords, style = config.styles.keywords }) -- any other keyword - hl.set('MellifluousMainKeyword', { fg = colors.main_keywords, style = config.styles.keywords }) -- Mainly keywords related to control flow - hl.set('Exception', { link = 'MellifluousMainKeyword' }) -- try, catch, throw - hl.set('PreProc', { fg = colors.functions }) -- (*) Generic Preprocessor - hl.set('Include', { link = 'PreProc' }) -- Preprocessor #include - hl.set('Define', { link = 'PreProc' }) -- Preprocessor #define - hl.set('Macro', { link = 'PreProc' }) -- Same as Define - hl.set('PreCondit', { link = 'PreProc' }) -- Preprocessor #if, #else, #endif, etc. - hl.set('Type', { fg = colors.types, style = config.styles.types or {} }) -- (*) int, long, char, etc. - hl.set('StorageClass', { link = 'Type' }) -- static, register, volatile, etc. - hl.set('Structure', { link = 'Type' }) -- struct, union, enum, etc. - hl.set('Typedef', { link = 'Type' }) -- A typedef - hl.set('Special', { fg = colors.other_keywords }) -- (*) Any special symbol - hl.set('SpecialChar', { link = 'Special' }) -- Special character in a constant - hl.set('Tag', { link = 'Special' }) -- You can use CTRL-] on this - hl.set('Delimiter', { link = 'Operator' }) -- Character that needs attention - hl.set('SpecialComment', { link = 'Special' }) -- Special things inside a comment (e.g. '\n') - hl.set('Debug', { link = 'Special' }) -- Debugging statements - hl.set('Underlined', { underline = true, fg = colors.fg3 }) -- Text that stands out, HTML links + }) -- 'sizeof', '+', '*', etc. + hl.set('Keyword', { fg = colors.other_keywords, style = config.styles.keywords }) -- any other keyword + hl.set('Exception', groups.MainKeyword) -- try, catch, throw + hl.set('PreProc', { fg = colors.functions }) -- (*) Generic Preprocessor + hl.set('Include', { link = 'PreProc' }) -- Preprocessor #include + hl.set('Define', { link = 'PreProc' }) -- Preprocessor #define + hl.set('Macro', { link = 'PreProc' }) -- Same as Define + hl.set('PreCondit', { link = 'PreProc' }) -- Preprocessor #if, #else, #endif, etc. + hl.set('Type', { fg = colors.types, style = config.styles.types or {} }) -- (*) int, long, char, etc. + hl.set('StorageClass', { link = 'Type' }) -- static, register, volatile, etc. + hl.set('Structure', { link = 'Type' }) -- struct, union, enum, etc. + hl.set('Typedef', { link = 'Type' }) -- A typedef + hl.set('Special', { fg = colors.other_keywords }) -- (*) Any special symbol + hl.set('SpecialChar', { link = 'Special' }) -- Special character in a constant + hl.set('Tag', { link = 'Special' }) -- You can use CTRL-] on this + hl.set('Delimiter', { link = 'Operator' }) -- Character that needs attention + hl.set('SpecialComment', { link = 'Special' }) -- Special things inside a comment (e.g. '\n') + hl.set('Debug', { link = 'Special' }) -- Debugging statements + hl.set('Underlined', { underline = true, fg = colors.fg3 }) -- Text that stands out, HTML links hl.set('Bold', { bold = config.bold }) hl.set('Italic', { italic = config.italic }) hl.set('Ignore', { fg = colors.fg5 }) -- Left blank, hidden |hl-Ignore| (NOTE: May be invisible here in template) diff --git a/lua/mellifluous/highlights/plugins/indent_blankline.lua b/lua/mellifluous/highlights/plugins/indent_blankline.lua index 08ac694..a697b9e 100644 --- a/lua/mellifluous/highlights/plugins/indent_blankline.lua +++ b/lua/mellifluous/highlights/plugins/indent_blankline.lua @@ -1,10 +1,10 @@ local M = {} function M.set(hl, colors) - local config = require('mellifluous.config').config + local groups = require('mellifluous.highlights.custom_groups').get(colors) - hl.set('IblIndent', { fg = (config.is_bg_dark and colors.bg4) or colors.dark_bg2 }) - hl.set('IblScope', { fg = colors.fg5 }) + hl.set('IblIndent', groups.IndentLineInactive(colors.bg)) + hl.set('IblScope', groups.IndentLineActive(colors.bg)) hl.set('IblWhitespace', { link = 'Whitespace' }) end diff --git a/lua/mellifluous/highlights/plugins/lazy.lua b/lua/mellifluous/highlights/plugins/lazy.lua index 9fb33d5..2c21333 100644 --- a/lua/mellifluous/highlights/plugins/lazy.lua +++ b/lua/mellifluous/highlights/plugins/lazy.lua @@ -2,10 +2,12 @@ local M = {} function M.set(hl, colors) local config = require('mellifluous.config').config + local groups = require('mellifluous.highlights.custom_groups').get(colors) + local bg = hl.get('NormalFloat').bg hl.set('LazyNormal', { bg = colors.bg2 }) - hl.set('LazyButton', { fg = colors.fg2, bg = colors.bg }) - hl.set('LazyButtonActive', { fg = colors.fg, bg = config.is_bg_dark and colors.bg5 or colors.bg4 }) + hl.set('LazyButton', groups.MenuButton) + hl.set('LazyButtonActive', groups.MenuButtonSelected(bg)) hl.set('LazyH1', { link = 'LazyButtonActive' }) hl.set('LazyProgressTodo', { fg = config.is_bg_dark and colors.fg5 or colors.dark_bg }) diff --git a/lua/mellifluous/highlights/plugins/mason.lua b/lua/mellifluous/highlights/plugins/mason.lua index e04dd36..b9aa526 100644 --- a/lua/mellifluous/highlights/plugins/mason.lua +++ b/lua/mellifluous/highlights/plugins/mason.lua @@ -1,14 +1,15 @@ local M = {} function M.set(hl, colors) - local config = require('mellifluous.config').config + local groups = require('mellifluous.highlights.custom_groups').get(colors) + local bg = hl.get('NormalFloat').bg hl.set('MasonHeader', { fg = colors.dark_bg, bg = colors.ui_orange, bold = true }) hl.set('MasonHeaderSecondary', { fg = colors.dark_bg, bg = colors.ui_blue, bold = true }) - hl.set('MasonHighlightBlockBold', { fg = colors.fg, bg = config.is_bg_dark and colors.bg5 or colors.bg4, bold = true }) + hl.set('MasonHighlightBlockBold', groups.MenuButtonSelected(bg)) hl.set('MasonHighlightBlockBoldSecondary', { link = 'MasonHighlightBlockBold' }) hl.set('MasonHighlightBlock', { fg = colors.dark_bg, bg = colors.ui_green }) - hl.set('MasonMutedBlock', { fg = colors.fg2, bg = colors.bg }) + hl.set('MasonMutedBlock', groups.MenuButton) hl.set('MasonHighlight', { fg = colors.ui_yellow }) hl.set('MasonHighlightSecondary', { fg = colors.ui_purple }) hl.set('MasonMuted', { fg = colors.fg3 }) diff --git a/lua/mellifluous/highlights/plugins/neo_tree.lua b/lua/mellifluous/highlights/plugins/neo_tree.lua index 04579b1..c7dd3b0 100644 --- a/lua/mellifluous/highlights/plugins/neo_tree.lua +++ b/lua/mellifluous/highlights/plugins/neo_tree.lua @@ -2,7 +2,8 @@ local M = {} function M.set(hl, colors) local root_fg = colors.fg3 - local config = require('mellifluous.config').config + local groups = require('mellifluous.highlights.custom_groups').get(colors) + local normal_group = groups.FileTree hl.set('NeoTreeGitConflict', { fg = colors.ui_purple }) hl.set('NeoTreeGitDeleted', { fg = colors.red }) @@ -12,33 +13,18 @@ function M.set(hl, colors) hl.set('NeoTreeGitRenamed', { fg = colors.ui_orange }) hl.set('NeoTreeGitUntracked', { fg = colors.ui_orange }) - hl.set('NeoTreeNormal', { - bg = (config.transparent_background.file_tree and 'NONE') or (config.flat_background.file_tree and hl.get( - 'Normal' - ).bg) or colors.dark_bg, - fg = colors.fg2, - }) - hl.set('NeoTreeNormalNC', { link = 'NeoTreeNormal' }) - hl.set('NeoTreePopup', { link = 'NeoTreeNormal' }) - hl.set('NeoTreeWinSeparator', { - bg = hl.get('NeoTreeNormal').bg, - fg = (config.flat_background.line_numbers ~= config.flat_background.file_tree - and hl.get('NeoTreeNormal').bg) -- no separator if LineNr bg differs from this bg - or (config.flat_background.line_numbers - and config.flat_background.file_tree - and (config.is_bg_dark and colors.bg4) - or colors.dark_bg2) -- stronger separator if both bg are flat - or (config.is_bg_dark and colors.bg3) - or colors.dark_bg2, - }) - hl.set('NeoTreeIndentMarker', { fg = colors.fg5 }) - hl.set('NeoTreeEndOfBuffer', { bg = hl.get('NeoTreeNormal').bg, fg = hl.get('EndOfBuffer').fg }) + hl.set('NeoTreeNormal', normal_group) + hl.set('NeoTreeNormalNC', normal_group) + hl.set('NeoTreePopup', normal_group) + hl.set('NeoTreeWinSeparator', groups.FileTreeWinSeparator(normal_group.bg)) + hl.set('NeoTreeIndentMarker', groups.IndentLine(normal_group.bg)) + hl.set('NeoTreeEndOfBuffer', { bg = normal_group.bg, fg = hl.get('EndOfBuffer').fg }) hl.set('NeoTreeFolderIcon', { fg = hl.get('Directory').fg }) hl.set('NeoTreeRootName', { fg = root_fg }) - hl.set('NeoTreeStatusLine', { link = 'NeoTreeNormal' }) + hl.set('NeoTreeStatusLine', normal_group) hl.set('NeoTreeCursorLine', { link = 'CursorLine' }) hl.set('NeoTreeCursorLineSign', { bg = hl.get('CursorLine').bg }) - hl.set('NeoTreeSignColumn', { link = 'NeoTreeNormal' }) + hl.set('NeoTreeSignColumn', normal_group) hl.set('NeoTreeFloatTitle', { fg = colors.fg2 }) hl.set('NeoTreeTitleBar', { link = 'NeoTreeFloatTitle' }) end diff --git a/lua/mellifluous/highlights/plugins/neotest.lua b/lua/mellifluous/highlights/plugins/neotest.lua index 8c57040..80875c7 100644 --- a/lua/mellifluous/highlights/plugins/neotest.lua +++ b/lua/mellifluous/highlights/plugins/neotest.lua @@ -2,11 +2,12 @@ local M = {} function M.set(hl, colors) local config = require("mellifluous.config").config + local groups = require('mellifluous.highlights.custom_groups').get(colors) hl.set("NeotestAdapterName", { fg = colors.fg3 }) hl.set("NeotestFocused", { fg = hl.get("Normal").fg, bold = true }) hl.set("NeotestTarget", { style = { underline = true } }) - hl.set("NeotestIndent", { fg = colors.fg4 }) + hl.set("NeotestIndent", groups.IndentLine(colors.bg)) hl.set("NeotestExpandMarker", { link = "NeotestIndent" }) hl.set("NeotestDir", { fg = hl.get("Directory").fg }) diff --git a/lua/mellifluous/highlights/plugins/nvim_tree.lua b/lua/mellifluous/highlights/plugins/nvim_tree.lua index 615b5d6..23c1100 100644 --- a/lua/mellifluous/highlights/plugins/nvim_tree.lua +++ b/lua/mellifluous/highlights/plugins/nvim_tree.lua @@ -2,11 +2,9 @@ local M = {} function M.set(hl, colors) local config = require('mellifluous.config').config - local root_fg = colors.dark_bg - - if config.plugins.nvim_tree.show_root == true then - root_fg = colors.fg3 - end + local groups = require('mellifluous.highlights.custom_groups').get(colors) + local normal_group = groups.FileTree; + local root_fg = config.plugins.nvim_tree.show_root and colors.fg3 or colors.dark_bg hl.set('NvimTreeGitDeleted', { fg = colors.red }) hl.set('NvimTreeGitDirty', { fg = colors.ui_orange }) @@ -15,28 +13,13 @@ function M.set(hl, colors) hl.set('NvimTreeGitNew', { fg = colors.ui_blue }) hl.set('NvimTreeGitRenamed', { fg = colors.ui_orange }) hl.set('NvimTreeGitStaged', { fg = colors.ui_green }) - hl.set('NvimTreeNormal', { - bg = (config.transparent_background.file_tree and 'NONE') - or (config.flat_background.file_tree and hl.get('Normal').bg) - or colors.dark_bg, - fg = colors.fg2 - }) - hl.set('NvimTreeNormalNC', { link = 'NvimTreeNormal' }) - hl.set('NvimTreePopup', { link = 'NvimTreeNormal' }) - hl.set('NvimTreeSignColumn', { link = 'NvimTreeNormal' }) - hl.set('NvimTreeWinSeparator', { - bg = hl.get('NvimTreeNormal').bg, - fg = (config.flat_background.line_numbers ~= config.flat_background.file_tree - and hl.get('NvimTreeNormal').bg) -- no separator if LineNr bg differs from this bg - or (config.flat_background.line_numbers - and config.flat_background.file_tree - and (config.is_bg_dark and colors.bg4) - or colors.dark_bg2) -- stronger separator if both bg are flat - or (config.is_bg_dark and colors.bg3) - or colors.dark_bg2 - }) - hl.set('NvimTreeIndentMarker', { fg = hl.get('Directory').fg }) - hl.set('NvimTreeEndOfBuffer', { bg = hl.get('NvimTreeNormal').bg, fg = hl.get('EndOfBuffer').fg }) + hl.set('NvimTreeNormal', normal_group) + hl.set('NvimTreeNormalNC', normal_group) + hl.set('NvimTreePopup', normal_group) + hl.set('NvimTreeSignColumn', normal_group) + hl.set('NvimTreeWinSeparator', groups.FileTreeWinSeparator(normal_group.bg)) + hl.set('NvimTreeIndentMarker', groups.IndentLine(normal_group.bg)) + hl.set('NvimTreeEndOfBuffer', { bg = normal_group.bg, fg = hl.get('EndOfBuffer').fg }) hl.set('NvimTreeFolderIcon', { fg = hl.get('Directory').fg }) hl.set('NvimTreeRootFolder', { fg = root_fg }) end diff --git a/lua/mellifluous/highlights/plugins/semantic_tokens.lua b/lua/mellifluous/highlights/plugins/semantic_tokens.lua index 49297ae..e3aaaee 100644 --- a/lua/mellifluous/highlights/plugins/semantic_tokens.lua +++ b/lua/mellifluous/highlights/plugins/semantic_tokens.lua @@ -1,6 +1,8 @@ local M = {} function M.set(hl, colors) + local groups = require('mellifluous.highlights.custom_groups').get(colors) + hl.set('@lsp.type.comment', {}) -- let treesitter handle those hl.set('@lsp.type.enum', { link = 'Type' }) hl.set('@lsp.type.enumMember', { link = 'Constant' }) @@ -12,7 +14,7 @@ function M.set(hl, colors) hl.set('@lsp.type.property', { fg = colors.fg }) hl.set('@lsp.type.variable', {}) hl.set('@lsp.typemod.variable.constant', { link = 'Constant' }) - hl.set('@lsp.typemod.keyword.controlFlow', { fg = colors.main_keywords }) + hl.set('@lsp.typemod.keyword.controlFlow', groups.MainKeyword) end return M diff --git a/lua/mellifluous/highlights/plugins/treesitter.lua b/lua/mellifluous/highlights/plugins/treesitter.lua index 6b5d9a0..e2f8b22 100644 --- a/lua/mellifluous/highlights/plugins/treesitter.lua +++ b/lua/mellifluous/highlights/plugins/treesitter.lua @@ -3,6 +3,7 @@ local M = {} function M.set(hl, colors) local shader = require('mellifluous.utils.shader') local config = require('mellifluous.config').config + local groups = require('mellifluous.highlights.custom_groups').get(colors) -- Identifiers hl.set('@variable', { link = 'Identifier' }) -- Variable names that don't fit into other categories. @@ -55,13 +56,13 @@ function M.set(hl, colors) -- Keywords hl.set('@keyword', { link = 'Keyword' }) -- Keywords that don't fit into other categories. - hl.set('@keyword.coroutine', { link = 'MellifluousMainKeyword' }) -- Keywords related to coroutines (e.g. `go` in Go, `async/await` in Python) - hl.set('@keyword.function', { link = 'MellifluousMainKeyword' }) -- Keywords used to define a function: `function` in Lua, `def` and `lambda` in Python. + hl.set('@keyword.coroutine', groups.MainKeyword) -- Keywords related to coroutines (e.g. `go` in Go, `async/await` in Python) + hl.set('@keyword.function', groups.MainKeyword) -- Keywords used to define a function: `function` in Lua, `def` and `lambda` in Python. hl.set('@keyword.operator', { fg = colors.other_keywords, style = config.styles.operators }) -- Unary and binary operators that are English words: `and`, `or` in Python; `sizeof` in C. hl.set('@keyword.import', { link = 'Function' }) -- File or module inclusion keywords: `#include` in C, `use` or `extern crate` in Rust. hl.set('@keyword.storage', { link = 'StorageClass' }) -- Keywords that affect how a variable is stored: `static`, `comptime`, `extern`, etc. hl.set('@keyword.repeat', { link = 'Repeat' }) -- Keywords related to loops: `for`, `while`, etc. - hl.set('@keyword.return', { link = 'MellifluousMainKeyword' }) -- Keywords like `return` and `yield`. + hl.set('@keyword.return', groups.MainKeyword) -- Keywords like `return` and `yield`. hl.set('@keyword.debug', { link = 'Keyword' }) -- Debugging statements. hl.set('@keyword.exception', { link = 'Exception' }) -- Exception related keywords: `try`, `except`, `finally` in Python. hl.set('@keyword.conditional', { link = 'Conditional' }) -- Keywords related to conditionals: `if`, `when`, `cond`, etc.