From c030a380ef697dad7ff099f3343830c2d64a1ccd Mon Sep 17 00:00:00 2001 From: shadmansaleh <13149513+shadmansaleh@users.noreply.github.com> Date: Thu, 25 Nov 2021 12:57:00 +0600 Subject: [PATCH] feat: add support for inline custom components --- lua/lualine/component.lua | 2 ++ lua/lualine/config.lua | 12 ++++++----- lua/lualine/utils/loader.lua | 12 ++++++++--- lua/lualine/utils/utils.lua | 42 ++++++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 8 deletions(-) diff --git a/lua/lualine/component.lua b/lua/lualine/component.lua index 853ec9a..a9c25fb 100644 --- a/lua/lualine/component.lua +++ b/lua/lualine/component.lua @@ -18,6 +18,8 @@ function M:__tostring() return str end +M.__is_lualine_component = true + ---initialize new component ---@param options table options for component function M:init(options) diff --git a/lua/lualine/config.lua b/lua/lualine/config.lua index fc794e2..10ead32 100644 --- a/lua/lualine/config.lua +++ b/lua/lualine/config.lua @@ -1,5 +1,7 @@ -- Copyright (c) 2020-2021 hoob3rt -- MIT license, see LICENSE for more details. +local utils = require 'lualine.utils.utils' + local config = { options = { icons_enabled = true, @@ -46,7 +48,7 @@ end ---@return table copy of config local function apply_configuration(config_table) if not config_table then - return vim.deepcopy(config) + return utils.deepcopy(config) end local function parse_sections(section_group_name) if config_table[section_group_name] == nil then @@ -57,7 +59,7 @@ local function apply_configuration(config_table) return end for section_name, section in pairs(config_table[section_group_name]) do - config[section_group_name][section_name] = vim.deepcopy(section) + config[section_group_name][section_name] = utils.deepcopy(section) end end parse_sections 'options' @@ -65,17 +67,17 @@ local function apply_configuration(config_table) parse_sections 'inactive_sections' parse_sections 'tabline' if config_table.extensions then - config.extensions = vim.deepcopy(config_table.extensions) + config.extensions = utils.deepcopy(config_table.extensions) end config.options.section_separators = fix_separators(config.options.section_separators) config.options.component_separators = fix_separators(config.options.component_separators) - return vim.deepcopy(config) + return utils.deepcopy(config) end --- returns current active config ---@return table a copy of config local function get_current_config() - return vim.deepcopy(config) + return utils.deepcopy(config) end return { diff --git a/lua/lualine/utils/loader.lua b/lua/lualine/utils/loader.lua index 5b37bbf..258982a 100644 --- a/lua/lualine/utils/loader.lua +++ b/lua/lualine/utils/loader.lua @@ -4,6 +4,7 @@ local lualine_require = require 'lualine_require' local require = lualine_require.require local modules = lualine_require.lazy_require { + utils = 'lualine.utils.utils', notice = 'lualine.utils.notices', } local is_valid_filename = lualine_require.is_valid_filename @@ -11,6 +12,10 @@ local sep = lualine_require.sep --- function that loads specific type of component local component_types = { + -- loads custion component + custom = function(component) + return component[1](component) + end, --- loads lua functions as component lua_fun = function(component) return require 'lualine.components.special.function_component'(component) @@ -53,8 +58,7 @@ local component_types = { local function component_loader(component) if type(component[1]) == 'function' then return component_types.lua_fun(component) - end - if type(component[1]) == 'string' then + elseif type(component[1]) == 'string' then -- load the component if component.type ~= nil then if component_types[component.type] and component.type ~= 'lua_fun' then @@ -81,6 +85,8 @@ component type '%s' isn't recognised. Check if spelling is correct.]], else return component_types['_'](component) end + elseif type(component[1]) == 'table' then + return component_types.custom(component) end end @@ -168,7 +174,7 @@ end local function load_sections(sections, options) for section_name, section in pairs(sections) do for index, component in pairs(section) do - if type(component) == 'string' or type(component) == 'function' then + if (type(component) == 'string' or type(component) == 'function') or modules.utils.is_component(component) then component = { component } end if is_valid_component_type(index, component) then diff --git a/lua/lualine/utils/utils.lua b/lua/lualine/utils/utils.lua index b089601..d2a7eca 100644 --- a/lua/lualine/utils/utils.lua +++ b/lua/lualine/utils/utils.lua @@ -101,4 +101,46 @@ function M.charAt(str, pos) return string.char(str:byte(pos)) end +-- deepcopy adapted from penlight +-- https://github.com/lunarmodules/Penlight/blob/0653cdb05591454a9804a7fee8c873b8f06b0b8f/lua/pl/tablex.lua#L98-L122 +local function cycle_aware_copy(t, cache) + if type(t) ~= 'table' then + return t + end + if cache[t] then + return cache[t] + end + local res = {} + cache[t] = res + local mt = getmetatable(t) + for k, v in pairs(t) do + k = cycle_aware_copy(k, cache) + v = cycle_aware_copy(v, cache) + res[k] = v + end + setmetatable(res, mt) + return res +end + +--- make a deep copy of a table, recursively copying all the keys and fields. +-- This supports cycles in tables; cycles will be reproduced in the copy. +-- This will also set the copied table's metatable to that of the original. +-- @within Copying +-- @tab t A table +-- @return new table +function M.deepcopy(t) + return cycle_aware_copy(t, {}) +end + +--- Check if comp is a lualine component +--- @param comp any +--- @return boolean +function M.is_component(comp) + if type(comp) ~= 'table' then + return false + end + local mt = getmetatable(comp) + return mt and mt.__is_lualine_component == true +end + return M