Skip to content

Commit

Permalink
feat: add support for dynamic color with functions in color options (#…
Browse files Browse the repository at this point in the history
…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>
  • Loading branch information
shadmansaleh and shadmansaleh committed Mar 2, 2022
1 parent 016a207 commit 37a314b
Show file tree
Hide file tree
Showing 20 changed files with 424 additions and 158 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ endif
@rm -rf tmp_home

docgen:
@bash ./scripts/docgen.sh
@sh ./scripts/docgen.sh

precommit_check: docgen format test lint

Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -374,15 +374,19 @@ sections = {

-- 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:
-- '|' 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:
-- 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 = '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.

-- Specify what type a component is, if omitted, lualine will guess it for you.
Expand Down
8 changes: 6 additions & 2 deletions doc/lualine.txt
Original file line number Diff line number Diff line change
Expand Up @@ -387,15 +387,19 @@ General component options These are options that control behavior
-- 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:
-- '|' 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:
-- 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 = '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.
-- Specify what type a component is, if omitted, lualine will guess it for you.
Expand Down
7 changes: 4 additions & 3 deletions examples/evil_lualine.lua
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ ins_left {
ins_left {
-- mode component
function()
return ''
end,
color = function()
-- auto change color according to neovims mode
local mode_color = {
n = colors.red,
Expand All @@ -112,10 +115,8 @@ ins_left {
['!'] = colors.red,
t = colors.red,
}
vim.api.nvim_command('hi! LualineMode guifg=' .. mode_color[vim.fn.mode()] .. ' guibg=' .. colors.bg)
return ''
return { fg = mode_color[vim.fn.mode()] }
end,
color = 'LualineMode',
padding = { right = 1 },
}

Expand Down
4 changes: 2 additions & 2 deletions lua/lualine.lua
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ local statusline = modules.utils.retry_call_wrap(function(sections, is_focused)
if #section_data > 0 then
if not applied_midsection_divider and section_name > 'c' then
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
if not applied_trunc and section_name > 'b' then
applied_trunc = true
Expand All @@ -170,7 +170,7 @@ local statusline = modules.utils.retry_call_wrap(function(sections, is_focused)
end
if applied_midsection_divider == false and config.options.always_divide_middle ~= false then
-- 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
return apply_transitional_separators(table.concat(status))
end)
Expand Down
22 changes: 18 additions & 4 deletions lua/lualine/component.lua
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ end
function M:set_separator()
if self.options.separator == nil 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
else
self.options.separator = self.options.component_separators.right
Expand All @@ -54,7 +54,8 @@ function M:create_option_highlights()
self.options.color_highlight = highlight.create_component_highlight_group(
self.options.color,
self.options.component_name,
self.options
self.options,
false
)
end
end
Expand Down Expand Up @@ -89,7 +90,9 @@ end
---applies custom highlights for component
function M:apply_highlights(default_highlight)
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
if type(self.options.separator) ~= 'table' and self.status:find('%%#') then
-- Apply default highlight only when we aren't applying trans sep and
Expand Down Expand Up @@ -119,7 +122,7 @@ function M:apply_separator()
local separator = self.options.separator
if type(separator) == 'table' 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
else
separator = self.options.component_separators.right
Expand Down Expand Up @@ -159,6 +162,16 @@ function M:strip_separator()
return self.status
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
---actual function that updates a component. Must be overwritten with component functionality
function M:update_status(is_focused) end
Expand All @@ -172,6 +185,7 @@ function M:draw(default_highlight, is_focused)
if self.options.cond ~= nil and self.options.cond() ~= true then
return self.status
end
self.default_hl = default_highlight
local status = self:update_status(is_focused)
if self.options.fmt then
status = self.options.fmt(status or '')
Expand Down
4 changes: 2 additions & 2 deletions lua/lualine/components/buffers/buffer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ function Buffer:render()
.. line

-- 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()
line = sep_before .. line
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()
line = line .. sep_after
self.len = self.len + vim.fn.strchars(sep_after)
Expand Down
14 changes: 8 additions & 6 deletions lua/lualine/components/buffers/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,22 @@ end
function M:init(options)
M.super.init(self, options)
default_options.buffers_color = {
active = get_hl(options.self.section, true),
inactive = get_hl(options.self.section, false),
active = get_hl('lualine_' .. options.self.section, true),
inactive = get_hl('lualine_' .. options.self.section, false),
}
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
self.highlights = {
active = highlight.create_component_highlight_group(
self.options.buffers_color.active,
'buffers_active',
self.options
self.options,
false
),
inactive = highlight.create_component_highlight_group(
self.options.buffers_color.inactive,
'buffers_active',
self.options
'buffers_inactive',
self.options,
false
),
}
end
Expand Down Expand Up @@ -112,7 +114,7 @@ function M:update_status()
if current == -2 then
local b = Buffer { bufnr = vim.api.nvim_get_current_buf(), options = self.options, highlights = self.highlights }
b.current = true
if self.options.self.section < 'lualine_x' then
if self.options.self.section < 'x' then
b.last = true
if #buffers > 0 then
buffers[#buffers].last = nil
Expand Down
12 changes: 8 additions & 4 deletions lua/lualine/components/diagnostics/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,26 @@ function M:init(options)
error = modules.highlight.create_component_highlight_group(
self.options.diagnostics_color.error,
'diagnostics_error',
self.options
self.options,
false
),
warn = modules.highlight.create_component_highlight_group(
self.options.diagnostics_color.warn,
'diagnostics_warn',
self.options
self.options,
false
),
info = modules.highlight.create_component_highlight_group(
self.options.diagnostics_color.info,
'diagnostics_info',
self.options
self.options,
false
),
hint = modules.highlight.create_component_highlight_group(
self.options.diagnostics_color.hint,
'diagnostics_hint',
self.options
self.options,
false
),
}
end
Expand Down
9 changes: 6 additions & 3 deletions lua/lualine/components/diff/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,20 @@ function M:init(options)
added = modules.highlight.create_component_highlight_group(
self.options.diff_color.added,
'diff_added',
self.options
self.options,
false
),
modified = modules.highlight.create_component_highlight_group(
self.options.diff_color.modified,
'diff_modified',
self.options
self.options,
false
),
removed = modules.highlight.create_component_highlight_group(
self.options.diff_color.removed,
'diff_removed',
self.options
self.options,
false
),
}
end
Expand Down
11 changes: 7 additions & 4 deletions lua/lualine/components/filetype.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ function M.update_status()
return modules.utils.stl_escape(ft)
end

local icon_hl_cache = {}
function M:apply_icon()
if not self.options.icons_enabled then
return
Expand All @@ -36,14 +37,16 @@ function M:apply_icon()

if icon and self.options.colored then
local highlight_color = modules.utils.extract_highlight_colors(icon_highlight_group, 'fg')
local default_highlight = modules.highlight.format_highlight(self.options.self.section)
local icon_highlight = self.options.self.section .. '_' .. icon_highlight_group
if not modules.highlight.highlight_exists(icon_highlight .. '_normal') then
local default_highlight = self:get_default_hl()
local icon_highlight = icon_hl_cache[highlight_color]
if not icon_highlight or not modules.highlight.highlight_exists(icon_highlight.name .. '_normal') then
icon_highlight = modules.highlight.create_component_highlight_group(
{ fg = highlight_color },
icon_highlight_group,
self.options
self.options,
false
)
icon_hl_cache[highlight_color] = icon_highlight
end

icon = modules.highlight.component_format_highlight(icon_highlight) .. icon .. default_highlight
Expand Down
12 changes: 7 additions & 5 deletions lua/lualine/components/tabs/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,23 @@ end
function M:init(options)
M.super.init(self, options)
default_options.tabs_color = {
active = get_hl(options.self.section, true),
inactive = get_hl(options.self.section, false),
active = get_hl('lualine_' .. options.self.section, true),
inactive = get_hl('lualine_' .. options.self.section, false),
}
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
-- stylua: ignore
self.highlights = {
active = highlight.create_component_highlight_group(
self.options.tabs_color.active,
'tabs_active',
self.options
self.options,
false
),
inactive = highlight.create_component_highlight_group(
self.options.tabs_color.inactive,
'tabs_active',
self.options
'tabs_inactive',
self.options,
false
),
}
end
Expand Down
4 changes: 2 additions & 2 deletions lua/lualine/components/tabs/tab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ function Tab:render()
.. line

-- 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()
line = sep_before .. line
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()
line = line .. sep_after
self.len = self.len + vim.fn.strchars(sep_after)
Expand Down
Loading

0 comments on commit 37a314b

Please sign in to comment.