From ee5c56e911dbf65dbcbf845a94c2b679673977c6 Mon Sep 17 00:00:00 2001 From: shadmansaleh <13149513+shadmansaleh@users.noreply.github.com> Date: Sat, 14 Aug 2021 20:22:52 +0600 Subject: [PATCH] enhance: Allow external sources to overwrite components and extensions this is like the themes now . If some component/extension found in both lualine repo and in some other rtp path then the one outside the repo will be loaded. + Added better error handling for extensions. --- lua/lualine/utils/loader.lua | 113 ++++++++++++++++++++++++++--------- 1 file changed, 84 insertions(+), 29 deletions(-) diff --git a/lua/lualine/utils/loader.lua b/lua/lualine/utils/loader.lua index de90993..c5adb51 100644 --- a/lua/lualine/utils/loader.lua +++ b/lua/lualine/utils/loader.lua @@ -1,23 +1,81 @@ -- Copyright (c) 2020-2021 hoob3rt -- MIT license, see LICENSE for more details. +local notice = require'lualine.utils.notices' + +local function lualine_load(patern, use_cache) + local retval, cache_name = nil, nil + local sep = package.config:sub(1,1) + + if use_cache == true then + -- Turn {lua, lualine, module, name} -> lualine.module.name + -- same formst that require uses + -- then check if it's in requires cache + local copy_patern = {} + local start = patern[1] == 'lua' and 2 or 1 + local copy_start = 1 + for i=start, #patern do + copy_patern[copy_start] = patern[i] + copy_start = copy_start + 1 + end + cache_name = table.concat(copy_patern, '.') + if package.loaded[cache_name] then + return package.loaded[cache_name] + end + end + + -- Get all the runtime files that match the patern + local files = vim.fn.uniq(vim.api.nvim_get_runtime_file( + table.concat(patern, sep)..'.lua', true)) + local n_files = #files + + if n_files == 0 then + -- No match found + error(table.concat(patern, sep) .. " Not found") + elseif n_files == 1 then + -- when only one is found run that and return it's return value + retval = dofile(files[1]) + else + -- More then 1 found . Use the first one that isn't in lualines repo + local lualine_repo_pattern = table.concat({'lualine.nvim', 'lua', 'lualine'}, sep) + local file_found = false + for _, file in ipairs(files) do + if not file:find(lualine_repo_pattern) then + retval = dofile(file) + file_found = true + break + end + end + if not file_found then + -- This shouldn't happen but somehow we have multiple files but they + -- apear to be in lualines repo . Just run the first one + retval = dofile(files[1]) + end + end + + if use_cache == true and cache_name then + package.loaded[cache_name] = retval + end + return retval +end + local function component_loader(component) if type(component[1]) == 'function' then return - require 'lualine.components.special.function_component':new(component) + lualine_load({'lua', 'lualine', 'components', 'special', 'function_component'}, true):new(component) end if type(component[1]) == 'string' then -- load the component - local ok, loaded_component = pcall(require, - 'lualine.components.' .. component[1]) + local ok, loaded_component = pcall(lualine_load, + {'lua', 'lualine', 'components', component[1]}, true) if ok then component.component_name = component[1] loaded_component = loaded_component:new(component) elseif component[1]:find('[gvtwb]?o?:') == 1 then loaded_component = - require 'lualine.components.special.vim_var_component':new(component) + lualine_load({'lua', 'lualine', 'components', 'special', 'vim_var_component'}, true):new(component) else loaded_component = - require 'lualine.components.special.eval_func_component':new(component) + lualine_load({'lua', 'lualine', 'components', 'special', 'eval_func_component'}, true):new(component) end return loaded_component end @@ -45,17 +103,26 @@ local function load_components(config) end local function load_extensions(config) - for index, extension in pairs(config.extensions) do + local loaded_extensions = {} + for _, extension in pairs(config.extensions) do if type(extension) == 'string' then - local local_extension = vim.deepcopy(require('lualine.extensions.' .. extension)) - load_sections(local_extension.sections, config.options) - if local_extension.inactive_sections then - load_sections(local_extension.inactive_sections, config.options) + local ok, local_extension = pcall(lualine_load, {'lua', 'lualine', 'extensions', extension}, true) + if ok then + local_extension = vim.deepcopy(local_extension) + load_sections(local_extension.sections, config.options) + if local_extension.inactive_sections then + load_sections(local_extension.inactive_sections, config.options) + end + if type(local_extension.init) == 'function' then + local_extension.init() + end + table.insert(loaded_extensions, local_extension) + else + notice.add_notice(string.format([[ +### Extensions +Extension named `%s` was not found . Check if spelling is correct. +]], extension)) end - if type(local_extension.init) == 'function' then - local_extension.init() - end - config.extensions[index] = local_extension elseif type(extension) == 'table' then local local_extension = vim.deepcopy(extension) load_sections(local_extension.sections, config.options) @@ -65,9 +132,10 @@ local function load_extensions(config) if type(local_extension.init) == 'function' then local_extension.init() end - config.extensions[index] = local_extension + table.insert(loaded_extensions, local_extension) end end + config.extensions = loaded_extensions end local function load_all(config) @@ -75,21 +143,8 @@ local function load_all(config) load_extensions(config) end -local function load(patern) - local files = vim.fn.uniq(vim.api.nvim_get_runtime_file(patern, true)) - local n_files = #files - if n_files == 0 then return nil - elseif n_files == 1 then return dofile(files[1]) - else - for _, file in ipairs(files) do - if not file:find('lualine.nvim') then return dofile(file) end - end - end -end - local function load_theme(theme_name) - return load(table.concat( - {'lua', 'lualine', 'themes', theme_name..'.lua'}, package.config:sub(1, 1))) + return lualine_load({'lua', 'lualine', 'themes', theme_name}, false) end return {