feat: powerline like section seperators (#94)
This commit is contained in:
parent
6af9932d89
commit
202487d2ef
16
README.md
16
README.md
|
@ -86,17 +86,19 @@ All available themes are listed in [THEMES.md](./THEMES.md)
|
|||
Please create a pr if you managed to port a popular theme before me, [here is how to do it](./CONTRIBUTING.md).
|
||||
|
||||
### Changing separator in section
|
||||
Lualine defines a separator between components in given section, the default
|
||||
separator is `|`. You can change the separator this way:
|
||||
Lualine defines two kinds of seperators. One is for sections and other is for components. Default section seperators are '', '' and component separators are '', ''.
|
||||
They require powerline patched fonts. But you can easily change yours to something else like below
|
||||
|
||||
```lua
|
||||
lualine.options.separator = '|'
|
||||
lualine.section_separators = {'', ''}
|
||||
lualine.component_separators = {'', ''}
|
||||
```
|
||||
|
||||
or disable it
|
||||
|
||||
```lua
|
||||
lualine.options.separator = ''
|
||||
lualine.section_separators = nil
|
||||
lualine.component_separators = nil
|
||||
```
|
||||
|
||||
### Changing components in lualine sections
|
||||
|
@ -304,7 +306,8 @@ All available extensions are listed in [EXTENSIONS.md](./EXTENSIONS.md)
|
|||
local lualine = require('lualine')
|
||||
lualine.options = {
|
||||
theme = 'gruvbox',
|
||||
separator = '|',
|
||||
section_separators = {'', ''},
|
||||
component_separators = {'', ''},
|
||||
icons_enabled = true,
|
||||
}
|
||||
lualine.sections = {
|
||||
|
@ -341,7 +344,8 @@ lua << EOF
|
|||
local lualine = require('lualine')
|
||||
lualine.options = {
|
||||
theme = 'gruvbox',
|
||||
separator = '|',
|
||||
section_separators = {'', ''},
|
||||
component_separators = {'', ''},
|
||||
icons_enabled = true,
|
||||
}
|
||||
lualine.sections = {
|
||||
|
|
|
@ -113,15 +113,19 @@ how to do it (./CONTRIBUTING.md).
|
|||
|
||||
CHANGING SEPARATOR IN SECTION *lualine_changing_separator*
|
||||
|
||||
Lualine defines a separator between components in given section, the default
|
||||
separator is `|`. You can change the separator this way:
|
||||
Lualine defines two kinds of seperators. One is for sections and other is
|
||||
for components. Default section seperators are '', '' and component
|
||||
separators are '', ''.They require powerline patched fonts. But you can
|
||||
easily change yours to something else like below.
|
||||
>
|
||||
lualine.options.separator = '|'
|
||||
lualine.section_separators = {'', ''}
|
||||
lualine.component_separators = {'', ''}
|
||||
<
|
||||
|
||||
or disable it
|
||||
>
|
||||
lualine.options.separator = ''
|
||||
lualine.section_separators = nil
|
||||
lualine.component_separators = nil
|
||||
<
|
||||
|
||||
CHANGING COMPONENTS IN LUALINE SECTIONS *lualine_changing_components*
|
||||
|
@ -349,7 +353,8 @@ packer config
|
|||
local lualine = require('lualine')
|
||||
lualine.options = {
|
||||
theme = 'gruvbox',
|
||||
separator = '|',
|
||||
section_separators = {'', ''},
|
||||
component_separators = {'', ''},
|
||||
icons_enabled = true,
|
||||
}
|
||||
lualine.sections = {
|
||||
|
@ -385,9 +390,10 @@ vimrc config
|
|||
local lualine = require('lualine')
|
||||
lualine.options = {
|
||||
theme = 'gruvbox',
|
||||
separator = '|',
|
||||
icons_enabled = true,
|
||||
}
|
||||
section_separators = {'', ''},
|
||||
component_separators = {'', ''},
|
||||
icons_enabled = true,
|
||||
}
|
||||
lualine.sections = {
|
||||
lualine_a = { 'mode' },
|
||||
lualine_b = { 'branch' },
|
||||
|
|
140
lua/lualine.lua
140
lua/lualine.lua
|
@ -12,9 +12,11 @@ local theme_set = {}
|
|||
M.options = {
|
||||
icons_enabled = true,
|
||||
theme = 'gruvbox',
|
||||
separator = '|',
|
||||
component_separators = {'', ''},
|
||||
section_separators = {'', ''},
|
||||
}
|
||||
|
||||
|
||||
M.sections = {
|
||||
lualine_a = { 'mode' },
|
||||
lualine_b = { 'branch' },
|
||||
|
@ -36,6 +38,17 @@ M.inactive_sections = {
|
|||
M.extensions = {
|
||||
}
|
||||
|
||||
local function check_single_separator()
|
||||
local compoennt_separator = M.options.component_separators
|
||||
local section_separator = M.options.section_separators
|
||||
if type(M.options.component_separators) == 'string' then
|
||||
M.options.component_separators = {compoennt_separator, compoennt_separator}
|
||||
end
|
||||
if type(M.options.section_separators) == 'string' then
|
||||
M.options.section_separators = {section_separator, section_separator}
|
||||
end
|
||||
end
|
||||
|
||||
local function load_special_components(component)
|
||||
return function()
|
||||
-- precedence lualine_component > vim_var > lua_var > vim_function
|
||||
|
@ -56,12 +69,12 @@ local function load_special_components(component)
|
|||
if ok then return return_val end
|
||||
return ''
|
||||
elseif loadstring(string.format('return %s ~= nil', component)) and
|
||||
loadstring(string.format([[return %s ~= nil]], component))() then
|
||||
loadstring(string.format([[return %s ~= nil]], component))() then
|
||||
-- lua veriable component
|
||||
return loadstring(string.format([[
|
||||
local ok, return_val = pcall(tostring, %s)
|
||||
if ok then return return_val end
|
||||
return '']], component))()
|
||||
local ok, return_val = pcall(tostring, %s)
|
||||
if ok then return return_val end
|
||||
return '']], component))()
|
||||
else
|
||||
-- vim function component
|
||||
local ok, return_val = pcall(vim.fn[component])
|
||||
|
@ -138,43 +151,91 @@ local function load_extensions()
|
|||
end
|
||||
end
|
||||
|
||||
local function set_lualine_theme()
|
||||
local function lualine_set_theme()
|
||||
if type(M.options.theme) == 'string' then
|
||||
M.options.theme = require('lualine.themes.'.. M.options.theme)
|
||||
local function reset_component_theme(sections)
|
||||
for _, section in pairs(sections)do
|
||||
for _, component in pairs(section) do
|
||||
if type(component) == 'table' then
|
||||
component.theme = M.options.theme
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
reset_component_theme(M.sections)
|
||||
reset_component_theme(M.inactive_sections)
|
||||
end
|
||||
highlight.clear_highlights()
|
||||
highlight.create_highlight_groups(M.options.theme)
|
||||
theme_set = M.options.theme
|
||||
end
|
||||
|
||||
local function statusline(sections, is_focused)
|
||||
if M.theme ~= theme_set then
|
||||
set_lualine_theme()
|
||||
if M.options.theme ~= theme_set then
|
||||
_G.lualine_set_theme()
|
||||
end
|
||||
local function create_status_builder()
|
||||
-- The sequence sections should maintain
|
||||
local section_sequence = {'a', 'b', 'c', 'x', 'y', 'z'}
|
||||
local status_builder = {}
|
||||
for _, section_name in ipairs(section_sequence) do
|
||||
if sections['lualine_'..section_name] then
|
||||
-- insert highlight+components of this section to status_builder
|
||||
local section_highlight = highlight.format_highlight(is_focused,
|
||||
'lualine_'..section_name)
|
||||
local section_data = utils_component.draw_section(sections['lualine_'..section_name], section_highlight)
|
||||
if #section_data > 0 then
|
||||
table.insert(status_builder, {name = section_name, data = section_data,})
|
||||
end
|
||||
end
|
||||
end
|
||||
return status_builder
|
||||
end
|
||||
-- status_builder stores statusline without section_separators
|
||||
local status_builder = create_status_builder()
|
||||
|
||||
-- Actual statusline
|
||||
local status = {}
|
||||
if sections.lualine_a then
|
||||
local hl = highlight.format_highlight(is_focused, 'lualine_a')
|
||||
table.insert(status, utils_component.draw_section(sections.lualine_a, hl))
|
||||
local half_passed = false
|
||||
for i=1,#status_builder do
|
||||
-- midsection divider
|
||||
if not half_passed and status_builder[i].name > 'c' then
|
||||
table.insert(status, highlight.format_highlight(is_focused, 'lualine_c') .. '%=')
|
||||
half_passed = true
|
||||
end
|
||||
-- provide section_separators when statusline is in focus
|
||||
if is_focused then
|
||||
-- component separator needs to have fg = current_section.bg
|
||||
-- and bg = adjacent_section.bg
|
||||
local previous_section = status_builder[i-1] or {}
|
||||
local current_section = status_builder[i]
|
||||
local next_section = status_builder[i+1] or {}
|
||||
-- For 2nd half we need to show separator before section
|
||||
if current_section.name > 'x' then
|
||||
local transitional_highlight = highlight.get_transitional_highlights(previous_section.data, current_section.data, true)
|
||||
if transitional_highlight and M.options.section_separators and M.options.section_separators[2] then
|
||||
table.insert(status, transitional_highlight .. M.options.section_separators[2])
|
||||
end
|
||||
end
|
||||
|
||||
-- **( insert the actual section in the middle )** --
|
||||
table.insert(status, status_builder[i].data)
|
||||
|
||||
-- For 1st half we need to show separator after section
|
||||
if current_section.name < 'c' then
|
||||
local transitional_highlight = highlight.get_transitional_highlights(current_section.data, next_section.data)
|
||||
if transitional_highlight and M.options.section_separators and M.options.section_separators[1] then
|
||||
table.insert(status, transitional_highlight .. M.options.section_separators[1])
|
||||
end
|
||||
end
|
||||
else -- when not in focus
|
||||
table.insert(status, status_builder[i].data)
|
||||
end
|
||||
end
|
||||
if sections.lualine_b then
|
||||
local hl = highlight.format_highlight(is_focused, 'lualine_b')
|
||||
table.insert(status, utils_component.draw_section(sections.lualine_b, hl))
|
||||
end
|
||||
if sections.lualine_c then
|
||||
local hl = highlight.format_highlight(is_focused, 'lualine_c')
|
||||
table.insert(status, utils_component.draw_section(sections.lualine_c, hl))
|
||||
end
|
||||
table.insert(status, "%=")
|
||||
if sections.lualine_x then
|
||||
local hl = highlight.format_highlight(is_focused, 'lualine_c')
|
||||
table.insert(status, utils_component.draw_section(sections.lualine_x, hl))
|
||||
end
|
||||
if sections.lualine_y then
|
||||
local hl = highlight.format_highlight(is_focused, 'lualine_b')
|
||||
table.insert(status, utils_component.draw_section(sections.lualine_y, hl))
|
||||
end
|
||||
if sections.lualine_z then
|
||||
local hl = highlight.format_highlight(is_focused, 'lualine_a')
|
||||
table.insert(status, utils_component.draw_section(sections.lualine_z, hl))
|
||||
-- incase none of x,y,z was configured lets not fill whole statusline with a,b,c section
|
||||
if not half_passed then
|
||||
table.insert(status, highlight.format_highlight(is_focused,'lualine_c').."%=")
|
||||
end
|
||||
return table.concat(status)
|
||||
end
|
||||
|
@ -188,20 +249,21 @@ local function status_dispatch()
|
|||
end
|
||||
|
||||
local function exec_autocommands()
|
||||
_G.set_lualine_theme = set_lualine_theme
|
||||
_G.lualine_set_theme = lualine_set_theme
|
||||
_G.lualine_statusline = status_dispatch
|
||||
vim.api.nvim_exec([[
|
||||
augroup lualine
|
||||
autocmd!
|
||||
autocmd ColorScheme * call v:lua.set_lualine_theme()
|
||||
autocmd WinLeave,BufLeave * lua vim.wo.statusline=lualine_statusline()
|
||||
autocmd WinEnter,BufEnter * setlocal statusline=%!v:lua.lualine_statusline()
|
||||
augroup END
|
||||
augroup lualine
|
||||
autocmd!
|
||||
autocmd ColorScheme * call v:lua.lualine_set_theme()
|
||||
autocmd WinLeave,BufLeave * lua vim.wo.statusline=lualine_statusline()
|
||||
autocmd WinEnter,BufEnter * setlocal statusline=%!v:lua.lualine_statusline()
|
||||
augroup END
|
||||
]], false)
|
||||
end
|
||||
|
||||
function M.status()
|
||||
set_lualine_theme()
|
||||
check_single_separator()
|
||||
lualine_set_theme()
|
||||
exec_autocommands()
|
||||
load_components()
|
||||
load_extensions()
|
||||
|
|
|
@ -12,13 +12,13 @@ local function signify(options)
|
|||
if options.colored == nil then options.colored = true end
|
||||
-- apply colors
|
||||
if not options.color_added then
|
||||
options.color_added = utils.extract_highlight_colors('diffAdded', 'foreground') or default_color_added
|
||||
options.color_added = utils.extract_highlight_colors('diffAdded', 'guifg') or default_color_added
|
||||
end
|
||||
if not options.color_modified then
|
||||
options.color_modified = utils.extract_highlight_colors('diffChanged', 'foreground') or default_color_modified
|
||||
options.color_modified = utils.extract_highlight_colors('diffChanged', 'guifg') or default_color_modified
|
||||
end
|
||||
if not options.color_removed then
|
||||
options.color_removed = utils.extract_highlight_colors('diffRemoved', 'foreground') or default_color_removed
|
||||
options.color_removed = utils.extract_highlight_colors('diffRemoved', 'guifg') or default_color_removed
|
||||
end
|
||||
|
||||
local highlights = {}
|
||||
|
@ -36,7 +36,6 @@ local function signify(options)
|
|||
if options.colored then
|
||||
create_highlights()
|
||||
utils.expand_set_theme(create_highlights)
|
||||
options.custom_highlight = true
|
||||
end
|
||||
|
||||
-- Function that runs everytime statusline is updated
|
||||
|
|
|
@ -3,18 +3,38 @@
|
|||
|
||||
local M = { }
|
||||
local utils_colors = require "lualine.utils.cterm_colors"
|
||||
local utils = require 'lualine.utils.utils'
|
||||
local section_highlight_map = {x = 'c', y = 'b', z = 'a'}
|
||||
local loaded_highlights = {}
|
||||
|
||||
-- @description: clears Highlights in loaded_highlights
|
||||
function M.clear_highlights()
|
||||
for no, highlight_name in ipairs(loaded_highlights)do
|
||||
if highlight_name and #highlight_name > 0 and utils.highlight_exists(highlight_name) then
|
||||
vim.cmd('highlight clear ' .. highlight_name)
|
||||
end
|
||||
loaded_highlights[no] = nil
|
||||
end
|
||||
end
|
||||
|
||||
local function highlight (name, foreground, background, gui)
|
||||
local command = {
|
||||
'highlight', name,
|
||||
'ctermfg=' .. (foreground[2] or utils_colors.get_cterm_color(foreground)),
|
||||
'ctermbg=' .. (background[2] or utils_colors.get_cterm_color(background)),
|
||||
'cterm=' .. (gui or 'none'),
|
||||
'guifg=' .. (foreground[1] or foreground),
|
||||
'guibg=' .. (background[1] or background),
|
||||
'gui=' .. (gui or 'none'),
|
||||
}
|
||||
return table.concat(command, ' ')
|
||||
local command = { 'highlight', name, }
|
||||
if foreground then
|
||||
table.insert(command, 'ctermfg=' .. (foreground[2] or
|
||||
(foreground ~= 'none' and utils_colors.get_cterm_color(foreground)) or 'none'))
|
||||
table.insert(command, 'guifg=' .. (foreground[1] or foreground))
|
||||
end
|
||||
if background then
|
||||
table.insert(command, 'ctermbg=' .. (background[2] or
|
||||
(background ~= 'none' and utils_colors.get_cterm_color(background)) or 'none'))
|
||||
table.insert(command, 'guibg=' .. (background[1] or background))
|
||||
end
|
||||
if gui then
|
||||
table.insert(command, 'cterm=' .. (gui or 'none'))
|
||||
table.insert(command, 'gui=' .. (gui or 'none'))
|
||||
end
|
||||
vim.cmd(table.concat(command, ' '))
|
||||
table.insert(loaded_highlights, name)
|
||||
end
|
||||
|
||||
local function apply_defaults_to_theme(theme)
|
||||
|
@ -36,11 +56,14 @@ function M.create_highlight_groups(theme)
|
|||
for mode, sections in pairs(theme) do
|
||||
for section, colorscheme in pairs(sections) do
|
||||
local highlight_group_name = { 'lualine', section, mode }
|
||||
vim.cmd(highlight(table.concat(highlight_group_name, '_'), colorscheme.fg, colorscheme.bg, colorscheme.gui))
|
||||
highlight(table.concat(highlight_group_name, '_'), colorscheme.fg, colorscheme.bg, colorscheme.gui)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- @description: adds '_mode' at end of highlight_group
|
||||
-- @param highlight_group:(string) name of highlight group
|
||||
-- @return: (string) highlight group name with mode
|
||||
local function append_mode(highlight_group)
|
||||
local mode = require('lualine.components.mode')()
|
||||
if mode == 'VISUAL' or mode == 'V-BLOCK' or mode == 'V-LINE'
|
||||
|
@ -68,51 +91,138 @@ end
|
|||
-- @@highlight_tag is unique tag for highlight group
|
||||
-- returns the name of highlight group
|
||||
-- @@options is parameter of component.init() function
|
||||
-- @return: (string) unique name that can be used by component_format_highlight
|
||||
-- to retrive highlight group
|
||||
function M.create_component_highlight_group(color , highlight_tag, options)
|
||||
if color.bg and color.fg then
|
||||
-- When bg and fg are both present we donn't need to set highlighs for
|
||||
-- each mode as they will surely look the same
|
||||
-- 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'}, '_')
|
||||
vim.cmd(highlight(highlight_group_name, color.fg, color.bg, color.gui))
|
||||
highlight(highlight_group_name, color.fg, color.bg, color.gui)
|
||||
return highlight_group_name
|
||||
end
|
||||
|
||||
local modes = {'normal', 'insert', 'visual', 'replace', 'command', 'terminal', 'inactive'}
|
||||
local normal_hl
|
||||
-- convert lualine_a -> a before setting section
|
||||
local section = options.self.section:match('lualine_(.*)')
|
||||
if section > 'c' then
|
||||
section = section_highlight_map[section]
|
||||
end
|
||||
for _, mode in ipairs(modes) do
|
||||
local highlight_group_name = { options.self.section, highlight_tag, mode }
|
||||
-- convert lualine_a -> a before setting section
|
||||
local section = options.self.section:match('lualine_(.*)')
|
||||
local bg = (color.bg or options.theme[mode][section]['bg'])
|
||||
local fg = (color.fg or options.theme[mode][section]['fg'])
|
||||
vim.cmd(highlight(table.concat(highlight_group_name, '_'), fg, bg, color.gui))
|
||||
local default_color_table = options.theme[mode] and
|
||||
options.theme[mode][section] or options.theme.normal[section]
|
||||
local bg = (color.bg or default_color_table.bg)
|
||||
local fg = (color.fg or default_color_table.fg)
|
||||
-- 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 and fg ~= normal_hl.fg then
|
||||
highlight(table.concat(highlight_group_name, '_'), fg, bg, color.gui)
|
||||
end
|
||||
else
|
||||
normal_hl = {bg = bg, fg = fg}
|
||||
highlight(table.concat(highlight_group_name, '_'), fg, bg, color.gui)
|
||||
end
|
||||
end
|
||||
return options.self.section..'_'..highlight_tag
|
||||
end
|
||||
|
||||
-- retrieve highlight_groups for components
|
||||
-- @@highlight_name received from create_component_highlight_group
|
||||
-- @description: retrieve highlight_groups for components
|
||||
-- @param highlight_name:(string) highlight group name without mode
|
||||
-- return value of create_component_highlight_group is to be passed in
|
||||
-- this parameter to receive highlight that was created
|
||||
-- @return: (string) formated highlight group name
|
||||
function M.component_format_highlight(highlight_name)
|
||||
local highlight_group = [[%#]]..highlight_name
|
||||
local highlight_group = highlight_name
|
||||
if highlight_name:find('no_mode') == #highlight_name - #'no_mode' + 1 then
|
||||
return highlight_group..'#'
|
||||
return '%#'..highlight_group..'#'
|
||||
end
|
||||
if vim.g.statusline_winid == vim.fn.win_getid() then
|
||||
highlight_group = append_mode(highlight_group)..'#'
|
||||
highlight_group = append_mode(highlight_group)
|
||||
else
|
||||
highlight_group = highlight_group..'_inactive'..'#'
|
||||
highlight_group = highlight_group..'_inactive'
|
||||
end
|
||||
if utils.highlight_exists(highlight_group)then
|
||||
return '%#'..highlight_group..'#'
|
||||
else
|
||||
return '%#'..highlight_name..'_normal#'
|
||||
end
|
||||
return highlight_group
|
||||
end
|
||||
|
||||
function M.format_highlight(is_focused, highlight_group)
|
||||
highlight_group = [[%#]] .. highlight_group
|
||||
if not is_focused then
|
||||
highlight_group = highlight_group .. [[_inactive]]
|
||||
else
|
||||
highlight_group = append_mode(highlight_group)
|
||||
if highlight_group > 'lualine_c' then
|
||||
highlight_group = 'lualine_' .. section_highlight_map[highlight_group:match('lualine_(.)')]
|
||||
end
|
||||
highlight_group = highlight_group .. [[#]]
|
||||
return highlight_group
|
||||
local highlight_name = highlight_group
|
||||
if not is_focused then
|
||||
return '%#' .. highlight_group .. [[_inactive#]]
|
||||
else
|
||||
highlight_name = append_mode(highlight_group)
|
||||
end
|
||||
return '%#' .. highlight_name ..'#'
|
||||
end
|
||||
|
||||
-- @description : Provides transitional highlights for section separators.
|
||||
-- @param left_section_data :(string) section before separator
|
||||
-- @param right_section_data:(string) section after separator
|
||||
-- @param reverse :(string) Whether it's a left separator or right separator
|
||||
-- '▶️' and '◀️' needs reverse colors so this parameter needs to be set true.
|
||||
-- @return: (string) formated highlight group name
|
||||
function M.get_transitional_highlights(left_section_data, right_section_data, reverse )
|
||||
local left_highlight_name, right_highlight_name
|
||||
-- Grab the last highlighter of left section
|
||||
if left_section_data then
|
||||
-- extract highlight_name from .....%#highlight_name#
|
||||
left_highlight_name = left_section_data:match('.*%%#(.*)#')
|
||||
else
|
||||
-- When right section us unavailable default to lualine_c
|
||||
left_highlight_name = append_mode('lualine_c')
|
||||
if not utils.highlight_exists(left_highlight_name) then
|
||||
left_highlight_name = 'lualine_c_normal'
|
||||
end
|
||||
end
|
||||
if right_section_data then
|
||||
-- using vim-regex cause lua-paterns don't have non-greedy matching
|
||||
-- extract highlight_name from %#highlight_name#....
|
||||
right_highlight_name = vim.fn.matchlist(right_section_data, [[%#\(.\{-\}\)#]])[2]
|
||||
else
|
||||
-- When right section us unavailable default to lualine_c
|
||||
right_highlight_name = append_mode('lualine_c')
|
||||
if not utils.highlight_exists(right_highlight_name) then
|
||||
right_highlight_name = 'lualine_c_normal'
|
||||
end
|
||||
end
|
||||
-- When both left and right highlights are same nothing to transition to
|
||||
if left_highlight_name == right_highlight_name then return end
|
||||
|
||||
-- construct the name of hightlight group
|
||||
local highlight_name
|
||||
if left_highlight_name:find('lualine_') == 1 then
|
||||
highlight_name = left_highlight_name .. '_to_' .. right_highlight_name
|
||||
else
|
||||
highlight_name = 'lualine_' .. left_highlight_name .. '_to_' .. right_highlight_name
|
||||
end
|
||||
|
||||
if not utils.highlight_exists(highlight_name) then
|
||||
-- Create the highlight_group if needed
|
||||
local function set_transitional_highlights()
|
||||
-- Get colors from highlights
|
||||
-- using string.format to convert decimal to hexadecimal
|
||||
local fg = utils.extract_highlight_colors(left_highlight_name, 'guibg')
|
||||
local bg = utils.extract_highlight_colors(right_highlight_name, 'guibg')
|
||||
if not fg then fg = 'none' end
|
||||
if not bg then bg = 'none' end
|
||||
-- swap the bg and fg when reverse is true. As in that case highlight will
|
||||
-- be placed before section
|
||||
if reverse then fg, bg = bg, fg end
|
||||
highlight(highlight_name, fg, bg)
|
||||
end
|
||||
-- Create highlights and setup to survive colorscheme changes
|
||||
set_transitional_highlights()
|
||||
utils.expand_set_theme(set_transitional_highlights)
|
||||
end
|
||||
return '%#' .. highlight_name .. '#'
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
|
@ -44,51 +44,76 @@ end
|
|||
|
||||
-- Apply separator at end of component only when
|
||||
-- custom highlights haven't affected background
|
||||
local function apply_spearator(status, options)
|
||||
if options.separator and #options.separator > 0 and
|
||||
(not options.color or not options.color.bg) then
|
||||
status = status .. options.separator
|
||||
options.separator_applied = true
|
||||
local function apply_spearator(status, options, highlight_name)
|
||||
local separator
|
||||
if options.separator and #options.separator > 0 then
|
||||
separator = options.separator
|
||||
elseif options.component_separators then
|
||||
if options.self.section < 'lualine_x' then separator = options.component_separators[1]
|
||||
else separator = options.component_separators[2] end
|
||||
if not separator then
|
||||
options.separator_applied = nil
|
||||
return status
|
||||
end
|
||||
options.separator = separator
|
||||
else
|
||||
options.separator_applied = nil
|
||||
return status
|
||||
end
|
||||
separator = highlight_name .. separator
|
||||
status = status .. separator
|
||||
options.separator_applied = separator
|
||||
return status
|
||||
end
|
||||
|
||||
local function strip_separator(status, options)
|
||||
if options.separator_applied then
|
||||
status = status:sub(1, #status - #options.separator_applied)
|
||||
options.separator_applied = nil
|
||||
end
|
||||
return status
|
||||
end
|
||||
|
||||
-- Returns formated string for a section
|
||||
function M.draw_section(section, highlight)
|
||||
function M.draw_section(section, highlight_name)
|
||||
local status = {}
|
||||
local drawn_components = {}
|
||||
for _, component in pairs(section) do
|
||||
-- Reset flags
|
||||
component.drawn = false -- Flag to check if a component was drawn or not
|
||||
component.separator_applied = false -- Flag to check if separator was applied
|
||||
local localstatus = component[1]()
|
||||
if #localstatus > 0 then
|
||||
local custom_highlight_at_begining = localstatus:find('%%#.*#') == 1 or component.color ~= nil
|
||||
-- Apply modifier functions for options
|
||||
if component.format then localstatus = component.format(localstatus) end
|
||||
localstatus = apply_icon(localstatus, component)
|
||||
localstatus = apply_case(localstatus, component)
|
||||
localstatus = apply_padding(localstatus, component)
|
||||
localstatus = apply_highlights(localstatus, component)
|
||||
localstatus = apply_spearator(localstatus, component)
|
||||
table.insert(status, localstatus)
|
||||
component.drawn = true
|
||||
localstatus = apply_spearator(localstatus, component, highlight_name)
|
||||
if custom_highlight_at_begining or
|
||||
(#drawn_components > 0 and not drawn_components[#drawn_components].separator_applied)then
|
||||
-- Don't prepend with old highlight when the component changes it imidiately
|
||||
-- Or when it was already applied with separator
|
||||
table.insert(status, localstatus)
|
||||
else
|
||||
table.insert(status, highlight_name .. localstatus)
|
||||
end
|
||||
table.insert(drawn_components, component)
|
||||
end
|
||||
end
|
||||
-- Draw nothing when all the components were empty
|
||||
if #status == 0 then return '' end
|
||||
-- convert to single string
|
||||
-- highlight is used as separator so custom highlights don't affect
|
||||
-- later components
|
||||
local status_str = highlight .. table.concat(status, highlight)
|
||||
-- Remove separator from last drawn component if available
|
||||
for last_component = #section, 1, -1 do
|
||||
if section[last_component].drawn then
|
||||
if section[last_component].separator_applied then
|
||||
status_str = status_str:sub(1, #status_str - #section[last_component].separator)
|
||||
-- Remove separators sorounding custom highlighted component
|
||||
for i=1,#status do
|
||||
if (drawn_components[i].color and drawn_components[i].color.bg)
|
||||
or drawn_components[i].custom_highlight then
|
||||
status[i] = strip_separator(status[i], drawn_components[i])
|
||||
if i > 1 then
|
||||
status[i - 1] = strip_separator(status[i - 1], drawn_components[i - 1])
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
return status_str
|
||||
status[#status] = strip_separator(status[#status], drawn_components[#status])
|
||||
return table.concat(status)
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ local M = {}
|
|||
-- functionality at runtime .
|
||||
function M.expand_set_theme(func)
|
||||
-- execute a local version of global function to not get in a inf recurtion
|
||||
local set_theme = _G.set_lualine_theme
|
||||
_G.set_lualine_theme = function()
|
||||
local set_theme = _G.lualine_set_theme
|
||||
_G.lualine_set_theme = function()
|
||||
set_theme()
|
||||
func()
|
||||
end
|
||||
|
@ -16,8 +16,33 @@ end
|
|||
|
||||
-- Note for now only works for termguicolors scope can be background or foreground
|
||||
function M.extract_highlight_colors(color_group, scope)
|
||||
local color = string.format('#%06x', vim.api.nvim_get_hl_by_name(color_group, true)[scope])
|
||||
return color or nil
|
||||
if not M.highlight_exists(color_group) then return nil end
|
||||
local gui_colors = vim.api.nvim_get_hl_by_name(color_group, true)
|
||||
local cterm_colors = vim.api.nvim_get_hl_by_name(color_group, false)
|
||||
local color = {
|
||||
ctermfg = cterm_colors.foreground,
|
||||
ctermbg = cterm_colors.background,
|
||||
}
|
||||
if gui_colors.background then
|
||||
color.guibg = string.format('#%06x', gui_colors.background)
|
||||
gui_colors.background = nil
|
||||
end
|
||||
if gui_colors.foreground then
|
||||
color.guifg = string.format('#%06x', gui_colors.foreground)
|
||||
gui_colors.foreground = nil
|
||||
end
|
||||
cterm_colors.background = nil
|
||||
cterm_colors.foreground = nil
|
||||
color = vim.tbl_extend('keep', color, gui_colors, cterm_colors)
|
||||
if scope then return color[scope] end
|
||||
return color
|
||||
end
|
||||
|
||||
-- determine if an highlight exist and isn't cleared
|
||||
function M.highlight_exists(highlight_name)
|
||||
local ok, result = pcall(vim.api.nvim_exec, 'highlight '..highlight_name, true)
|
||||
if not ok then return false end
|
||||
return result:find('xxx cleared') == nil
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
Loading…
Reference in New Issue