lualine.nvim/lua/lualine/utils/loader.lua

257 lines
8.5 KiB
Lua
Raw Normal View History

-- Copyright (c) 2020-2021 hoob3rt
-- MIT license, see LICENSE for more details.
local lualine_require = require('lualine_require')
local require = lualine_require.require
2022-02-01 08:04:03 +00:00
local modules = lualine_require.lazy_require {
utils = 'lualine.utils.utils',
notice = 'lualine.utils.notices',
fn_store = 'lualine.utils.fn_store',
2022-02-01 08:04:03 +00:00
}
local is_valid_filename = lualine_require.is_valid_filename
local sep = lualine_require.sep
2021-10-12 14:04:47 +00:00
--- function that loads specific type of component
local component_types = {
-- loads custom component
custom = function(component)
return component[1](component)
end,
2021-10-12 14:04:47 +00:00
--- loads lua functions as component
lua_fun = function(component)
return require('lualine.components.special.function_component')(component)
end,
2021-10-12 14:04:47 +00:00
--- loads lua modules as components (ones in /lua/lualine/components/)
mod = function(component)
local ok, loaded_component = pcall(require, 'lualine.components.' .. component[1])
if ok then
component.component_name = component[1]
if type(loaded_component) == 'table' then
loaded_component = loaded_component(component)
elseif type(loaded_component) == 'function' then
component[1] = loaded_component
loaded_component = require('lualine.components.special.function_component')(component)
end
return loaded_component
end
end,
2021-10-12 14:04:47 +00:00
--- loads builtin statusline patterns as component
stl = function(component)
local stl_expr = component[1] -- Vim's %p %l statusline elements
component[1] = function()
return stl_expr
end
return require('lualine.components.special.function_component')(component)
end,
--- loads variables & options (g:,go:,b:,bo:...) as components
var = function(component)
return require('lualine.components.special.vim_var_component')(component)
end,
2021-10-12 14:04:47 +00:00
--- loads vim functions and lua expressions as components
['_'] = function(component)
return require('lualine.components.special.eval_func_component')(component)
end,
}
---load a component from component config
2021-10-12 14:04:47 +00:00
---@param component table component + component options
---@return table the loaded & initialized component
local function component_loader(component)
if type(component[1]) == 'function' then
return component_types.lua_fun(component)
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
return component_types[component.type](component)
elseif component.type == 'vim_fun' or component.type == 'lua_expr' then
return component_types['_'](component)
else
modules.notice.add_notice(string.format(
[[
### component.type
component type '%s' isn't recognised. Check if spelling is correct.]],
component.type
))
end
end
local loaded_component = component_types.mod(component)
if loaded_component then
return loaded_component
elseif string.char(component[1]:byte(1)) == '%' then
return component_types.stl(component)
elseif component[1]:find('[gvtwb]?o?:') == 1 then
return component_types.var(component)
else
return component_types['_'](component)
end
elseif type(component[1]) == 'table' then
return component_types.custom(component)
end
end
--- Shows notice about invalid types passed as component
--- @param index number the index of component in section table
--- @param component table containing component elements
--- return bool whether check passed or not
local function is_valid_component_type(index, component)
if type(component_types) == 'table' and type(index) == 'number' then
return true
end
modules.notice.add_notice(string.format(
[[
### Unrecognized component
Only functions, strings and tables can be used as component.
You seem to have a `%s` as component indexed as `%s`.
Something like:
```lua
%s = %s,
```
This commonly occurs when you forget to pass table with option for component.
When a component has option that component needs to be a table which holds
the component as first element and the options as key value pairs.
For example:
```lua
lualine_c = {
{'diagnostics',
sources = {'nvim'},
}
}
```
Notice the inner extra {} surrounding the component and it's options.
Make sure your config follows this.
]],
type(component),
index,
index,
vim.inspect(component)
))
return false
end
2021-10-12 14:04:47 +00:00
---loads all the section from a config
---@param sections table list of sections
---@param options table global options table
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') or modules.utils.is_component(component) then
component = { component }
end
if is_valid_component_type(index, component) then
component.self = {}
component.self.section = section_name:match('lualine_(.*)')
-- apply default args
component = vim.tbl_extend('keep', component, options)
section[index] = component_loader(component)
end
end
end
end
2021-10-12 14:04:47 +00:00
---loads all the configs (active, inactive, tabline)
---@param config table user config
local function load_components(config)
2022-07-22 13:30:37 +00:00
local sec_names = { 'sections', 'inactive_sections', 'tabline', 'winbar', 'inactive_winbar' }
for _, section in ipairs(sec_names) do
load_sections(config[section], config.options)
end
end
2021-10-12 14:04:47 +00:00
---loads all the extensions
---@param config table user config
local function load_extensions(config)
local loaded_extensions = {}
2022-07-22 13:30:37 +00:00
local sec_names = { 'sections', 'inactive_sections', 'winbar', 'inactive_winbar' }
for _, extension in pairs(config.extensions) do
2021-05-14 18:24:54 +00:00
if type(extension) == 'string' then
local ok
ok, extension = pcall(require, 'lualine.extensions.' .. extension)
if not ok then
modules.notice.add_notice(string.format(
[[
### Extensions
Extension named `%s` was not found . Check if spelling is correct.
]],
extension
))
2021-08-13 01:20:56 +00:00
end
end
if type(extension) == 'table' then
local local_extension = modules.utils.deepcopy(extension)
for _, section in ipairs(sec_names) do
if local_extension[section] then
load_sections(local_extension[section], config.options)
end
end
2021-08-13 01:20:56 +00:00
if type(local_extension.init) == 'function' then
local_extension.init()
end
table.insert(loaded_extensions, local_extension)
2021-05-14 18:24:54 +00:00
end
end
config.extensions = loaded_extensions
end
2021-10-12 14:04:47 +00:00
---loads sections and extensions or entire user config
---@param config table user config
local function load_all(config)
require('lualine.component')._reset_components()
modules.fn_store.clear_fns()
require('lualine.utils.nvim_opts').reset_cache()
load_components(config)
load_extensions(config)
end
2021-10-12 14:04:47 +00:00
---loads a theme from lua module
---prioritizes external themes (from user config or other plugins) over the bundled ones
2021-10-12 14:04:47 +00:00
---@param theme_name string
---@return table theme definition from module
local function load_theme(theme_name)
assert(is_valid_filename(theme_name), 'Invalid filename')
local retval
2022-02-01 08:04:03 +00:00
local path = table.concat { 'lua/lualine/themes/', theme_name, '.lua' }
local files = vim.api.nvim_get_runtime_file(path, true)
if #files <= 0 then
2022-02-01 08:04:03 +00:00
path = table.concat { 'lua/lualine/themes/', theme_name, '/init.lua' }
files = vim.api.nvim_get_runtime_file(path, true)
end
local n_files = #files
if n_files == 0 then
-- No match found
error(path .. ' 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
-- put entries from user config path in front
local user_config_path = vim.fn.stdpath('config')
table.sort(files, function(a, b)
return vim.startswith(a, user_config_path) or not vim.startswith(b, user_config_path)
end)
-- 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
return retval
end
return {
load_all = load_all,
load_theme = load_theme,
}