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).
|
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
|
### Changing separator in section
|
||||||
Lualine defines a separator between components in given section, the default
|
Lualine defines two kinds of seperators. One is for sections and other is for components. Default section seperators are '', '' and component separators are '', ''.
|
||||||
separator is `|`. You can change the separator this way:
|
They require powerline patched fonts. But you can easily change yours to something else like below
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
lualine.options.separator = '|'
|
lualine.section_separators = {'', ''}
|
||||||
|
lualine.component_separators = {'', ''}
|
||||||
```
|
```
|
||||||
|
|
||||||
or disable it
|
or disable it
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
lualine.options.separator = ''
|
lualine.section_separators = nil
|
||||||
|
lualine.component_separators = nil
|
||||||
```
|
```
|
||||||
|
|
||||||
### Changing components in lualine sections
|
### Changing components in lualine sections
|
||||||
|
@ -304,7 +306,8 @@ All available extensions are listed in [EXTENSIONS.md](./EXTENSIONS.md)
|
||||||
local lualine = require('lualine')
|
local lualine = require('lualine')
|
||||||
lualine.options = {
|
lualine.options = {
|
||||||
theme = 'gruvbox',
|
theme = 'gruvbox',
|
||||||
separator = '|',
|
section_separators = {'', ''},
|
||||||
|
component_separators = {'', ''},
|
||||||
icons_enabled = true,
|
icons_enabled = true,
|
||||||
}
|
}
|
||||||
lualine.sections = {
|
lualine.sections = {
|
||||||
|
@ -341,7 +344,8 @@ lua << EOF
|
||||||
local lualine = require('lualine')
|
local lualine = require('lualine')
|
||||||
lualine.options = {
|
lualine.options = {
|
||||||
theme = 'gruvbox',
|
theme = 'gruvbox',
|
||||||
separator = '|',
|
section_separators = {'', ''},
|
||||||
|
component_separators = {'', ''},
|
||||||
icons_enabled = true,
|
icons_enabled = true,
|
||||||
}
|
}
|
||||||
lualine.sections = {
|
lualine.sections = {
|
||||||
|
|
|
@ -113,15 +113,19 @@ how to do it (./CONTRIBUTING.md).
|
||||||
|
|
||||||
CHANGING SEPARATOR IN SECTION *lualine_changing_separator*
|
CHANGING SEPARATOR IN SECTION *lualine_changing_separator*
|
||||||
|
|
||||||
Lualine defines a separator between components in given section, the default
|
Lualine defines two kinds of seperators. One is for sections and other is
|
||||||
separator is `|`. You can change the separator this way:
|
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
|
or disable it
|
||||||
>
|
>
|
||||||
lualine.options.separator = ''
|
lualine.section_separators = nil
|
||||||
|
lualine.component_separators = nil
|
||||||
<
|
<
|
||||||
|
|
||||||
CHANGING COMPONENTS IN LUALINE SECTIONS *lualine_changing_components*
|
CHANGING COMPONENTS IN LUALINE SECTIONS *lualine_changing_components*
|
||||||
|
@ -349,7 +353,8 @@ packer config
|
||||||
local lualine = require('lualine')
|
local lualine = require('lualine')
|
||||||
lualine.options = {
|
lualine.options = {
|
||||||
theme = 'gruvbox',
|
theme = 'gruvbox',
|
||||||
separator = '|',
|
section_separators = {'', ''},
|
||||||
|
component_separators = {'', ''},
|
||||||
icons_enabled = true,
|
icons_enabled = true,
|
||||||
}
|
}
|
||||||
lualine.sections = {
|
lualine.sections = {
|
||||||
|
@ -385,7 +390,8 @@ vimrc config
|
||||||
local lualine = require('lualine')
|
local lualine = require('lualine')
|
||||||
lualine.options = {
|
lualine.options = {
|
||||||
theme = 'gruvbox',
|
theme = 'gruvbox',
|
||||||
separator = '|',
|
section_separators = {'', ''},
|
||||||
|
component_separators = {'', ''},
|
||||||
icons_enabled = true,
|
icons_enabled = true,
|
||||||
}
|
}
|
||||||
lualine.sections = {
|
lualine.sections = {
|
||||||
|
|
114
lua/lualine.lua
114
lua/lualine.lua
|
@ -12,9 +12,11 @@ local theme_set = {}
|
||||||
M.options = {
|
M.options = {
|
||||||
icons_enabled = true,
|
icons_enabled = true,
|
||||||
theme = 'gruvbox',
|
theme = 'gruvbox',
|
||||||
separator = '|',
|
component_separators = {'', ''},
|
||||||
|
section_separators = {'', ''},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
M.sections = {
|
M.sections = {
|
||||||
lualine_a = { 'mode' },
|
lualine_a = { 'mode' },
|
||||||
lualine_b = { 'branch' },
|
lualine_b = { 'branch' },
|
||||||
|
@ -36,6 +38,17 @@ M.inactive_sections = {
|
||||||
M.extensions = {
|
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)
|
local function load_special_components(component)
|
||||||
return function()
|
return function()
|
||||||
-- precedence lualine_component > vim_var > lua_var > vim_function
|
-- precedence lualine_component > vim_var > lua_var > vim_function
|
||||||
|
@ -138,43 +151,91 @@ local function load_extensions()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function set_lualine_theme()
|
local function lualine_set_theme()
|
||||||
if type(M.options.theme) == 'string' then
|
if type(M.options.theme) == 'string' then
|
||||||
M.options.theme = require('lualine.themes.'.. M.options.theme)
|
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
|
||||||
|
end
|
||||||
|
reset_component_theme(M.sections)
|
||||||
|
reset_component_theme(M.inactive_sections)
|
||||||
|
end
|
||||||
|
highlight.clear_highlights()
|
||||||
highlight.create_highlight_groups(M.options.theme)
|
highlight.create_highlight_groups(M.options.theme)
|
||||||
theme_set = M.options.theme
|
theme_set = M.options.theme
|
||||||
end
|
end
|
||||||
|
|
||||||
local function statusline(sections, is_focused)
|
local function statusline(sections, is_focused)
|
||||||
if M.theme ~= theme_set then
|
if M.options.theme ~= theme_set then
|
||||||
set_lualine_theme()
|
_G.lualine_set_theme()
|
||||||
end
|
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 = {}
|
local status = {}
|
||||||
if sections.lualine_a then
|
local half_passed = false
|
||||||
local hl = highlight.format_highlight(is_focused, 'lualine_a')
|
for i=1,#status_builder do
|
||||||
table.insert(status, utils_component.draw_section(sections.lualine_a, hl))
|
-- 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
|
end
|
||||||
if sections.lualine_b then
|
-- provide section_separators when statusline is in focus
|
||||||
local hl = highlight.format_highlight(is_focused, 'lualine_b')
|
if is_focused then
|
||||||
table.insert(status, utils_component.draw_section(sections.lualine_b, hl))
|
-- 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
|
||||||
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
|
end
|
||||||
table.insert(status, "%=")
|
|
||||||
if sections.lualine_x then
|
-- **( insert the actual section in the middle )** --
|
||||||
local hl = highlight.format_highlight(is_focused, 'lualine_c')
|
table.insert(status, status_builder[i].data)
|
||||||
table.insert(status, utils_component.draw_section(sections.lualine_x, hl))
|
|
||||||
|
-- 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
|
||||||
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
|
end
|
||||||
if sections.lualine_z then
|
else -- when not in focus
|
||||||
local hl = highlight.format_highlight(is_focused, 'lualine_a')
|
table.insert(status, status_builder[i].data)
|
||||||
table.insert(status, utils_component.draw_section(sections.lualine_z, hl))
|
end
|
||||||
|
end
|
||||||
|
-- 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
|
end
|
||||||
return table.concat(status)
|
return table.concat(status)
|
||||||
end
|
end
|
||||||
|
@ -188,12 +249,12 @@ local function status_dispatch()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function exec_autocommands()
|
local function exec_autocommands()
|
||||||
_G.set_lualine_theme = set_lualine_theme
|
_G.lualine_set_theme = lualine_set_theme
|
||||||
_G.lualine_statusline = status_dispatch
|
_G.lualine_statusline = status_dispatch
|
||||||
vim.api.nvim_exec([[
|
vim.api.nvim_exec([[
|
||||||
augroup lualine
|
augroup lualine
|
||||||
autocmd!
|
autocmd!
|
||||||
autocmd ColorScheme * call v:lua.set_lualine_theme()
|
autocmd ColorScheme * call v:lua.lualine_set_theme()
|
||||||
autocmd WinLeave,BufLeave * lua vim.wo.statusline=lualine_statusline()
|
autocmd WinLeave,BufLeave * lua vim.wo.statusline=lualine_statusline()
|
||||||
autocmd WinEnter,BufEnter * setlocal statusline=%!v:lua.lualine_statusline()
|
autocmd WinEnter,BufEnter * setlocal statusline=%!v:lua.lualine_statusline()
|
||||||
augroup END
|
augroup END
|
||||||
|
@ -201,7 +262,8 @@ local function exec_autocommands()
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.status()
|
function M.status()
|
||||||
set_lualine_theme()
|
check_single_separator()
|
||||||
|
lualine_set_theme()
|
||||||
exec_autocommands()
|
exec_autocommands()
|
||||||
load_components()
|
load_components()
|
||||||
load_extensions()
|
load_extensions()
|
||||||
|
|
|
@ -12,13 +12,13 @@ local function signify(options)
|
||||||
if options.colored == nil then options.colored = true end
|
if options.colored == nil then options.colored = true end
|
||||||
-- apply colors
|
-- apply colors
|
||||||
if not options.color_added then
|
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
|
end
|
||||||
if not options.color_modified then
|
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
|
end
|
||||||
if not options.color_removed then
|
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
|
end
|
||||||
|
|
||||||
local highlights = {}
|
local highlights = {}
|
||||||
|
@ -36,7 +36,6 @@ local function signify(options)
|
||||||
if options.colored then
|
if options.colored then
|
||||||
create_highlights()
|
create_highlights()
|
||||||
utils.expand_set_theme(create_highlights)
|
utils.expand_set_theme(create_highlights)
|
||||||
options.custom_highlight = true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Function that runs everytime statusline is updated
|
-- Function that runs everytime statusline is updated
|
||||||
|
|
|
@ -3,18 +3,38 @@
|
||||||
|
|
||||||
local M = { }
|
local M = { }
|
||||||
local utils_colors = require "lualine.utils.cterm_colors"
|
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 function highlight (name, foreground, background, gui)
|
||||||
local command = {
|
local command = { 'highlight', name, }
|
||||||
'highlight', name,
|
if foreground then
|
||||||
'ctermfg=' .. (foreground[2] or utils_colors.get_cterm_color(foreground)),
|
table.insert(command, 'ctermfg=' .. (foreground[2] or
|
||||||
'ctermbg=' .. (background[2] or utils_colors.get_cterm_color(background)),
|
(foreground ~= 'none' and utils_colors.get_cterm_color(foreground)) or 'none'))
|
||||||
'cterm=' .. (gui or 'none'),
|
table.insert(command, 'guifg=' .. (foreground[1] or foreground))
|
||||||
'guifg=' .. (foreground[1] or foreground),
|
end
|
||||||
'guibg=' .. (background[1] or background),
|
if background then
|
||||||
'gui=' .. (gui or 'none'),
|
table.insert(command, 'ctermbg=' .. (background[2] or
|
||||||
}
|
(background ~= 'none' and utils_colors.get_cterm_color(background)) or 'none'))
|
||||||
return table.concat(command, ' ')
|
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
|
end
|
||||||
|
|
||||||
local function apply_defaults_to_theme(theme)
|
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 mode, sections in pairs(theme) do
|
||||||
for section, colorscheme in pairs(sections) do
|
for section, colorscheme in pairs(sections) do
|
||||||
local highlight_group_name = { 'lualine', section, mode }
|
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
|
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 function append_mode(highlight_group)
|
||||||
local mode = require('lualine.components.mode')()
|
local mode = require('lualine.components.mode')()
|
||||||
if mode == 'VISUAL' or mode == 'V-BLOCK' or mode == 'V-LINE'
|
if mode == 'VISUAL' or mode == 'V-BLOCK' or mode == 'V-LINE'
|
||||||
|
@ -68,51 +91,138 @@ end
|
||||||
-- @@highlight_tag is unique tag for highlight group
|
-- @@highlight_tag is unique tag for highlight group
|
||||||
-- returns the name of highlight group
|
-- returns the name of highlight group
|
||||||
-- @@options is parameter of component.init() function
|
-- @@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)
|
function M.create_component_highlight_group(color , highlight_tag, options)
|
||||||
if color.bg and color.fg then
|
if 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
|
-- 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', 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
|
return highlight_group_name
|
||||||
end
|
end
|
||||||
|
|
||||||
local modes = {'normal', 'insert', 'visual', 'replace', 'command', 'terminal', 'inactive'}
|
local modes = {'normal', 'insert', 'visual', 'replace', 'command', 'terminal', 'inactive'}
|
||||||
for _, mode in ipairs(modes) do
|
local normal_hl
|
||||||
local highlight_group_name = { options.self.section, highlight_tag, mode }
|
|
||||||
-- convert lualine_a -> a before setting section
|
-- convert lualine_a -> a before setting section
|
||||||
local section = options.self.section:match('lualine_(.*)')
|
local section = options.self.section:match('lualine_(.*)')
|
||||||
local bg = (color.bg or options.theme[mode][section]['bg'])
|
if section > 'c' then
|
||||||
local fg = (color.fg or options.theme[mode][section]['fg'])
|
section = section_highlight_map[section]
|
||||||
vim.cmd(highlight(table.concat(highlight_group_name, '_'), fg, bg, color.gui))
|
end
|
||||||
|
for _, mode in ipairs(modes) do
|
||||||
|
local highlight_group_name = { options.self.section, highlight_tag, mode }
|
||||||
|
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
|
end
|
||||||
return options.self.section..'_'..highlight_tag
|
return options.self.section..'_'..highlight_tag
|
||||||
end
|
end
|
||||||
|
|
||||||
-- retrieve highlight_groups for components
|
-- @description: retrieve highlight_groups for components
|
||||||
-- @@highlight_name received from create_component_highlight_group
|
-- @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)
|
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
|
if highlight_name:find('no_mode') == #highlight_name - #'no_mode' + 1 then
|
||||||
return highlight_group..'#'
|
return '%#'..highlight_group..'#'
|
||||||
end
|
end
|
||||||
if vim.g.statusline_winid == vim.fn.win_getid() then
|
if vim.g.statusline_winid == vim.fn.win_getid() then
|
||||||
highlight_group = append_mode(highlight_group)..'#'
|
highlight_group = append_mode(highlight_group)
|
||||||
else
|
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
|
end
|
||||||
return highlight_group
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.format_highlight(is_focused, highlight_group)
|
function M.format_highlight(is_focused, highlight_group)
|
||||||
highlight_group = [[%#]] .. highlight_group
|
if highlight_group > 'lualine_c' then
|
||||||
if not is_focused then
|
highlight_group = 'lualine_' .. section_highlight_map[highlight_group:match('lualine_(.)')]
|
||||||
highlight_group = highlight_group .. [[_inactive]]
|
|
||||||
else
|
|
||||||
highlight_group = append_mode(highlight_group)
|
|
||||||
end
|
end
|
||||||
highlight_group = highlight_group .. [[#]]
|
local highlight_name = highlight_group
|
||||||
return 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
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|
|
@ -44,51 +44,76 @@ end
|
||||||
|
|
||||||
-- Apply separator at end of component only when
|
-- Apply separator at end of component only when
|
||||||
-- custom highlights haven't affected background
|
-- custom highlights haven't affected background
|
||||||
local function apply_spearator(status, options)
|
local function apply_spearator(status, options, highlight_name)
|
||||||
if options.separator and #options.separator > 0 and
|
local separator
|
||||||
(not options.color or not options.color.bg) then
|
if options.separator and #options.separator > 0 then
|
||||||
status = status .. options.separator
|
separator = options.separator
|
||||||
options.separator_applied = true
|
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
|
end
|
||||||
return status
|
return status
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns formated string for a section
|
-- Returns formated string for a section
|
||||||
function M.draw_section(section, highlight)
|
function M.draw_section(section, highlight_name)
|
||||||
local status = {}
|
local status = {}
|
||||||
|
local drawn_components = {}
|
||||||
for _, component in pairs(section) do
|
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]()
|
local localstatus = component[1]()
|
||||||
if #localstatus > 0 then
|
if #localstatus > 0 then
|
||||||
|
local custom_highlight_at_begining = localstatus:find('%%#.*#') == 1 or component.color ~= nil
|
||||||
-- Apply modifier functions for options
|
-- Apply modifier functions for options
|
||||||
if component.format then localstatus = component.format(localstatus) end
|
if component.format then localstatus = component.format(localstatus) end
|
||||||
localstatus = apply_icon(localstatus, component)
|
localstatus = apply_icon(localstatus, component)
|
||||||
localstatus = apply_case(localstatus, component)
|
localstatus = apply_case(localstatus, component)
|
||||||
localstatus = apply_padding(localstatus, component)
|
localstatus = apply_padding(localstatus, component)
|
||||||
localstatus = apply_highlights(localstatus, component)
|
localstatus = apply_highlights(localstatus, component)
|
||||||
localstatus = apply_spearator(localstatus, component)
|
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)
|
table.insert(status, localstatus)
|
||||||
component.drawn = true
|
else
|
||||||
|
table.insert(status, highlight_name .. localstatus)
|
||||||
|
end
|
||||||
|
table.insert(drawn_components, component)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- Draw nothing when all the components were empty
|
-- Draw nothing when all the components were empty
|
||||||
if #status == 0 then return '' end
|
if #status == 0 then return '' end
|
||||||
-- convert to single string
|
-- Remove separators sorounding custom highlighted component
|
||||||
-- highlight is used as separator so custom highlights don't affect
|
for i=1,#status do
|
||||||
-- later components
|
if (drawn_components[i].color and drawn_components[i].color.bg)
|
||||||
local status_str = highlight .. table.concat(status, highlight)
|
or drawn_components[i].custom_highlight then
|
||||||
-- Remove separator from last drawn component if available
|
status[i] = strip_separator(status[i], drawn_components[i])
|
||||||
for last_component = #section, 1, -1 do
|
if i > 1 then
|
||||||
if section[last_component].drawn then
|
status[i - 1] = strip_separator(status[i - 1], drawn_components[i - 1])
|
||||||
if section[last_component].separator_applied then
|
|
||||||
status_str = status_str:sub(1, #status_str - #section[last_component].separator)
|
|
||||||
end
|
|
||||||
break
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return status_str
|
end
|
||||||
|
status[#status] = strip_separator(status[#status], drawn_components[#status])
|
||||||
|
return table.concat(status)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,8 @@ local M = {}
|
||||||
-- functionality at runtime .
|
-- functionality at runtime .
|
||||||
function M.expand_set_theme(func)
|
function M.expand_set_theme(func)
|
||||||
-- execute a local version of global function to not get in a inf recurtion
|
-- execute a local version of global function to not get in a inf recurtion
|
||||||
local set_theme = _G.set_lualine_theme
|
local set_theme = _G.lualine_set_theme
|
||||||
_G.set_lualine_theme = function()
|
_G.lualine_set_theme = function()
|
||||||
set_theme()
|
set_theme()
|
||||||
func()
|
func()
|
||||||
end
|
end
|
||||||
|
@ -16,8 +16,33 @@ end
|
||||||
|
|
||||||
-- Note for now only works for termguicolors scope can be background or foreground
|
-- Note for now only works for termguicolors scope can be background or foreground
|
||||||
function M.extract_highlight_colors(color_group, scope)
|
function M.extract_highlight_colors(color_group, scope)
|
||||||
local color = string.format('#%06x', vim.api.nvim_get_hl_by_name(color_group, true)[scope])
|
if not M.highlight_exists(color_group) then return nil end
|
||||||
return color or nil
|
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
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|
Loading…
Reference in New Issue