From 20d7f33ef961eaa5161db899778f2f47d3e6c536 Mon Sep 17 00:00:00 2001 From: Shadman Date: Tue, 16 Feb 2021 00:09:12 +0600 Subject: [PATCH] feat: adding component specific options (#60) --- README.md | 110 +++++++++++++- doc/lualine.txt | 138 ++++++++++++++++-- doc/tags | 1 + lua/lualine.lua | 94 ++++++++---- lua/lualine/components/branch.lua | 33 ++--- lua/lualine/components/fileformat.lua | 20 ++- lua/lualine/components/filename.lua | 35 ++++- lua/lualine/components/filetype.lua | 34 ++--- lua/lualine/highlight.lua | 85 ++++++++--- lua/lualine/utils/component.lua | 95 ++++++++++++ .../{utils.lua => utils/cterm_colors.lua} | 22 +-- lua/lualine/utils/utils.lua | 17 +++ 12 files changed, 549 insertions(+), 135 deletions(-) create mode 100644 lua/lualine/utils/component.lua rename lua/lualine/{utils.lua => utils/cterm_colors.lua} (95%) create mode 100644 lua/lualine/utils/utils.lua diff --git a/README.md b/README.md index dac6b22..bd87fbd 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ lualine.status() ``` ### Setting a theme ```lua -lualine.theme = 'gruvbox' +lualine.options.theme = 'gruvbox' ``` All available themes are listed in [THEMES.md](./THEMES.md) @@ -90,13 +90,13 @@ Lualine defines a separator between components in given section, the default separator is `|`. You can change the separator this way: ```lua -lualine.separator = '|' +lualine.options.separator = '|' ``` or disable it ```lua -lualine.separator = '' +lualine.options.separator = '' ``` ### Changing components in lualine sections @@ -120,7 +120,7 @@ lualine.inactive_sections = { lualine_c = { 'filename' }, lualine_x = { 'location' }, lualine_y = { }, - lualine_z = { } + lualine_z = { } } ``` @@ -158,6 +158,7 @@ lualine.sections.lualine_a = { hello }
+ Using vim functions as lualine component You can use vim functions as a lualine component @@ -181,6 +182,93 @@ lualine.sections.lualine_b = { 'g:coc_status', 'bo:filetype' }
+
+Options for components + +### Available options: + +#### Global Default options + +Default options act as default for all components +- icons_enabled (Default: true) + Displays icons on components + You should have powerline supported fonts to see + icons properly.\ + *Suported by branch, fileformat, filetype, location*\ + Example: + ```lua + lualine.options.icons_enabled = true + + ``` + +#### Genaral options + These options are available for all components.\ + option     (default_value)\ + ----------       ---------------------- +- padding (1)\ + spaces on left and right +- left_padding (1)\ + spaces on left +- right_padding (1)\ + spaces on right +- icon (depends on component) + displays an icon infront of component +- icons_enabled (true) + whether to show icon(if available) +- separator ('|') + which separator to use at end of component +- upper (false)\ + Displayed in upper case +- lower (false)\ + Displayed in lower case +- format (nil)\ + Takes a function . The funtion gets the result of component + as argument and it's return value is displayed. So this function + can parse and format the output as user wants. +- color (Theme colors)\ + color option can be used to set custom color to a component\ + **Color format:**\ + `lua color = {fg = '#rrggbb', bg= '#rrggbb', gui='style'}`\ + the members of color table are optional and default to theme + +#### Component specific options + These options are available for specific components only.\ + List of options are given below. +- filename + - file_status (true)\ + Whether to display filemodified status in filename + - shorten (true)\ + Whether to display full/relative path with filename + - full_path (false)\ + Whether to display full path when shorten is false +- fileformat + - icons_enabled (true)\ + Whether to displays icon before component + +**Example:** +```lua +lualine.sections.lualine_b = { + { + 'branch', + icon = '', + upper = true, + color = { fg = '#00aa22' } + }, + { + 'filename', + full_name = true, + relative = true, + format = function(name) + -- Capitalize first charecter of filename to capital. + local path, fname = name:match('(.*/)(.*)') + rerurn path .. fname[1, 1]:upper() .. fname[2, #fname] + end + } +} +``` + +
+ ### Loading plugin extensions Lualine extensions change statusline appearance for a window/buffer with a plugin loaded e.g. [junegunn/fzf.vim](https://github.com/junegunn/fzf.vim) @@ -202,8 +290,11 @@ All available extensions are listed in [EXTENSIONS.md](./EXTENSIONS.md) requires = {'kyazdani42/nvim-web-devicons', opt = true}, config = function() local lualine = require('lualine') - lualine.theme = 'gruvbox' - lualine.separator = '|' + lualine.options = { + theme = 'gruvbox', + separator = '|', + icons_enabled = true, + } lualine.sections = { lualine_a = { 'mode' }, lualine_b = { 'branch' }, @@ -236,8 +327,11 @@ All available extensions are listed in [EXTENSIONS.md](./EXTENSIONS.md) ```vim lua << EOF local lualine = require('lualine') - lualine.theme = 'gruvbox' - lualine.separator = '|' + lualine.options = { + theme = 'gruvbox', + separator = '|', + icons_enabled = true, + } lualine.sections = { lualine_a = { 'mode' }, lualine_b = { 'branch' }, diff --git a/doc/lualine.txt b/doc/lualine.txt index 6d93bee..c836387 100644 --- a/doc/lualine.txt +++ b/doc/lualine.txt @@ -32,14 +32,15 @@ CONTENTS *lualline-contents* 1.2.2.packer.nvim..................................|lualine-packer.nvim| 1.3. Usage and customization...............|lualine-usage_and_customization| 1.3.1. Starting lualine.......................|lualine-starting_lualine| - 1.3.2. Setting a theme.........................|lualine-setting_a_theme| + 1.3.2. Setting theme.............................|lualine-setting_theme| 1.3.3. Changing separator...................|lualine-changing_separator| 1.3.4. Changing components.................|lualine-changing_components| 1.3.5. Building Custom components............|lualine-custom_components| - 1.3.6. Loading plugin extensions.....|lualine-loading_plugin_extensions| - 1.3.7 Config examples.........................|lualine-config_examples| - 1.3.7.1. Packer.nvim......|lualine-config_example_using_packer.nvim| - 1.3.7.2 VIML example.......|lualine-full_config_example_inside_viml| + 1.3.6. Custom options...........................|lualine-custom_options| + 1.3.7. Loading plugin extensions.....|lualine-loading_plugin_extensions| + 1.3.8 Config examples.........................|lualine-config_examples| + 1.3.8.1. Packer.nvim......|lualine-config_example_using_packer.nvim| + 1.3.8.2 VIML example.......|lualine-full_config_example_inside_viml| 1.4. Contributing.....................................|lualine-contributing| 1.5. Screenshots.......................................|lualine-screenshots| @@ -100,9 +101,9 @@ STARTING LUALINE *lualine-starting_lualine* lualine.status() < -SETTING A THEME *lualine-setting_a_theme* +SETTING THEME *lualine-setting_theme* > - lualine.theme = 'gruvbox' + lualine.options.theme = 'gruvbox' < All available themes are listed in THEMES.md (./THEMES.md) @@ -115,12 +116,12 @@ 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.separator = '|' + lualine.options.separator = '|' < or disable it > - lualine.separator = '' + lualine.options.separator = '' < CHANGING COMPONENTS IN LUALINE SECTIONS *lualine-changing_components* @@ -196,6 +197,111 @@ can be used. Scopes ending with o are options usualy accessed with `&` in vimscr lualine.sections.lualine_x = { 'vim.bo.fileencoding' } < +-------------------------------------------------------------------------------- +CUSTOM OPTIONS FOR COMPONENTS *lualine-custom_options* + + +Options for components~ +====================== + +Global Default options~ +---------------------- + +Default options act as default for all components + +icons_enabled (Default: true) + + Displays icons on components + You should have powerline supported fonts to see + icons properly. + Suported by branch, fileformat, filetype, location + + Example: + `lualine.options.icons_enabled = true` + +Genaral options~ +--------------- +These options are available for all components. + +option (default_value) +------ --------------- + + • padding (1) + spaces on left and right + + • left_padding (1) + spaces on left + + • icon (depends on component) + displays an icon infront of a component + + • icons_enabled (true) + whether to show icon(if available) + + • right_padding (1) + spaces on right + + • separator ('|') + which separator to use at end of component + + • upper (false) + Displayed in upper case + + • lower (false) + Displayed in lower case + + • format (nil) + Takes a function . The funtion gets the result of component + as argument and it's return value is displayed. So this function + can parse and format the output as user wants. + + • color (Theme colors) + color option can be used to set custom color to a component + Color format: + `lua color = {fg = '#rrggbb', bg= '#rrggbb', gui='style'}` + the members of color table are optional and default to theme + + +Component specific options~ +-------------------------- +These options are available for specific components only. +List of options are given below. + + • filename~ + • file_status (true) + Whether to display filemodified status in filename + + • shorten (true) + Whether to display full/relative path with filename + + • full_path (false) + Whether to display full path when shorten is false + + • fileformat~ + • icons_enabled (true) + Whether to displays icon before component + +Example:~ +> + lualine.sections.lualine_b = { + { + 'branch', + icon = '', + upper = true, + color = { fg = '#00aa22' } + }, + { + 'filename', + full_name = true, + relative = true, + format = function(name) + -- Capitalize first charecter of filename to capital. + local path, fname = name:match('(.*/)(.*)') + rerurn path .. fname[1, 1]:upper() .. fname[2, #fname] + end + } + } +< -------------------------------------------------------------------------------- LOADING PLUGIN EXTENSIONS *lualine-loading_plugin_extensions* @@ -224,8 +330,11 @@ packer config requires = {'kyazdani42/nvim-web-devicons', opt = true}, config = function() local lualine = require('lualine') - lualine.theme = 'gruvbox' - lualine.separator = '|' + lualine.options = { + theme = 'gruvbox', + separator = '|', + icons_enabled = true, + } lualine.sections = { lualine_a = { 'mode' }, lualine_b = { 'branch' }, @@ -257,8 +366,11 @@ vimrc config > lua << EOF local lualine = require('lualine') - lualine.theme = 'gruvbox' - lualine.separator = '|' + lualine.options = { + theme = 'gruvbox', + separator = '|', + icons_enabled = true, + } lualine.sections = { lualine_a = { 'mode' }, lualine_b = { 'branch' }, diff --git a/doc/tags b/doc/tags index b2ed772..fd0447d 100644 --- a/doc/tags +++ b/doc/tags @@ -5,6 +5,7 @@ lualine-config_example_using_packer.nvim lualine.txt /*lualine-config_example_us lualine-config_examples lualine.txt /*lualine-config_examples* lualine-contributing lualine.txt /*lualine-contributing* lualine-custom_components lualine.txt /*lualine-custom_components* +lualine-custom_options lualine.txt /*lualine-custom_options* lualine-full_config_example_inside_viml lualine.txt /*lualine-full_config_example_inside_viml* lualine-installation lualine.txt /*lualine-installation* lualine-loading_plugin_extensions lualine.txt /*lualine-loading_plugin_extensions* diff --git a/lua/lualine.lua b/lua/lualine.lua index 3d8b344..bad4437 100644 --- a/lua/lualine.lua +++ b/lua/lualine.lua @@ -1,15 +1,19 @@ -- Copyright (c) 2020-2021 hoob3rt -- MIT license, see LICENSE for more details. -local utils = require('lualine.utils') +local utils_component = require('lualine.utils.component') +local utils = require('lualine.utils.utils') local highlight = require('lualine.highlight') local M = { } -M.theme = 'gruvbox' local theme_set = {} -M.separator = '|' +M.options = { + icons_enabled = true, + theme = 'gruvbox', + separator = '|', +} M.sections = { lualine_a = { 'mode' }, @@ -68,17 +72,51 @@ local function load_special_components(component) end end +local function component_loader(component) + if type(component[1]) == 'function' then return component end + if type(component[1]) == 'string' then + -- Keep component name for later use as component[1] will be overwritten + -- With component function + component.component_name = component[1] + -- apply default args + for opt_name, opt_val in pairs(M.options) do + if component[opt_name] == nil then + component[opt_name] = opt_val + end + end + -- load the component + local ok, loaded_component = pcall(require, 'lualine.components.' .. component.component_name) + if not ok then + loaded_component = load_special_components(component.component_name) + end + component[1] = loaded_component + if type(component[1]) == 'table' then + component[1] = component[1].init(component) + end + -- set custom highlights + if component.color then + local function update_color() + component.color_highlight = highlight.create_component_highlight_group( + component.color, component.component_name, component) + end + update_color() + utils.expand_set_theme(update_color) + end + end +end + + local function load_components() local function load_sections(sections) - for _, section in pairs(sections) do + for section_name, section in pairs(sections) do for index, component in pairs(section) do - if type(component) == 'string' then - local ok,loaded_component = pcall(require, 'lualine.components.' .. component) - if not ok then - loaded_component = load_special_components(component) - end - section[index] = loaded_component + if type(component) == 'string' or type(component) == 'function' then + component = {component} end + component.self = {} + component.self.section = section_name + component_loader(component) + section[index] = component end end end @@ -101,11 +139,11 @@ local function load_extensions() end local function set_lualine_theme() - if type(M.theme) == 'string' then - M.theme = require('lualine.themes.'.. M.theme) + if type(M.options.theme) == 'string' then + M.options.theme = require('lualine.themes.'.. M.options.theme) end - highlight.create_highlight_groups(M.theme) - theme_set = M.theme + highlight.create_highlight_groups(M.options.theme) + theme_set = M.options.theme end local function statusline(sections, is_focused) @@ -114,29 +152,29 @@ local function statusline(sections, is_focused) end local status = {} if sections.lualine_a then - table.insert(status, highlight.format_highlight(is_focused, 'lualine_a')) - table.insert(status, utils.draw_section(sections.lualine_a, M.separator)) + local hl = highlight.format_highlight(is_focused, 'lualine_a') + table.insert(status, utils_component.draw_section(sections.lualine_a, hl)) end if sections.lualine_b then - table.insert(status, highlight.format_highlight(is_focused, 'lualine_b')) - table.insert(status, utils.draw_section(sections.lualine_b, M.separator)) + 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 - table.insert(status, highlight.format_highlight(is_focused, 'lualine_c')) - table.insert(status, utils.draw_section(sections.lualine_c, M.separator)) + 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 - table.insert(status, highlight.format_highlight(is_focused, 'lualine_c')) - table.insert(status, utils.draw_section(sections.lualine_x, M.separator)) + 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 - table.insert(status, highlight.format_highlight(is_focused, 'lualine_b')) - table.insert(status, utils.draw_section(sections.lualine_y, M.separator)) + 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 - table.insert(status, highlight.format_highlight(is_focused, 'lualine_a')) - table.insert(status, utils.draw_section(sections.lualine_z, M.separator)) + local hl = highlight.format_highlight(is_focused, 'lualine_a') + table.insert(status, utils_component.draw_section(sections.lualine_z, hl)) end return table.concat(status) end @@ -160,10 +198,10 @@ local function exec_autocommands() end function M.status() - load_components() - load_extensions() set_lualine_theme() exec_autocommands() + load_components() + load_extensions() _G.lualine_statusline = status_dispatch vim.o.statusline = '%!v:lua.lualine_statusline()' end diff --git a/lua/lualine/components/branch.lua b/lua/lualine/components/branch.lua index 6c01ec7..65377d0 100644 --- a/lua/lualine/components/branch.lua +++ b/lua/lualine/components/branch.lua @@ -1,4 +1,4 @@ --- Copyright (c) 2020-2021 hoob3rt +-- Copyright (c) 2020-2021 shadmansaleh -- MIT license, see LICENSE for more details. local git_branch @@ -62,31 +62,24 @@ local function watch_head() end end --- returns the git_branch value to be shown on statusline -local function branch() - if not git_branch or #git_branch == 0 then return '' end - local ok,devicons = pcall(require,'nvim-web-devicons') - if ok then - local icon = devicons.get_icon('git') - if icon ~= nil then - return icon .. ' ' .. git_branch - end +local function branch(options) + if not options.icon then + options.icon = '' -- e0a0 + end + + return function() + if not git_branch or #git_branch == 0 then return '' end return git_branch end - ok = vim.fn.exists("*WebDevIconsGetFileTypeSymbol") - if ok ~= 0 then - local icon = '' - return icon .. ' ' .. git_branch - end - return git_branch end -- run watch head on load so branch is present when component is loaded watch_head() --- TODO Don't export as a global function -_G.lualine_branch_update = watch_head -- update branch state of BufEnter as different Buffer may be on different repos -vim.cmd[[autocmd BufEnter * call v:lua.lualine_branch_update()]] +vim.cmd[[autocmd BufEnter * lua require'lualine.components.branch'.lualine_branch_update()]] -return branch +return { + init = function(options) return branch(options) end, + lualine_branch_update = watch_head + } diff --git a/lua/lualine/components/fileformat.lua b/lua/lualine/components/fileformat.lua index 92a9073..095eb6d 100644 --- a/lua/lualine/components/fileformat.lua +++ b/lua/lualine/components/fileformat.lua @@ -1,9 +1,19 @@ --- Copyright (c) 2020-2021 hoob3rt +-- Copyright (c) 2020-2021 shadmansaleh -- MIT license, see LICENSE for more details. -local function fileformat() - local data = [[%{&ff}]] - return data +local function fileformat(options) + local icon_linux = "" -- e712 + local icon_windos = "" -- e70f + local icon_mac = "" -- e711 + return function() + if options.icons_enabled and not options.icon then + local format = vim.bo.fileformat + if format == 'unix' then return icon_linux + elseif format == 'dos' then return icon_windos + elseif format == 'mac' then return icon_mac end + end + return vim.bo.fileformat + end end -return fileformat +return { init = function(options) return fileformat(options) end } diff --git a/lua/lualine/components/filename.lua b/lua/lualine/components/filename.lua index f748daf..c951ead 100644 --- a/lua/lualine/components/filename.lua +++ b/lua/lualine/components/filename.lua @@ -1,9 +1,34 @@ --- Copyright (c) 2020-2021 hoob3rt +-- Copyright (c) 2020-2021 shadmansaleh -- MIT license, see LICENSE for more details. -local function filename() - local data = [[%t %m]] - return data +local function filename(options) + -- setting defaults + local file_status, shorten, full_path = true, true, false + if options.file_status ~= nil then file_status = options.file_status end + if options.shorten ~= nil then shorten = options.shorten end + if options.full_path ~= nil then full_path = options.full_path end + + return function() + local data + if shorten then + data = vim.fn.expand('%:t') + elseif full_path then + data = vim.fn.expand('%:p') + else + data = vim.fn.expand('%') + end + if data == '' then + data = '[No Name]' + elseif vim.fn.winwidth(0) <= 84 or #data > 40 then + data = vim.fn.pathshorten(data) + end + + if file_status then + if vim.bo.modified then data = data .. "[+]" + elseif vim.bo.modifiable == false then data = data .. "[-]" end + end + return data + end end -return filename +return { init = function(options) return filename(options) end } diff --git a/lua/lualine/components/filetype.lua b/lua/lualine/components/filetype.lua index f212479..8d8f9c7 100644 --- a/lua/lualine/components/filetype.lua +++ b/lua/lualine/components/filetype.lua @@ -1,26 +1,24 @@ -- Copyright (c) 2020-2021 hoob3rt -- MIT license, see LICENSE for more details. -local function filetype() - local data = vim.bo.filetype - if #data > 0 then - local ok,devicons = pcall(require,'nvim-web-devicons') - if ok then - local f_name,f_extension = vim.fn.expand('%:t'),vim.fn.expand('%:e') - local icon = devicons.get_icon(f_name,f_extension) - if icon ~= nil then - return icon .. ' ' .. data +local function filetype(options) + return function() + local data = vim.bo.filetype + if #data > 0 then + local ok, devicons = pcall(require,'nvim-web-devicons') + if ok and not options.icon then + local f_name,f_extension = vim.fn.expand('%:t'),vim.fn.expand('%:e') + options.icon = devicons.get_icon(f_name,f_extension) + else + ok = vim.fn.exists("*WebDevIconsGetFileTypeSymbol") + if ok ~= 0 and not options.icon then + options.icon = vim.fn.WebDevIconsGetFileTypeSymbol() + end end - return data + return data end - ok = vim.fn.exists("*WebDevIconsGetFileTypeSymbol") - if ok ~= 0 then - local icon = vim.fn.WebDevIconsGetFileTypeSymbol() - return icon .. ' ' .. data - end - return data + return '' end - return '' end -return filetype +return { init = function(options) return filetype(options) end } diff --git a/lua/lualine/highlight.lua b/lua/lualine/highlight.lua index 0c40c73..b24130f 100644 --- a/lua/lualine/highlight.lua +++ b/lua/lualine/highlight.lua @@ -2,13 +2,13 @@ -- MIT license, see LICENSE for more details. local M = { } -local utils = require "lualine.utils" +local utils_colors = require "lualine.utils.cterm_colors" local function highlight (name, foreground, background, gui) local command = { 'highlight', name, - 'ctermfg=' .. (foreground[2] or utils.get_cterm_color(foreground)), - 'ctermbg=' .. (background[2] or utils.get_cterm_color(background)), + '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), @@ -41,26 +41,75 @@ function M.create_highlight_groups(theme) end end -function M.format_highlight(is_focused, highlight_group) +local function append_mode(highlight_group) local mode = require('lualine.components.mode')() + if mode == 'VISUAL' or mode == 'V-BLOCK' or mode == 'V-LINE' + or mode == 'SELECT' or mode == 'S-LINE' or mode == 'S-BLOCK'then + highlight_group = highlight_group .. '_visual' + elseif mode == 'REPLACE' or mode == 'V-REPLACE' then + highlight_group = highlight_group .. '_replace' + elseif mode == 'INSERT' then + highlight_group = highlight_group .. '_insert' + elseif mode == 'COMMAND' or mode == 'EX' or mode == 'MORE' or mode == 'CONFIRM'then + highlight_group = highlight_group .. '_command' + elseif mode == 'TERMINAL' then + highlight_group = highlight_group .. '_terminal' + else + highlight_group = highlight_group .. '_normal' + end + return highlight_group +end + +-- Create highlight group with fg bg and gui from theme +-- section and theme are extracted from @options.self table +-- @@color has to be { fg = "#rrggbb", bg="#rrggbb" gui = "effect" } +-- all the color elements are optional if fg or bg is not given options must be provided +-- So fg and bg can default the themes colors +-- @@highlight_tag is unique tag for highlight group +-- returns the name of highlight group +-- @@options is parameter of component.init() function +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 + local highlight_group_name = table.concat({ 'lualine', highlight_tag, 'no_mode'}, '_') + vim.cmd(highlight(highlight_group_name, color.fg, color.bg, color.gui)) + return highlight_group_name + end + + local modes = {'normal', 'insert', 'visual', 'replace', 'command', 'terminal', 'inactive'} + 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)) + end + return options.self.section..'_'..highlight_tag +end + +-- retrieve highlight_groups for components +-- @@highlight_name received from create_component_highlight_group +function M.component_format_highlight(highlight_name) + local highlight_group = [[%#]]..highlight_name + if highlight_name:find('no_mode') == #highlight_name - #'no_mode' + 1 then + return highlight_group..'#' + end + if vim.g.statusline_winid == vim.fn.win_getid() then + highlight_group = append_mode(highlight_group)..'#' + else + highlight_group = highlight_group..'_inactive'..'#' + 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 - if mode == 'VISUAL' or mode == 'V-BLOCK' or mode == 'V-LINE' - or mode == 'SELECT' or mode == 'S-LINE' or mode == 'S-BLOCK'then - highlight_group = highlight_group .. '_visual' - elseif mode == 'REPLACE' or mode == 'V-REPLACE' then - highlight_group = highlight_group .. '_replace' - elseif mode == 'INSERT' then - highlight_group = highlight_group .. '_insert' - elseif mode == 'COMMAND' or mode == 'EX' or mode == 'MORE' or mode == 'CONFIRM'then - highlight_group = highlight_group .. '_command' - elseif mode == 'TERMINAL' then - highlight_group = highlight_group .. '_terminal' - else - highlight_group = highlight_group .. '_normal' - end + highlight_group = append_mode(highlight_group) end highlight_group = highlight_group .. [[#]] return highlight_group diff --git a/lua/lualine/utils/component.lua b/lua/lualine/utils/component.lua new file mode 100644 index 0000000..8afd5cf --- /dev/null +++ b/lua/lualine/utils/component.lua @@ -0,0 +1,95 @@ +-- Copyright (c) 2020-2021 shadmansaleh +-- MIT license, see LICENSE for more details. + +local M = { } + +local highlight = require'lualine.highlight' + +-- set upper or lower case +local function apply_case(status, options) + -- Donn't work on components that emit vim statusline escaped chars + if status:find('%%') and not status:find('%%%%') then return status end + if options.upper == true then + return status:upper() + elseif options.lower == true then + return status:lower() + end + return status +end + +-- Adds spaces to left and right of a component +local function apply_padding(status, options) + local l_padding = (options.left_padding or options.padding or 1) + local r_padding = (options.right_padding or options.padding or 1) + if l_padding then status = string.rep(' ', l_padding)..status end + if r_padding then status = status..string.rep(' ', r_padding) end + return status +end + +-- Applies custom highlights for component +local function apply_highlights(status, options) + if options.color_highlight then + status = highlight.component_format_highlight(options.color_highlight) .. status + end + return status +end + +-- Apply icon in front of component +local function apply_icon(status, options) + if options.icons_enabled and options.icon then + status = options.icon .. ' ' .. status + end + return status +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 + end + return status +end + +-- Returns formated string for a section +function M.draw_section(section, highlight) + local status = {} + 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 + -- 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 + 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) + end + break + end + end + return status_str +end + + +return M diff --git a/lua/lualine/utils.lua b/lua/lualine/utils/cterm_colors.lua similarity index 95% rename from lua/lualine/utils.lua rename to lua/lualine/utils/cterm_colors.lua index 8bedb5e..71bae5a 100644 --- a/lua/lualine/utils.lua +++ b/lua/lualine/utils/cterm_colors.lua @@ -1,25 +1,8 @@ --- Copyright (c) 2020-2021 hoob3rt +-- Copyright (c) 2020-2021 shadmansaleh -- MIT license, see LICENSE for more details. -local M = { } +local M = {} -function M.draw_section(section, separator) - local status = {} - for _, status_function in pairs(section) do - local localstatus = status_function() - if #localstatus > 0 then - table.insert(status, localstatus) - end - end - if #status == 0 then - return '' - end - local sep = ' ' - if #separator > 0 then - sep = ' ' .. separator .. ' ' - end - return ' ' .. table.concat(status, sep) .. ' ' -end -- color conversion local color_table = { @@ -317,5 +300,4 @@ function M.get_cterm_color(hex_color) return closest_cterm_color end - return M diff --git a/lua/lualine/utils/utils.lua b/lua/lualine/utils/utils.lua new file mode 100644 index 0000000..5b984be --- /dev/null +++ b/lua/lualine/utils/utils.lua @@ -0,0 +1,17 @@ +-- Copyright (c) 2020-2021 shadmansaleh +-- MIT license, see LICENSE for more details. + +local M = {} + +-- Works as a decorator to expand set_lualine_theme functions +-- 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() + set_theme() + func() + end +end + +return M