feat: add support for dynamic color with functions in color options (#566)
* feat: allow functions in color options. * update_evilline * docs: document color functions * remove unnecesery stuff * add dynamic color supoort for themes * chore: autogen (vimdocs+formating) * fix dynamic colors not working as color fallback * fix transitional separators not updating for dynamic colors dynamic colors * fix failing tests * apply format * Allow cases where theme doesn't even define nornal color for some mode * allow color function to return nil * some enhancements * more enhancements * code cleanup * if we don't have even normal in theme we should just nvim highlight it with it's ususal stl colors * not sure how it get here . It should be in different pr * keep only c of lualine_c in component section name * use sh to run docgen * fix filetype component not respecting color option properly * fix section x,y,z not falling back to correct colors * auto format * actually fix xyz not falling back to correct mode * fix comp sep not correctly removed properly on function hl * pass only section in color fn * more enhancements * update docs * update create_comp_hl call locations * enhancements+fixes * fix broken hls in tabline * Fix function color options not inheriting right colors * some enhancements * fix tests * tweek docs Co-authored-by: shadmansaleh <shadmansaleh@users.noreply.github.com>
This commit is contained in:
parent
016a20711e
commit
37a314b9e3
2
Makefile
2
Makefile
|
@ -31,7 +31,7 @@ endif
|
||||||
@rm -rf tmp_home
|
@rm -rf tmp_home
|
||||||
|
|
||||||
docgen:
|
docgen:
|
||||||
@bash ./scripts/docgen.sh
|
@sh ./scripts/docgen.sh
|
||||||
|
|
||||||
precommit_check: docgen format test lint
|
precommit_check: docgen format test lint
|
||||||
|
|
||||||
|
|
|
@ -374,15 +374,19 @@ sections = {
|
||||||
|
|
||||||
-- Defines a custom color for the component:
|
-- Defines a custom color for the component:
|
||||||
--
|
--
|
||||||
-- 'highlight_group_name' | { fg = '#rrggbb'|cterm_value(0-255)|'color_name(red)', bg= '#rrggbb', gui='style' }
|
-- 'highlight_group_name' | { fg = '#rrggbb'|cterm_value(0-255)|'color_name(red)', bg= '#rrggbb', gui='style' } | function
|
||||||
-- Note:
|
-- Note:
|
||||||
-- '|' is synonymous with 'or', meaning a different acceptable format for that placeholder.
|
-- '|' is synonymous with 'or', meaning a different acceptable format for that placeholder.
|
||||||
|
-- color function has to return one of other color types ('highlight_group_name' | { fg = '#rrggbb'|cterm_value(0-255)|'color_name(red)', bg= '#rrggbb', gui='style' })
|
||||||
|
-- color functions can be used to have different colors based on state as shown below.
|
||||||
--
|
--
|
||||||
-- Examples:
|
-- Examples:
|
||||||
-- color = { fg = '#ffaa88', bg = 'grey', gui='italic,bold' },
|
-- color = { fg = '#ffaa88', bg = 'grey', gui='italic,bold' },
|
||||||
-- color = { fg = 204 } -- When fg/bg are omitted, they default to the your theme's fg/bg.
|
-- color = { fg = 204 } -- When fg/bg are omitted, they default to the your theme's fg/bg.
|
||||||
-- color = 'WarningMsg' -- Highlight groups can also be used.
|
-- color = 'WarningMsg' -- Highlight groups can also be used.
|
||||||
--
|
-- color = function(section)
|
||||||
|
-- return { fg = vim.bo.modified and '#aa3355' or '#33aa88' }
|
||||||
|
-- end,
|
||||||
color = nil, -- The default is your theme's color for that section and mode.
|
color = nil, -- The default is your theme's color for that section and mode.
|
||||||
|
|
||||||
-- Specify what type a component is, if omitted, lualine will guess it for you.
|
-- Specify what type a component is, if omitted, lualine will guess it for you.
|
||||||
|
|
|
@ -387,15 +387,19 @@ General component options These are options that control behavior
|
||||||
|
|
||||||
-- Defines a custom color for the component:
|
-- Defines a custom color for the component:
|
||||||
--
|
--
|
||||||
-- 'highlight_group_name' | { fg = '#rrggbb'|cterm_value(0-255)|'color_name(red)', bg= '#rrggbb', gui='style' }
|
-- 'highlight_group_name' | { fg = '#rrggbb'|cterm_value(0-255)|'color_name(red)', bg= '#rrggbb', gui='style' } | function
|
||||||
-- Note:
|
-- Note:
|
||||||
-- '|' is synonymous with 'or', meaning a different acceptable format for that placeholder.
|
-- '|' is synonymous with 'or', meaning a different acceptable format for that placeholder.
|
||||||
|
-- color function has to return one of other color types ('highlight_group_name' | { fg = '#rrggbb'|cterm_value(0-255)|'color_name(red)', bg= '#rrggbb', gui='style' })
|
||||||
|
-- color functions can be used to have different colors based on state as shown below.
|
||||||
--
|
--
|
||||||
-- Examples:
|
-- Examples:
|
||||||
-- color = { fg = '#ffaa88', bg = 'grey', gui='italic,bold' },
|
-- color = { fg = '#ffaa88', bg = 'grey', gui='italic,bold' },
|
||||||
-- color = { fg = 204 } -- When fg/bg are omitted, they default to the your theme's fg/bg.
|
-- color = { fg = 204 } -- When fg/bg are omitted, they default to the your theme's fg/bg.
|
||||||
-- color = 'WarningMsg' -- Highlight groups can also be used.
|
-- color = 'WarningMsg' -- Highlight groups can also be used.
|
||||||
--
|
-- color = function(section)
|
||||||
|
-- return { fg = vim.bo.modified and '#aa3355' or '#33aa88' }
|
||||||
|
-- end,
|
||||||
color = nil, -- The default is your theme's color for that section and mode.
|
color = nil, -- The default is your theme's color for that section and mode.
|
||||||
|
|
||||||
-- Specify what type a component is, if omitted, lualine will guess it for you.
|
-- Specify what type a component is, if omitted, lualine will guess it for you.
|
||||||
|
|
|
@ -89,6 +89,9 @@ ins_left {
|
||||||
ins_left {
|
ins_left {
|
||||||
-- mode component
|
-- mode component
|
||||||
function()
|
function()
|
||||||
|
return ''
|
||||||
|
end,
|
||||||
|
color = function()
|
||||||
-- auto change color according to neovims mode
|
-- auto change color according to neovims mode
|
||||||
local mode_color = {
|
local mode_color = {
|
||||||
n = colors.red,
|
n = colors.red,
|
||||||
|
@ -112,10 +115,8 @@ ins_left {
|
||||||
['!'] = colors.red,
|
['!'] = colors.red,
|
||||||
t = colors.red,
|
t = colors.red,
|
||||||
}
|
}
|
||||||
vim.api.nvim_command('hi! LualineMode guifg=' .. mode_color[vim.fn.mode()] .. ' guibg=' .. colors.bg)
|
return { fg = mode_color[vim.fn.mode()] }
|
||||||
return ''
|
|
||||||
end,
|
end,
|
||||||
color = 'LualineMode',
|
|
||||||
padding = { right = 1 },
|
padding = { right = 1 },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -158,7 +158,7 @@ local statusline = modules.utils.retry_call_wrap(function(sections, is_focused)
|
||||||
if #section_data > 0 then
|
if #section_data > 0 then
|
||||||
if not applied_midsection_divider and section_name > 'c' then
|
if not applied_midsection_divider and section_name > 'c' then
|
||||||
applied_midsection_divider = true
|
applied_midsection_divider = true
|
||||||
section_data = modules.highlight.format_highlight('lualine_c') .. '%=' .. section_data
|
section_data = modules.highlight.format_highlight('c', is_focused) .. '%=' .. section_data
|
||||||
end
|
end
|
||||||
if not applied_trunc and section_name > 'b' then
|
if not applied_trunc and section_name > 'b' then
|
||||||
applied_trunc = true
|
applied_trunc = true
|
||||||
|
@ -170,7 +170,7 @@ local statusline = modules.utils.retry_call_wrap(function(sections, is_focused)
|
||||||
end
|
end
|
||||||
if applied_midsection_divider == false and config.options.always_divide_middle ~= false then
|
if applied_midsection_divider == false and config.options.always_divide_middle ~= false then
|
||||||
-- When non of section x,y,z is present
|
-- When non of section x,y,z is present
|
||||||
table.insert(status, modules.highlight.format_highlight('lualine_c') .. '%=')
|
table.insert(status, modules.highlight.format_highlight('c', is_focused) .. '%=')
|
||||||
end
|
end
|
||||||
return apply_transitional_separators(table.concat(status))
|
return apply_transitional_separators(table.concat(status))
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -38,7 +38,7 @@ end
|
||||||
function M:set_separator()
|
function M:set_separator()
|
||||||
if self.options.separator == nil then
|
if self.options.separator == nil then
|
||||||
if self.options.component_separators then
|
if self.options.component_separators then
|
||||||
if self.options.self.section < 'lualine_x' then
|
if self.options.self.section < 'x' then
|
||||||
self.options.separator = self.options.component_separators.left
|
self.options.separator = self.options.component_separators.left
|
||||||
else
|
else
|
||||||
self.options.separator = self.options.component_separators.right
|
self.options.separator = self.options.component_separators.right
|
||||||
|
@ -54,7 +54,8 @@ function M:create_option_highlights()
|
||||||
self.options.color_highlight = highlight.create_component_highlight_group(
|
self.options.color_highlight = highlight.create_component_highlight_group(
|
||||||
self.options.color,
|
self.options.color,
|
||||||
self.options.component_name,
|
self.options.component_name,
|
||||||
self.options
|
self.options,
|
||||||
|
false
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -89,7 +90,9 @@ end
|
||||||
---applies custom highlights for component
|
---applies custom highlights for component
|
||||||
function M:apply_highlights(default_highlight)
|
function M:apply_highlights(default_highlight)
|
||||||
if self.options.color_highlight then
|
if self.options.color_highlight then
|
||||||
self.status = highlight.component_format_highlight(self.options.color_highlight) .. self.status
|
local hl_fmt
|
||||||
|
hl_fmt, M.color_fn_cache = highlight.component_format_highlight(self.options.color_highlight)
|
||||||
|
self.status = hl_fmt .. self.status
|
||||||
end
|
end
|
||||||
if type(self.options.separator) ~= 'table' and self.status:find('%%#') then
|
if type(self.options.separator) ~= 'table' and self.status:find('%%#') then
|
||||||
-- Apply default highlight only when we aren't applying trans sep and
|
-- Apply default highlight only when we aren't applying trans sep and
|
||||||
|
@ -119,7 +122,7 @@ function M:apply_separator()
|
||||||
local separator = self.options.separator
|
local separator = self.options.separator
|
||||||
if type(separator) == 'table' then
|
if type(separator) == 'table' then
|
||||||
if self.options.separator[2] == '' then
|
if self.options.separator[2] == '' then
|
||||||
if self.options.self.section < 'lualine_x' then
|
if self.options.self.section < 'x' then
|
||||||
separator = self.options.component_separators.left
|
separator = self.options.component_separators.left
|
||||||
else
|
else
|
||||||
separator = self.options.component_separators.right
|
separator = self.options.component_separators.right
|
||||||
|
@ -159,6 +162,16 @@ function M:strip_separator()
|
||||||
return self.status
|
return self.status
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function M:get_default_hl()
|
||||||
|
if self.options.color_highlight then
|
||||||
|
return highlight.component_format_highlight(self.options.color_highlight)
|
||||||
|
elseif self.default_hl then
|
||||||
|
return self.default_hl
|
||||||
|
else
|
||||||
|
return highlight.format_highlight(self.options.self.section)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- luacheck: push no unused args
|
-- luacheck: push no unused args
|
||||||
---actual function that updates a component. Must be overwritten with component functionality
|
---actual function that updates a component. Must be overwritten with component functionality
|
||||||
function M:update_status(is_focused) end
|
function M:update_status(is_focused) end
|
||||||
|
@ -172,6 +185,7 @@ function M:draw(default_highlight, is_focused)
|
||||||
if self.options.cond ~= nil and self.options.cond() ~= true then
|
if self.options.cond ~= nil and self.options.cond() ~= true then
|
||||||
return self.status
|
return self.status
|
||||||
end
|
end
|
||||||
|
self.default_hl = default_highlight
|
||||||
local status = self:update_status(is_focused)
|
local status = self:update_status(is_focused)
|
||||||
if self.options.fmt then
|
if self.options.fmt then
|
||||||
status = self.options.fmt(status or '')
|
status = self.options.fmt(status or '')
|
||||||
|
|
|
@ -77,11 +77,11 @@ function Buffer:render()
|
||||||
.. line
|
.. line
|
||||||
|
|
||||||
-- apply separators
|
-- apply separators
|
||||||
if self.options.self.section < 'lualine_x' and not self.first then
|
if self.options.self.section < 'x' and not self.first then
|
||||||
local sep_before = self:separator_before()
|
local sep_before = self:separator_before()
|
||||||
line = sep_before .. line
|
line = sep_before .. line
|
||||||
self.len = self.len + vim.fn.strchars(sep_before)
|
self.len = self.len + vim.fn.strchars(sep_before)
|
||||||
elseif self.options.self.section >= 'lualine_x' and not self.last then
|
elseif self.options.self.section >= 'x' and not self.last then
|
||||||
local sep_after = self:separator_after()
|
local sep_after = self:separator_after()
|
||||||
line = line .. sep_after
|
line = line .. sep_after
|
||||||
self.len = self.len + vim.fn.strchars(sep_after)
|
self.len = self.len + vim.fn.strchars(sep_after)
|
||||||
|
|
|
@ -44,20 +44,22 @@ end
|
||||||
function M:init(options)
|
function M:init(options)
|
||||||
M.super.init(self, options)
|
M.super.init(self, options)
|
||||||
default_options.buffers_color = {
|
default_options.buffers_color = {
|
||||||
active = get_hl(options.self.section, true),
|
active = get_hl('lualine_' .. options.self.section, true),
|
||||||
inactive = get_hl(options.self.section, false),
|
inactive = get_hl('lualine_' .. options.self.section, false),
|
||||||
}
|
}
|
||||||
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
|
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
|
||||||
self.highlights = {
|
self.highlights = {
|
||||||
active = highlight.create_component_highlight_group(
|
active = highlight.create_component_highlight_group(
|
||||||
self.options.buffers_color.active,
|
self.options.buffers_color.active,
|
||||||
'buffers_active',
|
'buffers_active',
|
||||||
self.options
|
self.options,
|
||||||
|
false
|
||||||
),
|
),
|
||||||
inactive = highlight.create_component_highlight_group(
|
inactive = highlight.create_component_highlight_group(
|
||||||
self.options.buffers_color.inactive,
|
self.options.buffers_color.inactive,
|
||||||
'buffers_active',
|
'buffers_inactive',
|
||||||
self.options
|
self.options,
|
||||||
|
false
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
@ -112,7 +114,7 @@ function M:update_status()
|
||||||
if current == -2 then
|
if current == -2 then
|
||||||
local b = Buffer { bufnr = vim.api.nvim_get_current_buf(), options = self.options, highlights = self.highlights }
|
local b = Buffer { bufnr = vim.api.nvim_get_current_buf(), options = self.options, highlights = self.highlights }
|
||||||
b.current = true
|
b.current = true
|
||||||
if self.options.self.section < 'lualine_x' then
|
if self.options.self.section < 'x' then
|
||||||
b.last = true
|
b.last = true
|
||||||
if #buffers > 0 then
|
if #buffers > 0 then
|
||||||
buffers[#buffers].last = nil
|
buffers[#buffers].last = nil
|
||||||
|
|
|
@ -33,22 +33,26 @@ function M:init(options)
|
||||||
error = modules.highlight.create_component_highlight_group(
|
error = modules.highlight.create_component_highlight_group(
|
||||||
self.options.diagnostics_color.error,
|
self.options.diagnostics_color.error,
|
||||||
'diagnostics_error',
|
'diagnostics_error',
|
||||||
self.options
|
self.options,
|
||||||
|
false
|
||||||
),
|
),
|
||||||
warn = modules.highlight.create_component_highlight_group(
|
warn = modules.highlight.create_component_highlight_group(
|
||||||
self.options.diagnostics_color.warn,
|
self.options.diagnostics_color.warn,
|
||||||
'diagnostics_warn',
|
'diagnostics_warn',
|
||||||
self.options
|
self.options,
|
||||||
|
false
|
||||||
),
|
),
|
||||||
info = modules.highlight.create_component_highlight_group(
|
info = modules.highlight.create_component_highlight_group(
|
||||||
self.options.diagnostics_color.info,
|
self.options.diagnostics_color.info,
|
||||||
'diagnostics_info',
|
'diagnostics_info',
|
||||||
self.options
|
self.options,
|
||||||
|
false
|
||||||
),
|
),
|
||||||
hint = modules.highlight.create_component_highlight_group(
|
hint = modules.highlight.create_component_highlight_group(
|
||||||
self.options.diagnostics_color.hint,
|
self.options.diagnostics_color.hint,
|
||||||
'diagnostics_hint',
|
'diagnostics_hint',
|
||||||
self.options
|
self.options,
|
||||||
|
false
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -47,17 +47,20 @@ function M:init(options)
|
||||||
added = modules.highlight.create_component_highlight_group(
|
added = modules.highlight.create_component_highlight_group(
|
||||||
self.options.diff_color.added,
|
self.options.diff_color.added,
|
||||||
'diff_added',
|
'diff_added',
|
||||||
self.options
|
self.options,
|
||||||
|
false
|
||||||
),
|
),
|
||||||
modified = modules.highlight.create_component_highlight_group(
|
modified = modules.highlight.create_component_highlight_group(
|
||||||
self.options.diff_color.modified,
|
self.options.diff_color.modified,
|
||||||
'diff_modified',
|
'diff_modified',
|
||||||
self.options
|
self.options,
|
||||||
|
false
|
||||||
),
|
),
|
||||||
removed = modules.highlight.create_component_highlight_group(
|
removed = modules.highlight.create_component_highlight_group(
|
||||||
self.options.diff_color.removed,
|
self.options.diff_color.removed,
|
||||||
'diff_removed',
|
'diff_removed',
|
||||||
self.options
|
self.options,
|
||||||
|
false
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,6 +22,7 @@ function M.update_status()
|
||||||
return modules.utils.stl_escape(ft)
|
return modules.utils.stl_escape(ft)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local icon_hl_cache = {}
|
||||||
function M:apply_icon()
|
function M:apply_icon()
|
||||||
if not self.options.icons_enabled then
|
if not self.options.icons_enabled then
|
||||||
return
|
return
|
||||||
|
@ -36,14 +37,16 @@ function M:apply_icon()
|
||||||
|
|
||||||
if icon and self.options.colored then
|
if icon and self.options.colored then
|
||||||
local highlight_color = modules.utils.extract_highlight_colors(icon_highlight_group, 'fg')
|
local highlight_color = modules.utils.extract_highlight_colors(icon_highlight_group, 'fg')
|
||||||
local default_highlight = modules.highlight.format_highlight(self.options.self.section)
|
local default_highlight = self:get_default_hl()
|
||||||
local icon_highlight = self.options.self.section .. '_' .. icon_highlight_group
|
local icon_highlight = icon_hl_cache[highlight_color]
|
||||||
if not modules.highlight.highlight_exists(icon_highlight .. '_normal') then
|
if not icon_highlight or not modules.highlight.highlight_exists(icon_highlight.name .. '_normal') then
|
||||||
icon_highlight = modules.highlight.create_component_highlight_group(
|
icon_highlight = modules.highlight.create_component_highlight_group(
|
||||||
{ fg = highlight_color },
|
{ fg = highlight_color },
|
||||||
icon_highlight_group,
|
icon_highlight_group,
|
||||||
self.options
|
self.options,
|
||||||
|
false
|
||||||
)
|
)
|
||||||
|
icon_hl_cache[highlight_color] = icon_highlight
|
||||||
end
|
end
|
||||||
|
|
||||||
icon = modules.highlight.component_format_highlight(icon_highlight) .. icon .. default_highlight
|
icon = modules.highlight.component_format_highlight(icon_highlight) .. icon .. default_highlight
|
||||||
|
|
|
@ -35,8 +35,8 @@ end
|
||||||
function M:init(options)
|
function M:init(options)
|
||||||
M.super.init(self, options)
|
M.super.init(self, options)
|
||||||
default_options.tabs_color = {
|
default_options.tabs_color = {
|
||||||
active = get_hl(options.self.section, true),
|
active = get_hl('lualine_' .. options.self.section, true),
|
||||||
inactive = get_hl(options.self.section, false),
|
inactive = get_hl('lualine_' .. options.self.section, false),
|
||||||
}
|
}
|
||||||
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
|
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
|
||||||
-- stylua: ignore
|
-- stylua: ignore
|
||||||
|
@ -44,12 +44,14 @@ function M:init(options)
|
||||||
active = highlight.create_component_highlight_group(
|
active = highlight.create_component_highlight_group(
|
||||||
self.options.tabs_color.active,
|
self.options.tabs_color.active,
|
||||||
'tabs_active',
|
'tabs_active',
|
||||||
self.options
|
self.options,
|
||||||
|
false
|
||||||
),
|
),
|
||||||
inactive = highlight.create_component_highlight_group(
|
inactive = highlight.create_component_highlight_group(
|
||||||
self.options.tabs_color.inactive,
|
self.options.tabs_color.inactive,
|
||||||
'tabs_active',
|
'tabs_inactive',
|
||||||
self.options
|
self.options,
|
||||||
|
false
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -70,11 +70,11 @@ function Tab:render()
|
||||||
.. line
|
.. line
|
||||||
|
|
||||||
-- apply separators
|
-- apply separators
|
||||||
if self.options.self.section < 'lualine_x' and not self.first then
|
if self.options.self.section < 'x' and not self.first then
|
||||||
local sep_before = self:separator_before()
|
local sep_before = self:separator_before()
|
||||||
line = sep_before .. line
|
line = sep_before .. line
|
||||||
self.len = self.len + vim.fn.strchars(sep_before)
|
self.len = self.len + vim.fn.strchars(sep_before)
|
||||||
elseif self.options.self.section >= 'lualine_x' and not self.last then
|
elseif self.options.self.section >= 'x' and not self.last then
|
||||||
local sep_after = self:separator_after()
|
local sep_after = self:separator_after()
|
||||||
line = line .. sep_after
|
line = line .. sep_after
|
||||||
self.len = self.len + vim.fn.strchars(sep_after)
|
self.len = self.len + vim.fn.strchars(sep_after)
|
||||||
|
|
|
@ -10,6 +10,7 @@ local modules = lualine_require.lazy_require {
|
||||||
|
|
||||||
local section_highlight_map = { x = 'c', y = 'b', z = 'a' }
|
local section_highlight_map = { x = 'c', y = 'b', z = 'a' }
|
||||||
local active_theme = nil
|
local active_theme = nil
|
||||||
|
local theme_hls = {}
|
||||||
local create_cterm_colors = false
|
local create_cterm_colors = false
|
||||||
|
|
||||||
-- table to store the highlight names created by lualine
|
-- table to store the highlight names created by lualine
|
||||||
|
@ -44,14 +45,17 @@ end
|
||||||
local function clear_highlights()
|
local function clear_highlights()
|
||||||
for highlight_name, _ in pairs(loaded_highlights) do
|
for highlight_name, _ in pairs(loaded_highlights) do
|
||||||
vim.cmd('highlight clear ' .. highlight_name)
|
vim.cmd('highlight clear ' .. highlight_name)
|
||||||
loaded_highlights[highlight_name] = nil
|
|
||||||
end
|
end
|
||||||
|
loaded_highlights = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
---converts cterm, color_name type colors to #rrggbb format
|
---converts cterm, color_name type colors to #rrggbb format
|
||||||
---@param color string|number
|
---@param color string|number
|
||||||
---@return string
|
---@return string
|
||||||
local function sanitize_color(color)
|
local function sanitize_color(color)
|
||||||
|
if color == nil or color == '' then
|
||||||
|
return 'None'
|
||||||
|
end
|
||||||
if type(color) == 'string' then
|
if type(color) == 'string' then
|
||||||
if color:sub(1, 1) == '#' then
|
if color:sub(1, 1) == '#' then
|
||||||
return color
|
return color
|
||||||
|
@ -65,6 +69,28 @@ local function sanitize_color(color)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function M.get_lualine_hl(name)
|
||||||
|
local hl = loaded_highlights[name]
|
||||||
|
if hl and not hl.empty then
|
||||||
|
if hl.link then
|
||||||
|
return modules.utils.extract_highlight_colors(hl.link)
|
||||||
|
end
|
||||||
|
local hl_def = {
|
||||||
|
fg = hl.fg ~= 'None' and vim.deepcopy(hl.fg),
|
||||||
|
bg = hl.bg ~= 'None' and vim.deepcopy(hl.bg),
|
||||||
|
}
|
||||||
|
if hl.gui then
|
||||||
|
for _, flag in ipairs(vim.split(hl.gui, ',')) do
|
||||||
|
if flag ~= 'None' then
|
||||||
|
hl_def[flag] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return hl_def
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--- Define a hl_group
|
--- Define a hl_group
|
||||||
---@param name string
|
---@param name string
|
||||||
---@param foreground string|number: color
|
---@param foreground string|number: color
|
||||||
|
@ -74,46 +100,113 @@ end
|
||||||
function M.highlight(name, foreground, background, gui, link)
|
function M.highlight(name, foreground, background, gui, link)
|
||||||
local command = { 'highlight!' }
|
local command = { 'highlight!' }
|
||||||
if link and #link > 0 then
|
if link and #link > 0 then
|
||||||
|
if loaded_highlights[name] and loaded_highlights[name].link == link then
|
||||||
|
return
|
||||||
|
end
|
||||||
vim.list_extend(command, { 'link', name, link })
|
vim.list_extend(command, { 'link', name, link })
|
||||||
else
|
else
|
||||||
foreground = sanitize_color(foreground)
|
foreground = sanitize_color(foreground)
|
||||||
background = sanitize_color(background)
|
background = sanitize_color(background)
|
||||||
|
gui = (gui ~= nil and gui ~= '') and gui or 'None'
|
||||||
|
if
|
||||||
|
loaded_highlights[name]
|
||||||
|
and loaded_highlights[name].fg == foreground
|
||||||
|
and loaded_highlights[name].bg == background
|
||||||
|
and loaded_highlights[name].gui == gui
|
||||||
|
then
|
||||||
|
return -- color is already defined why are we doing this anyway ?
|
||||||
|
end
|
||||||
table.insert(command, name)
|
table.insert(command, name)
|
||||||
if foreground and foreground ~= 'None' then
|
table.insert(command, 'guifg=' .. foreground)
|
||||||
table.insert(command, 'guifg=' .. foreground)
|
table.insert(command, 'guibg=' .. background)
|
||||||
if create_cterm_colors then
|
table.insert(command, 'gui=' .. gui)
|
||||||
table.insert(command, 'ctermfg=' .. modules.color_utils.rgb2cterm(foreground))
|
if create_cterm_colors then
|
||||||
end
|
table.insert(command, 'ctermfg=' .. modules.color_utils.rgb2cterm(foreground))
|
||||||
end
|
table.insert(command, 'ctermbg=' .. modules.color_utils.rgb2cterm(background))
|
||||||
if background and background ~= 'None' then
|
|
||||||
table.insert(command, 'guibg=' .. background)
|
|
||||||
if create_cterm_colors then
|
|
||||||
table.insert(command, 'ctermbg=' .. modules.color_utils.rgb2cterm(background))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if gui then
|
|
||||||
table.insert(command, 'cterm=' .. gui)
|
table.insert(command, 'cterm=' .. gui)
|
||||||
table.insert(command, 'gui=' .. gui)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
vim.cmd(table.concat(command, ' '))
|
vim.cmd(table.concat(command, ' '))
|
||||||
loaded_highlights[name] = true
|
|
||||||
|
-- update attached hl groups
|
||||||
|
local old_hl_def = loaded_highlights[name]
|
||||||
|
if old_hl_def and next(old_hl_def.attached) then
|
||||||
|
-- Update attached hl groups as they announced to depend on hl_group 'name'
|
||||||
|
-- 'hl' being in 'name'a attached table means 'hl'
|
||||||
|
-- depends of 'name'.
|
||||||
|
-- 'hl' key in attached table will contain a table that
|
||||||
|
-- defines the reletaion between 'hl' & 'name'.
|
||||||
|
-- name.attached.hl = { bg = 'fg' } means
|
||||||
|
-- hl's fg is same as 'names' bg . So 'hl's fg should
|
||||||
|
-- be updated when ever 'name' changes it's 'bg'
|
||||||
|
local bg_changed = old_hl_def.bg ~= background
|
||||||
|
local fg_changed = old_hl_def.bg ~= foreground
|
||||||
|
local gui_changed = old_hl_def.gui ~= gui
|
||||||
|
for attach_name, attach_desc in pairs(old_hl_def.attached) do
|
||||||
|
if bg_changed and attach_desc.bg and loaded_highlights[attach_name] then
|
||||||
|
M.highlight(
|
||||||
|
attach_name,
|
||||||
|
attach_desc.bg == 'fg' and background or loaded_highlights[attach_name].fg,
|
||||||
|
attach_desc.bg == 'bg' and background or loaded_highlights[attach_name].bg,
|
||||||
|
loaded_highlights[attach_name].gui,
|
||||||
|
loaded_highlights[attach_name].link
|
||||||
|
)
|
||||||
|
end
|
||||||
|
if fg_changed and attach_desc.fg and loaded_highlights[attach_name] then
|
||||||
|
M.highlight(
|
||||||
|
attach_name,
|
||||||
|
attach_desc.fg == 'fg' and foreground or loaded_highlights[attach_name].fg,
|
||||||
|
attach_desc.fg == 'bg' and foreground or loaded_highlights[attach_name].bg,
|
||||||
|
loaded_highlights[attach_name].gui,
|
||||||
|
loaded_highlights[attach_name].link
|
||||||
|
)
|
||||||
|
end
|
||||||
|
if gui_changed and attach_desc.gui and loaded_highlights[attach_name] then
|
||||||
|
M.highlight(
|
||||||
|
attach_name,
|
||||||
|
loaded_highlights[attach_name].fg,
|
||||||
|
loaded_highlights[attach_name].bg,
|
||||||
|
gui,
|
||||||
|
loaded_highlights[attach_name].link
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- store current hl state
|
||||||
|
loaded_highlights[name] = {
|
||||||
|
fg = foreground,
|
||||||
|
bg = background,
|
||||||
|
gui = gui,
|
||||||
|
link = link,
|
||||||
|
attached = old_hl_def and old_hl_def.attached or {},
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Attach an hl to another so attachee auto updated on change to hl it's attached too.
|
||||||
|
---@param provider string the hl receiver is getting attached to
|
||||||
|
---@param receiver string the hl that will be auto updated upon change to provider
|
||||||
|
---@param provider_el_type string (fg/bg) what element receiver relates to of provider
|
||||||
|
---@param receiver_el_type string (fg/bg) what element provider relates to of receiver
|
||||||
|
local function attach_hl(provider, receiver, provider_el_type, receiver_el_type)
|
||||||
|
if loaded_highlights[provider] == nil then
|
||||||
|
loaded_highlights[provider] = { empty = true, attached = {} }
|
||||||
|
end
|
||||||
|
loaded_highlights[provider].attached[receiver] = { [provider_el_type] = receiver_el_type }
|
||||||
|
end
|
||||||
---define hl_groups for a theme
|
---define hl_groups for a theme
|
||||||
---@param theme table
|
---@param theme table
|
||||||
function M.create_highlight_groups(theme)
|
function M.create_highlight_groups(theme)
|
||||||
clear_highlights()
|
clear_highlights()
|
||||||
active_theme = theme
|
active_theme = theme
|
||||||
|
theme_hls = {}
|
||||||
|
local psudo_options = { self = { section = 'a' } }
|
||||||
create_cterm_colors = not vim.go.termguicolors
|
create_cterm_colors = not vim.go.termguicolors
|
||||||
for mode, sections in pairs(theme) do
|
for mode, sections in pairs(theme) do
|
||||||
|
theme_hls[mode] = {}
|
||||||
for section, color in pairs(sections) do
|
for section, color in pairs(sections) do
|
||||||
local highlight_group_name = { 'lualine', section, mode }
|
local hl_tag = mode
|
||||||
if type(color) == 'string' then -- link to a highlight group
|
psudo_options.self.section = section
|
||||||
M.highlight(table.concat(highlight_group_name, '_'), nil, nil, nil, color)
|
theme_hls[mode][section] = M.create_component_highlight_group(color, hl_tag, psudo_options, true)
|
||||||
else -- Define a new highlight
|
|
||||||
M.highlight(table.concat(highlight_group_name, '_'), color.fg, color.bg, color.gui, nil)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -121,7 +214,7 @@ end
|
||||||
---@description: adds '_mode' at end of highlight_group
|
---@description: adds '_mode' at end of highlight_group
|
||||||
---@param highlight_group string name of highlight group
|
---@param highlight_group string name of highlight group
|
||||||
---@return string highlight group name with mode
|
---@return string highlight group name with mode
|
||||||
function M.append_mode(highlight_group, is_focused)
|
local function append_mode(highlight_group, is_focused)
|
||||||
if is_focused == nil then
|
if is_focused == nil then
|
||||||
is_focused = modules.utils.is_focused()
|
is_focused = modules.utils.is_focused()
|
||||||
end
|
end
|
||||||
|
@ -134,27 +227,67 @@ end
|
||||||
|
|
||||||
-- Helper function for create component highlight
|
-- Helper function for create component highlight
|
||||||
---Handles fall back of colors when creating highlight group
|
---Handles fall back of colors when creating highlight group
|
||||||
|
---@param hl_name string name of highlight that we are setting default values for
|
||||||
|
---@param mode string mode which default component color should be given.
|
||||||
|
---@param section string the lualine section component is in.
|
||||||
---@param color table color passed for creating component highlight
|
---@param color table color passed for creating component highlight
|
||||||
---@param options_color table color set by color option for component
|
---@param options table Options table of component this is first fall back
|
||||||
--- this is first fall back
|
local function get_default_component_color(hl_name, mode, section, color, options)
|
||||||
---@param default_color table colors et in theme this is 2nd fall back
|
local default_theme_color
|
||||||
---@param kind string fg/bg
|
if active_theme[mode] and active_theme[mode][section] then
|
||||||
local function get_default_component_color(color, options_color, default_color, kind)
|
default_theme_color = active_theme[mode][section]
|
||||||
if color[kind] then
|
elseif section >= 'c' and active_theme[mode] and active_theme[mode][section_highlight_map[section]] then
|
||||||
return color[kind]
|
default_theme_color = active_theme[mode][section_highlight_map[section]]
|
||||||
|
elseif section >= 'c' and active_theme.normal[section_highlight_map[section]] then
|
||||||
|
default_theme_color = active_theme.normal[section_highlight_map[section]]
|
||||||
|
else
|
||||||
|
default_theme_color = active_theme.normal[section]
|
||||||
end
|
end
|
||||||
if options_color then
|
|
||||||
if type(options_color) == 'table' and options_color[kind] then
|
local ret = { fg = color.fg, bg = color.bg, gui = color.gui }
|
||||||
return options_color[kind]
|
if ret.fg and ret.bg then
|
||||||
elseif type(options_color) == 'string' then
|
return ret
|
||||||
return modules.utils.extract_highlight_colors(options_color, kind)
|
end
|
||||||
|
|
||||||
|
local function apply_default(def_color, def_name)
|
||||||
|
if type(def_color) == 'function' and loaded_highlights[def_name] and not loaded_highlights[def_name].empty then
|
||||||
|
if loaded_highlights[def_name].link then
|
||||||
|
def_color = loaded_highlights[def_name].link
|
||||||
|
else
|
||||||
|
def_color = loaded_highlights[def_name]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if type(def_color) == 'function' then
|
||||||
|
def_color = def_color { section = section }
|
||||||
|
end
|
||||||
|
if type(def_color) == 'string' then
|
||||||
|
def_color = modules.utils.extract_highlight_colors(def_color)
|
||||||
|
end
|
||||||
|
if type(def_color) == 'table' then
|
||||||
|
if not ret.fg then
|
||||||
|
ret.fg = def_color.fg
|
||||||
|
attach_hl(def_name, hl_name, 'fg', 'fg')
|
||||||
|
end
|
||||||
|
if not ret.bg then
|
||||||
|
ret.bg = def_color.bg
|
||||||
|
attach_hl(def_name, hl_name, 'bg', 'bg')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if type(default_color) == 'table' then
|
|
||||||
return default_color[kind]
|
if
|
||||||
elseif type(default_color) == 'string' then
|
options.color
|
||||||
return modules.utils.extract_highlight_colors(default_color, kind)
|
and options.color_highlight
|
||||||
|
and options.color_highlight.name
|
||||||
|
and options.color_highlight.name .. '_' .. mode ~= hl_name
|
||||||
|
then
|
||||||
|
apply_default(options.color, options.color_highlight.name .. '_' .. mode)
|
||||||
|
else
|
||||||
|
apply_default(default_theme_color, string.format('lualine_%s_%s', section, mode))
|
||||||
end
|
end
|
||||||
|
ret.fg = sanitize_color(ret.fg)
|
||||||
|
ret.bg = sanitize_color(ret.bg)
|
||||||
|
return ret
|
||||||
end
|
end
|
||||||
|
|
||||||
---Create highlight group with fg bg and gui from theme
|
---Create highlight group with fg bg and gui from theme
|
||||||
|
@ -164,31 +297,50 @@ end
|
||||||
---@param highlight_tag string is unique tag for highlight group
|
---@param highlight_tag string is unique tag for highlight group
|
||||||
---returns the name of highlight group
|
---returns the name of highlight group
|
||||||
---@param options table is parameter of component.init() function
|
---@param options table is parameter of component.init() function
|
||||||
---@return string unique name that can be used by component_format_highlight
|
---@return table that can be used by component_format_highlight
|
||||||
--- to retrieve highlight group
|
--- to retrieve highlight group
|
||||||
function M.create_component_highlight_group(color, highlight_tag, options)
|
function M.create_component_highlight_group(color, highlight_tag, options, apply_no_default)
|
||||||
|
local section = options.self.section
|
||||||
|
if section > 'c' and not active_theme.normal[section] then
|
||||||
|
section = section_highlight_map[section]
|
||||||
|
end
|
||||||
|
|
||||||
local tag_id = 0
|
local tag_id = 0
|
||||||
while
|
while
|
||||||
M.highlight_exists(table.concat({ 'lualine', highlight_tag, 'no_mode' }, '_'))
|
M.highlight_exists(table.concat({ 'lualine', section, highlight_tag }, '_'))
|
||||||
or (
|
or (section and M.highlight_exists(table.concat({ 'lualine', section, highlight_tag, 'normal' }, '_')))
|
||||||
options.self.section
|
|
||||||
and M.highlight_exists(table.concat({ options.self.section, highlight_tag, 'normal' }, '_'))
|
|
||||||
)
|
|
||||||
do
|
do
|
||||||
highlight_tag = highlight_tag .. '_' .. tostring(tag_id)
|
highlight_tag = highlight_tag .. '_' .. tostring(tag_id)
|
||||||
tag_id = tag_id + 1
|
tag_id = tag_id + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
if type(color) == 'string' then
|
if type(color) == 'string' then
|
||||||
local highlight_group_name = table.concat({ 'lualine', highlight_tag, 'no_mode' }, '_')
|
local highlight_group_name = table.concat({ 'lualine', section, highlight_tag }, '_')
|
||||||
M.highlight(highlight_group_name, nil, nil, nil, color) -- l8nk to group
|
M.highlight(highlight_group_name, nil, nil, nil, color) -- l8nk to group
|
||||||
return highlight_group_name
|
return {
|
||||||
|
name = highlight_group_name,
|
||||||
|
fn = nil,
|
||||||
|
no_mode = true,
|
||||||
|
link = true,
|
||||||
|
section = section,
|
||||||
|
options = options,
|
||||||
|
no_default = apply_no_default,
|
||||||
|
}
|
||||||
end
|
end
|
||||||
if color.bg and color.fg then
|
|
||||||
|
if type(color) ~= 'function' and (apply_no_default or (color.bg and color.fg)) then
|
||||||
-- When bg and fg are both present we donn't need to set highlighs for
|
-- When bg and fg are both present we donn't need to set highlighs for
|
||||||
-- each mode as they will surely look the same. So we can work without options
|
-- each mode as they will surely look the same. So we can work without options
|
||||||
local highlight_group_name = table.concat({ 'lualine', highlight_tag, 'no_mode' }, '_')
|
local highlight_group_name = table.concat({ 'lualine', section, highlight_tag }, '_')
|
||||||
M.highlight(highlight_group_name, color.fg, color.bg, color.gui, nil)
|
M.highlight(highlight_group_name, color.fg, color.bg, color.gui, nil)
|
||||||
return highlight_group_name
|
return {
|
||||||
|
name = highlight_group_name,
|
||||||
|
fn = nil,
|
||||||
|
no_mode = true,
|
||||||
|
section = section,
|
||||||
|
options = options,
|
||||||
|
no_default = apply_no_default,
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
local modes = {
|
local modes = {
|
||||||
|
@ -200,64 +352,87 @@ function M.create_component_highlight_group(color, highlight_tag, options)
|
||||||
'terminal',
|
'terminal',
|
||||||
'inactive',
|
'inactive',
|
||||||
}
|
}
|
||||||
local normal_hl
|
|
||||||
-- convert lualine_a -> a before setting section
|
|
||||||
local section = options.self.section:match('lualine_(.*)')
|
|
||||||
if section > 'c' and not active_theme.normal[section] then
|
|
||||||
section = section_highlight_map[section]
|
|
||||||
end
|
|
||||||
for _, mode in ipairs(modes) do
|
for _, mode in ipairs(modes) do
|
||||||
local highlight_group_name = { options.self.section, highlight_tag, mode }
|
local hl_name = table.concat({ 'lualine', section, highlight_tag, mode }, '_')
|
||||||
local default_color_table = active_theme[mode] and active_theme[mode][section] or active_theme.normal[section]
|
local cl = color
|
||||||
local bg = get_default_component_color(color, options.color, default_color_table, 'bg')
|
if type(color) == 'function' then
|
||||||
local fg = get_default_component_color(color, options.color, default_color_table, 'fg')
|
cl = color { section = section } or {}
|
||||||
-- Check if it's same as normal mode if it is no need to create aditional highlight
|
|
||||||
if mode ~= 'normal' then
|
|
||||||
if bg ~= normal_hl.bg or fg ~= normal_hl.fg then
|
|
||||||
M.highlight(table.concat(highlight_group_name, '_'), fg, bg, color.gui, nil)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
normal_hl = { bg = bg, fg = fg }
|
|
||||||
M.highlight(table.concat(highlight_group_name, '_'), fg, bg, color.gui, nil)
|
|
||||||
end
|
end
|
||||||
|
if type(cl) == 'string' then
|
||||||
|
cl = { link = cl }
|
||||||
|
else
|
||||||
|
cl = get_default_component_color(hl_name, mode, section, cl, options)
|
||||||
|
end
|
||||||
|
M.highlight(hl_name, cl.fg, cl.bg, cl.gui, cl.link)
|
||||||
end
|
end
|
||||||
return options.self.section .. '_' .. highlight_tag
|
return {
|
||||||
|
name = table.concat({ 'lualine', section, highlight_tag }, '_'),
|
||||||
|
fn = type(color) == 'function' and color,
|
||||||
|
no_mode = false,
|
||||||
|
link = false,
|
||||||
|
section = section,
|
||||||
|
options = options,
|
||||||
|
no_default = apply_no_default,
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
---@description: retrieve highlight_groups for components
|
---@description: retrieve highlight_groups for components
|
||||||
---@param highlight_name string highlight group name without mode
|
---@param highlight table return value of create_component_highlight_group
|
||||||
--- return value of create_component_highlight_group is to be passed in
|
--- return value of create_component_highlight_group is to be passed in
|
||||||
--- this parameter to receive highlight that was created
|
--- this parameter to receive highlight that was created
|
||||||
---@return string formatted highlight group name
|
---@return string formatted highlight group name
|
||||||
function M.component_format_highlight(highlight_name)
|
function M.component_format_highlight(highlight, is_focused)
|
||||||
local highlight_group = highlight_name
|
if not highlight.fn then
|
||||||
if highlight_name:find('no_mode') == #highlight_name - #'no_mode' + 1 then
|
local highlight_group = highlight.name
|
||||||
return '%#' .. highlight_group .. '#'
|
if highlight.no_mode then
|
||||||
end
|
return '%#' .. highlight_group .. '#'
|
||||||
highlight_group = M.append_mode(highlight_group)
|
end
|
||||||
if M.highlight_exists(highlight_group) then
|
highlight_group = append_mode(highlight_group, is_focused)
|
||||||
return '%#' .. highlight_group .. '#'
|
return '%#' .. highlight_group .. '#'
|
||||||
else
|
else
|
||||||
return '%#' .. highlight_name .. '_normal#'
|
local color = highlight.fn { section = highlight.section } or {}
|
||||||
|
local hl_name = highlight.name
|
||||||
|
if type(color) == 'string' then
|
||||||
|
M.highlight(hl_name, nil, nil, nil, color)
|
||||||
|
return '%#' .. hl_name .. '#'
|
||||||
|
elseif type(color) == 'table' then
|
||||||
|
if not highlight.no_default and not (color.fg and color.bg) then
|
||||||
|
hl_name = append_mode(highlight.name, is_focused)
|
||||||
|
color = get_default_component_color(
|
||||||
|
hl_name,
|
||||||
|
append_mode(''):sub(2),
|
||||||
|
highlight.section,
|
||||||
|
color,
|
||||||
|
highlight.options
|
||||||
|
)
|
||||||
|
end
|
||||||
|
M.highlight(hl_name, color.fg, color.bg, color.gui, color.link)
|
||||||
|
return '%#' .. hl_name .. '#', color
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---@description: retrieve highlight_groups for section
|
---@description: retrieve highlight_groups for section
|
||||||
---@param highlight_group string highlight group name without mode
|
---@param section string highlight group name without mode
|
||||||
--- return value of create_component_highlight_group is to be passed in
|
--- return value of create_component_highlight_group is to be passed in
|
||||||
--- this parameter to receive highlight that was created
|
--- this parameter to receive highlight that was created
|
||||||
---@param is_focused boolean
|
---@param is_focused boolean
|
||||||
---@return string formatted highlight group name
|
---@return string formatted highlight group name
|
||||||
function M.format_highlight(highlight_group, is_focused)
|
function M.format_highlight(section, is_focused)
|
||||||
local highlight_name = M.append_mode(highlight_group, is_focused)
|
local mode = append_mode('', is_focused):sub(2)
|
||||||
if highlight_group > 'lualine_c' and not M.highlight_exists(highlight_name) then
|
local ret = ''
|
||||||
highlight_group = 'lualine_' .. section_highlight_map[highlight_group:match('lualine_(.)')]
|
|
||||||
highlight_name = M.append_mode(highlight_group, is_focused)
|
if theme_hls[mode] and theme_hls[mode][section] then
|
||||||
|
ret = M.component_format_highlight(theme_hls[mode][section], is_focused)
|
||||||
|
elseif theme_hls[mode] and section > 'c' and theme_hls[mode][section_highlight_map[section]] then
|
||||||
|
ret = M.component_format_highlight(theme_hls[mode][section_highlight_map[section]], is_focused)
|
||||||
|
elseif theme_hls['normal'] and theme_hls['normal'][section] then
|
||||||
|
ret = M.component_format_highlight(theme_hls['normal'][section], is_focused)
|
||||||
|
elseif theme_hls['normal'] and section > 'c' and theme_hls['normal'][section_highlight_map[section]] then
|
||||||
|
ret = M.component_format_highlight(theme_hls['normal'][section_highlight_map[section]], is_focused)
|
||||||
end
|
end
|
||||||
if M.highlight_exists(highlight_name) then
|
|
||||||
return '%#' .. highlight_name .. '#'
|
return ret
|
||||||
end
|
|
||||||
return '%#' .. highlight_group .. '_normal#'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
---@description : Provides transitional highlights for section separators.
|
---@description : Provides transitional highlights for section separators.
|
||||||
|
@ -286,6 +461,8 @@ function M.get_transitional_highlights(left_hl, right_hl)
|
||||||
return nil -- Separator won't be visible anyway
|
return nil -- Separator won't be visible anyway
|
||||||
end
|
end
|
||||||
M.highlight(highlight_name, fg, bg, nil)
|
M.highlight(highlight_name, fg, bg, nil)
|
||||||
|
attach_hl(left_hl, highlight_name, 'bg', 'fg')
|
||||||
|
attach_hl(right_hl, highlight_name, 'bg', 'bg')
|
||||||
end
|
end
|
||||||
return '%#' .. highlight_name .. '#'
|
return '%#' .. highlight_name .. '#'
|
||||||
end
|
end
|
||||||
|
|
|
@ -91,7 +91,7 @@ component type '%s' isn't recognised. Check if spelling is correct.]],
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Shows notice about invalid types passed as component
|
--- Shows notice about invalid types passed as component
|
||||||
--- @param index number the index of component jn section table
|
--- @param index number the index of component in section table
|
||||||
--- @param component table containing component elements
|
--- @param component table containing component elements
|
||||||
--- return bool whether check passed or not
|
--- return bool whether check passed or not
|
||||||
local function is_valid_component_type(index, component)
|
local function is_valid_component_type(index, component)
|
||||||
|
@ -141,7 +141,7 @@ local function load_sections(sections, options)
|
||||||
end
|
end
|
||||||
if is_valid_component_type(index, component) then
|
if is_valid_component_type(index, component) then
|
||||||
component.self = {}
|
component.self = {}
|
||||||
component.self.section = section_name
|
component.self.section = section_name:match('lualine_(.*)')
|
||||||
-- apply default args
|
-- apply default args
|
||||||
component = vim.tbl_extend('keep', component, options)
|
component = vim.tbl_extend('keep', component, options)
|
||||||
section[index] = component_loader(component)
|
section[index] = component_loader(component)
|
||||||
|
|
|
@ -15,7 +15,7 @@ local highlight = require('lualine.highlight')
|
||||||
---@return string formated string for a section
|
---@return string formated string for a section
|
||||||
--TODO Clean this up this does lots of messy stuff.
|
--TODO Clean this up this does lots of messy stuff.
|
||||||
function M.draw_section(section, section_name, is_focused)
|
function M.draw_section(section, section_name, is_focused)
|
||||||
local highlight_name = highlight.format_highlight('lualine_' .. section_name, is_focused)
|
local highlight_name = highlight.format_highlight(section_name, is_focused)
|
||||||
|
|
||||||
local status = {}
|
local status = {}
|
||||||
for _, component in pairs(section) do
|
for _, component in pairs(section) do
|
||||||
|
@ -26,6 +26,8 @@ function M.draw_section(section, section_name, is_focused)
|
||||||
table.insert(status, component:draw(highlight_name, is_focused))
|
table.insert(status, component:draw(highlight_name, is_focused))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local section_color = utils.extract_highlight_colors(string.match(highlight_name, '%%#(.*)#'))
|
||||||
|
|
||||||
-- Flags required for knowing when to remove component separator
|
-- Flags required for knowing when to remove component separator
|
||||||
local strip_next_component = false
|
local strip_next_component = false
|
||||||
local last_component_found = false
|
local last_component_found = false
|
||||||
|
@ -60,8 +62,18 @@ function M.draw_section(section, section_name, is_focused)
|
||||||
end
|
end
|
||||||
-- Remove component separator when color option is used to color background
|
-- Remove component separator when color option is used to color background
|
||||||
if
|
if
|
||||||
(type(section[component_no].options.color) == 'table' and section[component_no].options.color.bg)
|
(
|
||||||
|
type(section[component_no].options.color) == 'table'
|
||||||
|
and section[component_no].options.color.bg
|
||||||
|
and section[component_no].options.color.bg ~= section_color.bg
|
||||||
|
)
|
||||||
or type(section[component_no].options.color) == 'string'
|
or type(section[component_no].options.color) == 'string'
|
||||||
|
or (
|
||||||
|
type(section[component_no].options.color) == 'function'
|
||||||
|
and section[component_no].color_fn_cache
|
||||||
|
and section[component_no].color_fn_cache.bg
|
||||||
|
and section[component_no].color_fn_cache.bg ~= section_color.bg
|
||||||
|
)
|
||||||
then
|
then
|
||||||
strip_next_component = true
|
strip_next_component = true
|
||||||
status[component_no] = section[component_no]:strip_separator()
|
status[component_no] = section[component_no]:strip_separator()
|
||||||
|
|
|
@ -9,17 +9,20 @@ local M = {}
|
||||||
---@return table|string returns #rrggbb formated color when scope is specified
|
---@return table|string returns #rrggbb formated color when scope is specified
|
||||||
---- or comolete color table when scope isn't specified
|
---- or comolete color table when scope isn't specified
|
||||||
function M.extract_highlight_colors(color_group, scope)
|
function M.extract_highlight_colors(color_group, scope)
|
||||||
if vim.fn.hlexists(color_group) == 0 then
|
local color = require('lualine.highlight').get_lualine_hl(color_group)
|
||||||
return nil
|
if not color then
|
||||||
end
|
if vim.fn.hlexists(color_group) == 0 then
|
||||||
local color = vim.api.nvim_get_hl_by_name(color_group, true)
|
return nil
|
||||||
if color.background ~= nil then
|
end
|
||||||
color.bg = string.format('#%06x', color.background)
|
color = vim.api.nvim_get_hl_by_name(color_group, true)
|
||||||
color.background = nil
|
if color.background ~= nil then
|
||||||
end
|
color.bg = string.format('#%06x', color.background)
|
||||||
if color.foreground ~= nil then
|
color.background = nil
|
||||||
color.fg = string.format('#%06x', color.foreground)
|
end
|
||||||
color.foreground = nil
|
if color.foreground ~= nil then
|
||||||
|
color.fg = string.format('#%06x', color.foreground)
|
||||||
|
color.foreground = nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
if scope then
|
if scope then
|
||||||
return color[scope]
|
return color[scope]
|
||||||
|
|
|
@ -29,10 +29,10 @@ function M.init_component(component, opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Checks ouput of a component
|
-- Checks ouput of a component
|
||||||
M.assert_component = function(component, opts, result)
|
M.assert_component = function(component, opts, result, is_active)
|
||||||
local comp = M.init_component(component, opts)
|
local comp = M.init_component(component, opts)
|
||||||
-- for testing global options
|
-- for testing global options
|
||||||
eq(result, comp:draw(opts.hl))
|
eq(result, comp:draw(opts.hl, is_active or true))
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.assert_component_instence(comp, result)
|
function M.assert_component_instence(comp, result)
|
||||||
|
@ -49,7 +49,7 @@ M.build_component_opts = function(opts)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if not opts.self then
|
if not opts.self then
|
||||||
opts.self = { section = 'lualine_c' }
|
opts.self = { section = 'c' }
|
||||||
end
|
end
|
||||||
if not opts.theme then
|
if not opts.theme then
|
||||||
opts.theme = 'gruvbox'
|
opts.theme = 'gruvbox'
|
||||||
|
|
|
@ -15,7 +15,7 @@ describe('Component:', function()
|
||||||
local comp = require('lualine.components.special.function_component')(opts)
|
local comp = require('lualine.components.special.function_component')(opts)
|
||||||
-- correct for lualine_c
|
-- correct for lualine_c
|
||||||
eq('', comp.options.separator)
|
eq('', comp.options.separator)
|
||||||
local opts2 = build_component_opts { self = { section = 'lualine_y' } }
|
local opts2 = build_component_opts { self = { section = 'y' } }
|
||||||
local comp2 = require('lualine.components.special.function_component')(opts2)
|
local comp2 = require('lualine.components.special.function_component')(opts2)
|
||||||
-- correct for lualine_u
|
-- correct for lualine_u
|
||||||
eq('', comp2.options.separator)
|
eq('', comp2.options.separator)
|
||||||
|
@ -40,7 +40,12 @@ describe('Component:', function()
|
||||||
-- color highlight wan't in options when create_comp_hl was
|
-- color highlight wan't in options when create_comp_hl was
|
||||||
-- called so remove it before assert
|
-- called so remove it before assert
|
||||||
comp1.options.color_highlight = nil
|
comp1.options.color_highlight = nil
|
||||||
assert.stub(hl.create_component_highlight_group).was_called_with(color, comp1.options.component_name, comp1.options)
|
assert.stub(hl.create_component_highlight_group).was_called_with(
|
||||||
|
color,
|
||||||
|
comp1.options.component_name,
|
||||||
|
comp1.options,
|
||||||
|
false
|
||||||
|
)
|
||||||
hl.create_component_highlight_group:revert()
|
hl.create_component_highlight_group:revert()
|
||||||
color = 'MyHl'
|
color = 'MyHl'
|
||||||
local opts2 = build_component_opts { color = color }
|
local opts2 = build_component_opts { color = color }
|
||||||
|
@ -51,7 +56,12 @@ describe('Component:', function()
|
||||||
-- color highlight wan't in options when create_comp_hl was
|
-- color highlight wan't in options when create_comp_hl was
|
||||||
-- called so remove it before assert
|
-- called so remove it before assert
|
||||||
comp2.options.color_highlight = nil
|
comp2.options.color_highlight = nil
|
||||||
assert.stub(hl.create_component_highlight_group).was_called_with(color, comp2.options.component_name, comp2.options)
|
assert.stub(hl.create_component_highlight_group).was_called_with(
|
||||||
|
color,
|
||||||
|
comp2.options.component_name,
|
||||||
|
comp2.options,
|
||||||
|
false
|
||||||
|
)
|
||||||
hl.create_component_highlight_group:revert()
|
hl.create_component_highlight_group:revert()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
@ -186,7 +196,7 @@ describe('Component:', function()
|
||||||
color = 'MyHl',
|
color = 'MyHl',
|
||||||
}
|
}
|
||||||
local comp = require('lualine.components.special.function_component')(opts)
|
local comp = require('lualine.components.special.function_component')(opts)
|
||||||
local custom_link_hl_name = 'lualine_' .. comp.options.component_name .. '_no_mode'
|
local custom_link_hl_name = 'lualine_c_' .. comp.options.component_name
|
||||||
eq('%#' .. custom_link_hl_name .. '#test', comp:draw(opts.hl))
|
eq('%#' .. custom_link_hl_name .. '#test', comp:draw(opts.hl))
|
||||||
local opts2 = build_component_opts {
|
local opts2 = build_component_opts {
|
||||||
component_separators = { left = '', right = '' },
|
component_separators = { left = '', right = '' },
|
||||||
|
@ -280,26 +290,36 @@ describe('Filetype component', function()
|
||||||
return '*', 'test_highlight_group'
|
return '*', 'test_highlight_group'
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
vim.g.actual_curwin = tostring(vim.api.nvim_get_current_win())
|
||||||
local hl = require('lualine.highlight')
|
local hl = require('lualine.highlight')
|
||||||
local utils = require('lualine.utils.utils')
|
local utils = require('lualine.utils.utils')
|
||||||
stub(hl, 'create_component_highlight_group')
|
stub(hl, 'create_component_highlight_group')
|
||||||
|
stub(hl, 'format_highlight')
|
||||||
stub(utils, 'extract_highlight_colors')
|
stub(utils, 'extract_highlight_colors')
|
||||||
hl.create_component_highlight_group.returns('MyCompHl')
|
hl.create_component_highlight_group.returns { name = 'MyCompHl', no_mode = false, section = 'a' }
|
||||||
|
hl.format_highlight.returns('%#lualine_c_normal#')
|
||||||
utils.extract_highlight_colors.returns('#000')
|
utils.extract_highlight_colors.returns('#000')
|
||||||
|
|
||||||
local opts = build_component_opts {
|
local opts = build_component_opts {
|
||||||
component_separators = { left = '', right = '' },
|
component_separators = { left = '', right = '' },
|
||||||
|
hl = '%#lualine_c_normal#',
|
||||||
padding = 0,
|
padding = 0,
|
||||||
colored = true,
|
colored = true,
|
||||||
icon_only = false,
|
icon_only = false,
|
||||||
}
|
}
|
||||||
assert_component('filetype', opts, '%#MyCompHl_normal#*%#lualine_c_normal# lua')
|
assert_component('filetype', opts, '%#MyCompHl_normal#*%#lualine_c_normal# lua%#lualine_c_normal#')
|
||||||
assert.stub(utils.extract_highlight_colors).was_called_with('test_highlight_group', 'fg')
|
assert.stub(utils.extract_highlight_colors).was_called_with('test_highlight_group', 'fg')
|
||||||
assert.stub(hl.create_component_highlight_group).was_called_with({ fg = '#000' }, 'test_highlight_group', opts)
|
assert.stub(hl.create_component_highlight_group).was_called_with(
|
||||||
|
{ fg = '#000' },
|
||||||
|
'test_highlight_group',
|
||||||
|
opts,
|
||||||
|
false
|
||||||
|
)
|
||||||
hl.create_component_highlight_group:revert()
|
hl.create_component_highlight_group:revert()
|
||||||
|
hl.format_highlight:revert()
|
||||||
utils.extract_highlight_colors:revert()
|
utils.extract_highlight_colors:revert()
|
||||||
package.loaded['nvim-web-devicons'] = nil
|
package.loaded['nvim-web-devicons'] = nil
|
||||||
|
vim.g.actual_curwin = nil
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it("Doesn't color when colored is false", function()
|
it("Doesn't color when colored is false", function()
|
||||||
|
|
|
@ -5,6 +5,7 @@ local helpers = require('tests.helpers')
|
||||||
|
|
||||||
local eq = assert.are.same
|
local eq = assert.are.same
|
||||||
local build_component_opts = helpers.build_component_opts
|
local build_component_opts = helpers.build_component_opts
|
||||||
|
local stub = require('luassert.stub')
|
||||||
|
|
||||||
describe('Utils', function()
|
describe('Utils', function()
|
||||||
local utils = require('lualine.utils.utils')
|
local utils = require('lualine.utils.utils')
|
||||||
|
@ -55,6 +56,10 @@ describe('Cterm genarator', function()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('Section genarator', function()
|
describe('Section genarator', function()
|
||||||
|
local hl = require('lualine.highlight')
|
||||||
|
stub(hl, 'format_highlight')
|
||||||
|
hl.format_highlight.returns('%#lualine_c_normal#')
|
||||||
|
|
||||||
local sec = require('lualine.utils.section')
|
local sec = require('lualine.utils.section')
|
||||||
it('can draw', function()
|
it('can draw', function()
|
||||||
local opts = build_component_opts { section_separators = { left = '', right = '' } }
|
local opts = build_component_opts { section_separators = { left = '', right = '' } }
|
||||||
|
@ -62,10 +67,18 @@ describe('Section genarator', function()
|
||||||
require('lualine.components.special.function_component')(opts),
|
require('lualine.components.special.function_component')(opts),
|
||||||
require('lualine.components.special.function_component')(opts),
|
require('lualine.components.special.function_component')(opts),
|
||||||
}
|
}
|
||||||
eq('%#lualine_MySection_normal# test %#lualine_MySection_normal# test ', sec.draw_section(section, 'MySection'))
|
eq('%#lualine_c_normal# test %#lualine_c_normal# test ', sec.draw_section(section, 'c', true))
|
||||||
|
|
||||||
|
hl.format_highlight:revert()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('can remove separators from component with custom colors', function()
|
it('can remove separators from component with custom colors', function()
|
||||||
|
stub(hl, 'format_highlight')
|
||||||
|
stub(hl, 'get_lualine_hl')
|
||||||
|
hl.format_highlight.returns('%#lualine_MySection_normal#')
|
||||||
|
hl.get_lualine_hl.returns { fg = '#000000', bg = '#ffffff' }
|
||||||
|
|
||||||
|
vim.g.actual_curwin = tostring(vim.api.nvim_get_current_win())
|
||||||
local opts = build_component_opts { section_separators = { left = '', right = '' } }
|
local opts = build_component_opts { section_separators = { left = '', right = '' } }
|
||||||
local opts_colored = build_component_opts { color = 'MyColor' }
|
local opts_colored = build_component_opts { color = 'MyColor' }
|
||||||
local opts_colored2 = build_component_opts {
|
local opts_colored2 = build_component_opts {
|
||||||
|
@ -82,20 +95,20 @@ describe('Section genarator', function()
|
||||||
require('lualine.components.special.function_component')(opts_colored),
|
require('lualine.components.special.function_component')(opts_colored),
|
||||||
require('lualine.components.special.function_component')(opts),
|
require('lualine.components.special.function_component')(opts),
|
||||||
}
|
}
|
||||||
local highlight_name2 = 'lualine_' .. section[2].options.component_name .. '_no_mode'
|
local highlight_name2 = 'lualine_c_' .. section[2].options.component_name
|
||||||
-- Removes separator on string color
|
-- Removes separator on string color
|
||||||
eq(
|
eq(
|
||||||
'%#lualine_MySection_normal# test %#' .. highlight_name2 .. '#' .. ' test %#lualine_MySection_normal# test ',
|
'%#lualine_MySection_normal# test %#' .. highlight_name2 .. '#' .. ' test %#lualine_MySection_normal# test ',
|
||||||
sec.draw_section(section, 'MySection')
|
sec.draw_section(section, 'MySection')
|
||||||
)
|
)
|
||||||
section[2] = require('lua.lualine.components.special.function_component')(opts_colored2)
|
section[2] = require('lualine.components.special.function_component')(opts_colored2)
|
||||||
local highlight_name = '%#lualine_c_' .. section[2].options.component_name .. '_normal#'
|
local highlight_name = '%#lualine_c_' .. section[2].options.component_name .. '_normal#'
|
||||||
-- Removes separator on color with bg
|
-- Removes separator on color with bg
|
||||||
eq(
|
eq(
|
||||||
'%#lualine_MySection_normal# test ' .. highlight_name .. ' test %#lualine_MySection_normal# test ',
|
'%#lualine_MySection_normal# test ' .. highlight_name .. ' test %#lualine_MySection_normal# test ',
|
||||||
sec.draw_section(section, 'MySection')
|
sec.draw_section(section, 'MySection')
|
||||||
)
|
)
|
||||||
section[2] = require('lua.lualine.components.special.function_component')(opts_colored3)
|
section[2] = require('lualine.components.special.function_component')(opts_colored3)
|
||||||
highlight_name2 = '%#lualine_c_' .. section[2].options.component_name .. '_normal#'
|
highlight_name2 = '%#lualine_c_' .. section[2].options.component_name .. '_normal#'
|
||||||
-- Doesn't remove separator on color without bg
|
-- Doesn't remove separator on color without bg
|
||||||
eq(
|
eq(
|
||||||
|
@ -104,5 +117,9 @@ describe('Section genarator', function()
|
||||||
.. ' test %#lualine_MySection_normal#%#lualine_MySection_normal# test ',
|
.. ' test %#lualine_MySection_normal#%#lualine_MySection_normal# test ',
|
||||||
sec.draw_section(section, 'MySection')
|
sec.draw_section(section, 'MySection')
|
||||||
)
|
)
|
||||||
|
vim.g.actual_curwin = nil
|
||||||
|
|
||||||
|
hl.format_highlight:revert()
|
||||||
|
hl.get_lualine_hl:revert()
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
Loading…
Reference in New Issue